Build kleopatra from KDE Master with patches
authorAndre Heinecke <aheinecke@intevation.de>
Wed, 17 Feb 2016 09:57:26 +0000 (10:57 +0100)
committerAndre Heinecke <aheinecke@intevation.de>
Wed, 17 Feb 2016 09:57:26 +0000 (10:57 +0100)
* Makefile.am (EXTRA_DIST): Add patches.
* packages/packages.current: Use unmodified git master tarball.
* patches/kleopatra: Add patches not yet upstream.
* src/Makefile.am: Add necessary build defines.

--
The Tarball used before contained uncommited changes. Now
the changes are cleaned up into functional patches.

Makefile.am
packages/packages.current
patches/kleopatra/0001-Implement-KDBusService-alternative-for-Windows.patch [new file with mode: 0755]
patches/kleopatra/0002-Add-alternative-configuredialog-wihout-KCMUtils.patch [new file with mode: 0755]
patches/kleopatra/0003-Add-option-to-disable-KWatchGnuPG.patch [new file with mode: 0755]
patches/kleopatra/0004-Make-DBus-integration-of-the-smime-conf-optional.patch [new file with mode: 0755]
patches/kleopatra/0005-Hack-generated-conf-files-for-Crosscompiling.patch [new file with mode: 0755]
src/Makefile.am

index 1d68d5a..29eefe8 100644 (file)
@@ -41,12 +41,17 @@ EXTRA_DIST = autogen.sh README.GIT ONEWS \
         patches/kxmlgui/0001-Make-KGlobalAccel-dependency-optional.patch \
         patches/kxmlgui/0002-Make-QDBus-dependency-optional.patch \
         patches/kxmlgui/0003-Make-KTextWidgets-optional.patch \
-        patches/kxmlgui/0004-Crudely-disable-KSendbugmail.patch \
+        patches/kxmlgui/0004-Cruedly-disable-KSendbugmail.patch \
         patches/kconfigwidgets/0001-Make-QDbus-optional.patch \
         patches/kconfigwidgets/0002-Crudely-remove-KF5Auth-depedency.patch \
         patches/kiconthemes/0001-Make-DBus-optional.patch \
         patches/qtsvg/qtsvg-link-zlib.patch \
-        patches/extra-cmake-modules/0001-Add-convert-utility-support-for-Windows-icons.patch
+        patches/extra-cmake-modules/0001-Add-convert-utility-support-for-Windows-icons.patch \
+        patches/kleopatra/0001-Implement-KDBusService-alternative-for-Windows.patch \
+        patches/kleopatra/0002-Add-alternative-configuredialog-wihout-KCMUtils.patch \
+        patches/kleopatra/0003-Add-option-to-disable-KWatchGnuPG.patch \
+        patches/kleopatra/0004-Make-DBus-integration-of-the-smime-conf-optional.patch \
+        patches/kleopatra/0005-Hack-generated-conf-files-for-Crosscompiling.patch
 
 copy-news:
        cp NEWS doc/website/NEWS.last
index d131b86..8051eb9 100644 (file)
@@ -527,5 +527,5 @@ chk 668b115e7e025b5408f53ced73056f5c4f660993
 # last changed: 2016-02-04
 # by: ah
 # verified: Tarball created by ah.
