Hello community, here is the log from the commit of package kcmutils for openSUSE:Leap:15.2 checked in at 2020-06-11 16:17:58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/kcmutils (Old) and /work/SRC/openSUSE:Leap:15.2/.kcmutils.new.3606 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kcmutils" Thu Jun 11 16:17:58 2020 rev:65 rq:809903 version:5.70.0 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/kcmutils/kcmutils.changes 2020-05-12 11:38:48.832552717 +0200 +++ /work/SRC/openSUSE:Leap:15.2/.kcmutils.new.3606/kcmutils.changes 2020-06-11 16:18:01.158746436 +0200 @@ -1,0 +2,18 @@ +Fri May 22 14:53:24 UTC 2020 - Wolfgang Bauer <[email protected]> + +- Update Fix-crash-when-loading-external-app.patch to last version + that actually was committed upstream +- Add upstream patches to fix loading normal settings modules that + got broken by the previous fix (kde#421898), and add unit tests: + * Rename-KCModuleInfo-unittest-and-extend-it-with-fake-KCM.patch + * Add-test-for-a-normal-KCM-with-desktop-file.patch + * Repair-kcmshell5-after-previous-commits.patch + * Port-these-two-to-KCModuleInfo_property-as-well.patch + +------------------------------------------------------------------- +Wed May 20 21:07:16 UTC 2020 - Wolfgang Bauer <[email protected]> + +- Add Fix-crash-when-loading-external-app.patch to fix loading the + Yast entry in systemsettings (boo#1171916, kde#421566) + +------------------------------------------------------------------- New: ---- Add-test-for-a-normal-KCM-with-desktop-file.patch Fix-crash-when-loading-external-app.patch Port-these-two-to-KCModuleInfo_property-as-well.patch Rename-KCModuleInfo-unittest-and-extend-it-with-fake-KCM.patch Repair-kcmshell5-after-previous-commits.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kcmutils.spec ++++++ --- /var/tmp/diff_new_pack.LHrCpe/_old 2020-06-11 16:18:01.718747886 +0200 +++ /var/tmp/diff_new_pack.LHrCpe/_new 2020-06-11 16:18:01.718747886 +0200 @@ -36,6 +36,13 @@ Source2: frameworks.keyring %endif Source99: baselibs.conf +# PATCH-FIX-UPSTREAM +Patch: Fix-crash-when-loading-external-app.patch +# PATCH-FIX-UPSTREAM +Patch1: Rename-KCModuleInfo-unittest-and-extend-it-with-fake-KCM.patch +Patch2: Add-test-for-a-normal-KCM-with-desktop-file.patch +Patch3: Repair-kcmshell5-after-previous-commits.patch +Patch4: Port-these-two-to-KCModuleInfo_property-as-well.patch BuildRequires: cmake >= 3.5 BuildRequires: extra-cmake-modules >= %{_kf5_bugfix_version} BuildRequires: fdupes @@ -87,6 +94,7 @@ %prep %setup -q +%autopatch -p1 %build %cmake_kf5 -d build ++++++ Add-test-for-a-normal-KCM-with-desktop-file.patch ++++++ >From b1f56973ea194f69a5c8040ebdc500e23ef01f28 Mon Sep 17 00:00:00 2001 From: David Faure <[email protected]> Date: Fri, 22 May 2020 12:47:00 +0200 Subject: Add test for a "normal" KCM with desktop file --- autotests/CMakeLists.txt | 1 + autotests/desktopfilekcm/CMakeLists.txt | 6 ++ autotests/desktopfilekcm/kcmtest.cpp | 32 +++++++ autotests/desktopfilekcm/kcmtest.desktop | 149 +++++++++++++++++++++++++++++++ autotests/desktopfilekcm/kcmtest.h | 29 ++++++ autotests/kcmoduleinfotest.cpp | 20 +++++ 6 files changed, 237 insertions(+) create mode 100644 autotests/desktopfilekcm/CMakeLists.txt create mode 100644 autotests/desktopfilekcm/kcmtest.cpp create mode 100644 autotests/desktopfilekcm/kcmtest.desktop create mode 100644 autotests/desktopfilekcm/kcmtest.h diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 358ca4e..35ce99d 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -7,3 +7,4 @@ ecm_add_tests( ) add_subdirectory(jsonplugin) +add_subdirectory(desktopfilekcm) diff --git a/autotests/desktopfilekcm/CMakeLists.txt b/autotests/desktopfilekcm/CMakeLists.txt new file mode 100644 index 0000000..eb01930 --- /dev/null +++ b/autotests/desktopfilekcm/CMakeLists.txt @@ -0,0 +1,6 @@ +add_library(kcmtest MODULE kcmtest.cpp) + +kcoreaddons_desktop_to_json(kcmtest kcmtest.desktop) + +target_link_libraries(kcmtest KF5::CoreAddons) + diff --git a/autotests/desktopfilekcm/kcmtest.cpp b/autotests/desktopfilekcm/kcmtest.cpp new file mode 100644 index 0000000..574adb4 --- /dev/null +++ b/autotests/desktopfilekcm/kcmtest.cpp @@ -0,0 +1,32 @@ +/* + Copyright (c) 2020 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License or ( at + your option ) version 3 or, at the discretion of KDE e.V. ( which shall + act as a proxy as in section 14 of the GPLv3 ), 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 Lesser 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 "kcmtest.h" +#include <kpluginfactory.h> + +KCMTest::KCMTest(QObject *parent, const QVariantList &args) + : QObject(parent) +{ + Q_UNUSED(args) +} + +K_PLUGIN_FACTORY_WITH_JSON(kcmtestfactory, "kcmtest.json", registerPlugin<KCMTest>();) + +#include "kcmtest.moc" diff --git a/autotests/desktopfilekcm/kcmtest.desktop b/autotests/desktopfilekcm/kcmtest.desktop new file mode 100644 index 0000000..7d97fe0 --- /dev/null +++ b/autotests/desktopfilekcm/kcmtest.desktop @@ -0,0 +1,149 @@ +[Desktop Entry] +Exec=kcmshell5 kcmkded +Icon=preferences-system-session-services +Type=Service +X-KDE-ServiceTypes=KCModule + +X-KDE-Library=kcm_kded +X-KDE-ParentApp=kcontrol + +X-KDE-System-Settings-Parent-Category=session +X-KDE-Weight=50 +X-DocPath=kcontrol/kded/index.html + +Name=Background Services +Name[ar]=خدمات الخلفيّة +Name[ast]=Servicios en segundu planu +Name[bs]=Pozadinski servisi +Name[ca]=Serveis en segon pla +Name[ca@valencia]=Serveis en segon pla +Name[cs]=Služby na pozadí +Name[da]=Baggrundstjenester +Name[de]=Hintergrunddienste +Name[el]=Υπηρεσίες παρασκηνίου +Name[en_GB]=Background Services +Name[es]=Servicios en segundo plano +Name[et]=Taustateenused +Name[eu]=Atzeko planoko zerbitzuak +Name[fi]=Taustapalvelut +Name[fr]=Services d'arrière plan +Name[gl]=Servizos en segundo plano +Name[he]=שירותי רקע +Name[hu]=Háttérszolgáltatások +Name[ia]=Servicios de fundo (in background) +Name[id]=Layanan Latarbelakang +Name[is]=Bakgrunnsþjónustur +Name[it]=Servizi in background +Name[ko]=배경 서비스 +Name[lt]=Foninės tarnybos +Name[nb]=Bakgrunnstjenester +Name[nds]=Achtergrunddeensten +Name[nl]=Achtergrondservices +Name[nn]=Bakgrunnstenester +Name[pa]=ਬੈਕਗਰਾਊਂਡ ਸੇਵਾਵਾਂ +Name[pl]=Usługi w tle +Name[pt]=Serviços de Segundo Plano +Name[pt_BR]=Serviços de segundo plano +Name[ru]=Управление службами +Name[sk]=Služby pozadia +Name[sl]=Storitve v ozadju +Name[sr]=Позадински сервиси +Name[sr@ijekavian]=Позадински сервиси +Name[sr@ijekavianlatin]=Pozadinski servisi +Name[sr@latin]=Pozadinski servisi +Name[sv]=Bakgrundstjänster +Name[tr]=Arkaplan Servisleri +Name[uk]=Фонові служби +Name[x-test]=xxBackground Servicesxx +Name[zh_CN]=后台服务 +Name[zh_TW]=背景服務 +Comment=Configure background services +Comment[ast]=Configura los servicios en segundu planu +Comment[ca]=Configura els serveis en segon pla +Comment[cs]=Nastavit služby na pozadí +Comment[de]=Hintergrunddienste einrichten +Comment[en_GB]=Configure background services +Comment[es]=Configurar los servicios en segundo plano +Comment[et]=Taustateenuste seadistamine +Comment[eu]=Konfiguratu atzeko planoko zerbitzuak +Comment[fi]=Taustapalveluasetukset +Comment[fr]=Configurer les services d'arrière plan +Comment[ia]=Configura servicios de fundo +Comment[id]=Konfigurasikan layanan latarbelakang +Comment[it]=Configura i servizi in background +Comment[ko]=배경 서비스 설정 +Comment[lt]=Konfigūruoti fonines tarnybas +Comment[nl]=Achtergrondservices configureren +Comment[nn]=Set opp bakgrunnstenester +Comment[pt]=Configurar os serviços de segundo plano +Comment[pt_BR]=Configurar os serviços de segundo plano +Comment[ru]=Настройка служб KDE +Comment[sk]=Nastaviť služby na pozadí +Comment[sl]=Nastavi storitve v ozadju +Comment[sv]=Anpassa bakgrundstjänster +Comment[uk]=Налаштування фонових служб +Comment[x-test]=xxConfigure background servicesxx +Comment[zh_CN]=配置后台服务 +Comment[zh_TW]=設定背景服務 +X-KDE-Keywords=KDED,Daemon,Services +X-KDE-Keywords[ast]=KDED,Degorriu,Servicios +X-KDE-Keywords[bg]=KDED,Daemon,Services,Услуги +X-KDE-Keywords[bn]=KDED,Daemon,Services +X-KDE-Keywords[bs]=KDED,Daemon,Services,demon,usluge +X-KDE-Keywords[ca]=KDED,Dimoni,Serveis +X-KDE-Keywords[ca@valencia]=KDED,Dimoni,Serveis +X-KDE-Keywords[cs]=KDED,Démon,Služby +X-KDE-Keywords[da]=KDED,dæmon,tjenester +X-KDE-Keywords[de]=KDED,Dienst,Services,Dienste +X-KDE-Keywords[el]=KDED,Daemon,Services +X-KDE-Keywords[en_GB]=KDED,Daemon,Services +X-KDE-Keywords[eo]=KDED,Demono,Servoj +X-KDE-Keywords[es]=KDED,Demonio,Servicios +X-KDE-Keywords[et]=KDED,deemon,teenused +X-KDE-Keywords[eu]=KDED,daemon-a,zerbitzuak +X-KDE-Keywords[fa]=KDED,Daemon,Services +X-KDE-Keywords[fi]=KDED,Palvelu,Taustaprosessi,Palvelin,Palvelut +X-KDE-Keywords[fr]=KDED, démon, services +X-KDE-Keywords[ga]=KDED,Deamhan,Seirbhísí +X-KDE-Keywords[gl]=KDED,servizo,servizos +X-KDE-Keywords[gu]=KDED,ડેમન,સેવાઓ +X-KDE-Keywords[he]=KDED,Daemon,Services,שירותים +X-KDE-Keywords[hi]=KDED,डेमन सेवाएँ +X-KDE-Keywords[hu]=KDED,Démon,Szolgáltatások +X-KDE-Keywords[ia]=KDED,Daemon,Servicios +X-KDE-Keywords[id]=KDED,Daemon,Layanan +X-KDE-Keywords[is]=KDED,Þjónusta,Þjónustur +X-KDE-Keywords[it]=KDED,demone,servizi +X-KDE-Keywords[kk]=KDED,Daemon,Services +X-KDE-Keywords[km]=KDED ដេមិន សេវាកម្ម +X-KDE-Keywords[ko]=KDED,Daemon,Services,데몬,서비스 +X-KDE-Keywords[lt]=KDED,tarnyba,paslaugos +X-KDE-Keywords[lv]=KDED,dēmons,servisi +X-KDE-Keywords[mr]=केडीईD, डीमन, सेवा +X-KDE-Keywords[nb]=KDED,Daemon,Tjenester +X-KDE-Keywords[nds]=KDED,Dämoon,Deensten +X-KDE-Keywords[nl]=KDED,daemon,services +X-KDE-Keywords[nn]=KDED,daemon,tenester,tenester +X-KDE-Keywords[pa]=KDED,ਡੈਮਨ,ਸਰਵਿਸਾਂ +X-KDE-Keywords[pl]=KDED,Demon,Usługi +X-KDE-Keywords[pt]=KDED,Servidor,Serviços +X-KDE-Keywords[pt_BR]=KDED,Servidor,Serviços +X-KDE-Keywords[ro]=KDED,Servicii,Demon +X-KDE-Keywords[ru]=KDED,Daemon,Services,фоновая служба,демон,служба +X-KDE-Keywords[sk]=KDED,Démon,Služby +X-KDE-Keywords[sl]=KDED,ozadnji program,storitve +X-KDE-Keywords[sr]=KDED,Daemon,Services,КДЕД,демон,сервис +X-KDE-Keywords[sr@ijekavian]=KDED,Daemon,Services,КДЕД,демон,сервис +X-KDE-Keywords[sr@ijekavianlatin]=KDED,Daemon,Services,KDED,demon,servis +X-KDE-Keywords[sr@latin]=KDED,Daemon,Services,KDED,demon,servis +X-KDE-Keywords[sv]=KDED,Demon,Tjänster +X-KDE-Keywords[tr]=KDED,Servis,Servisler +X-KDE-Keywords[ug]=KDED،Daemon، مۇلازىمەتلەر +X-KDE-Keywords[uk]=KDED,Daemon,Services,служба,служби,фонова служба,фонові служби +X-KDE-Keywords[vi]=KDED,Trình nền,Dịch vụ, Daemon,Services +X-KDE-Keywords[wa]=KDED,Démon,Demon,Siervices +X-KDE-Keywords[x-test]=xxKDEDxx,xxDaemonxx,xxServicesxx +X-KDE-Keywords[zh_CN]=KDED,Daemon,Services,服务,后台进程 +X-KDE-Keywords[zh_TW]=KDED,Daemon,Services + +Categories=Qt;KDE;X-KDE-settings-components; diff --git a/autotests/desktopfilekcm/kcmtest.h b/autotests/desktopfilekcm/kcmtest.h new file mode 100644 index 0000000..84a34f1 --- /dev/null +++ b/autotests/desktopfilekcm/kcmtest.h @@ -0,0 +1,29 @@ +/* + Copyright (c) 2020 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License or ( at + your option ) version 3 or, at the discretion of KDE e.V. ( which shall + act as a proxy as in section 14 of the GPLv3 ), 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 Lesser 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 <QObject> +#include <QVariantList> + +class KCMTest : public QObject +{ + Q_OBJECT +public: + explicit KCMTest(QObject* parent, const QVariantList& foo = QVariantList()); +}; diff --git a/autotests/kcmoduleinfotest.cpp b/autotests/kcmoduleinfotest.cpp index 48c271d..8b2dbae 100644 --- a/autotests/kcmoduleinfotest.cpp +++ b/autotests/kcmoduleinfotest.cpp @@ -32,6 +32,7 @@ class KCModuleInfoTest : public QObject private Q_SLOTS: void testExternalApp(); void testFakeKCM(); + void testDesktopFileKCM(); }; void KCModuleInfoTest::testExternalApp() @@ -58,11 +59,30 @@ void KCModuleInfoTest::testFakeKCM() // THEN QCOMPARE(info.pluginInfo().name(), QStringLiteral("Test")); QCOMPARE(QFileInfo(info.library()).fileName(), QStringLiteral("jsonplugin.so")); + QCOMPARE(QFileInfo(info.fileName()).fileName(), QStringLiteral("jsonplugin.so")); QCOMPARE(info.icon(), QStringLiteral("view-pim-mail")); QCOMPARE(info.comment(), QStringLiteral("Test plugin")); QCOMPARE(info.docPath(), QStringLiteral("doc/path")); QVERIFY(!info.service()); } +void KCModuleInfoTest::testDesktopFileKCM() +{ + const QString desktopFile = QFINDTESTDATA("desktopfilekcm/kcmtest.desktop"); + QVERIFY(!desktopFile.isEmpty()); + + // WHEN + KCModuleInfo info(desktopFile); + + // THEN + QVERIFY(info.service()); + QVERIFY(!info.pluginInfo().isValid()); + QCOMPARE(QFileInfo(info.library()).fileName(), QStringLiteral("kcm_kded")); + QCOMPARE(QFileInfo(info.fileName()).fileName(), QStringLiteral("kcmtest.desktop")); + QCOMPARE(info.icon(), QStringLiteral("preferences-system-session-services")); + QCOMPARE(info.comment(), QStringLiteral("Configure background services")); + QCOMPARE(info.docPath(), QStringLiteral("kcontrol/kded/index.html")); +} + QTEST_MAIN(KCModuleInfoTest) #include "kcmoduleinfotest.moc" -- cgit v1.1 ++++++ Fix-crash-when-loading-external-app.patch ++++++ >From 53b41bc90b354ce7642f29d0f0a0464b32b29860 Mon Sep 17 00:00:00 2001 From: David Faure <[email protected]> Date: Wed, 20 May 2020 22:50:35 +0200 Subject: Fix crash when loading an external app KCM like yast This re-instates the use of KService as a first-class citizen in KCModuleInfo, apparently needed for non-plugins. A unittest ensures that the very basic use of service() on such a desktop file doesn't crash. BUG: 421566 --- CMakeLists.txt | 5 ++- autotests/CMakeLists.txt | 7 ++++ autotests/YaST-systemsettings.desktop | 8 ++++ autotests/kplugininfotest.cpp | 42 +++++++++++++++++++ src/kcmoduleinfo.cpp | 76 +++++++++++++++++++++++++++-------- 5 files changed, 120 insertions(+), 18 deletions(-) create mode 100644 autotests/CMakeLists.txt create mode 100644 autotests/YaST-systemsettings.desktop create mode 100644 autotests/kplugininfotest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e3a3d5c..6131840 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(KDECMakeSettings) set(REQUIRED_QT_VERSION 5.12.0) -find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE REQUIRED Widgets DBus Qml Quick QuickWidgets) +find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE REQUIRED Widgets DBus Qml Quick QuickWidgets Test) include(ECMGenerateExportHeader) include(ECMSetupVersion) @@ -58,6 +58,9 @@ if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po") endif() add_definitions(-DQT_NO_FOREACH) add_subdirectory(src) +if(BUILD_TESTING) +add_subdirectory(autotests) +endif() # create a Config.cmake and a ConfigVersion.cmake file and install them diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt new file mode 100644 index 0000000..d494215 --- /dev/null +++ b/autotests/CMakeLists.txt @@ -0,0 +1,7 @@ +include(ECMAddTests) + +ecm_add_tests( + kplugininfotest.cpp + + LINK_LIBRARIES KF5KCMUtils Qt5::Test +) diff --git a/autotests/YaST-systemsettings.desktop b/autotests/YaST-systemsettings.desktop new file mode 100644 index 0000000..c33c091 --- /dev/null +++ b/autotests/YaST-systemsettings.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Type=Service +Name=YaST +Icon=yast-control-center +GenericName=Administrator Settings +Exec=kdesu -c /sbin/yast2 +X-KDE-System-Settings-Parent-Category=system-administration +X-KDE-ServiceTypes=SystemSettingsExternalApp diff --git a/autotests/kplugininfotest.cpp b/autotests/kplugininfotest.cpp new file mode 100644 index 0000000..6541eb4 --- /dev/null +++ b/autotests/kplugininfotest.cpp @@ -0,0 +1,42 @@ +/* This file is part of the KDE Frameworks + Copyright (c) 2020 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License or ( at + your option ) version 3 or, at the discretion of KDE e.V. ( which shall + act as a proxy as in section 14 of the GPLv3 ), 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 Lesser 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 <QTest> +#include <QObject> +#include <KCModuleInfo> + +class KPluginInfoTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void testExternalApp(); +}; + +void KPluginInfoTest::testExternalApp() +{ + const QString yast = QFINDTESTDATA("YaST-systemsettings.desktop"); + QVERIFY(!yast.isEmpty()); + KCModuleInfo info(yast); + QVERIFY(info.service()); +} + +QTEST_MAIN(KPluginInfoTest) +#include "kplugininfotest.moc" diff --git a/src/kcmoduleinfo.cpp b/src/kcmoduleinfo.cpp index 11d6643..8f27b9c 100644 --- a/src/kcmoduleinfo.cpp +++ b/src/kcmoduleinfo.cpp @@ -43,8 +43,12 @@ public: bool allLoaded = false; int weight = 100; + // For real C++ plugins KPluginInfo pluginInfo; + // Can be a C++ plugin, or just a desktop file launching an executable (see autotest) + KService::Ptr service; + /** * Reads the service entries specific for KCModule from the desktop file. * The usual desktop entries are read in the Private ctor. @@ -73,19 +78,35 @@ KCModuleInfo::Private::Private(const KPluginInfo &pluginInfo) keywords = pluginInfo.property(QStringLiteral("Keywords")).toStringList(); } +KCModuleInfo::Private::Private(const KService::Ptr &service) + : allLoaded(false), + pluginInfo(), + service(service) +{ + if (!service) { + return; + } + + name = service->name(); + comment = service->comment(); + icon = service->icon(); + fileName = service->entryPath(); + lib = service->library(); + keywords = service->keywords(); +} + KCModuleInfo::KCModuleInfo() : d(new Private) { } KCModuleInfo::KCModuleInfo(const QString &desktopFile) -// TODO KF6: turn this into KPluginMetaData(file) so that most callers still work, after adding the JSON to the .so files - : d(new Private(KPluginInfo(KService::serviceByStorageId(desktopFile)))) + : d(new Private(KService::serviceByStorageId(desktopFile))) { } KCModuleInfo::KCModuleInfo(KService::Ptr service) - : d(new Private(KPluginInfo(service))) + : d(new Private(service)) { } @@ -125,24 +146,39 @@ void KCModuleInfo::Private::loadAll() { allLoaded = true; - if (!pluginInfo.isValid()) { /* We have a bogus service. All get functions will return empty/zero values */ + if (!pluginInfo.isValid() && !service) { /* We have a bogus service. All get functions will return empty/zero values */ return; } - // get the documentation path - doc = pluginInfo.property(QStringLiteral("X-DocPath")).toString(); - if (doc.isEmpty()) { - doc = pluginInfo.property(QStringLiteral("DocPath")).toString(); + if (service) { + // get the documentation path + doc = service->property(QStringLiteral("X-DocPath"), QVariant::String).toString(); + if (doc.isEmpty()) { + doc = service->property(QStringLiteral("DocPath"), QVariant::String).toString(); + } + + // read weight + QVariant tmp = service->property(QStringLiteral("X-KDE-Weight"), QVariant::Int); + weight = tmp.isValid() ? tmp.toInt() : 100; + + // factory handle + tmp = service->property(QStringLiteral("X-KDE-FactoryName"), QVariant::String); + handle = tmp.isValid() ? tmp.toString() : lib; + } else { + // get the documentation path + doc = pluginInfo.property(QStringLiteral("X-DocPath")).toString(); + if (doc.isEmpty()) { + doc = pluginInfo.property(QStringLiteral("DocPath")).toString(); + } + + // read weight + QVariant tmp = pluginInfo.property(QStringLiteral("X-KDE-Weight")).toInt(); + weight = tmp.isValid() ? tmp.toInt() : 100; + + // factory handle + tmp = pluginInfo.property(QStringLiteral("X-KDE-FactoryName")); + handle = tmp.isValid() ? tmp.toString() : lib; } - - // read weight - QVariant tmp = pluginInfo.property(QStringLiteral("X-KDE-Weight")).toInt(); - weight = tmp.isValid() ? tmp.toInt() : 100; - - // factory handle - tmp = pluginInfo.property(QStringLiteral("X-KDE-FactoryName")); - handle = tmp.isValid() ? tmp.toString() : lib; - } QString KCModuleInfo::fileName() const @@ -162,6 +198,12 @@ QString KCModuleInfo::moduleName() const KService::Ptr KCModuleInfo::service() const { + if (d->service) { + return d->service; + } + if (!d->pluginInfo.isValid()) { + return {}; + } return d->pluginInfo.service(); } -- cgit v1.1 ++++++ Port-these-two-to-KCModuleInfo_property-as-well.patch ++++++ >From e290e9e666fcf7a84dcd42529f4069d4c92098ae Mon Sep 17 00:00:00 2001 From: David Faure <[email protected]> Date: Fri, 22 May 2020 14:18:42 +0200 Subject: Port these two to KCModuleInfo::property() as well, seems to fix Configure Kontact NO_CHANGELOG --- src/ksettings/dialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ksettings/dialog.cpp b/src/ksettings/dialog.cpp index 2412413..08bd4a1 100644 --- a/src/ksettings/dialog.cpp +++ b/src/ksettings/dialog.cpp @@ -329,7 +329,7 @@ void DialogPrivate::createDialogFromServices() //qDebug() << kcmInfos.count(); for (const KCModuleInfo &info : qAsConst(kcmInfos)) { - const QStringList parentComponents = info.pluginInfo().property(QStringLiteral("X-KDE-ParentComponents")).toStringList(); + const QStringList parentComponents = info.property(QStringLiteral("X-KDE-ParentComponents")).toStringList(); bool blacklisted = false; for (const QString &parentComponent : parentComponents) { if (componentBlacklist.contains(parentComponent)) { @@ -340,7 +340,7 @@ void DialogPrivate::createDialogFromServices() if (blacklisted) { continue; } - const QString parentId = info.pluginInfo().property(QStringLiteral("X-KDE-CfgDlgHierarchy")).toString(); + const QString parentId = info.property(QStringLiteral("X-KDE-CfgDlgHierarchy")).toString(); KPageWidgetItem *parent = pageItemForGroupId.value(parentId); if (!parent) { // dummy kcm -- cgit v1.1 ++++++ Rename-KCModuleInfo-unittest-and-extend-it-with-fake-KCM.patch ++++++ >From a65c6819464b5a91e038d17f422bb43cfcdf30be Mon Sep 17 00:00:00 2001 From: David Faure <[email protected]> Date: Fri, 22 May 2020 12:29:20 +0200 Subject: Rename KCModuleInfo unittest and extend it with the "fake KCM" testcase --- autotests/CMakeLists.txt | 4 +- autotests/jsonplugin/CMakeLists.txt | 8 ++++ autotests/jsonplugin/jsonplugin.cpp | 18 +++++++++ autotests/jsonplugin/jsonplugin.desktop | 17 +++++++++ autotests/jsonplugin/jsonplugin.h | 20 ++++++++++ autotests/kcmoduleinfotest.cpp | 68 +++++++++++++++++++++++++++++++++ autotests/kplugininfotest.cpp | 42 -------------------- 7 files changed, 134 insertions(+), 43 deletions(-) create mode 100644 autotests/jsonplugin/CMakeLists.txt create mode 100644 autotests/jsonplugin/jsonplugin.cpp create mode 100644 autotests/jsonplugin/jsonplugin.desktop create mode 100644 autotests/jsonplugin/jsonplugin.h create mode 100644 autotests/kcmoduleinfotest.cpp delete mode 100644 autotests/kplugininfotest.cpp diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index d494215..358ca4e 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -1,7 +1,9 @@ include(ECMAddTests) ecm_add_tests( - kplugininfotest.cpp + kcmoduleinfotest.cpp LINK_LIBRARIES KF5KCMUtils Qt5::Test ) + +add_subdirectory(jsonplugin) diff --git a/autotests/jsonplugin/CMakeLists.txt b/autotests/jsonplugin/CMakeLists.txt new file mode 100644 index 0000000..739f4a4 --- /dev/null +++ b/autotests/jsonplugin/CMakeLists.txt @@ -0,0 +1,8 @@ + +add_library(jsonplugin MODULE jsonplugin.cpp) + +kcoreaddons_desktop_to_json(jsonplugin jsonplugin.desktop) + +target_link_libraries(jsonplugin KF5::CoreAddons) + +set_target_properties(jsonplugin PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/testplugins") diff --git a/autotests/jsonplugin/jsonplugin.cpp b/autotests/jsonplugin/jsonplugin.cpp new file mode 100644 index 0000000..f2eff39 --- /dev/null +++ b/autotests/jsonplugin/jsonplugin.cpp @@ -0,0 +1,18 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler <[email protected]> + + SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +*/ + +#include "jsonplugin.h" +#include <kpluginfactory.h> + +JsonPlugin::JsonPlugin(QObject *parent, const QVariantList &args) + : QObject(parent) +{ + Q_UNUSED(args) +} + +K_PLUGIN_FACTORY_WITH_JSON(jsonpluginfa, "jsonplugin.json", registerPlugin<JsonPlugin>();) + +#include "jsonplugin.moc" diff --git a/autotests/jsonplugin/jsonplugin.desktop b/autotests/jsonplugin/jsonplugin.desktop new file mode 100644 index 0000000..6f4c64a --- /dev/null +++ b/autotests/jsonplugin/jsonplugin.desktop @@ -0,0 +1,17 @@ +[Desktop Entry] +Type=Service +Icon=view-pim-mail +X-KDE-ServiceTypes=KPluginInfo + +X-KDE-Library=jsonplugin + +X-KDE-PluginInfo-Name=jsonplugin +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +X-DocPath=doc/path + +Comment=Test plugin +Name=Test + diff --git a/autotests/jsonplugin/jsonplugin.h b/autotests/jsonplugin/jsonplugin.h new file mode 100644 index 0000000..1ffe6ae --- /dev/null +++ b/autotests/jsonplugin/jsonplugin.h @@ -0,0 +1,20 @@ +/* + SPDX-FileCopyrightText: 2013 Sebastian Kügler <[email protected]> + + SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +*/ + +#ifndef JSONPLUGIN_H +#define JSONPLUGIN_H + +#include <QObject> + +class JsonPlugin : public QObject +{ + Q_OBJECT + +public: + explicit JsonPlugin(QObject *parent, const QVariantList &args); +}; + +#endif // JSONPLUGIN_H diff --git a/autotests/kcmoduleinfotest.cpp b/autotests/kcmoduleinfotest.cpp new file mode 100644 index 0000000..48c271d --- /dev/null +++ b/autotests/kcmoduleinfotest.cpp @@ -0,0 +1,68 @@ +/* This file is part of the KDE Frameworks + Copyright (c) 2020 David Faure <[email protected]> + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License or ( at + your option ) version 3 or, at the discretion of KDE e.V. ( which shall + act as a proxy as in section 14 of the GPLv3 ), 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 Lesser 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 <QTest> +#include <QObject> +#include <KCModuleInfo> +#include <KPluginLoader> +#include <KPluginMetaData> +#include <KPluginInfo> + +class KCModuleInfoTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void testExternalApp(); + void testFakeKCM(); +}; + +void KCModuleInfoTest::testExternalApp() +{ + const QString yast = QFINDTESTDATA("YaST-systemsettings.desktop"); + QVERIFY(!yast.isEmpty()); + KCModuleInfo info(yast); + QVERIFY(info.service()); +} + +void KCModuleInfoTest::testFakeKCM() +{ + // Similar to kontact's code + const QVector<KPluginMetaData> pluginMetaDatas = KPluginLoader::findPlugins( + QStringLiteral("testplugins"), [](const KPluginMetaData &) { return true; }); + const QList<KPluginInfo> pluginInfos = KPluginInfo::fromMetaData(pluginMetaDatas); + QVERIFY(pluginInfos.count() > 0); + KPluginInfo pluginInfo = pluginInfos.at(0); + QVERIFY(pluginInfo.isValid()); + + // WHEN + KCModuleInfo info(pluginInfo); // like Dialog::addPluginInfos does + + // THEN + QCOMPARE(info.pluginInfo().name(), QStringLiteral("Test")); + QCOMPARE(QFileInfo(info.library()).fileName(), QStringLiteral("jsonplugin.so")); + QCOMPARE(info.icon(), QStringLiteral("view-pim-mail")); + QCOMPARE(info.comment(), QStringLiteral("Test plugin")); + QCOMPARE(info.docPath(), QStringLiteral("doc/path")); + QVERIFY(!info.service()); +} + +QTEST_MAIN(KCModuleInfoTest) +#include "kcmoduleinfotest.moc" diff --git a/autotests/kplugininfotest.cpp b/autotests/kplugininfotest.cpp deleted file mode 100644 index 6541eb4..0000000 --- a/autotests/kplugininfotest.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* This file is part of the KDE Frameworks - Copyright (c) 2020 David Faure <[email protected]> - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2 of the License or ( at - your option ) version 3 or, at the discretion of KDE e.V. ( which shall - act as a proxy as in section 14 of the GPLv3 ), 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 Lesser 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 <QTest> -#include <QObject> -#include <KCModuleInfo> - -class KPluginInfoTest : public QObject -{ - Q_OBJECT - -private Q_SLOTS: - void testExternalApp(); -}; - -void KPluginInfoTest::testExternalApp() -{ - const QString yast = QFINDTESTDATA("YaST-systemsettings.desktop"); - QVERIFY(!yast.isEmpty()); - KCModuleInfo info(yast); - QVERIFY(info.service()); -} - -QTEST_MAIN(KPluginInfoTest) -#include "kplugininfotest.moc" -- cgit v1.1 ++++++ Repair-kcmshell5-after-previous-commits.patch ++++++ >From c2db5f797fd3f1eb632de8baa7c034469af69ed1 Mon Sep 17 00:00:00 2001 From: David Faure <[email protected]> Date: Fri, 22 May 2020 13:22:54 +0200 Subject: Repair kcmshell5 after previous commits, now with unittest --- autotests/kcmoduleinfotest.cpp | 16 ++++++++++++++++ src/kcmoduleinfo.cpp | 14 ++++++++++++++ src/kcmoduleinfo.h | 14 ++++++++++++++ src/kcmoduleloader.cpp | 6 ++++-- src/kcmultidialog.cpp | 4 ++-- src/kpluginselector.cpp | 2 +- src/ksettings/dialog.cpp | 2 +- 7 files changed, 52 insertions(+), 6 deletions(-) diff --git a/autotests/kcmoduleinfotest.cpp b/autotests/kcmoduleinfotest.cpp index 8b2dbae..9e7bc6a 100644 --- a/autotests/kcmoduleinfotest.cpp +++ b/autotests/kcmoduleinfotest.cpp @@ -21,6 +21,7 @@ #include <QTest> #include <QObject> #include <KCModuleInfo> +#include <KCMultiDialog> #include <KPluginLoader> #include <KPluginMetaData> #include <KPluginInfo> @@ -33,6 +34,7 @@ private Q_SLOTS: void testExternalApp(); void testFakeKCM(); void testDesktopFileKCM(); + void testInvalidKCM(); }; void KCModuleInfoTest::testExternalApp() @@ -41,6 +43,7 @@ void KCModuleInfoTest::testExternalApp() QVERIFY(!yast.isEmpty()); KCModuleInfo info(yast); QVERIFY(info.service()); + QVERIFY(info.isValid()); } void KCModuleInfoTest::testFakeKCM() @@ -57,6 +60,7 @@ void KCModuleInfoTest::testFakeKCM() KCModuleInfo info(pluginInfo); // like Dialog::addPluginInfos does // THEN + QVERIFY(info.isValid()); QCOMPARE(info.pluginInfo().name(), QStringLiteral("Test")); QCOMPARE(QFileInfo(info.library()).fileName(), QStringLiteral("jsonplugin.so")); QCOMPARE(QFileInfo(info.fileName()).fileName(), QStringLiteral("jsonplugin.so")); @@ -75,6 +79,7 @@ void KCModuleInfoTest::testDesktopFileKCM() KCModuleInfo info(desktopFile); // THEN + QVERIFY(info.isValid()); QVERIFY(info.service()); QVERIFY(!info.pluginInfo().isValid()); QCOMPARE(QFileInfo(info.library()).fileName(), QStringLiteral("kcm_kded")); @@ -82,6 +87,17 @@ void KCModuleInfoTest::testDesktopFileKCM() QCOMPARE(info.icon(), QStringLiteral("preferences-system-session-services")); QCOMPARE(info.comment(), QStringLiteral("Configure background services")); QCOMPARE(info.docPath(), QStringLiteral("kcontrol/kded/index.html")); + + // WHEN actually loading the module + KCMultiDialog dlg; + QVERIFY(dlg.addModule(info)); +} + +void KCModuleInfoTest::testInvalidKCM() +{ + KCModuleInfo info(QStringLiteral("doest_not_exist.desktop")); + QVERIFY(!info.isValid()); + QVERIFY(!info.service()); } QTEST_MAIN(KCModuleInfoTest) diff --git a/src/kcmoduleinfo.cpp b/src/kcmoduleinfo.cpp index 8f27b9c..faea919 100644 --- a/src/kcmoduleinfo.cpp +++ b/src/kcmoduleinfo.cpp @@ -142,6 +142,11 @@ KCModuleInfo::~KCModuleInfo() delete d; } +bool KCModuleInfo::isValid() const +{ + return d->pluginInfo.isValid() || d->service; +} + void KCModuleInfo::Private::loadAll() { allLoaded = true; @@ -254,3 +259,12 @@ int KCModuleInfo::weight() const return d->weight; } +QVariant KCModuleInfo::property(const QString &key) const +{ + if (d->service) { + return d->service->property(key); + } else { + return d->pluginInfo.property(key); + } +} + diff --git a/src/kcmoduleinfo.h b/src/kcmoduleinfo.h index 4dc998e..529ba33 100644 --- a/src/kcmoduleinfo.h +++ b/src/kcmoduleinfo.h @@ -111,6 +111,12 @@ public: ~KCModuleInfo(); /** + * Returns true if the KCM was found + * @since 5.71 + */ + bool isValid() const; + + /** * @return the filename of the .desktop file that describes the KCM */ QString fileName() const; @@ -170,6 +176,14 @@ public: */ int weight() const; + /** + * @return The value associated to the @p key. You can use it if you + * want to read custom values. To do this you need to define + * your own servicetype and add it to the ServiceTypes keys. + * @since 5.71 + */ + QVariant property(const QString &key) const; + private: class Private; Private *d; diff --git a/src/kcmoduleloader.cpp b/src/kcmoduleloader.cpp index 197023e..113da6f 100644 --- a/src/kcmoduleloader.cpp +++ b/src/kcmoduleloader.cpp @@ -74,14 +74,16 @@ KCModule *KCModuleLoader::loadModule(const KCModuleInfo &mod, ErrorReporting rep * from the factory. */ - if (!mod.pluginInfo().isValid()) + if (!mod.isValid()) { return reportError(report, i18n("The module %1 could not be found.", mod.moduleName()), i18n("<qt><p>The diagnosis is:<br />The desktop file %1 could not be found.</p></qt>", mod.fileName()), parent); - if (mod.service() && mod.service()->noDisplay()) + } + if (mod.service() && mod.service()->noDisplay()) { return reportError(report, i18n("The module %1 is disabled.", mod.moduleName()), i18n("<qt><p>Either the hardware/software the module configures is not available or the module has been disabled by the administrator.</p></qt>"), parent); + } if (!mod.library().isEmpty()) { QString error; diff --git a/src/kcmultidialog.cpp b/src/kcmultidialog.cpp index 82d0fb1..49e9137 100644 --- a/src/kcmultidialog.cpp +++ b/src/kcmultidialog.cpp @@ -464,7 +464,7 @@ KPageWidgetItem *KCMultiDialog::addModule(const KCModuleInfo &moduleInfo, KPageWidgetItem *parentItem, const QStringList &args) { Q_D(KCMultiDialog); - if (!moduleInfo.pluginInfo().isValid()) { + if (!moduleInfo.isValid()) { return nullptr; } @@ -490,7 +490,7 @@ KPageWidgetItem *KCMultiDialog::addModule(const KCModuleInfo &moduleInfo, KCMultiDialogPrivate::CreatedModule cm; cm.kcm = kcm; cm.item = item; - cm.componentNames = moduleInfo.pluginInfo().property(QStringLiteral("X-KDE-ParentComponents")).toStringList(); + cm.componentNames = moduleInfo.property(QStringLiteral("X-KDE-ParentComponents")).toStringList(); d->modules.append(cm); if (qobject_cast<KCModuleQml *>(kcm->realModule())) { diff --git a/src/kpluginselector.cpp b/src/kpluginselector.cpp index 9788e36..3477fc2 100644 --- a/src/kpluginselector.cpp +++ b/src/kpluginselector.cpp @@ -891,7 +891,7 @@ void KPluginSelector::Private::PluginDelegate::configure(const QModelIndex& inde if (configDialog.exec() == QDialog::Accepted) { for (KCModuleProxy *moduleProxy : qAsConst(moduleProxyList)) { - const QStringList parentComponents = moduleProxy->moduleInfo().pluginInfo().property(QStringLiteral("X-KDE-ParentComponents")).toStringList(); + const QStringList parentComponents = moduleProxy->moduleInfo().property(QStringLiteral("X-KDE-ParentComponents")).toStringList(); moduleProxy->save(); for (const QString &parentComponent : parentComponents) { emit configCommitted(parentComponent.toLatin1()); diff --git a/src/ksettings/dialog.cpp b/src/ksettings/dialog.cpp index c64da39..2412413 100644 --- a/src/ksettings/dialog.cpp +++ b/src/ksettings/dialog.cpp @@ -191,7 +191,7 @@ bool DialogPrivate::isPluginForKCMEnabled(const KCModuleInfo *moduleinfo, KPlugi bool enabled = true; //qDebug() << "check whether the '" << moduleinfo->moduleName() << "' KCM should be shown"; // for all parent components - const QStringList parentComponents = moduleinfo->pluginInfo().property( + const QStringList parentComponents = moduleinfo->property( QStringLiteral("X-KDE-ParentComponents")).toStringList(); for (QStringList::ConstIterator pcit = parentComponents.begin(); pcit != parentComponents.end(); ++pcit) { -- cgit v1.1
