From 79cffa4975b51a57406fb36918b63df2f1fc745d Mon Sep 17 00:00:00 2001 From: David Korth Date: Wed, 19 Dec 2018 20:02:18 -0500 Subject: [PATCH] [kde5] RpOverlayIconPlugin: New plugin (and forwarder) for overlay icons. Currently returns "security-medium" for all URLs. TODO: - The JSON file is not currently used. Should use kcoreaddons_add_plugin() in CMake to make use of it. - Consolidate common code in the plugin forwarders into a templated class. (Or don't; it's not *that* much duplicated code...) - Actually check the RomData subclass for overlay icons. --- debian/rom-properties-kde5.install | 1 + src/kde/kde5/CMakeLists.txt | 35 +++++- src/kde/kde5/RpOverlayIconPlugin.cpp | 91 ++++++++++++++ src/kde/kde5/RpOverlayIconPlugin.hpp | 69 ++++++++++ src/kde/kde5/RpOverlayIconPluginForwarder.cpp | 119 ++++++++++++++++++ src/kde/kde5/RpOverlayIconPluginForwarder.hpp | 74 +++++++++++ .../kde5/RpOverlayIconPluginForwarder.json | 8 ++ 7 files changed, 396 insertions(+), 1 deletion(-) create mode 100644 src/kde/kde5/RpOverlayIconPlugin.cpp create mode 100644 src/kde/kde5/RpOverlayIconPlugin.hpp create mode 100644 src/kde/kde5/RpOverlayIconPluginForwarder.cpp create mode 100644 src/kde/kde5/RpOverlayIconPluginForwarder.hpp create mode 100644 src/kde/kde5/RpOverlayIconPluginForwarder.json diff --git a/debian/rom-properties-kde5.install b/debian/rom-properties-kde5.install index 99b6803be..786788a96 100644 --- a/debian/rom-properties-kde5.install +++ b/debian/rom-properties-kde5.install @@ -1,3 +1,4 @@ usr/lib/*/qt5/plugins/rom-properties-kde5.so usr/lib/*/qt5/plugins/kf5/kfilemetadata/kfilemetadata_rom-properties-kde5.so +usr/lib/*/qt5/plugins/kf5/overlayicon/overlayiconplugin_rom-properties-kde5.so usr/share/kservices5/rom-properties-kde5.desktop diff --git a/src/kde/kde5/CMakeLists.txt b/src/kde/kde5/CMakeLists.txt index f10948bae..a64e49a3d 100644 --- a/src/kde/kde5/CMakeLists.txt +++ b/src/kde/kde5/CMakeLists.txt @@ -73,6 +73,7 @@ IF(ECM_MODULE_PATH AND ECM_KDE_MODULE_DIR) # TODO: Can we get the subdirectory from KFileMetaData? SET(KFMD_PLUGIN_INSTALL_DIR "${PLUGIN_INSTALL_DIR}/kf5/kfilemetadata") + SET(KFOV_PLUGIN_INSTALL_DIR "${PLUGIN_INSTALL_DIR}/kf5/overlayicon") ELSE() # Qt5 not found. SET(BUILD_KDE5 OFF CACHE "" INTERNAL FORCE) @@ -91,11 +92,13 @@ STRING(REGEX REPLACE "([^;]+)" "../\\1" rom-properties-kde5_UIS "${rom-properti SET(rom-properties-kde5_SRCS ${rom-properties-kde5_SRCS} RpExtractorPlugin.cpp + RpOverlayIconPlugin.cpp RomPropertiesDialogPluginFactoryKDE5.cpp ) SET(rom-properties-kde5_H ${rom-properties-kde5_H} RpExtractorPlugin.hpp + RpOverlayIconPlugin.hpp ) IF(COMMAND QT5_WRAP_UI) @@ -152,12 +155,30 @@ IF(BUILD_KDE5) TARGET_COMPILE_DEFINITIONS(kfilemetadata_rom-properties-kde5 PRIVATE PLUGIN_INSTALL_DIR=\"${PLUGIN_INSTALL_DIR}\" ) - # Link in libdl if it's required for dlopen(). IF(CMAKE_DL_LIBS) TARGET_LINK_LIBRARIES(kfilemetadata_rom-properties-kde5 ${CMAKE_DL_LIBS}) ENDIF(CMAKE_DL_LIBS) + # RpOverlayIconPluginForwarder + # TODO: Use kcoreaddons_add_plugin() for the JSON? + # https://github.com/owncloud/client/blob/master/shell_integration/dolphin/CMakeLists.txt + # TODO: Better name. + ADD_LIBRARY(overlayiconplugin_rom-properties-kde5 MODULE + RpOverlayIconPluginForwarder.cpp + RpOverlayIconPluginForwarder.hpp + ) + SET_TARGET_PROPERTIES(overlayiconplugin_rom-properties-kde5 PROPERTIES PREFIX "") + DO_SPLIT_DEBUG(overlayiconplugin_rom-properties-kde5) + TARGET_LINK_LIBRARIES(overlayiconplugin_rom-properties-kde5 KF5::KIOCore KF5::KIOWidgets) + TARGET_COMPILE_DEFINITIONS(overlayiconplugin_rom-properties-kde5 + PRIVATE PLUGIN_INSTALL_DIR=\"${PLUGIN_INSTALL_DIR}\" + ) + # Link in libdl if it's required for dlopen(). + IF(CMAKE_DL_LIBS) + TARGET_LINK_LIBRARIES(overlayiconplugin_rom-properties-kde5 ${CMAKE_DL_LIBS}) + ENDIF(CMAKE_DL_LIBS) + # FIXME: Workaround for gcc-5.4.0 LTO bug. # Disabling LTO for the KDE5 build if using gcc-5.4.0 or earlier, # and decryption is enabled. (It crashes when compiling the moc @@ -187,6 +208,10 @@ IF(BUILD_KDE5) LIBRARY DESTINATION "${KFMD_PLUGIN_INSTALL_DIR}" COMPONENT "plugin" ) + INSTALL(TARGETS overlayiconplugin_rom-properties-kde5 + LIBRARY DESTINATION "${KFOV_PLUGIN_INSTALL_DIR}" + COMPONENT "plugin" + ) INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/rom-properties-kde5.desktop" DESTINATION "${SERVICES_INSTALL_DIR}" COMPONENT "plugin" @@ -211,5 +236,13 @@ IF(BUILD_KDE5) COMPONENT "debug" ) ENDIF(DEBUG_FILENAME) + + GET_TARGET_PROPERTY(DEBUG_FILENAME overlayiconplugin_rom-properties-kde5 PDB) + IF(DEBUG_FILENAME) + INSTALL(FILES "${DEBUG_FILENAME}" + DESTINATION "lib/debug/${CMAKE_INSTALL_PREFIX}/${KFOV_PLUGIN_INSTALL_DIR}" + COMPONENT "debug" + ) + ENDIF(DEBUG_FILENAME) ENDIF(INSTALL_DEBUG) ENDIF(BUILD_KDE5) diff --git a/src/kde/kde5/RpOverlayIconPlugin.cpp b/src/kde/kde5/RpOverlayIconPlugin.cpp new file mode 100644 index 000000000..0c4f1815e --- /dev/null +++ b/src/kde/kde5/RpOverlayIconPlugin.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** + * ROM Properties Page shell extension. (KDE) * + * RpOverlayIconPlugin.cpp: KOverlayIconPlugin. * + * * + * Qt's plugin system prevents a single shared library from exporting * + * multiple plugins, so this file acts as a KOverlayIconPlugin, * + * and then forwards the request to the main library. * + * * + * Copyright (c) 2018 by David Korth. * + * * + * This program 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. * + * * + * This program 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, see . * + ***************************************************************************/ + +#include "RpOverlayIconPlugin.hpp" + +// librpbase +#include "librpbase/RomData.hpp" +#include "librpbase/file/RpFile.hpp" +using LibRpBase::RomData; +using LibRpBase::IRpFile; +using LibRpBase::RpFile; + +// libromdata +#include "libromdata/RomDataFactory.hpp" +using LibRomData::RomDataFactory; + +// C includes. (C++ namespace) +#include + +// C++ includes. +#include +#include +#include +using std::string; +using std::unique_ptr; +using std::vector; + +// Qt includes. +#include + +// KDE includes. +#include +#include +using KFileMetaData::ExtractorPlugin; +using KFileMetaData::ExtractionResult; +using namespace KFileMetaData::Property; + +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + +#include + +namespace RomPropertiesKDE { + +/** + * Factory method. + * NOTE: Unlike the ThumbCreator version, this one is specific to + * rom-properties, and is called by a forwarder library. + */ +extern "C" { + Q_DECL_EXPORT RpOverlayIconPlugin *PFN_CREATEOVERLAYICONPLUGINKDE_FN(QObject *parent) + { + return new RpOverlayIconPlugin(parent); + } +} + +RpOverlayIconPlugin::RpOverlayIconPlugin(QObject *parent) + : super(parent) +{ } + +QStringList RpOverlayIconPlugin::getOverlays(const QUrl &item) +{ + // TODO: Check the RomData object. + QStringList sl; + sl += QLatin1String("security-medium"); + return sl; +} + +} + +#endif /* QT_VERSION >= QT_VERSION_CHECK(5,0,0) */ diff --git a/src/kde/kde5/RpOverlayIconPlugin.hpp b/src/kde/kde5/RpOverlayIconPlugin.hpp new file mode 100644 index 000000000..4aeaae714 --- /dev/null +++ b/src/kde/kde5/RpOverlayIconPlugin.hpp @@ -0,0 +1,69 @@ +/*************************************************************************** + * ROM Properties Page shell extension. (KDE) * + * RpOverlayIconPlugin.hpp: KOverlayIconPlugin. * + * * + * Qt's plugin system prevents a single shared library from exporting * + * multiple plugins, so this file acts as a KOverlayIconPlugin, * + * and then forwards the request to the main library. * + * * + * Copyright (c) 2018 by David Korth. * + * * + * This program 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. * + * * + * This program 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, see . * + ***************************************************************************/ + +#ifndef __ROMPROPERTIES_KDE_RPOVERLAYICONPLUGIN_HPP__ +#define __ROMPROPERTIES_KDE_RPOVERLAYICONPLUGIN_HPP__ + +// FIXME: Test on KDE4. +#include + +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + +#include + +namespace RomPropertiesKDE { + +class RpOverlayIconPlugin : public KOverlayIconPlugin +{ + Q_OBJECT + //Q_INTERFACES(KOverlayIconPlugin) + + public: + explicit RpOverlayIconPlugin(QObject *parent = nullptr); + + private: + typedef KOverlayIconPlugin super; + Q_DISABLE_COPY(RpOverlayIconPlugin); + + public: + QStringList getOverlays(const QUrl &item) final; +}; + +// Exported function pointer to create a new RpExtractorPlugin. +typedef RpOverlayIconPlugin* (*pfn_createOverlayIconPluginKDE_t)(QObject *parent); +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) +# error Qt6 is not supported. +#elif QT_VERSION >= QT_VERSION_CHECK(5,0,0) +# define PFN_CREATEOVERLAYICONPLUGINKDE_FN createOverlayIconPluginKDE5 +# define PFN_CREATEOVERLAYICONPLUGINKDE_NAME "createOverlayIconPluginKDE5" +#else /* QT_VERSION < QT_VERSION_CHECK(5,0,0) */ +# define PFN_CREATEOVERLAYICONPLUGINKDE_FN createOverlayIconPluginKDE4 +# define PFN_CREATEOVERLAYICONPLUGINKDE_NAME "createOverlayIconPluginKDE4" +#endif + +} + +#endif /* QT_VERSION >= QT_VERSION_CHECK(5,0,0) */ + +#endif /* __ROMPROPERTIES_KDE_RPOVERLAYICONPLUGIN_HPP__ */ diff --git a/src/kde/kde5/RpOverlayIconPluginForwarder.cpp b/src/kde/kde5/RpOverlayIconPluginForwarder.cpp new file mode 100644 index 000000000..a303501a7 --- /dev/null +++ b/src/kde/kde5/RpOverlayIconPluginForwarder.cpp @@ -0,0 +1,119 @@ +/*************************************************************************** + * ROM Properties Page shell extension. (KDE) * + * RpOverlayIconPluginForwarder.cpp: KOverlayIconPlugin forwarder. * + * * + * Qt's plugin system prevents a single shared library from exporting * + * multiple plugins, so this file acts as a KOverlayIconPlugin, * + * and then forwards the request to the main library. * + * * + * Copyright (c) 2018 by David Korth. * + * * + * This program 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. * + * * + * This program 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, see . * + ***************************************************************************/ + +#include "RpOverlayIconPluginForwarder.hpp" +#include "RpOverlayIconPlugin.hpp" + +// C includes. +#include + +// KDE includes. +#include + +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + +#include + +namespace RomPropertiesKDE { + +RpOverlayIconPluginForwarder::RpOverlayIconPluginForwarder(QObject *parent) + : super(parent) + , hRpKdeSo(nullptr) + , fwd_plugin(nullptr) +{ +#ifndef PLUGIN_INSTALL_DIR +# error PLUGIN_INSTALL_DIR is not set. +#endif + // FIXME: Check the .desktop file? + QString pluginPath(QString::fromUtf8(PLUGIN_INSTALL_DIR)); + pluginPath += QLatin1String("/rom-properties-kde5.so"); + + // Attempt to load the plugin. + hRpKdeSo = dlopen(pluginPath.toUtf8().constData(), RTLD_LOCAL|RTLD_LAZY); + if (!hRpKdeSo) { + // Unable to open the plugin. + // NOTE: We can't use mismatched plugins here. + return; + } + + // Load the symbol. + pfn_createOverlayIconPluginKDE_t pfn = reinterpret_cast( + dlsym(hRpKdeSo, PFN_CREATEOVERLAYICONPLUGINKDE_NAME)); + if (!pfn) { + // Symbol not found. + dlclose(hRpKdeSo); + hRpKdeSo = nullptr; + return; + } + + // Create an RpOverlayIconPlugin object. + fwd_plugin = pfn(this); + if (!fwd_plugin) { + // Unable to create an RpOverlayIconPlugin object. + dlclose(hRpKdeSo); + hRpKdeSo = nullptr; + return; + } + + // Make sure we know if the OverlayPlugin gets deleted. + // This *shouldn't* happen, but it's possible that our parent + // object enumerates child objects and does weird things. + connect(fwd_plugin, SIGNAL(destroyed(QObject*)), + this, SLOT(fwd_plugin_destroyed(QObject*))); +} + +RpOverlayIconPluginForwarder::~RpOverlayIconPluginForwarder() +{ + delete fwd_plugin; + + // FIXME: What does dlclose(nullptr) do? + if (hRpKdeSo) { + dlclose(hRpKdeSo); + } +} + +QStringList RpOverlayIconPluginForwarder::getOverlays(const QUrl &item) +{ + if (fwd_plugin) { + return fwd_plugin->getOverlays(item); + } + return QStringList(); +} + +/** + * fwd_plugin was destroyed. + * @param obj + */ +void RpOverlayIconPluginForwarder::fwd_plugin_destroyed(QObject *obj) +{ + if (obj == fwd_plugin) { + // Object matches. + // NULL it out so we don't have problems later. + fwd_plugin = nullptr; + } +} + +} + +#endif /* QT_VERSION >= QT_VERSION_CHECK(5,0,0) */ diff --git a/src/kde/kde5/RpOverlayIconPluginForwarder.hpp b/src/kde/kde5/RpOverlayIconPluginForwarder.hpp new file mode 100644 index 000000000..927d0620b --- /dev/null +++ b/src/kde/kde5/RpOverlayIconPluginForwarder.hpp @@ -0,0 +1,74 @@ +/*************************************************************************** + * ROM Properties Page shell extension. (KDE) * + * RpOverlayIconPluginForwarder.hpp: KOverlayIconPlugin forwarder. * + * * + * Qt's plugin system prevents a single shared library from exporting * + * multiple plugins, so this file acts as a KOverlayIconPlugin, * + * and then forwards the request to the main library. * + * * + * Copyright (c) 2018 by David Korth. * + * * + * This program 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. * + * * + * This program 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, see . * + ***************************************************************************/ + +#ifndef __ROMPROPERTIES_KDE_OVERLAYICONPLUGINFORWARDER_HPP__ +#define __ROMPROPERTIES_KDE_OVERLAYICONPLUGINFORWARDER_HPP__ + +// FIXME: Test on KDE4. +#include + +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + +#include + +namespace RomPropertiesKDE { + +class RpOverlayIconPluginForwarder : public KOverlayIconPlugin +{ + Q_OBJECT + // NOTE: KDE doesn't have a standard IID for KOverlayIconPlugin... + Q_PLUGIN_METADATA(IID "com.gerbilsoft.rom-properties.KOverlayIconPlugin" FILE "RpOverlayIconPluginForwarder.json") + //Q_INTERFACES(KOverlayIconPlugin) + + public: + explicit RpOverlayIconPluginForwarder(QObject *parent = nullptr); + virtual ~RpOverlayIconPluginForwarder(); + + private: + typedef KOverlayIconPlugin super; + Q_DISABLE_COPY(RpOverlayIconPluginForwarder); + + public: + QStringList getOverlays(const QUrl &item) final; + + private: + // rom-properties-kde5.so handle. + void *hRpKdeSo; + + // Actual OverlayPlugin. + KOverlayIconPlugin *fwd_plugin; + + private slots: + /** + * fwd_plugin was destroyed. + * @param obj + */ + void fwd_plugin_destroyed(QObject *obj = nullptr); +}; + +} + +#endif /* QT_VERSION >= QT_VERSION_CHECK(5,0,0) */ + +#endif /* __ROMPROPERTIES_KDE_OVERLAYICONPLUGINFORWARDER_HPP__ */ diff --git a/src/kde/kde5/RpOverlayIconPluginForwarder.json b/src/kde/kde5/RpOverlayIconPluginForwarder.json new file mode 100644 index 000000000..cba627f00 --- /dev/null +++ b/src/kde/kde5/RpOverlayIconPluginForwarder.json @@ -0,0 +1,8 @@ +{ + "KPlugin": { + "Description": "Overlay icon for rom-properties", + "ServiceTypes": [ + "KOverlayIconPlugin" + ] + } +}