-file kleopatra/kleopatra-201602041645.tar.gz
-chk 9a18625324bf6ae42635470d220e722d66e91513
+file kleopatra/kleopatra-201602161838.tar.gz
+chk 8ea366ecf4ba0276c886d13521983ff1d7034b89
diff --git a/patches/kleopatra/0001-Implement-KDBusService-alternative-for-Windows.patch b/patches/kleopatra/0001-Implement-KDBusService-alternative-for-Windows.patch
new file mode 100755 (executable)
index 0000000..9b3ea4f
--- /dev/null
@@ -0,0 +1,784 @@
+#! /bin/sh
+patch -p2 -l -f $* < $0
+exit $?
+
+From 0af0ec9c52422aa23cfd4881880ceed44f57c17b Mon Sep 17 00:00:00 2001
+From: Andre Heinecke <aheinecke@intevation.de>
+Date: Fri, 29 Jan 2016 17:00:54 +0100
+Subject: [PATCH 1/5] Implement KDBusService alternative for Windows
+
+Instead of using KDBusService we can just use Window
+Messages to communicate with other processes on Windows.
+---
+ kleopatra/CMakeLists.txt                   |  31 +++-
+ kleopatra/autotests/CMakeLists.txt         |  13 ++
+ kleopatra/autotests/kuniqueservicetest.cpp | 177 +++++++++++++++++++++++
+ kleopatra/kleopatraapplication.cpp         |   2 +
+ kleopatra/kwatchgnupg/CMakeLists.txt       |   6 +
+ kleopatra/kwatchgnupg/main.cpp             |   4 +-
+ kleopatra/main.cpp                         |   7 +-
+ kleopatra/utils/kuniqueservice.h           |  91 ++++++++++++
+ kleopatra/utils/kuniqueservice_dbus.cpp    |  64 +++++++++
+ kleopatra/utils/kuniqueservice_win.cpp     | 219 +++++++++++++++++++++++++++++
+ 10 files changed, 606 insertions(+), 8 deletions(-)
+ create mode 100644 kleopatra/autotests/CMakeLists.txt
+ create mode 100644 kleopatra/autotests/kuniqueservicetest.cpp
+ create mode 100644 kleopatra/utils/kuniqueservice.h
+ create mode 100644 kleopatra/utils/kuniqueservice_dbus.cpp
+ create mode 100644 kleopatra/utils/kuniqueservice_win.cpp
+
+diff --git a/kleopatra/CMakeLists.txt b/kleopatra/CMakeLists.txt
+index e2135c5..9d049f1 100644
+--- a/kleopatra/CMakeLists.txt
++++ b/kleopatra/CMakeLists.txt
+@@ -33,7 +33,6 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${kleopatra_SOURCE_DIR})
+
+ # Find KF5 packages
+   find_package(KF5Codecs ${KF5_VERSION} CONFIG REQUIRED)
+-  find_package(KF5DBusAddons ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5KCMUtils ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5Config ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5I18n ${KF5_VERSION} CONFIG REQUIRED)
+@@ -43,6 +42,19 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${kleopatra_SOURCE_DIR})
+   find_package(KF5WindowSystem ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5TextWidgets ${KF5_VERSION} CONFIG REQUIRED)
+
++# Optional packages
++if (WIN32)
++  # Only a replacement available for Windows so this
++  # is required on other platforms.
++  find_package(KF5DBusAddons ${KF5_VERSION} CONFIG)
++  set_package_properties(KF5DBusAddons PROPERTIES DESCRIPTION "Support library to work with DBus"
++                         PURPOSE "DBus session integration"
++                         URL "http://inqlude.org/libraries/kdbusaddons.html"
++                         TYPE OPTIONAL)
++else()
++  find_package(KF5DBusAddons ${KF5_VERSION} CONFIG REQUIRED)
++endif()
++
+ # Kdepimlibs packages
+   find_package(KF5Libkleo ${LIBKLEO_VERSION} CONFIG REQUIRED)
+   find_package(KF5Mime ${KMIME_VERSION} CONFIG REQUIRED)
+@@ -338,6 +350,13 @@ set(_kleopatra_SRCS
+   main.cpp
+ )
+
++if (KF5DBusAddons_FOUND)
++  set(_kleopatra_SRCS ${_kleopatra_SRCS} utils/kuniqueservice_dbus.cpp)
++else()
++  # Alternative currently only implemented for windows
++  set(_kleopatra_SRCS ${_kleopatra_SRCS} utils/kuniqueservice_win.cpp)
++endif()
++
+ ecm_qt_declare_logging_category(_kleopatra_SRCS HEADER kleopatra_debug.h IDENTIFIER KLEOPATRA_LOG CATEGORY_NAME log_kleopatra)
+
+ if(KLEO_MODEL_TEST)
+@@ -381,6 +400,10 @@ qt5_add_resources(_kleopatra_SRCS kleopatra.qrc)
+ add_executable(kleopatra_bin ${_kleopatra_SRCS} ${_kleopatra_uiserver_SRCS})
+ set_target_properties(kleopatra_bin PROPERTIES OUTPUT_NAME kleopatra)
+
++if (KF5DBusAddons_FOUND)
++  set(_kleopatra_dbusaddons_libs KF5::DBusAddons)
++endif()
++
+ target_link_libraries(kleopatra_bin
+   ${_kleopatra_extra_libs}
+   KF5::Libkleo
+@@ -390,7 +413,7 @@ target_link_libraries(kleopatra_bin
+   KF5::XmlGui
+   KF5::IconThemes
+   KF5::WindowSystem
+-  KF5::DBusAddons
++  ${_kleopatra_dbusaddons_libs}
+   Qt5::Network
+   ${_kleopatra_uiserver_extra_libs}
+   kleopatraclientcore
+@@ -416,3 +439,7 @@ install(
+ )
+
+ add_subdirectory(icons)
++
++if(BUILD_TESTING)
++    add_subdirectory(autotests)
++endif()
+diff --git a/kleopatra/autotests/CMakeLists.txt b/kleopatra/autotests/CMakeLists.txt
+new file mode 100644
+index 0000000..b987250
+--- /dev/null
++++ b/kleopatra/autotests/CMakeLists.txt
+@@ -0,0 +1,13 @@
++set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
++
++if (KF5DBusAddons_FOUND)
++    set(kuniqueservicetest_src kuniqueservicetest.cpp ../utils/kuniqueservice_dbus.cpp)
++else()
++    set(kuniqueservicetest_src kuniqueservicetest.cpp ../utils/kuniqueservice_win.cpp)
++endif()
++
++ecm_qt_declare_logging_category(kuniqueservicetest_src HEADER kleopatra_debug.h IDENTIFIER KLEOPATRA_LOG CATEGORY_NAME log_kleopatra)
++add_executable(kuniqueservicetest ${kuniqueservicetest_src})
++add_test(kuniqueservicetest kuniqueservicetest)
++ecm_mark_as_test(kuniqueservicetest)
++target_link_libraries(kuniqueservicetest Qt5::Test ${_kleopatra_dbusaddons_libs})
+diff --git a/kleopatra/autotests/kuniqueservicetest.cpp b/kleopatra/autotests/kuniqueservicetest.cpp
+new file mode 100644
+index 0000000..1a83a5e
+--- /dev/null
++++ b/kleopatra/autotests/kuniqueservicetest.cpp
+@@ -0,0 +1,177 @@
++/* This file is part of Kleopatra
++
++   Copyright (c) 2016 Intevation GmbH
++
++   It is based on libkdbus kdbusservicetest which is:
++
++   Copyright (c) 1999 Waldo Bastian <bastian@kde.org>
++   Copyright (c) 2011 David Faure <faure@kde.org>
++   Copyright (c) 2011 Kevin Ottens <ervin@kde.org>
++
++   This library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Library General Public
++   License version 2 as published by the Free Software Foundation.
++
++   This library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Library General Public License for more details.
++
++   You should have received a copy of the GNU Library General Public License
++   along with this library; see the file COPYING.LIB.  If not, write to
++   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++   Boston, MA 02110-1301, USA.
++*/
++
++/* The main modification in this test is that every activateRequested
++ * call needs to set the exit code to signal the application it's done. */
++
++#include <QCoreApplication>
++#include <QDebug>
++#include <QDir>
++#include <QFile>
++#include <QMetaObject>
++#include <QProcess>
++#include <QTimer>
++
++#include "utils/kuniqueservice.h"
++
++#include <stdio.h>
++
++class TestObject : public QObject
++{
++    Q_OBJECT
++public:
++    TestObject(KUniqueService *service)
++        : m_proc(Q_NULLPTR), m_callCount(0),
++          m_service(service)
++    {}
++
++    ~TestObject()
++    {
++        if (m_proc) {
++            m_proc->waitForFinished();
++        }
++    }
++
++    int callCount() const
++    {
++        return m_callCount;
++    }
++
++private Q_SLOTS:
++    void slotActivateRequested(const QStringList &args, const QString &workingDirectory)
++    {
++        Q_UNUSED(workingDirectory);
++        qDebug() << "Application executed with args" << args;
++
++        ++m_callCount;
++
++        if (m_callCount == 1) {
++            Q_ASSERT(args.count() == 1);
++            Q_ASSERT(args.at(0) == QLatin1String("dummy call"));
++            m_service->setExitValue(0);
++        } else if (m_callCount == 2) {
++            Q_ASSERT(args.count() == 2);
++            Q_ASSERT(args.at(1) == QLatin1String("bad call"));
++            m_service->setExitValue(4);
++        } else if (m_callCount == 3) {
++            Q_ASSERT(args.count() == 3);
++            Q_ASSERT(args.at(1) == QLatin1String("real call"));
++            Q_ASSERT(args.at(2) == QLatin1String("second arg"));
++            m_service->setExitValue(0);
++            // OK, all done, quit
++            QCoreApplication::instance()->quit();
++        }
++    }
++
++    void slotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
++    {
++        Q_UNUSED(exitStatus)
++        qDebug() << "Process exited with code" << exitCode;
++        m_proc = 0;
++        if (m_callCount == 2) {
++            Q_ASSERT(exitCode == 4);
++            secondCall();
++        }
++    }
++
++    void firstCall()
++    {
++        QStringList args;
++        args << QStringLiteral("bad call");
++        executeNewChild(args);
++    }
++
++    void secondCall()
++    {
++        QStringList args;
++        args << QStringLiteral("real call") << QStringLiteral("second arg");
++        executeNewChild(args);
++    }
++
++private:
++    void executeNewChild(const QStringList &args)
++    {
++        // Duplicated from kglobalsettingstest.cpp - make a shared helper method?
++        m_proc = new QProcess(this);
++        connect(m_proc, SIGNAL(finished(int,QProcess::ExitStatus)),
++                this, SLOT(slotProcessFinished(int,QProcess::ExitStatus)));
++        QString appName = QStringLiteral("kuniqueservicetest");
++#ifdef Q_OS_WIN
++        appName += QStringLiteral(".exe");
++#else
++        if (QFile::exists(appName + QStringLiteral(".shell"))) {
++            appName = QStringLiteral("./") + appName + QStringLiteral(".shell");
++        } else {
++            Q_ASSERT(QFile::exists(appName));
++            appName = QStringLiteral("./") + appName;
++        }
++#endif
++        qDebug() << "about to run" << appName << args;
++        m_proc->start(appName, args);
++    }
++
++    QProcess *m_proc;
++    int m_callCount;
++    KUniqueService *m_service;
++};
++
++int main(int argc, char *argv[])
++{
++    QCoreApplication a(argc, argv);
++
++    QCoreApplication::setApplicationName(QStringLiteral("kuniqueservicetest"));
++    QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org"));
++
++    KUniqueService service;
++    TestObject testObject(&service);
++    QObject::connect(&service, SIGNAL(activateRequested(QStringList, QString)),
++                     &testObject, SLOT(slotActivateRequested(QStringList, QString)));
++
++    // Testcase for the problem coming from the old fork-on-startup solution:
++    // the "Activate" D-Bus call would time out if the app took too much time
++    // to be ready.
++    //printf("Sleeping.\n");
++    //sleep(200);
++    QStringList args;
++    args << QStringLiteral("dummy call");
++
++    QMetaObject::invokeMethod(&service, "activateRequested",
++                              Qt::QueuedConnection,
++                              Q_ARG(QStringList, args),
++                              Q_ARG(QString, QDir::currentPath()));
++    QTimer::singleShot(400, &testObject, SLOT(firstCall()));
++
++    qDebug() << "Running.";
++    a.exec();
++    qDebug() << "Terminating.";
++
++    Q_ASSERT(testObject.callCount() == 3);
++    const bool ok = testObject.callCount() == 3;
++
++    return ok ? 0 : 1;
++}
++
++#include "kuniqueservicetest.moc"
++
+diff --git a/kleopatra/kleopatraapplication.cpp b/kleopatra/kleopatraapplication.cpp
+index 457aacc..b22a573 100644
+--- a/kleopatra/kleopatraapplication.cpp
++++ b/kleopatra/kleopatraapplication.cpp
+@@ -236,7 +236,9 @@ void KleopatraApplication::slotActivateRequested(const QStringList &arguments,
+     if (!err.isEmpty()) {
+         KMessageBox::sorry(NULL, err.toHtmlEscaped(), i18n("Failed to execute command"));
+         Q_EMIT setExitValue(1);
++        return;
+     }
++    Q_EMIT setExitValue(0);
+ }
+
+ QString KleopatraApplication::newInstance(const QCommandLineParser &parser,
+diff --git a/kleopatra/kwatchgnupg/CMakeLists.txt b/kleopatra/kwatchgnupg/CMakeLists.txt
+index 26034c1..a1488af 100644
+--- a/kleopatra/kwatchgnupg/CMakeLists.txt
++++ b/kleopatra/kwatchgnupg/CMakeLists.txt
+@@ -9,6 +9,12 @@ set(kwatchgnupg_SRCS
+   tray.cpp
+   main.cpp
+ )
++if (KF5DBusAddons_FOUND)
++  set(kwatchgnupg_SRCS ${kwatchgnupg_SRCS} ${kleopatra_SOURCE_DIR}/utils/kuniqueservice_dbus.cpp)
++else()
++  set(kwatchgnupg_SRCS ${kwatchgnupg_SRCS} ${kleopatra_SOURCE_DIR}/utils/kuniqueservice_win.cpp)
++endif()
++
+ ecm_qt_declare_logging_category(kwatchgnupg_SRCS HEADER kwatchgnupg_debug.h IDENTIFIER KWATCHGNUPG_LOG CATEGORY_NAME log_kwatchgnupg)
+ qt5_add_resources(kwatchgnupg_SRCS kwatchgnupg.qrc)
+
+diff --git a/kleopatra/kwatchgnupg/main.cpp b/kleopatra/kwatchgnupg/main.cpp
+index af7a4fd..78d2d7f 100644
+--- a/kleopatra/kwatchgnupg/main.cpp
++++ b/kleopatra/kwatchgnupg/main.cpp
+@@ -35,7 +35,7 @@
+ #include "aboutdata.h"
+ #include "kwatchgnupgmainwin.h"
+ #include <kdelibs4configmigrator.h>
+-#include <KDBusService>
++#include "utils/kuniqueservice.h"
+
+ #include <kmessagebox.h>
+ #include <KLocalizedString>
+@@ -63,7 +63,7 @@ int main(int argc, char **argv)
+     parser.process(app);
+     aboutData.processCommandLine(&parser);
+
+-    KDBusService service(KDBusService::Unique);
++    KUniqueService service;
+
+     KWatchGnuPGMainWindow *mMainWin = new KWatchGnuPGMainWindow();
+     mMainWin->show();
+diff --git a/kleopatra/main.cpp b/kleopatra/main.cpp
+index 61d441c..fada938 100644
+--- a/kleopatra/main.cpp
++++ b/kleopatra/main.cpp
+@@ -43,6 +43,7 @@
+
+ #include <utils/gnupg-helper.h>
+ #include <utils/archivedefinition.h>
++#include "utils/kuniqueservice.h"
+
+ #ifdef HAVE_USABLE_ASSUAN
+ # include <uiserver/uiserver.h>
+@@ -74,8 +75,6 @@ class UiServer;
+ #include "kleopatra_debug.h"
+ #include "kleopatra_options.h"
+
+-#include <KDBusService>
+-
+ #include <KLocalizedString>
+ #include <kiconloader.h>
+ #include <QSplashScreen>
+@@ -213,8 +212,8 @@ int main(int argc, char **argv)
+
+     KLocalizedString::setApplicationDomain("kleopatra");
+
+-    KDBusService service(KDBusService::Unique);
+-    QObject::connect(&service, &KDBusService::activateRequested,
++    KUniqueService service;
++    QObject::connect(&service, &KUniqueService::activateRequested,
+                      &app, &KleopatraApplication::slotActivateRequested);
+     QObject::connect(&app, &KleopatraApplication::setExitValue,
+     &service, [&service](int i) {
+diff --git a/kleopatra/utils/kuniqueservice.h b/kleopatra/utils/kuniqueservice.h
+new file mode 100644
+index 0000000..074cf01
+--- /dev/null
++++ b/kleopatra/utils/kuniqueservice.h
+@@ -0,0 +1,91 @@
++#ifndef KUNIQUESERVICE_H
++#define KUNIQUESERVICE_H
++/*
++    kuniqueservice.h
++
++    This file is part of Kleopatra, the KDE keymanager
++    Copyright (c) 2016 Intevation GmbH
++
++    Kleopatra is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    Kleopatra is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
++
++    In addition, as a special exception, the copyright holders give
++    permission to link the code of this program with any edition of
++    the Qt library by Trolltech AS, Norway (or with modified versions
++    of Qt that use the same license as Qt), and distribute linked
++    combinations including the two.  You must obey the GNU General
++    Public License in all respects for all of the code used other than
++    Qt.  If you modify this file, you may extend this exception to
++    your version of the file, but you are not obligated to do so.  If
++    you do not wish to do so, delete this exception statement from
++    your version.
++*/
++#include <QObject>
++#include <QString>
++#include <QStringList>
++
++/**
++ * This class can be used to create a unique service and redirect calls
++ * to this service similarly to KDBusService(KDBusService::Unique).
++ * @code
++ *   YourApplication app(argc, argv);
++ *
++ *   KUniqueService service;
++ *   QObject::connect(&service, &KUniqueService::activateRequested,
++ *                    &app, &YourApplication::slotActivateRequested);
++ *   QObject::connect(&app, &YourApplication::setExitValue,
++ *   &service, [&service](int i) {
++ *       service.setExitValue(i);
++ *   });
++ * @endcode
++ * This will redirect calls to running instances over the
++ * the slotActivateRequested. When you set the exit
++ * value the calling process will afterwards exit with the
++ * code provided.
++ * If you do not set the exit value the application will not
++ * be terminated.
++ * @author Andre Heinecke (aheinecke@intevation.org)
++ */
++class KUniqueService : public QObject
++{
++    Q_OBJECT
++public:
++    /**
++     * Default constructor
++     */
++    KUniqueService();
++
++public Q_SLOTS:
++    /**
++     * Set the exit @p code the second app should use to terminate.
++     * If unset it exits with 0.
++     * @param code The exit code.
++     */
++    void setExitValue(int code);
++
++Q_SIGNALS:
++    void activateRequested(const QStringList &arguments,
++                           const QString &workingDirectory);
++
++private:
++    void emitActivateRequested(const QStringList &arguments,
++                               const QString &workingDirectory)
++    {
++        Q_EMIT activateRequested(arguments, workingDirectory);
++    }
++    class KUniqueServicePrivate;
++    Q_DECLARE_PRIVATE(KUniqueService)
++    KUniqueServicePrivate *d_ptr;
++};
++#endif // KUNIQUESERVICE_H
+diff --git a/kleopatra/utils/kuniqueservice_dbus.cpp b/kleopatra/utils/kuniqueservice_dbus.cpp
+new file mode 100644
+index 0000000..cf4ef96
+--- /dev/null
++++ b/kleopatra/utils/kuniqueservice_dbus.cpp
+@@ -0,0 +1,64 @@
++/*
++    kuniqueservice_dbus.cpp
++
++    This file is part of Kleopatra, the KDE keymanager
++    Copyright (c) 2016 Intevation GmbH
++
++    Kleopatra is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    Kleopatra is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
++
++    In addition, as a special exception, the copyright holders give
++    permission to link the code of this program with any edition of
++    the Qt library by Trolltech AS, Norway (or with modified versions
++    of Qt that use the same license as Qt), and distribute linked
++    combinations including the two.  You must obey the GNU General
++    Public License in all respects for all of the code used other than
++    Qt.  If you modify this file, you may extend this exception to
++    your version of the file, but you are not obligated to do so.  If
++    you do not wish to do so, delete this exception statement from
++    your version.
++*/
++
++#include "kuniqueservice.h"
++#include <KDBusService>
++
++class KUniqueService::KUniqueServicePrivate
++{
++    Q_DISABLE_COPY(KUniqueServicePrivate)
++
++public:
++    KUniqueServicePrivate(KUniqueService *q) : mService(KDBusService::Unique)
++    {
++        QObject::connect(&mService, &KDBusService::activateRequested,
++                         q, &KUniqueService::activateRequested);
++    }
++
++    void setExitValue(int code)
++    {
++        mService.setExitValue(code);
++    }
++
++private:
++    KDBusService mService;
++};
++
++KUniqueService::KUniqueService() : d_ptr(new KUniqueServicePrivate(this)) {}
++
++void KUniqueService::setExitValue(int code)
++{
++    Q_D(KUniqueService);
++    d->setExitValue(code);
++}
++
++#include "moc_kuniqueservice.cpp"
+diff --git a/kleopatra/utils/kuniqueservice_win.cpp b/kleopatra/utils/kuniqueservice_win.cpp
+new file mode 100644
+index 0000000..2ea830e
+--- /dev/null
++++ b/kleopatra/utils/kuniqueservice_win.cpp
+@@ -0,0 +1,219 @@
++/*
++    kuniqueservice_win.cpp
++
++    This file is part of Kleopatra, the KDE keymanager
++    Copyright (c) 2016 Intevation GmbH
++
++    Kleopatra is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    Kleopatra is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
++
++    In addition, as a special exception, the copyright holders give
++    permission to link the code of this program with any edition of
++    the Qt library by Trolltech AS, Norway (or with modified versions
++    of Qt that use the same license as Qt), and distribute linked
++    combinations including the two.  You must obey the GNU General
++    Public License in all respects for all of the code used other than
++    Qt.  If you modify this file, you may extend this exception to
++    your version of the file, but you are not obligated to do so.  If
++    you do not wish to do so, delete this exception statement from
++    your version.
++*/
++
++#include "kuniqueservice.h"
++
++#include <QCoreApplication>
++#include <QDataStream>
++#include <QDir>
++
++#include "kleopatra_debug.h"
++#include <windows.h>
++
++#define MY_DATA_TYPE 12
++
++class KUniqueService::KUniqueServicePrivate
++{
++    Q_DECLARE_PUBLIC(KUniqueService)
++    Q_DISABLE_COPY(KUniqueServicePrivate)
++
++private:
++    KUniqueService *q_ptr;
++    HWND mResponder;
++    HANDLE mCurrentProcess;
++
++    const QString getWindowName() const
++    {
++        return QCoreApplication::applicationName() + QStringLiteral("Responder");
++    }
++
++    HWND getForeignResponder() const
++    {
++        const QString qWndName = getWindowName();
++        wchar_t *wndName = (wchar_t *)qWndName.utf16();
++        HWND ret = FindWindow(wndName, wndName);
++        qCDebug(KLEOPATRA_LOG) << "Responder handle:" << ret;
++        return ret;
++    }
++
++    void createResponder()
++    {
++        WNDCLASS windowClass;
++        const QString qWndName = getWindowName();
++        wchar_t *wndName = (wchar_t*)qWndName.utf16();
++        windowClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
++        windowClass.lpfnWndProc = windowProc;
++        windowClass.hInstance   = (HINSTANCE) GetModuleHandle(NULL);
++        windowClass.lpszClassName = wndName;
++        windowClass.hIcon = Q_NULLPTR;
++        windowClass.hCursor = Q_NULLPTR;
++        windowClass.hbrBackground = Q_NULLPTR;
++        windowClass.lpszMenuName = Q_NULLPTR;
++        windowClass.cbClsExtra = 0;
++        windowClass.cbWndExtra = 0;
++        RegisterClass(&windowClass);
++        mResponder = CreateWindow(wndName, wndName,
++                                  0, 0, 0, 10, 10, Q_NULLPTR, Q_NULLPTR,
++                                  (HINSTANCE)GetModuleHandle(NULL), Q_NULLPTR);
++        qCDebug(KLEOPATRA_LOG) << "Created responder: " << qWndName
++                               << " with handle: " << mResponder;
++    }
++
++    void handleRequest(const COPYDATASTRUCT *cds)
++    {
++        Q_Q(KUniqueService);
++        if (cds->dwData != MY_DATA_TYPE) {
++            qCDebug(KLEOPATRA_LOG) << "Responder called with invalid data type:"
++                                   << cds->dwData;
++            return;
++        }
++        if (mCurrentProcess) {
++            qCDebug(KLEOPATRA_LOG) << "Already serving. Terminating process: "
++                                   << mCurrentProcess;
++            setExitValue(42);
++        }
++        const QByteArray serialized(static_cast<const char*>(cds->lpData),
++                                    cds->cbData);
++        QDataStream ds(serialized);
++        quint32 curProc;
++        ds >> curProc;
++        mCurrentProcess = (HANDLE) curProc;
++        QString workDir;
++        ds >> workDir;
++        QStringList args;
++        ds >> args;
++        qCDebug(KLEOPATRA_LOG) << "Proccess handle: " << mCurrentProcess
++                               << " requests activate with args "
++                               << args;
++        q->emitActivateRequested(args, workDir);
++        return;
++    }
++
++    KUniqueServicePrivate(KUniqueService *q) : q_ptr(q), mResponder(Q_NULLPTR),
++                                               mCurrentProcess(Q_NULLPTR)
++    {
++        HWND responder = getForeignResponder();
++        if (!responder) {
++            // We are the responder
++            createResponder();
++            return;
++        }
++        // We are the client
++
++        QByteArray serialized;
++        QDataStream ds(&serialized, QIODevice::WriteOnly);
++        DWORD targetId = 0;
++        GetWindowThreadProcessId(responder, &targetId);
++        if (!targetId) {
++            qCDebug(KLEOPATRA_LOG) << "No process id of responder window";
++            return;
++        }
++        HANDLE targetHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, targetId);
++        if (!targetHandle) {
++            qCDebug(KLEOPATRA_LOG) << "No target handle. Err: " << GetLastError();
++        }
++
++        // To allow the other process to terminate the process
++        // needs a handle to us with the required access.
++        if (!DuplicateHandle(GetCurrentProcess(),
++                             GetCurrentProcess(),
++                             targetHandle,
++                             &mCurrentProcess,
++                             0,
++                             FALSE,
++                             DUPLICATE_SAME_ACCESS)) {
++            qCDebug(KLEOPATRA_LOG) << "Failed to duplicate handle";
++        }
++        CloseHandle(targetHandle);
++
++        ds << (qint32) mCurrentProcess
++           << QDir::currentPath()
++           << QCoreApplication::arguments();
++        COPYDATASTRUCT cds;
++        cds.dwData = MY_DATA_TYPE;
++        cds.cbData = serialized.size();
++        cds.lpData = serialized.data();
++
++        qCDebug(KLEOPATRA_LOG) << "Sending message to existing Window.";
++        SendMessage(responder, WM_COPYDATA, 0, (LPARAM) &cds);
++        // Usually we should be terminated while sending the message.
++        qCDebug(KLEOPATRA_LOG) << "Send message returned.";
++    }
++
++    static KUniqueServicePrivate *instance(KUniqueService *q) {
++        static KUniqueServicePrivate *self;
++        if (self) {
++            return self;
++        }
++
++        self = new KUniqueServicePrivate(q);
++        return self;
++    }
++
++    static LRESULT CALLBACK windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
++    {
++        if (message == WM_COPYDATA)
++        {
++            const COPYDATASTRUCT *cds = (COPYDATASTRUCT*)lParam;
++            // windowProc must be static so the singleton pattern although
++            // it doesn't make much sense in here.
++            instance(Q_NULLPTR)->handleRequest(cds);
++            return 0;
++        }
++        return DefWindowProc(hWnd, message, wParam, lParam);
++    }
++
++    ~KUniqueServicePrivate()
++    {
++        if (mResponder) {
++            DestroyWindow(mResponder);
++        }
++    }
++
++    void setExitValue(int code)
++    {
++        TerminateProcess(mCurrentProcess, (unsigned int) code);
++        mCurrentProcess = Q_NULLPTR;
++    }
++};
++
++
++KUniqueService::KUniqueService() : d_ptr(KUniqueServicePrivate::instance(this))
++{
++}
++
++void KUniqueService::setExitValue(int code)
++{
++    Q_D(KUniqueService);
++    d->setExitValue(code);
++}
++#include "moc_kuniqueservice.cpp"
+--
+2.1.4
diff --git a/patches/kleopatra/0002-Add-alternative-configuredialog-wihout-KCMUtils.patch b/patches/kleopatra/0002-Add-alternative-configuredialog-wihout-KCMUtils.patch
new file mode 100755 (executable)
index 0000000..d025a80
--- /dev/null
@@ -0,0 +1,688 @@
+#! /bin/sh
+patch -p2 -l -f $* < $0
+exit $?
+
+From cbf48c48727025c585b3647c89ae668ba0d14d0d Mon Sep 17 00:00:00 2001
+From: Andre Heinecke <aheinecke@intevation.de>
+Date: Tue, 16 Feb 2016 17:48:44 +0100
+Subject: [PATCH 2/5] Add alternative configuredialog wihout KCMUtils
+
+KCMUtils heavily depends on QDbus and KService for
+a standalone deployment, like on Windows, we don't
+want those dependencies.
+---
+ kleopatra/CMakeLists.txt                |  22 ++-
+ kleopatra/conf/CMakeLists.txt           |  12 +-
+ kleopatra/conf/configuredialog.cpp      |  59 +++----
+ kleopatra/conf/configuredialog.h        |  23 ++-
+ kleopatra/conf/dirservconfigpage.h      |   2 +-
+ kleopatra/conf/kleopageconfigdialog.cpp | 304 ++++++++++++++++++++++++++++++++
+ kleopatra/conf/kleopageconfigdialog.h   |  73 ++++++++
+ kleopatra/config-kleopatra.h.cmake      |   4 +-
+ 8 files changed, 449 insertions(+), 50 deletions(-)
+ create mode 100644 kleopatra/conf/kleopageconfigdialog.cpp
+ create mode 100644 kleopatra/conf/kleopageconfigdialog.h
+
+diff --git a/kleopatra/CMakeLists.txt b/kleopatra/CMakeLists.txt
+index 9d049f1..2cb7b63 100644
+--- a/kleopatra/CMakeLists.txt
++++ b/kleopatra/CMakeLists.txt
+@@ -10,6 +10,9 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${kleopatra_SOURCE_DIR})
+   set(LIBKLEO_VERSION "5.1.41")
+   set(QT_REQUIRED_VERSION "5.4.0")
+
++  option(FORCE_DISABLE_KCMUTILS "Force building Kleopatra without KCMUtils. Doing this will disable configuration KCM Plugins. [default=OFF]" OFF)
++
++
+   find_package(ECM ${KF5_VERSION} REQUIRED NO_MODULE)
+   set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
+
+@@ -33,7 +36,6 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${kleopatra_SOURCE_DIR})
+
+ # Find KF5 packages
+   find_package(KF5Codecs ${KF5_VERSION} CONFIG REQUIRED)
+-  find_package(KF5KCMUtils ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5Config ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5I18n ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5IconThemes ${KF5_VERSION} CONFIG REQUIRED)
+@@ -41,6 +43,13 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${kleopatra_SOURCE_DIR})
+   find_package(KF5XmlGui ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5WindowSystem ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5TextWidgets ${KF5_VERSION} CONFIG REQUIRED)
++  find_package(KF5WidgetsAddons ${KF5_VERSION} CONFIG REQUIRED)
++  find_package(KF5ConfigWidgets ${KF5_VERSION} CONFIG REQUIRED)
++  find_package(KF5CoreAddons ${KF5_VERSION} CONFIG REQUIRED)
++
++if (NOT FORCE_DISABLE_KCMUTILS)
++  find_package(KF5KCMUtils ${KF5_VERSION} CONFIG REQUIRED)
++endif()
+
+ # Optional packages
+ if (WIN32)
+@@ -63,6 +72,8 @@ endif()
+   find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Widgets Test Network)
+ endif() # Standalone build
+
++set(HAVE_KCMUTILS ${KF5KCMUtils_FOUND})
++
+ find_package(Boost 1.34.0 REQUIRED)
+
+ find_path(Boost_TOPOLOGICAL_SORT_DIR NAMES boost/graph/topological_sort.hpp PATHS ${Boost_INCLUDE_DIRS})
+@@ -357,6 +368,13 @@ else()
+   set(_kleopatra_SRCS ${_kleopatra_SRCS} utils/kuniqueservice_win.cpp)
+ endif()
+
++if (KF5KCMUtils_FOUND)
++  set(_kleopatra_SRCS ${_kleopatra_SRCS} conf/kcmconfiguredialog.cpp)
++  set(_kleopatra_extra_libs ${_kleopatra_extra_libs} KF5::KCMUtils)
++else()
++  set(_kleopatra_SRCS ${_kleopatra_SRCS} conf/kleopageconfigdialog.cpp)
++endif()
++
+ ecm_qt_declare_logging_category(_kleopatra_SRCS HEADER kleopatra_debug.h IDENTIFIER KLEOPATRA_LOG CATEGORY_NAME log_kleopatra)
+
+ if(KLEO_MODEL_TEST)
+@@ -408,11 +426,11 @@ target_link_libraries(kleopatra_bin
+   ${_kleopatra_extra_libs}
+   KF5::Libkleo
+   KF5::Mime
+-  KF5::KCMUtils
+   KF5::I18n
+   KF5::XmlGui
+   KF5::IconThemes
+   KF5::WindowSystem
++  KF5::CoreAddons
+   ${_kleopatra_dbusaddons_libs}
+   Qt5::Network
+   ${_kleopatra_uiserver_extra_libs}
+diff --git a/kleopatra/conf/CMakeLists.txt b/kleopatra/conf/CMakeLists.txt
+index b74fbc4..7a57933 100644
+--- a/kleopatra/conf/CMakeLists.txt
++++ b/kleopatra/conf/CMakeLists.txt
+@@ -55,18 +55,18 @@ kconfig_add_kcfg_files(kcm_kleopatra_PART_SRCS
+   ${kleopatra_SOURCE_DIR}/kcfg/fileoperationspreferences.kcfgc
+ )
+
+-if(KLEO_STATIC_KCMODULES)
+-  add_library(kcm_kleopatra MODULE STATIC ${kcm_kleopatra_PART_SRCS})
+-else()
+-  add_library(kcm_kleopatra MODULE ${kcm_kleopatra_PART_SRCS})
++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::KCMUtils
+   KF5::IconThemes
+   KF5::I18n
+-  Qt5::DBus
++  KF5::WidgetsAddons
++  KF5::ConfigWidgets
+   ${_kcm_kleopatra_extra_libs}
+   ${_kcm_kleopatra_libkleopatraclient_extra_LIBS}
+ )
+diff --git a/kleopatra/conf/configuredialog.cpp b/kleopatra/conf/configuredialog.cpp
+index 3cb3104..b9ef7e4 100644
+--- a/kleopatra/conf/configuredialog.cpp
++++ b/kleopatra/conf/configuredialog.cpp
+@@ -31,53 +31,43 @@
+     your version.
+ */
+
+-#include <config-kleopatra.h>
++#include "config-kleopatra.h"
+
+ #include "configuredialog.h"
+-#include <kwindowsystem.h>
+-#include <kconfig.h>
+-#include <kiconloader.h>
+-#include <kcmultidialog.h>
++
++#include <KWindowSystem>
++#include <KConfig>
++#include <KIconLoader>
+ #include <KLocalizedString>
+-#include <kconfiggroup.h>
+-#include <QApplication>
++#include <KConfigGroup>
+ #include <KSharedConfig>
+-#include <QIcon>
+
+-#ifdef KLEO_STATIC_KCMODULES
+-# include <KDesktopFile>
+-# define KCM_IMPORT_PLUGIN( x ) extern "C" KCModule * create_##x( QWidget * parent = Q_NULLPTR, const QVariantList & args=QVariantList() );
+-# define addMyModule( x ) addModule( KCModuleInfo( KDesktopFile( "services", QLatin1String(#x) + QLatin1String(".desktop") ) ), create_##x() )
+-#else // KLEO_STATIC_KCMODULES
+-# define KCM_IMPORT_PLUGIN( x )
+-# define addMyModule( x ) addModule( QLatin1String(#x) )
+-#endif // KLEO_STATIC_KCMODULES
++#include <QApplication>
++#include <QIcon>
+
+-KCM_IMPORT_PLUGIN(kleopatra_config_dirserv)
+-KCM_IMPORT_PLUGIN(kleopatra_config_appear)
+-#ifdef HAVE_KLEOPATRACLIENT_LIBRARY
+-KCM_IMPORT_PLUGIN(kleopatra_config_cryptooperations)
+-KCM_IMPORT_PLUGIN(kleopatra_config_smimevalidation)
++#if HAVE_KCMUTILS
++# include "kcmconfiguredialog.h"
++#else
++# include "kleopageconfigdialog.h"
+ #endif
+-KCM_IMPORT_PLUGIN(kleopatra_config_gnupgsystem)
+
+ ConfigureDialog::ConfigureDialog(QWidget *parent)
++#if HAVE_KCMUTILS
+     : KCMultiDialog(parent)
++#else
++    : KleoPageConfigDialog(parent)
++#endif
+ {
+     setFaceType(KPageDialog::List);
+     setWindowTitle(i18n("Configure"));
+     KWindowSystem::setIcons(winId(), qApp->windowIcon().pixmap(IconSize(KIconLoader::Desktop), IconSize(KIconLoader::Desktop)),
+                             qApp->windowIcon().pixmap(IconSize(KIconLoader::Small), IconSize(KIconLoader::Small)));
+-    //QT5 showButton( User1, true );
+-
+-    addMyModule(kleopatra_config_dirserv);
+-    addMyModule(kleopatra_config_appear);
+-#ifdef HAVE_KLEOPATRACLIENT_LIBRARY
+-    addMyModule(kleopatra_config_cryptooperations);
+-    addMyModule(kleopatra_config_smimevalidation);
+-#endif
+-    addMyModule(kleopatra_config_gnupgsystem);
+
++    addModule(QStringLiteral("kleopatra_config_dirserv"));
++    addModule(QStringLiteral("kleopatra_config_appear"));
++    addModule(QStringLiteral("kleopatra_config_cryptooperations"));
++    addModule(QStringLiteral("kleopatra_config_smimevalidation"));
++    addModule(QStringLiteral("kleopatra_config_gnupgsystem"));
+     // We store the minimum size of the dialog on hide, because otherwise
+     // the KCMultiDialog starts with the size of the first kcm, not
+     // the largest one. This way at least after the first showing of
+@@ -96,13 +86,14 @@ void ConfigureDialog::hideEvent(QHideEvent *e)
+     KConfigGroup geometry(KSharedConfig::openConfig(), "Geometry");
+     geometry.writeEntry("ConfigureDialogWidth", minSize.width());
+     geometry.writeEntry("ConfigureDialogHeight", minSize.height());
++#if HAVE_KCMUTILS
+     KCMultiDialog::hideEvent(e);
++#else
++    KleoPageConfigDialog::hideEvent(e);
++#endif
+ }
+
+ ConfigureDialog::~ConfigureDialog()
+ {
+ }
+
+-#undef addMyModule
+-#undef KCM_IMPORT_PLUGIN
+-
+diff --git a/kleopatra/conf/configuredialog.h b/kleopatra/conf/configuredialog.h
+index 8096bbe..16fa2c0 100644
+--- a/kleopatra/conf/configuredialog.h
++++ b/kleopatra/conf/configuredialog.h
+@@ -1,16 +1,17 @@
+ /*
+-    configuredialog.cpp
++    configuredialog.h
+
+-    This file is part of kleopatra
++    This file is part of Kleopatra
+     Copyright (C) 2000 Espen Sand, espen@kde.org
+     Copyright (C) 2001-2002 Marc Mutz <mutz@kde.org>
+     Copyright (c) 2004 Klarälvdalens Datakonsult AB
++    Copyright (c) 2016 Intevation GmbH
+
+-    Libkleopatra is free software; you can redistribute it and/or
++    Kleopatra is free software; you can redistribute it and/or
+     modify it under the terms of the GNU General Public License,
+     version 2, as published by the Free Software Foundation.
+
+-    Libkleopatra is distributed in the hope that it will be useful,
++    Kleopatra is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+@@ -34,9 +35,21 @@
+ #ifndef __KLEOPATRA_CONF_CONFIGUREDIALOG_H__
+ #define __KLEOPATRA_CONF_CONFIGUREDIALOG_H__
+
+-#include <kcmultidialog.h>
++#include "config-kleopatra.h"
+
++/**
++ * This is a small wrapper class that holds common code between
++ * the KCM Config dialog (which is used when KCMUtils are available)
++ * and the KleoPageConfigDialog. Which is just a KPageView
++ * with the neccessary bits of the KCMultiDialog behavior.
++ */
++#if HAVE_KCMUTILS
++# include <KCMultiDialog>
+ class ConfigureDialog : public KCMultiDialog
++#else
++# include "kleopageconfigdialog.h"
++class ConfigureDialog : public KleoPageConfigDialog
++#endif
+ {
+     Q_OBJECT
+ public:
+diff --git a/kleopatra/conf/dirservconfigpage.h b/kleopatra/conf/dirservconfigpage.h
+index 28bf6c4..5660208 100644
+--- a/kleopatra/conf/dirservconfigpage.h
++++ b/kleopatra/conf/dirservconfigpage.h
+@@ -33,7 +33,7 @@
+ #ifndef DIRSERVCONFIGPAGE_H
+ #define DIRSERVCONFIGPAGE_H
+
+-#include <kcmodule.h>
++#include <KCModule>
+
+ #include "Libkleo/CryptoConfig"
+
+diff --git a/kleopatra/conf/kleopageconfigdialog.cpp b/kleopatra/conf/kleopageconfigdialog.cpp
+new file mode 100644
+index 0000000..ccc70ce
+--- /dev/null
++++ b/kleopatra/conf/kleopageconfigdialog.cpp
+@@ -0,0 +1,304 @@
++/*
++    kleopageconfigdialog.cpp
++
++    This file is part of Kleopatra
++    Copyright (c) 2016 Intevation GmbH
++
++    Kleopatra is free software; you can redistribute it and/or
++    modify it under the terms of the GNU General Public License,
++    version 2, as published by the Free Software Foundation.
++
++    Kleopatra is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
++
++    In addition, as a special exception, the copyright holders give
++    permission to link the code of this program with any edition of
++    the Qt library by Trolltech AS, Norway (or with modified versions
++    of Qt that use the same license as Qt), and distribute linked
++    combinations including the two.  You must obey the GNU General
++    Public License in all respects for all of the code used other than
++    Qt.  If you modify this file, you may extend this exception to
++    your version of the file, but you are not obligated to do so.  If
++    you do not wish to do so, delete this exception statement from
++    your version.
++
++    It is derived from KCMultidialog which is:
++
++    Copyright (c) 2000 Matthias Elter <elter@kde.org>
++    Copyright (c) 2003 Daniel Molkentin <molkentin@kde.org>
++    Copyright (c) 2003,2006 Matthias Kretz <kretz@kde.org>
++    Copyright (c) 2004 Frans Englich <frans.englich@telia.com>
++    Copyright (c) 2006 Tobias Koenig <tokoe@kde.org>
++
++    This library is free software; you can redistribute it and/or
++    modify it under the terms of the GNU Library General Public
++    License as published by the Free Software Foundation; either
++    version 2 of the License, or (at your option) any later version.
++
++    This library is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    Library General Public License for more details.
++
++    You should have received a copy of the GNU Library General Public License
++    along with this library; see the file COPYING.LIB.  If not, write to
++    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++    Boston, MA 02110-1301, USA.
++*/
++
++
++#include "kleopageconfigdialog.h"
++
++#include <QDialogButtonBox>
++#include <QPushButton>
++#include <QLibrary>
++#include <QCoreApplication>
++#include <QUrl>
++#include <QDesktopServices>
++#include <QProcess>
++
++#include <KCModule>
++#include <KDesktopFile>
++#include <KPluginLoader>
++#include <KStandardGuiItem>
++#include <KMessageBox>
++#include <KLocalizedString>
++
++#include "kleopatra_debug.h"
++
++#define KCM_LIBRARY_NAME "kcm_kleopatra"
++
++KleoPageConfigDialog::KleoPageConfigDialog(QWidget *parent)
++    : KPageDialog(parent)
++{
++    setModal(false);
++
++    QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
++    buttonBox->setStandardButtons(QDialogButtonBox::Help
++                                  | QDialogButtonBox::RestoreDefaults
++                                  | 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());
++    KGuiItem::assign(buttonBox->button(QDialogButtonBox::Help), KStandardGuiItem::help());
++    buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
++    buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
++
++    connect(buttonBox->button(QDialogButtonBox::Apply), &QAbstractButton::clicked,
++            this, &KleoPageConfigDialog::slotApplyClicked);
++    connect(buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked,
++            this, &KleoPageConfigDialog::slotOkClicked);
++    connect(buttonBox->button(QDialogButtonBox::RestoreDefaults), &QAbstractButton::clicked,
++            this, &KleoPageConfigDialog::slotDefaultClicked);
++    connect(buttonBox->button(QDialogButtonBox::Help), &QAbstractButton::clicked,
++            this, &KleoPageConfigDialog::slotHelpClicked);
++    connect(buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked,
++            this, &KleoPageConfigDialog::slotUser1Clicked);
++
++    setButtonBox(buttonBox);
++
++    connect(this, &KPageDialog::currentPageChanged,
++            this, &KleoPageConfigDialog::slotCurrentPageChanged);
++}
++
++void KleoPageConfigDialog::slotCurrentPageChanged(KPageWidgetItem *current, KPageWidgetItem *previous)
++{
++    if (!previous) {
++        return;
++    }
++    blockSignals(true);
++    setCurrentPage(previous);
++
++    KCModule *previousModule = qobject_cast<KCModule*>(previous->widget());
++    bool canceled = false;
++    if (previousModule && mChangedModules.contains(previousModule)) {
++        const int queryUser = KMessageBox::warningYesNoCancel(
++                          this,
++                          i18n("The settings of the current module have changed.\n"
++                               "Do you want to apply the changes or discard them?"),
++                          i18n("Apply Settings"),
++                          KStandardGuiItem::apply(),
++                          KStandardGuiItem::discard(),
++                          KStandardGuiItem::cancel());
++        if (queryUser == KMessageBox::Yes) {
++            previousModule->save();
++        } else if (queryUser == KMessageBox::No) {
++            previousModule->load();
++        }
++        canceled = queryUser == KMessageBox::Cancel;
++    }
++    if (!canceled) {
++        mChangedModules.removeAll(previousModule);
++        setCurrentPage(current);
++    }
++    blockSignals(false);
++
++    clientChanged();
++}
++
++void KleoPageConfigDialog::apply()
++{
++    QPushButton *applyButton = buttonBox()->button(QDialogButtonBox::Apply);
++    applyButton->setFocus();
++    foreach (KCModule *module, mChangedModules) {
++        module->save();
++    }
++    mChangedModules.clear();
++    Q_EMIT configCommitted();
++    clientChanged();
++}
++
++void KleoPageConfigDialog::slotDefaultClicked()
++{
++    const KPageWidgetItem *item = currentPage();
++    if (!item) {
++        return;
++    }
++
++    KCModule *module = qobject_cast<KCModule*>(item->widget());
++    if (!module) {
++        return;
++    }
++    module->defaults();
++    clientChanged();
++}
++
++void KleoPageConfigDialog::slotUser1Clicked()
++{
++    const KPageWidgetItem *item = currentPage();
++    if (!item) {
++        return;
++    }
++
++    KCModule *module = qobject_cast<KCModule*>(item->widget());
++    if (!module) {
++        return;
++    }
++    module->load();
++    mChangedModules.removeAll(module);
++    clientChanged();
++}
++
++void KleoPageConfigDialog::slotApplyClicked()
++{
++    apply();
++}
++
++void KleoPageConfigDialog::slotOkClicked()
++{
++    apply();
++    accept();
++}
++
++void KleoPageConfigDialog::slotHelpClicked()
++{
++    const KPageWidgetItem *item = currentPage();
++    if (!item) {
++        return;
++    }
++
++    const QString docPath = mHelpUrls.value(item->name());
++
++    QUrl docUrl = QUrl(QStringLiteral("help:/")).resolved(QUrl(docPath)); // same code as in KHelpClient::invokeHelp
++    if (docUrl.scheme() == QLatin1String("help") || docUrl.scheme() == QLatin1String("man") || docUrl.scheme() == QLatin1String("info")) {
++        QProcess::startDetached(QStringLiteral("khelpcenter"), QStringList() << docUrl.toString());
++    } else {
++        QDesktopServices::openUrl(docUrl);
++    }
++}
++
++static KCModule *loadModule(const QString &name)
++{
++    QLibrary lib(KPluginLoader::findPlugin(KCM_LIBRARY_NAME));
++    if (lib.load()) {
++        KCModule *(*create)(QWidget *, const char *);
++        QByteArray factorymethod("create_");
++        factorymethod += name.toLatin1();
++        create = reinterpret_cast<KCModule *(*)(QWidget *, const char *)>(lib.resolve(factorymethod.constData()));
++        if (create) {
++            return create(Q_NULLPTR, name.toLatin1().constData());
++        } else {
++            qCWarning(KLEOPATRA_LOG) << "Failed to load config module: " << name;
++            return Q_NULLPTR;
++        }
++    }
++    qCWarning(KLEOPATRA_LOG) << "Failed to load library: " << KCM_LIBRARY_NAME;
++    return Q_NULLPTR;
++}
++
++void KleoPageConfigDialog::addModule(const QString &name)
++{
++    // We use a path relative to our installation location
++    const QString path = qApp->applicationDirPath() +
++                         QLatin1String("/../share/kservices5/") +
++                         name + QLatin1String(".desktop");
++    KDesktopFile desktopModule(path);
++
++    KCModule *mod = loadModule(name);
++    mModules << mod;
++
++    const QString dName = desktopModule.readName();
++
++    KPageWidgetItem *item = addPage(mod, dName);
++    item->setIcon(QIcon::fromTheme(desktopModule.readIcon()));
++    item->setHeader(desktopModule.readComment());
++
++    connect(mod, SIGNAL(changed(bool)), this, SLOT(moduleChanged(bool)));
++
++    mHelpUrls.insert(dName, desktopModule.readDocPath());
++}
++
++void KleoPageConfigDialog::moduleChanged(bool state)
++{
++    KCModule *module = qobject_cast<KCModule*>(sender());
++    qCDebug(KLEOPATRA_LOG) << "Module changed: " << state << " mod " << module;
++    if (mChangedModules.contains(module)) {
++        if (!state) {
++            mChangedModules.removeAll(module);
++        }
++        return;
++    }
++    if (state) {
++        mChangedModules << module;
++    }
++    clientChanged();
++}
++
++void KleoPageConfigDialog::clientChanged()
++{
++    const KPageWidgetItem *item = currentPage();
++    if (!item) {
++        return;
++    }
++    KCModule *module = qobject_cast<KCModule*>(item->widget());
++
++    if (!module) {
++        return;
++    }
++    qCDebug(KLEOPATRA_LOG) << "Client changed: " << " mod " << module;
++
++    bool change = false;
++    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);
++    }
++}
+diff --git a/kleopatra/conf/kleopageconfigdialog.h b/kleopatra/conf/kleopageconfigdialog.h
+new file mode 100644
+index 0000000..809c930
+--- /dev/null
++++ b/kleopatra/conf/kleopageconfigdialog.h
+@@ -0,0 +1,73 @@
++/*
++    kleopageconfigdialog.h.h
++
++    This file is part of Kleopatra
++    Copyright (c) 2016 Intevation GmbH
++
++    Kleopatra is free software; you can redistribute it and/or
++    modify it under the terms of the GNU General Public License,
++    version 2, as published by the Free Software Foundation.
++
++    Kleopatra is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
++
++    In addition, as a special exception, the copyright holders give
++    permission to link the code of this program with any edition of
++    the Qt library by Trolltech AS, Norway (or with modified versions
++    of Qt that use the same license as Qt), and distribute linked
++    combinations including the two.  You must obey the GNU General
++    Public License in all respects for all of the code used other than
++    Qt.  If you modify this file, you may extend this exception to
++    your version of the file, but you are not obligated to do so.  If
++    you do not wish to do so, delete this exception statement from
++    your version.
++*/
++
++#ifndef __KLEOPATRA_CONF_KLEOPAGECONFIGDIALOG_H__
++#define __KLEOPATRA_CONF_KLEOPAGECONFIGDIALOG_H__
++
++#include <KPageDialog>
++#include <QList>
++
++class KCModule;
++class KPageWidgetItem;
++
++/**
++ * KPageDialog based config dialog to be used when
++ * KCMUtils are not available. */
++class KleoPageConfigDialog : public KPageDialog
++{
++    Q_OBJECT
++public:
++    explicit KleoPageConfigDialog(QWidget *parent = Q_NULLPTR);
++
++    void addModule(const QString &module);
++
++Q_SIGNALS:
++    void configCommitted();
++
++protected Q_SLOTS:
++    void slotDefaultClicked();
++    void slotUser1Clicked();
++    void slotApplyClicked();
++    void slotOkClicked();
++    void slotHelpClicked();
++    void slotCurrentPageChanged(KPageWidgetItem *current, KPageWidgetItem *previous);
++    void moduleChanged(bool value);
++
++private:
++    void clientChanged();
++    void apply();
++
++    QList<KCModule *> mModules;
++    QList<KCModule *> mChangedModules;
++    QMap<QString, QString> mHelpUrls;
++};
++
++#endif /* __KLEOPATRA_CONF_KLEOPAGECONFIGDIALOG_H__ */
+diff --git a/kleopatra/config-kleopatra.h.cmake b/kleopatra/config-kleopatra.h.cmake
+index 4fb4a8f..d0c7092 100644
+--- a/kleopatra/config-kleopatra.h.cmake
++++ b/kleopatra/config-kleopatra.h.cmake
+@@ -21,5 +21,5 @@
+ /* Define to 1 if you build libkleopatraclient */
+ #cmakedefine HAVE_KLEOPATRACLIENT_LIBRARY 1
+
+-/* Mirrored from cmake option */
+-#cmakedefine KLEO_STATIC_KCMODULES 1
++/* KF5KCMUtils available */
++#cmakedefine01 HAVE_KCMUTILS
+--
+2.1.4
diff --git a/patches/kleopatra/0003-Add-option-to-disable-KWatchGnuPG.patch b/patches/kleopatra/0003-Add-option-to-disable-KWatchGnuPG.patch
new file mode 100755 (executable)
index 0000000..ff97a26
--- /dev/null
@@ -0,0 +1,64 @@
+#! /bin/sh
+patch -p2 -l -f $* < $0
+exit $?
+
+From a10a900e0719f50dab4cdc862d6f7f1258cf5e62 Mon Sep 17 00:00:00 2001
+From: Andre Heinecke <aheinecke@intevation.de>
+Date: Tue, 16 Feb 2016 18:15:47 +0100
+Subject: [PATCH 3/5] Add option to disable KWatchGnuPG
+
+KWatchGnuPG currently pulls in KTextWidgets and KNotifications
+which are heavy dependencies for Kleopatra. So this can be disabled.
+A better solution would probably be to make the features optional.
+---
+ kleopatra/CMakeLists.txt | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/kleopatra/CMakeLists.txt b/kleopatra/CMakeLists.txt
+index 2cb7b63..0c8b20b 100644
+--- a/kleopatra/CMakeLists.txt
++++ b/kleopatra/CMakeLists.txt
+@@ -11,6 +11,7 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${kleopatra_SOURCE_DIR})
+   set(QT_REQUIRED_VERSION "5.4.0")
+
+   option(FORCE_DISABLE_KCMUTILS "Force building Kleopatra without KCMUtils. Doing this will disable configuration KCM Plugins. [default=OFF]" OFF)
++  option(DISABLE_KWATCHGNUPG "Don't build the kwatchgnupg tool [default=OFF]" OFF)
+
+
+   find_package(ECM ${KF5_VERSION} REQUIRED NO_MODULE)
+@@ -39,10 +40,8 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${kleopatra_SOURCE_DIR})
+   find_package(KF5Config ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5I18n ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5IconThemes ${KF5_VERSION} CONFIG REQUIRED)
+-  find_package(KF5Notifications ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5XmlGui ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5WindowSystem ${KF5_VERSION} CONFIG REQUIRED)
+-  find_package(KF5TextWidgets ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5WidgetsAddons ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5ConfigWidgets ${KF5_VERSION} CONFIG REQUIRED)
+   find_package(KF5CoreAddons ${KF5_VERSION} CONFIG REQUIRED)
+@@ -51,6 +50,11 @@ if (NOT FORCE_DISABLE_KCMUTILS)
+   find_package(KF5KCMUtils ${KF5_VERSION} CONFIG REQUIRED)
+ endif()
+
++if (NOT DISABLE_KWATCHGNUPG)
++  find_package(KF5Notifications ${KF5_VERSION} CONFIG REQUIRED)
++  find_package(KF5TextWidgets ${KF5_VERSION} CONFIG REQUIRED)
++endif()
++
+ # Optional packages
+ if (WIN32)
+   # Only a replacement available for Windows so this
+@@ -141,7 +145,9 @@ if(USABLE_ASSUAN_FOUND)
+   add_subdirectory(libkleopatraclient)
+ endif()
+
+-add_subdirectory(kwatchgnupg)
++if (NOT DISABLE_KWATCHGNUPG)
++  add_subdirectory(kwatchgnupg)
++endif()
+
+ if(BUILD_TESTING)
+     add_subdirectory(tests)
+--
+2.1.4
diff --git a/patches/kleopatra/0004-Make-DBus-integration-of-the-smime-conf-optional.patch b/patches/kleopatra/0004-Make-DBus-integration-of-the-smime-conf-optional.patch
new file mode 100755 (executable)
index 0000000..4dc96e1
--- /dev/null
@@ -0,0 +1,55 @@
+#! /bin/sh
+patch -p2 -l -f $* < $0
+exit $?
+
+From 5e9fd7ef2c4550b3893bbd52b2d15e4ad5f2fe9c Mon Sep 17 00:00:00 2001
+From: Andre Heinecke <aheinecke@intevation.de>
+Date: Tue, 16 Feb 2016 18:17:17 +0100
+Subject: [PATCH 4/5] Make DBus integration of the smime conf optional
+
+This is indirect because if you have KCMUtils you already
+have DBus and so you want to integrate with DBus in the
+S/MIME Config widget.
+---
+ kleopatra/conf/smimevalidationconfigurationwidget.cpp | 6 +++++-
+ kleopatra/config-kleopatra.h.cmake                    | 3 +++
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/kleopatra/conf/smimevalidationconfigurationwidget.cpp b/kleopatra/conf/smimevalidationconfigurationwidget.cpp
+index aab1e98..e3ba39f 100644
+--- a/kleopatra/conf/smimevalidationconfigurationwidget.cpp
++++ b/kleopatra/conf/smimevalidationconfigurationwidget.cpp
+@@ -44,7 +44,9 @@
+ #include <KLocalizedString>
+ #include "kleopatra_debug.h"
+
+-#include <QDBusConnection>
++#if HAVE_QDBUS
++# include <QDBusConnection>
++#endif
+
+ using namespace Kleo;
+ using namespace Kleo::Config;
+@@ -59,7 +61,9 @@ public:
+           customHTTPProxyWritable(false),
+           ui(q)
+     {
++#if HAVE_QDBUS
+         QDBusConnection::sessionBus().connect(QString(), QString(), QStringLiteral("org.kde.kleo.CryptoConfig"), QStringLiteral("changed"), q, SLOT(load()));
++#endif
+     }
+
+     bool customHTTPProxyWritable;
+diff --git a/kleopatra/config-kleopatra.h.cmake b/kleopatra/config-kleopatra.h.cmake
+index d0c7092..4842cca 100644
+--- a/kleopatra/config-kleopatra.h.cmake
++++ b/kleopatra/config-kleopatra.h.cmake
+@@ -23,3 +23,6 @@
+
+ /* KF5KCMUtils available */
+ #cmakedefine01 HAVE_KCMUTILS
++
++/* DBus available */
++#cmakedefine01 HAVE_QDBUS
+--
+2.1.4
diff --git a/patches/kleopatra/0005-Hack-generated-conf-files-for-Crosscompiling.patch b/patches/kleopatra/0005-Hack-generated-conf-files-for-Crosscompiling.patch
new file mode 100755 (executable)
index 0000000..90ac0aa
--- /dev/null
@@ -0,0 +1,528 @@
+#! /bin/sh
+patch -p2 -l -f $* < $0
+exit $?
+
+From eb0adaf1064e6344540abfb576ae4e52c1172bfa Mon Sep 17 00:00:00 2001
+From: Andre Heinecke <aheinecke@intevation.de>
+Date: Tue, 16 Feb 2016 18:19:07 +0100
+Subject: [PATCH 5/5] Hack generated conf files for Crosscompiling
+
+This patch can be removed once Gpg4win is built on a platform
+that has a packaged kconfig_compiler5.
+---
+ kleopatra/CMakeLists.txt                 | 22 ++++++---
+ kleopatra/conf/CMakeLists.txt            | 20 ++++----
+ kleopatra/emailoperationspreferences.cpp | 27 ++++++++++
+ kleopatra/emailoperationspreferences.h   | 84 ++++++++++++++++++++++++++++++++
+ kleopatra/fileoperationspreferences.cpp  | 21 ++++++++
+ kleopatra/fileoperationspreferences.h    | 48 ++++++++++++++++++
+ kleopatra/smimevalidationpreferences.cpp | 22 +++++++++
+ kleopatra/smimevalidationpreferences.h   | 55 +++++++++++++++++++++
+ kleopatra/tooltippreferences.cpp         | 27 ++++++++++
+ kleopatra/tooltippreferences.h           | 84 ++++++++++++++++++++++++++++++++
+ 10 files changed, 394 insertions(+), 16 deletions(-)
+ create mode 100644 kleopatra/emailoperationspreferences.cpp
+ create mode 100644 kleopatra/emailoperationspreferences.h
+ create mode 100644 kleopatra/fileoperationspreferences.cpp
+ create mode 100644 kleopatra/fileoperationspreferences.h
+ create mode 100644 kleopatra/smimevalidationpreferences.cpp
+ create mode 100644 kleopatra/smimevalidationpreferences.h
+ create mode 100644 kleopatra/tooltippreferences.cpp
+ create mode 100644 kleopatra/tooltippreferences.h
+
+diff --git a/kleopatra/CMakeLists.txt b/kleopatra/CMakeLists.txt
+index 0c8b20b..056e20a 100644
+--- a/kleopatra/CMakeLists.txt
++++ b/kleopatra/CMakeLists.txt
+@@ -408,13 +408,21 @@ ki18n_wrap_ui(_kleopatra_SRCS
+   newcertificatewizard/advancedsettingsdialog.ui
+ )
+
+-kconfig_add_kcfg_files(_kleopatra_SRCS
+-  kcfg/tooltippreferences.kcfgc
+-  kcfg/emailoperationspreferences.kcfgc
+-  kcfg/fileoperationspreferences.kcfgc
+-  kcfg/smimevalidationpreferences.kcfgc
+-)
+-
++if (NOT CMAKE_CROSSCOMPILING)
++  kconfig_add_kcfg_files(_kleopatra_SRCS
++    kcfg/tooltippreferences.kcfgc
++    kcfg/emailoperationspreferences.kcfgc
++    kcfg/fileoperationspreferences.kcfgc
++    kcfg/smimevalidationpreferences.kcfgc
++  )
++else()
++  set(_kleopatra_SRCS ${_kleopatra_SRCS}
++    tooltippreferences.cpp
++    emailoperationspreferences.cpp
++    fileoperationspreferences.cpp
++    smimevalidationpreferences.cpp
++  )
++endif()
+
+ file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/icons/*-apps-kleopatra.png")
+ ecm_add_app_icon(_kleopatra_SRCS ICONS ${ICONS_SRCS})
+diff --git a/kleopatra/conf/CMakeLists.txt b/kleopatra/conf/CMakeLists.txt
+index 7a57933..c0d4e3d 100644
+--- a/kleopatra/conf/CMakeLists.txt
++++ b/kleopatra/conf/CMakeLists.txt
+@@ -14,10 +14,6 @@ if(BUILD_libkleopatraclient)
+     cryptooperationsconfigwidget.ui
+   )
+
+-  kconfig_add_kcfg_files(_kcm_kleopatra_libkleopatraclient_extra_SRCS
+-    ${kleopatra_SOURCE_DIR}/kcfg/smimevalidationpreferences.kcfgc
+-  )
+-
+   set(_kcm_kleopatra_libkleopatraclient_extra_LIBS kleopatraclientgui)
+
+   set(_kcm_kleopatra_libkleopatraclient_extra_install_FILES
+@@ -34,7 +30,6 @@ else()
+ endif()
+
+ set(kcm_kleopatra_PART_SRCS
+-  ${_kcm_kleopatra_kleo_only_SRCS}
+   dirservconfigpage.cpp
+   appearanceconfigpage.cpp
+   appearanceconfigwidget.cpp
+@@ -49,10 +44,17 @@ ki18n_wrap_ui(kcm_kleopatra_PART_SRCS
+   smimevalidationconfigurationwidget.ui
+ )
+
+-kconfig_add_kcfg_files(kcm_kleopatra_PART_SRCS
+-  ${kleopatra_SOURCE_DIR}/kcfg/tooltippreferences.kcfgc
+-  ${kleopatra_SOURCE_DIR}/kcfg/emailoperationspreferences.kcfgc
+-  ${kleopatra_SOURCE_DIR}/kcfg/fileoperationspreferences.kcfgc
++if(CMAKE_CROSSCOMPILING)
++  set(_kcfg_generated_files_dir ${kleopatra_SOURCE_DIR})
++else()
++  set(_kcfg_generated_files_dir ${kleopatra_BINARY_DIR})
++endif()
++
++set(kcm_kleopatra_PART_SRCS ${kcm_kleopatra_PART_SRCS}
++  ${_kcfg_generated_files_dir}/tooltippreferences.cpp
++  ${_kcfg_generated_files_dir}/emailoperationspreferences.cpp
++  ${_kcfg_generated_files_dir}/fileoperationspreferences.cpp
++  ${_kcfg_generated_files_dir}/smimevalidationpreferences.cpp
+ )
+
+ add_library(kcm_kleopatra MODULE ${kcm_kleopatra_PART_SRCS})
+diff --git a/kleopatra/emailoperationspreferences.cpp b/kleopatra/emailoperationspreferences.cpp
+new file mode 100644
+index 0000000..730db97
+--- /dev/null
++++ b/kleopatra/emailoperationspreferences.cpp
+@@ -0,0 +1,27 @@
++// This file is generated by kconfig_compiler_kf5 from emailoperationspreferences.kcfg.
++// All changes you do to this file will be lost.
++
++#include "emailoperationspreferences.h"
++
++using namespace Kleo;
++
++EMailOperationsPreferences::EMailOperationsPreferences(  )
++  : KConfigSkeleton( QStringLiteral( "kleopatrarc" ) )
++{
++  setCurrentGroup( QStringLiteral( "EMailOperations" ) );
++
++  KConfigSkeleton::ItemBool  *itemQuickSignEMail;
++  itemQuickSignEMail = new KConfigSkeleton::ItemBool( currentGroup(), QStringLiteral( "quick-sign-email" ), mQuickSignEMail, false );
++  addItem( itemQuickSignEMail, QStringLiteral( "QuickSignEMail" ) );
++  KConfigSkeleton::ItemBool  *itemQuickEncryptEMail;
++  itemQuickEncryptEMail = new KConfigSkeleton::ItemBool( currentGroup(), QStringLiteral( "quick-encrypt-email" ), mQuickEncryptEMail, false );
++  addItem( itemQuickEncryptEMail, QStringLiteral( "QuickEncryptEMail" ) );
++  KConfigSkeleton::ItemRect  *itemDecryptVerifyPopupGeometry;
++  itemDecryptVerifyPopupGeometry = new KConfigSkeleton::ItemRect( currentGroup(), QStringLiteral( "decrypt-verify-popup-geometry" ), mDecryptVerifyPopupGeometry );
++  addItem( itemDecryptVerifyPopupGeometry, QStringLiteral( "DecryptVerifyPopupGeometry" ) );
++}
++
++EMailOperationsPreferences::~EMailOperationsPreferences()
++{
++}
++
+diff --git a/kleopatra/emailoperationspreferences.h b/kleopatra/emailoperationspreferences.h
+new file mode 100644
+index 0000000..58881f8
+--- /dev/null
++++ b/kleopatra/emailoperationspreferences.h
+@@ -0,0 +1,84 @@
++// This file is generated by kconfig_compiler_kf5 from emailoperationspreferences.kcfg.
++// All changes you do to this file will be lost.
++#ifndef KLEO_EMAILOPERATIONSPREFERENCES_H
++#define KLEO_EMAILOPERATIONSPREFERENCES_H
++
++#include <qglobal.h>
++#include <kconfigskeleton.h>
++#include <QCoreApplication>
++#include <QDebug>
++
++namespace Kleo {
++
++class EMailOperationsPreferences : public KConfigSkeleton
++{
++  public:
++
++    EMailOperationsPreferences( );
++    ~EMailOperationsPreferences();
++
++    /**
++      Set Quick Sign EMail
++    */
++    void setQuickSignEMail( bool v )
++    {
++      if (!isImmutable( QStringLiteral( "QuickSignEMail" ) ))
++        mQuickSignEMail = v;
++    }
++
++    /**
++      Get Quick Sign EMail
++    */
++    bool quickSignEMail() const
++    {
++      return mQuickSignEMail;
++    }
++
++    /**
++      Set Quick Encrypt EMail
++    */
++    void setQuickEncryptEMail( bool v )
++    {
++      if (!isImmutable( QStringLiteral( "QuickEncryptEMail" ) ))
++        mQuickEncryptEMail = v;
++    }
++
++    /**
++      Get Quick Encrypt EMail
++    */
++    bool quickEncryptEMail() const
++    {
++      return mQuickEncryptEMail;
++    }
++
++    /**
++      Set Decrypt/Verify Popup Geometry
++    */
++    void setDecryptVerifyPopupGeometry( const QRect & v )
++    {
++      if (!isImmutable( QStringLiteral( "DecryptVerifyPopupGeometry" ) ))
++        mDecryptVerifyPopupGeometry = v;
++    }
++
++    /**
++      Get Decrypt/Verify Popup Geometry
++    */
++    QRect decryptVerifyPopupGeometry() const
++    {
++      return mDecryptVerifyPopupGeometry;
++    }
++
++  protected:
++
++    // EMailOperations
++    bool mQuickSignEMail;
++    bool mQuickEncryptEMail;
++    QRect mDecryptVerifyPopupGeometry;
++
++  private:
++};
++
++}
++
++#endif
++
+diff --git a/kleopatra/fileoperationspreferences.cpp b/kleopatra/fileoperationspreferences.cpp
+new file mode 100644
+index 0000000..d2d20fc
+--- /dev/null
++++ b/kleopatra/fileoperationspreferences.cpp
+@@ -0,0 +1,21 @@
++// This file is generated by kconfig_compiler_kf5 from fileoperationspreferences.kcfg.
++// All changes you do to this file will be lost.
++
++#include "fileoperationspreferences.h"
++
++using namespace Kleo;
++
++FileOperationsPreferences::FileOperationsPreferences(  )
++  : KConfigSkeleton( QStringLiteral( "kleopatrarc" ) )
++{
++  setCurrentGroup( QStringLiteral( "FileOperations" ) );
++
++  KConfigSkeleton::ItemBool  *itemUsePGPFileExt;
++  itemUsePGPFileExt = new KConfigSkeleton::ItemBool( currentGroup(), QStringLiteral( "file-extension-pgp" ), mUsePGPFileExt, false );
++  addItem( itemUsePGPFileExt, QStringLiteral( "UsePGPFileExt" ) );
++}
++
++FileOperationsPreferences::~FileOperationsPreferences()
++{
++}
++
+diff --git a/kleopatra/fileoperationspreferences.h b/kleopatra/fileoperationspreferences.h
+new file mode 100644
+index 0000000..9866a70
+--- /dev/null
++++ b/kleopatra/fileoperationspreferences.h
+@@ -0,0 +1,48 @@
++// This file is generated by kconfig_compiler_kf5 from fileoperationspreferences.kcfg.
++// All changes you do to this file will be lost.
++#ifndef KLEO_FILEOPERATIONSPREFERENCES_H
++#define KLEO_FILEOPERATIONSPREFERENCES_H
++
++#include <qglobal.h>
++#include <kconfigskeleton.h>
++#include <QCoreApplication>
++#include <QDebug>
++
++namespace Kleo {
++
++class FileOperationsPreferences : public KConfigSkeleton
++{
++  public:
++
++    FileOperationsPreferences( );
++    ~FileOperationsPreferences();
++
++    /**
++      Set Use pgp as the default extension for generated OpenPGP files
++    */
++    void setUsePGPFileExt( bool v )
++    {
++      if (!isImmutable( QStringLiteral( "UsePGPFileExt" ) ))
++        mUsePGPFileExt = v;
++    }
++
++    /**
++      Get Use pgp as the default extension for generated OpenPGP files
++    */
++    bool usePGPFileExt() const
++    {
++      return mUsePGPFileExt;
++    }
++
++  protected:
++
++    // FileOperations
++    bool mUsePGPFileExt;
++
++  private:
++};
++
++}
++
++#endif
++
+diff --git a/kleopatra/smimevalidationpreferences.cpp b/kleopatra/smimevalidationpreferences.cpp
+new file mode 100644
+index 0000000..3d9a16f
+--- /dev/null
++++ b/kleopatra/smimevalidationpreferences.cpp
+@@ -0,0 +1,22 @@
++// This file is generated by kconfig_compiler_kf5 from smimevalidationpreferences.kcfg.
++// All changes you do to this file will be lost.
++
++#include "smimevalidationpreferences.h"
++
++using namespace Kleo;
++
++SMimeValidationPreferences::SMimeValidationPreferences(  )
++  : KConfigSkeleton( QStringLiteral( "kleopatrarc" ) )
++{
++  setCurrentGroup( QStringLiteral( "SMime Validation" ) );
++
++  KConfigSkeleton::ItemUInt  *itemRefreshInterval;
++  itemRefreshInterval = new KConfigSkeleton::ItemUInt( currentGroup(), QStringLiteral( "refresh-interval" ), mRefreshInterval, 1 );
++  itemRefreshInterval->setMaxValue(24);
++  addItem( itemRefreshInterval, QStringLiteral( "RefreshInterval" ) );
++}
++
++SMimeValidationPreferences::~SMimeValidationPreferences()
++{
++}
++
+diff --git a/kleopatra/smimevalidationpreferences.h b/kleopatra/smimevalidationpreferences.h
+new file mode 100644
+index 0000000..9617bd5
+--- /dev/null
++++ b/kleopatra/smimevalidationpreferences.h
+@@ -0,0 +1,55 @@
++// This file is generated by kconfig_compiler_kf5 from smimevalidationpreferences.kcfg.
++// All changes you do to this file will be lost.
++#ifndef KLEO_SMIMEVALIDATIONPREFERENCES_H
++#define KLEO_SMIMEVALIDATIONPREFERENCES_H
++
++#include <qglobal.h>
++#include <kconfigskeleton.h>
++#include <QCoreApplication>
++#include <QDebug>
++
++namespace Kleo {
++
++class SMimeValidationPreferences : public KConfigSkeleton
++{
++  public:
++
++    SMimeValidationPreferences( );
++    ~SMimeValidationPreferences();
++
++    /**
++      Set Certificate refresh interval (in hours). Zero (0) disables.
++    */
++    void setRefreshInterval( uint v )
++    {
++
++      if (v > 24)
++      {
++        qDebug() << "setRefreshInterval: value " << v << " is greater than the maximum value of 24";
++        v = 24;
++      }
++
++      if (!isImmutable( QStringLiteral( "RefreshInterval" ) ))
++        mRefreshInterval = v;
++    }
++
++    /**
++      Get Certificate refresh interval (in hours). Zero (0) disables.
++    */
++    uint refreshInterval() const
++    {
++      return mRefreshInterval;
++    }
++
++  protected:
++
++    // SMime Validation
++    uint mRefreshInterval;
++
++  private:
++};
++
++}
++
++#endif
++
+diff --git a/kleopatra/tooltippreferences.cpp b/kleopatra/tooltippreferences.cpp
+new file mode 100644
+index 0000000..7e85c6a
+--- /dev/null
++++ b/kleopatra/tooltippreferences.cpp
+@@ -0,0 +1,27 @@
++// This file is generated by kconfig_compiler_kf5 from tooltippreferences.kcfg.
++// All changes you do to this file will be lost.
++
++#include "tooltippreferences.h"
++
++using namespace Kleo;
++
++TooltipPreferences::TooltipPreferences(  )
++  : KConfigSkeleton( QStringLiteral( "kleopatrarc" ) )
++{
++  setCurrentGroup( QStringLiteral( "Tooltip" ) );
++
++  KConfigSkeleton::ItemBool  *itemShowValidity;
++  itemShowValidity = new KConfigSkeleton::ItemBool( currentGroup(), QStringLiteral( "show-validity" ), mShowValidity, true );
++  addItem( itemShowValidity, QStringLiteral( "ShowValidity" ) );
++  KConfigSkeleton::ItemBool  *itemShowOwnerInformation;
++  itemShowOwnerInformation = new KConfigSkeleton::ItemBool( currentGroup(), QStringLiteral( "show-owner-information" ), mShowOwnerInformation, false );
++  addItem( itemShowOwnerInformation, QStringLiteral( "ShowOwnerInformation" ) );
++  KConfigSkeleton::ItemBool  *itemShowCertificateDetails;
++  itemShowCertificateDetails = new KConfigSkeleton::ItemBool( currentGroup(), QStringLiteral( "show-certificate-details" ), mShowCertificateDetails, false );
++  addItem( itemShowCertificateDetails, QStringLiteral( "ShowCertificateDetails" ) );
++}
++
++TooltipPreferences::~TooltipPreferences()
++{
++}
++
+diff --git a/kleopatra/tooltippreferences.h b/kleopatra/tooltippreferences.h
+new file mode 100644
+index 0000000..44f77a2
+--- /dev/null
++++ b/kleopatra/tooltippreferences.h
+@@ -0,0 +1,84 @@
++// This file is generated by kconfig_compiler_kf5 from tooltippreferences.kcfg.
++// All changes you do to this file will be lost.
++#ifndef KLEO_TOOLTIPPREFERENCES_H
++#define KLEO_TOOLTIPPREFERENCES_H
++
++#include <qglobal.h>
++#include <kconfigskeleton.h>
++#include <QCoreApplication>
++#include <QDebug>
++
++namespace Kleo {
++
++class TooltipPreferences : public KConfigSkeleton
++{
++  public:
++
++    TooltipPreferences( );
++    ~TooltipPreferences();
++
++    /**
++      Set Show certificate validity
++    */
++    void setShowValidity( bool v )
++    {
++      if (!isImmutable( QStringLiteral( "ShowValidity" ) ))
++        mShowValidity = v;
++    }
++
++    /**
++      Get Show certificate validity
++    */
++    bool showValidity() const
++    {
++      return mShowValidity;
++    }
++
++    /**
++      Set Show certificate owner information
++    */
++    void setShowOwnerInformation( bool v )
++    {
++      if (!isImmutable( QStringLiteral( "ShowOwnerInformation" ) ))
++        mShowOwnerInformation = v;
++    }
++
++    /**
++      Get Show certificate owner information
++    */
++    bool showOwnerInformation() const
++    {
++      return mShowOwnerInformation;
++    }
++
++    /**
++      Set Show certificate details
++    */
++    void setShowCertificateDetails( bool v )
++    {
++      if (!isImmutable( QStringLiteral( "ShowCertificateDetails" ) ))
++        mShowCertificateDetails = v;
++    }
++
++    /**
++      Get Show certificate details
++    */
++    bool showCertificateDetails() const
++    {
++      return mShowCertificateDetails;
++    }
++
++  protected:
++
++    // Tooltip
++    bool mShowValidity;
++    bool mShowOwnerInformation;
++    bool mShowCertificateDetails;
++
++  private:
++};
++
++}
++
++#endif
++
+--
+2.1.4
index 3659538..62fdcf1 100644 (file)
@@ -334,7 +334,8 @@ define gpg4win_pkg_qtsvg_post_install
 endef
 
 gpg4win_pkg_kleopatra_configure = \
-    -DFORCE_DISABLE_KCMUTILS=ON
+    -DFORCE_DISABLE_KCMUTILS=ON \
+    -DDISABLE_KWATCHGNUPG=ON
 
 gpg4win_pkg_kxmlgui_configure = \
     -DFORCE_DISABLE_KGLOBALACCEL=ON \