diff --git a/CMakeLists.txt b/CMakeLists.txt
index 88187ff9..021378f9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,106 +1,106 @@
 cmake_minimum_required(VERSION 3.5)
-set(PIM_VERSION "5.15.81")
+set(PIM_VERSION "5.15.82")
 
 project(libkleo VERSION ${PIM_VERSION})
 
 set(KF5_MIN_VERSION "5.75.0")
 
 if (WIN32)
   set(KF5_WANT_VERSION "5.70.0")
 else ()
   set(KF5_WANT_VERSION ${KF5_MIN_VERSION})
 endif ()
 
 find_package(ECM ${KF5_WANT_VERSION} CONFIG REQUIRED)
 set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
 
 include(KDEInstallDirs)
 include(KDECMakeSettings)
 include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE)
 
 include(GenerateExportHeader)
 include(ECMSetupVersion)
 include(ECMGenerateHeaders)
 include(ECMGeneratePriFile)
 
 include(FeatureSummary)
 include(ECMQtDeclareLoggingCategory)
 include(ECMAddTests)
 
 
 
 set(LIBKLEO_LIB_VERSION ${PIM_VERSION})
 set(QT_REQUIRED_VERSION "5.13.0")
 set(KDEPIMTEXTEDIT_VERSION "5.15.40")
 
 find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Widgets)
 find_package(KF5I18n ${KF5_WANT_VERSION} CONFIG REQUIRED)
 find_package(KF5Config ${KF5_WANT_VERSION} CONFIG REQUIRED)
 find_package(KF5WidgetsAddons ${KF5_WANT_VERSION} CONFIG REQUIRED)
 find_package(KF5Completion ${KF5_WANT_VERSION} CONFIG REQUIRED)
 find_package(KF5CoreAddons ${KF5_WANT_VERSION} CONFIG REQUIRED)
 find_package(KF5Codecs ${KF5_WANT_VERSION} CONFIG REQUIRED)
 find_package(KF5ItemModels ${KF5_WANT_VERSION} CONFIG REQUIRED)
 find_package(KF5PimTextEdit ${KDEPIMTEXTEDIT_VERSION} CONFIG)
 
 set(GPGMEPP_LIB_VERSION "1.11.1")
 find_package(Gpgmepp ${GPGMEPP_LIB_VERSION} CONFIG REQUIRED)
 set_package_properties(Gpgmepp PROPERTIES DESCRIPTION "GpgME++ Library" URL "https://www.gnupg.org" TYPE REQUIRED PURPOSE "GpgME++ is required for OpenPGP support")
 find_package(QGpgme ${GPGMEPP_LIB_VERSION} CONFIG REQUIRED)
 message(STATUS "GPGME Version ${Gpgmepp_VERSION}")
 
 find_package(Boost 1.34.0)
 set_package_properties(Boost PROPERTIES DESCRIPTION "Boost C++ Libraries" URL "https://www.boost.org" TYPE REQUIRED PURPOSE "Boost is required for building most KDEPIM applications")
 
 
 set_package_properties(KF5PimTextEdit PROPERTIES DESCRIPTION
                        "A textedit with PIM-specific features."
                        URL "https://commits.kde.org/kpimtextedit"
                        TYPE OPTIONAL PURPOSE "Improved audit log viewer.")
 
 ecm_setup_version(PROJECT VARIABLE_PREFIX LIBKLEO
                         VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/libkleo_version.h"
                         PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5LibkleoConfigVersion.cmake"
                         SOVERSION 5
 )
 
 ########### Targets ###########
 add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0)
 #add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050f00)
 add_definitions(-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x054C00)
 remove_definitions(-DQT_NO_CAST_FROM_ASCII )
 add_definitions(-DQT_NO_EMIT)
 set(CMAKE_CXX_STANDARD 14)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 ########### CMake Config Files ###########
 set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KF5Libkleo")
 
 configure_package_config_file(
   "${CMAKE_CURRENT_SOURCE_DIR}/KF5LibkleoConfig.cmake.in"
   "${CMAKE_CURRENT_BINARY_DIR}/KF5LibkleoConfig.cmake"
   INSTALL_DESTINATION  ${CMAKECONFIG_INSTALL_DIR}
 )
 
 install(FILES
   "${CMAKE_CURRENT_BINARY_DIR}/KF5LibkleoConfig.cmake"
   "${CMAKE_CURRENT_BINARY_DIR}/KF5LibkleoConfigVersion.cmake"
   DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
   COMPONENT Devel
 )
 
 install(EXPORT KF5LibkleoTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KF5LibkleoTargets.cmake NAMESPACE KF5::)
 
 install(FILES
    ${CMAKE_CURRENT_BINARY_DIR}/libkleo_version.h
   DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5} COMPONENT Devel
 )
 
 
 
 add_subdirectory(src)
 ecm_qt_install_logging_categories(
         EXPORT LIBKLEO
         FILE libkleo.categories
         DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}
         )
 feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 776fa2c6..89495ec7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,222 +1,222 @@
 
 # target_include_directories does not handle empty include paths
 include_directories(${GPGME_INCLUDES})
 
 add_definitions(-DTRANSLATION_DOMAIN=\"libkleopatra\")
 
 #add_definitions( -DQT_NO_CAST_FROM_ASCII )
 #add_definitions( -DQT_NO_CAST_TO_ASCII )
 
 kde_enable_exceptions()
 
 add_definitions( -DGPGMEPP_ERR_SOURCE_DEFAULT=13 ) # 13 is GPG_ERR_SOURCE_KLEO, even if gpg-error's too old to know about
 
 add_subdirectory( pics )
 if (BUILD_TESTING)
    add_subdirectory( tests )
 endif()
 
 ########### next target ###############
 set(libkleo_core_SRCS
    kleo/checksumdefinition.cpp
    kleo/defaultkeyfilter.cpp
    kleo/defaultkeygenerationjob.cpp
    kleo/dn.cpp
    kleo/enum.cpp
-   kleo/exception.cpp
    kleo/kconfigbasedkeyfilter.cpp
    kleo/keyfiltermanager.cpp
    kleo/keyresolver.cpp
+   kleo/kleoexception.cpp
    models/keycache.cpp
    models/keylistmodel.cpp
    models/keylistsortfilterproxymodel.cpp
    models/keyrearrangecolumnsproxymodel.cpp
    models/subkeylistmodel.cpp
    models/useridlistmodel.cpp
    utils/filesystemwatcher.cpp
    utils/formatting.cpp
    utils/classify.cpp
    utils/gnupg.cpp
    utils/gnupg-registry.c
    utils/hex.cpp
    )
 ecm_qt_declare_logging_category(libkleo_core_SRCS HEADER libkleo_debug.h IDENTIFIER LIBKLEO_LOG CATEGORY_NAME org.kde.pim.libkleo
         DESCRIPTION "libkleo (kleo_core)"
         EXPORT LIBKLEO
     )
 
 
 set(libkleo_ui_common_SRCS
    ui/dnattributeorderconfigwidget.cpp
    ui/kdhorizontalline.cpp
    ui/filenamerequester.cpp
    ui/messagebox.cpp
    ui/cryptoconfigmodule.cpp
    ui/cryptoconfigdialog.cpp
    ui/directoryserviceswidget.cpp
    ui/progressbar.cpp
    ui/progressdialog.cpp
    ui/auditlogviewer.cpp
    )
 
 ecm_qt_declare_logging_category(libkleo_ui_common_SRCS HEADER kleo_ui_debug.h IDENTIFIER KLEO_UI_LOG CATEGORY_NAME org.kde.pim.kleo_ui
         DESCRIPTION "libkleo (kleo_ui)"
         OLD_CATEGORY_NAMES log_kleo_ui
         EXPORT LIBKLEO
     )
 
 
 set(libkleo_ui_SRCS    # make this a separate lib.
     ui/keylistview.cpp
     ui/keyselectiondialog.cpp
     ui/keyrequester.cpp
     ui/keyapprovaldialog.cpp
     ui/newkeyapprovaldialog.cpp
     ui/keyselectioncombo.cpp
     )
 
 ki18n_wrap_ui(libkleo_ui_common_SRCS
     ui/directoryserviceswidget.ui
 )
 
 set(kleo_LIB_SRCS ${libkleo_core_SRCS} ${libkleo_ui_SRCS}
                                        ${libkleo_ui_common_SRCS})
 
 set(kleo_LIB_LIBS PUBLIC QGpgme Gpgmepp PRIVATE Qt5::Widgets
                                                 KF5::I18n
                                                 KF5::Completion
                                                 KF5::ConfigCore
                                                 KF5::CoreAddons
                                                 KF5::WidgetsAddons
                                                 KF5::ItemModels
                                                 KF5::Codecs)
 
 if (KF5PimTextEdit_FOUND)
   add_definitions(-DHAVE_PIMTEXTEDIT)
   set(kleo_LIB_LIBS ${kleo_LIB_LIBS} PRIVATE KF5::PimTextEdit)
 endif()
 
 add_library(KF5Libkleo ${kleo_LIB_SRCS})
 generate_export_header(KF5Libkleo BASE_NAME kleo)
 add_library(KF5::Libkleo ALIAS KF5Libkleo)
 if(WIN32)
 target_link_libraries(KF5Libkleo ${kleo_LIB_LIBS}  ${GPGME_VANILLA_LIBRARIES} )
 else()
 target_link_libraries(KF5Libkleo ${kleo_LIB_LIBS} )
 endif()
 
 set_target_properties(KF5Libkleo PROPERTIES
     VERSION ${LIBKLEO_VERSION_STRING}
     SOVERSION ${LIBKLEO_SOVERSION}
     EXPORT_NAME Libkleo
 )
 
 install(TARGETS
     KF5Libkleo
     EXPORT KF5LibkleoTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS}
 )
 
 
 
 target_include_directories(KF5Libkleo PUBLIC "$<BUILD_INTERFACE:${libkleo_SOURCE_DIR}/src;${libkleo_BINARY_DIR}/src>")
 target_include_directories(KF5Libkleo INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF5}/Libkleo/;${KDE_INSTALL_INCLUDEDIR_KF5}/libkleo>")
 
 ecm_generate_headers(libkleo_CamelCase_HEADERS
   HEADER_NAMES
   ChecksumDefinition
   DefaultKeyFilter
   DefaultKeyGenerationJob
   Dn
   Enum
-  Exception
   KConfigBasedKeyFilter
   KeyFilter
   KeyFilterManager
   KeyResolver
+  KleoException
   OidMap
   Predicates
   Stl_Util
   REQUIRED_HEADERS libkleo_HEADERS
   PREFIX Libkleo
   RELATIVE kleo
 )
 
 ecm_generate_headers(libkleo_CamelCase_models_HEADERS
   HEADER_NAMES
   KeyCache
   KeyListModel
   KeyListModelInterface
   KeyListSortFilterProxyModel
   KeyRearrangeColumnsProxyModel
   SubkeyListModel
   UserIDListModel
   REQUIRED_HEADERS libkleo_models_HEADERS
   PREFIX Libkleo
   RELATIVE models
 )
 
 ecm_generate_headers(libkleo_CamelCase_utils_HEADERS
   HEADER_NAMES
   Classify
   FileSystemWatcher
   Formatting
   GnuPG
   REQUIRED_HEADERS libkleo_utils_HEADERS
   PREFIX Libkleo
   RELATIVE utils
 )
 
 ecm_generate_headers(libkleo_CamelCase_ui_HEADERS
   HEADER_NAMES
   CryptoConfigDialog
   CryptoConfigModule
   DNAttributeOrderConfigWidget
   DirectoryServicesWidget
   FileNameRequester
   KDHorizontalLine
   KeyApprovalDialog
   NewKeyApprovalDialog
   KeyRequester
   KeySelectionCombo
   KeySelectionDialog
   MessageBox
   ProgressDialog
   REQUIRED_HEADERS libkleo_ui_HEADERS
   PREFIX Libkleo
   RELATIVE ui
 )
 
 ecm_generate_pri_file(BASE_NAME Libkleo
     LIB_NAME KF5Libkleo
     DEPS "QGpgme" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/Libkleo
 )
 
 
 install(FILES
     ${libkleo_CamelCase_HEADERS}
     ${libkleo_CamelCase_models_HEADERS}
     ${libkleo_CamelCase_ui_HEADERS}
     ${libkleo_CamelCase_utils_HEADERS}
     DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/Libkleo
     COMPONENT Devel
 )
 
 install(FILES
     ${CMAKE_CURRENT_BINARY_DIR}/kleo_export.h
     ${libkleo_HEADERS}
     ${libkleo_models_HEADERS}
     ${libkleo_ui_HEADERS}
     ${libkleo_utils_HEADERS}
     DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/libkleo
     COMPONENT Devel
 )
 install(FILES
     ${PRI_FILENAME}
     DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
 
 
 if ( WIN32 )
 install ( FILES libkleopatrarc-win32.desktop DESTINATION ${KDE_INSTALL_CONFDIR} RENAME libkleopatrarc )
 else ()
 install ( FILES libkleopatrarc.desktop DESTINATION ${KDE_INSTALL_CONFDIR} RENAME libkleopatrarc )
 endif ()
diff --git a/src/kleo/checksumdefinition.cpp b/src/kleo/checksumdefinition.cpp
index 477384c2..22a94b18 100644
--- a/src/kleo/checksumdefinition.cpp
+++ b/src/kleo/checksumdefinition.cpp
@@ -1,402 +1,402 @@
 /* -*- mode: c++; c-basic-offset:4 -*-
     checksumdefinition.cpp
 
     This file is part of libkleopatra, the KDE keymanagement library
     SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 #include "checksumdefinition.h"
 
-#include "exception.h"
+#include "kleoexception.h"
 
 #include "libkleo_debug.h"
 
 #include <KConfigGroup>
 #include <KLocalizedString>
 #include <KConfig>
 #include <KShell>
 
 #include <QDebug>
 #include <QFileInfo>
 #include <QProcess>
 #include <QByteArray>
 #include <QMutex>
 #include <QCoreApplication>
 #include <QRegularExpression>
 
 #include <KSharedConfig>
 #include <QStandardPaths>
 
 #ifdef stdin
 # undef stdin // pah..
 #endif
 
 using namespace Kleo;
 
 static QMutex installPathMutex;
 Q_GLOBAL_STATIC(QString, _installPath)
 QString ChecksumDefinition::installPath()
 {
     const QMutexLocker locker(&installPathMutex);
     QString *const ip = _installPath();
     if (ip->isEmpty()) {
         if (QCoreApplication::instance()) {
             *ip = QCoreApplication::applicationDirPath();
         } else {
             qCWarning(LIBKLEO_LOG) << "checksumdefinition.cpp: installPath() called before QCoreApplication was constructed";
         }
     }
     return *ip;
 }
 void ChecksumDefinition::setInstallPath(const QString &ip)
 {
     const QMutexLocker locker(&installPathMutex);
     *_installPath() = ip;
 }
 
 // Checksum Definition #N groups
 static const QLatin1String ID_ENTRY("id");
 static const QLatin1String NAME_ENTRY("Name");
 static const QLatin1String CREATE_COMMAND_ENTRY("create-command");
 static const QLatin1String VERIFY_COMMAND_ENTRY("verify-command");
 static const QLatin1String FILE_PATTERNS_ENTRY("file-patterns");
 static const QLatin1String OUTPUT_FILE_ENTRY("output-file");
 static const QLatin1String FILE_PLACEHOLDER("%f");
 static const QLatin1String INSTALLPATH_PLACEHOLDER("%I");
 static const QLatin1String NULL_SEPARATED_STDIN_INDICATOR("0|");
 static const QLatin1Char   NEWLINE_SEPARATED_STDIN_INDICATOR('|');
 
 // ChecksumOperations group
 static const QLatin1String CHECKSUM_DEFINITION_ID_ENTRY("checksum-definition-id");
 
 namespace
 {
 
 class ChecksumDefinitionError : public Kleo::Exception
 {
     const QString m_id;
 public:
     ChecksumDefinitionError(const QString &id, const QString &message)
         : Kleo::Exception(GPG_ERR_INV_PARAMETER, i18n("Error in checksum definition %1: %2", id, message), MessageOnly),
           m_id(id)
     {
 
     }
     ~ChecksumDefinitionError() throw() {}
 
     const QString &checksumDefinitionId() const
     {
         return m_id;
     }
 };
 
 }
 
 static QString try_extensions(const QString &path)
 {
     static const char exts[][4] = {
         "", "exe", "bat", "bin", "cmd",
     };
     static const size_t numExts = sizeof exts / sizeof * exts;
     for (unsigned int i = 0; i < numExts; ++i) {
         const QFileInfo fi(path + QLatin1Char('.') + QLatin1String(exts[i]));
         if (fi.exists()) {
             return fi.filePath();
         }
     }
     return QString();
 }
 
 static void parse_command(QString cmdline, const QString &id, const QString &whichCommand,
                           QString *command, QStringList *prefix, QStringList *suffix, ChecksumDefinition::ArgumentPassingMethod *method)
 {
     Q_ASSERT(prefix);
     Q_ASSERT(suffix);
     Q_ASSERT(method);
 
     KShell::Errors errors;
     QStringList l;
 
     if (cmdline.startsWith(NULL_SEPARATED_STDIN_INDICATOR)) {
         *method = ChecksumDefinition::NullSeparatedInputFile;
         cmdline.remove(0, 2);
     } else if (cmdline.startsWith(NEWLINE_SEPARATED_STDIN_INDICATOR)) {
         *method = ChecksumDefinition::NewlineSeparatedInputFile;
         cmdline.remove(0, 1);
     } else {
         *method = ChecksumDefinition::CommandLine;
     }
     if (*method != ChecksumDefinition::CommandLine && cmdline.contains(FILE_PLACEHOLDER)) {
         throw ChecksumDefinitionError(id, i18n("Cannot use both %f and | in '%1'", whichCommand));
     }
     cmdline.replace(FILE_PLACEHOLDER,        QLatin1String("__files_go_here__"))
     .replace(INSTALLPATH_PLACEHOLDER, QStringLiteral("__path_goes_here__"));
     l = KShell::splitArgs(cmdline, KShell::AbortOnMeta | KShell::TildeExpand, &errors);
     l = l.replaceInStrings(QStringLiteral("__files_go_here__"), FILE_PLACEHOLDER);
     if (l.indexOf(QRegExp(QLatin1String(".*__path_goes_here__.*"))) >= 0) {
         l = l.replaceInStrings(QStringLiteral("__path_goes_here__"), ChecksumDefinition::installPath());
     }
     if (errors == KShell::BadQuoting) {
         throw ChecksumDefinitionError(id, i18n("Quoting error in '%1' entry", whichCommand));
     }
     if (errors == KShell::FoundMeta) {
         throw ChecksumDefinitionError(id, i18n("'%1' too complex (would need shell)", whichCommand));
     }
     qCDebug(LIBKLEO_LOG) << "ChecksumDefinition[" << id << ']' << l;
     if (l.empty()) {
         throw ChecksumDefinitionError(id, i18n("'%1' entry is empty/missing", whichCommand));
     }
     const QFileInfo fi1(l.front());
     if (fi1.isAbsolute()) {
         *command = try_extensions(l.front());
     } else {
         *command = QStandardPaths::findExecutable(fi1.fileName());
     }
     if (command->isEmpty()) {
         throw ChecksumDefinitionError(id, i18n("'%1' empty or not found", whichCommand));
     }
     const int idx1 = l.indexOf(FILE_PLACEHOLDER);
     if (idx1 < 0) {
         // none -> append
         *prefix = l.mid(1);
     } else {
         *prefix = l.mid(1, idx1 - 1);
         *suffix = l.mid(idx1 + 1);
     }
     switch (*method) {
     case ChecksumDefinition::CommandLine:
         qCDebug(LIBKLEO_LOG) << "ChecksumDefinition[" << id << ']' << *command << *prefix << FILE_PLACEHOLDER << *suffix;
         break;
     case ChecksumDefinition::NewlineSeparatedInputFile:
         qCDebug(LIBKLEO_LOG) << "ChecksumDefinition[" << id << ']' << "find | " << *command << *prefix;
         break;
     case ChecksumDefinition::NullSeparatedInputFile:
         qCDebug(LIBKLEO_LOG) << "ChecksumDefinition[" << id << ']' << "find -print0 | " << *command << *prefix;
         break;
     case ChecksumDefinition::NumArgumentPassingMethods:
         Q_ASSERT(!"Should not happen");
         break;
     }
 }
 
 namespace
 {
 
 class KConfigBasedChecksumDefinition : public ChecksumDefinition
 {
 public:
     explicit KConfigBasedChecksumDefinition(const KConfigGroup &group)
         : ChecksumDefinition(group.readEntryUntranslated(ID_ENTRY),
                              group.readEntry(NAME_ENTRY),
                              group.readEntry(OUTPUT_FILE_ENTRY),
                              group.readEntry(FILE_PATTERNS_ENTRY, QStringList()))
     {
         if (id().isEmpty()) {
             throw ChecksumDefinitionError(group.name(), i18n("'id' entry is empty/missing"));
         }
         if (outputFileName().isEmpty()) {
             throw ChecksumDefinitionError(id(), i18n("'output-file' entry is empty/missing"));
         }
         if (patterns().empty()) {
             throw ChecksumDefinitionError(id(), i18n("'file-patterns' entry is empty/missing"));
         }
 
         // create-command
         ArgumentPassingMethod method;
         parse_command(group.readEntry(CREATE_COMMAND_ENTRY), id(), CREATE_COMMAND_ENTRY,
                       &m_createCommand, &m_createPrefixArguments, &m_createPostfixArguments, &method);
         setCreateCommandArgumentPassingMethod(method);
 
         // verify-command
         parse_command(group.readEntry(VERIFY_COMMAND_ENTRY), id(), VERIFY_COMMAND_ENTRY,
                       &m_verifyCommand, &m_verifyPrefixArguments, &m_verifyPostfixArguments, &method);
         setVerifyCommandArgumentPassingMethod(method);
     }
 
 private:
     QString doGetCreateCommand() const override
     {
         return m_createCommand;
     }
     QStringList doGetCreateArguments(const QStringList &files) const override
     {
         return m_createPrefixArguments + files + m_createPostfixArguments;
     }
     QString doGetVerifyCommand() const override
     {
         return m_verifyCommand;
     }
     QStringList doGetVerifyArguments(const QStringList &files) const override
     {
         return m_verifyPrefixArguments + files + m_verifyPostfixArguments;
     }
 
 private:
     QString m_createCommand, m_verifyCommand;
     QStringList m_createPrefixArguments, m_createPostfixArguments;
     QStringList m_verifyPrefixArguments, m_verifyPostfixArguments;
 };
 
 }
 
 ChecksumDefinition::ChecksumDefinition(const QString &id, const QString &label, const QString &outputFileName, const QStringList &patterns)
     : m_id(id),
       m_label(label.isEmpty() ? id : label),
       m_outputFileName(outputFileName),
       m_patterns(patterns),
       m_createMethod(CommandLine),
       m_verifyMethod(CommandLine)
 {
 
 }
 
 ChecksumDefinition::~ChecksumDefinition() {}
 
 QString ChecksumDefinition::createCommand() const
 {
     return doGetCreateCommand();
 }
 
 QString ChecksumDefinition::verifyCommand() const
 {
     return doGetVerifyCommand();
 }
 
 #if 0
 QStringList ChecksumDefinition::createCommandArguments(const QStringList &files) const
 {
     return doGetCreateArguments(files);
 }
 
 QStringList ChecksumDefinition::verifyCommandArguments(const QStringList &files) const
 {
     return doGetVerifyArguments(files);
 }
 #endif
 
 static QByteArray make_input(const QStringList &files, char sep)
 {
     QByteArray result;
     for (const QString &file : files) {
         result += QFile::encodeName(file);
         result += sep;
     }
     return result;
 }
 
 static bool start_command(QProcess *p, const char *functionName,
                           const QString &cmd, const QStringList &args,
                           const QStringList &files, ChecksumDefinition::ArgumentPassingMethod method)
 {
     if (!p) {
         qCWarning(LIBKLEO_LOG) << functionName << ": process == NULL";
         return false;
     }
 
     switch (method) {
 
     case ChecksumDefinition::NumArgumentPassingMethods:
         Q_ASSERT(!"Should not happen");
 
     case ChecksumDefinition::CommandLine:
         qCDebug(LIBKLEO_LOG) << "Starting: " << cmd << " " << args.join(QLatin1Char(' '));
         p->start(cmd, args, QIODevice::ReadOnly);
         return true;
 
     case ChecksumDefinition::NewlineSeparatedInputFile:
     case ChecksumDefinition::NullSeparatedInputFile:
         qCDebug(LIBKLEO_LOG) << "Starting: " << cmd << " " << args.join(QLatin1Char(' '));
         p->start(cmd, args, QIODevice::ReadWrite);
         if (!p->waitForStarted()) {
             return false;
         }
         const char sep =
             method == ChecksumDefinition::NewlineSeparatedInputFile ? '\n' :
             /* else */                            '\0';
         const QByteArray stdin = make_input(files, sep);
         if (p->write(stdin) != stdin.size()) {
             return false;
         }
         p->closeWriteChannel();
         return true;
     }
 
     return false; // make compiler happy
 
 }
 
 bool ChecksumDefinition::startCreateCommand(QProcess *p, const QStringList &files) const
 {
     return start_command(p, Q_FUNC_INFO,
                          doGetCreateCommand(),
                          m_createMethod == CommandLine ? doGetCreateArguments(files) :
                          /* else */                      doGetCreateArguments(QStringList()),
                          files, m_createMethod);
 }
 
 bool ChecksumDefinition::startVerifyCommand(QProcess *p, const QStringList &files) const
 {
     return start_command(p, Q_FUNC_INFO,
                          doGetVerifyCommand(),
                          m_verifyMethod == CommandLine ? doGetVerifyArguments(files) :
                          /* else */                      doGetVerifyArguments(QStringList()),
                          files, m_verifyMethod);
 }
 
 // static
 std::vector< std::shared_ptr<ChecksumDefinition> > ChecksumDefinition::getChecksumDefinitions()
 {
     QStringList errors;
     return getChecksumDefinitions(errors);
 }
 
 // static
 std::vector< std::shared_ptr<ChecksumDefinition> > ChecksumDefinition::getChecksumDefinitions(QStringList &errors)
 {
     std::vector< std::shared_ptr<ChecksumDefinition> > result;
     KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("libkleopatrarc"));
     const QStringList groups = config->groupList().filter(QRegularExpression(QStringLiteral("^Checksum Definition #")));
     result.reserve(groups.size());
     for (const QString &group : groups)
         try {
             const std::shared_ptr<ChecksumDefinition> ad(new KConfigBasedChecksumDefinition(KConfigGroup(config, group)));
             result.push_back(ad);
         } catch (const std::exception &e) {
             qDebug() << e.what();
             errors.push_back(QString::fromLocal8Bit(e.what()));
         } catch (...) {
             errors.push_back(i18n("Caught unknown exception in group %1", group));
         }
     return result;
 }
 
 // static
 std::shared_ptr<ChecksumDefinition> ChecksumDefinition::getDefaultChecksumDefinition(const std::vector< std::shared_ptr<ChecksumDefinition> > &checksumDefinitions)
 {
     const KConfigGroup group(KSharedConfig::openConfig(), "ChecksumOperations");
     const QString checksumDefinitionId = group.readEntry(CHECKSUM_DEFINITION_ID_ENTRY, QStringLiteral("sha256sum"));
 
     if (!checksumDefinitionId.isEmpty())
         for (const std::shared_ptr<ChecksumDefinition> &cd : checksumDefinitions)
             if (cd && cd->id() == checksumDefinitionId) {
                 return cd;
             }
     if (!checksumDefinitions.empty()) {
         return checksumDefinitions.front();
     } else {
         return std::shared_ptr<ChecksumDefinition>();
     }
 }
 
 // static
 void ChecksumDefinition::setDefaultChecksumDefinition(const std::shared_ptr<ChecksumDefinition> &checksumDefinition)
 {
     if (!checksumDefinition) {
         return;
     }
     KConfigGroup group(KSharedConfig::openConfig(), "ChecksumOperations");
     group.writeEntry(CHECKSUM_DEFINITION_ID_ENTRY, checksumDefinition->id());
     group.sync();
 }
diff --git a/src/kleo/exception.cpp b/src/kleo/kleoexception.cpp
similarity index 91%
rename from src/kleo/exception.cpp
rename to src/kleo/kleoexception.cpp
index cbe0f444..074c0550 100644
--- a/src/kleo/exception.cpp
+++ b/src/kleo/kleoexception.cpp
@@ -1,12 +1,12 @@
 /* -*- mode: c++; c-basic-offset:4 -*-
     exception.cpp
 
     This file is part of libkleopatra, the KDE keymanagement library
     SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
-#include "exception.h"
+#include "kleoexception.h"
 
 Kleo::Exception::~Exception() throw() {}
diff --git a/src/kleo/exception.h b/src/kleo/kleoexception.h
similarity index 100%
rename from src/kleo/exception.h
rename to src/kleo/kleoexception.h
diff --git a/src/utils/hex.cpp b/src/utils/hex.cpp
index 30eda529..39ec7c6c 100644
--- a/src/utils/hex.cpp
+++ b/src/utils/hex.cpp
@@ -1,130 +1,130 @@
 /* -*- mode: c++; c-basic-offset:4 -*-
     utils/hex.cpp
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 #include "hex.h"
 
-#include <Libkleo/Exception>
+#include "kleo/kleoexception.h"
 
 #include <KLocalizedString>
 
 #include <QString>
 #include <QByteArray>
 
 using namespace Kleo;
 
 static unsigned char unhex(unsigned char ch)
 {
     if (ch >= '0' && ch <= '9') {
         return ch - '0';
     }
     if (ch >= 'A' && ch <= 'F') {
         return ch - 'A' + 10;
     }
     if (ch >= 'a' && ch <= 'f') {
         return ch - 'a' + 10;
     }
     const char cch = ch;
     throw Exception(gpg_error(GPG_ERR_ASS_SYNTAX),
                     i18n("Invalid hex char '%1' in input stream.",
                          QString::fromLatin1(&cch, 1)));
 }
 
 std::string Kleo::hexdecode(const std::string &in)
 {
     std::string result;
     result.reserve(in.size());
     for (std::string::const_iterator it = in.begin(), end = in.end(); it != end; ++it)
         if (*it == '%') {
             ++it;
             unsigned char ch = '\0';
             if (it == end)
                 throw Exception(gpg_error(GPG_ERR_ASS_SYNTAX),
                                 i18n("Premature end of hex-encoded char in input stream"));
             ch |= unhex(*it) << 4;
             ++it;
             if (it == end)
                 throw Exception(gpg_error(GPG_ERR_ASS_SYNTAX),
                                 i18n("Premature end of hex-encoded char in input stream"));
             ch |= unhex(*it);
             result.push_back(ch);
         } else if (*it == '+') {
             result += ' ';
         } else  {
             result.push_back(*it);
         }
     return result;
 }
 
 std::string Kleo::hexencode(const std::string &in)
 {
     std::string result;
     result.reserve(3 * in.size());
 
     static const char hex[] = "0123456789ABCDEF";
 
     for (std::string::const_iterator it = in.begin(), end = in.end(); it != end; ++it)
         switch (const unsigned char ch = *it) {
         default:
             if ((ch >= '!' && ch <= '~') || ch > 0xA0) {
                 result += ch;
                 break;
             }
         // else fall through
         case ' ':
             result += '+';
             break;
         case '"':
         case '#':
         case '$':
         case '%':
         case '\'':
         case '+':
         case '=':
             result += '%';
             result += hex[(ch & 0xF0) >> 4 ];
             result += hex[(ch & 0x0F)      ];
             break;
         }
 
     return result;
 }
 
 std::string Kleo::hexdecode(const char *in)
 {
     if (!in) {
         return std::string();
     }
     return hexdecode(std::string(in));
 }
 
 std::string Kleo::hexencode(const char *in)
 {
     if (!in) {
         return std::string();
     }
     return hexencode(std::string(in));
 }
 
 QByteArray Kleo::hexdecode(const QByteArray &in)
 {
     if (in.isNull()) {
         return QByteArray();
     }
     const std::string result = hexdecode(std::string(in.constData()));
     return QByteArray(result.data(), result.size());
 }
 
 QByteArray Kleo::hexencode(const QByteArray &in)
 {
     if (in.isNull()) {
         return QByteArray();
     }
     const std::string result = hexencode(std::string(in.constData()));
     return QByteArray(result.data(), result.size());
 }