From 9f8f0c8307f2ea948b99d56a449c38396dd05661 Mon Sep 17 00:00:00 2001 From: Nicolas Fella Date: Sat, 23 Apr 2022 21:06:25 +0200 Subject: [PATCH] Port plugin loading away from KPluginLoader It is deprecated This also simplifies the code a lot --- CMakeLists.txt | 2 +- src/cantor.cpp | 69 ++++++++++++++++------------------ src/cantor_part.cpp | 65 ++++++++++++-------------------- src/lib/backend.cpp | 49 +++++++----------------- src/lib/cantor_macros.h | 1 - src/lib/panelpluginhandler.cpp | 34 ++++++----------- 6 files changed, 83 insertions(+), 137 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2024e17b..44143dae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ set (RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE project(cantor VERSION ${RELEASE_SERVICE_VERSION}) -set(KF5_MIN_VERSION "5.70.0") +set(KF5_MIN_VERSION "5.86.0") find_package(ECM 5.15.0 REQUIRED CONFIG) set(CMAKE_MODULE_PATH ${cantor_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ) diff --git a/src/cantor.cpp b/src/cantor.cpp index 8ad798d5..90eb7d30 100644 --- a/src/cantor.cpp +++ b/src/cantor.cpp @@ -325,9 +325,10 @@ void CantorShell::addWorksheet(const QString& backendName) // this routine will find and load our Part. it finds the Part by // name which is a bad idea usually.. but it's alright in this // case since our Part is made for this Shell - KPluginLoader loader(QLatin1String("kf5/parts/cantorpart")); - KPluginFactory* factory = loader.factory(); - if (factory) + + const auto partResult = KPluginFactory::instantiatePlugin(KPluginMetaData(QStringLiteral("kf5/parts/cantorpart")), m_tabWidget, {backendName}); + + if (partResult) { Cantor::Backend* backend = nullptr; if (!backendName.isEmpty()) @@ -349,48 +350,42 @@ void CantorShell::addWorksheet(const QString& backendName) } // now that the Part is loaded, we cast it to a Part to get our hands on it - auto* part = factory->create(m_tabWidget, QVariantList()<)), this, SIGNAL(hierarchyChanged(QStringList, QStringList, QList))); - connect(part, SIGNAL(hierarhyEntryNameChange(QString, QString, int)), this, SIGNAL(hierarhyEntryNameChange(QString, QString, int))); - connect(this, SIGNAL(requestScrollToHierarchyEntry(QString)), part, SIGNAL(requestScrollToHierarchyEntry(QString))); - connect(this, SIGNAL(settingsChanges()), part, SIGNAL(settingsChanges())); - connect(part, SIGNAL(requestDocumentation(QString)), this, SIGNAL(requestDocumentation(QString))); - - m_parts.append(part); - if (backend) // If backend empty (loading worksheet from file), then we connect to signal and wait - m_parts2Backends[part] = backend->id(); - else - { - m_parts2Backends[part] = QString(); - connect(part, SIGNAL(setBackendName(QString)), this, SLOT(updateBackendForPart(QString))); - } - int tab = m_tabWidget->addTab(part->widget(), i18n("Session %1", sessionCount++)); - m_tabWidget->setCurrentIndex(tab); - // Setting focus on worksheet view, because Qt clear focus of added widget inside addTab - // This fix https://bugs.kde.org/show_bug.cgi?id=395976 - part->widget()->findChild()->setFocus(); - - // Force run updateCaption for getting proper backend icon - QMetaObject::invokeMethod(part, "updateCaption"); - - //show the default help string in the help panel - emit showHelp(backend->defaultHelp()); - } + auto part = partResult.plugin; + + connect(part, SIGNAL(setCaption(QString,QIcon)), this, SLOT(setTabCaption(QString,QIcon))); + connect(part, SIGNAL(worksheetSave(QUrl)), this, SLOT(onWorksheetSave(QUrl))); + connect(part, SIGNAL(showHelp(QString)), this, SIGNAL(showHelp(QString))); + connect(part, SIGNAL(hierarchyChanged(QStringList, QStringList, QList)), this, SIGNAL(hierarchyChanged(QStringList, QStringList, QList))); + connect(part, SIGNAL(hierarhyEntryNameChange(QString, QString, int)), this, SIGNAL(hierarhyEntryNameChange(QString, QString, int))); + connect(this, SIGNAL(requestScrollToHierarchyEntry(QString)), part, SIGNAL(requestScrollToHierarchyEntry(QString))); + connect(this, SIGNAL(settingsChanges()), part, SIGNAL(settingsChanges())); + connect(part, SIGNAL(requestDocumentation(QString)), this, SIGNAL(requestDocumentation(QString))); + + m_parts.append(part); + if (backend) // If backend empty (loading worksheet from file), then we connect to signal and wait + m_parts2Backends[part] = backend->id(); else { - qDebug()<<"error creating part "; + m_parts2Backends[part] = QString(); + connect(part, SIGNAL(setBackendName(QString)), this, SLOT(updateBackendForPart(QString))); } + int tab = m_tabWidget->addTab(part->widget(), i18n("Session %1", sessionCount++)); + m_tabWidget->setCurrentIndex(tab); + // Setting focus on worksheet view, because Qt clear focus of added widget inside addTab + // This fix https://bugs.kde.org/show_bug.cgi?id=395976 + part->widget()->findChild()->setFocus(); + + // Force run updateCaption for getting proper backend icon + QMetaObject::invokeMethod(part, "updateCaption"); + + //show the default help string in the help panel + emit showHelp(backend->defaultHelp()); } else { // if we couldn't find our Part, we exit since the Shell by // itself can't do anything useful - KMessageBox::error(this, i18n("Failed to find the Cantor Part with error %1", loader.errorString())); + KMessageBox::error(this, i18n("Failed to find the Cantor Part with error %1", partResult.errorString)); qApp->quit(); // we return here, cause qApp->quit() only means "exit the // next time we enter the event loop... diff --git a/src/cantor_part.cpp b/src/cantor_part.cpp index 8eea5cb0..effcdc35 100644 --- a/src/cantor_part.cpp +++ b/src/cantor_part.cpp @@ -752,53 +752,36 @@ void CantorPart::loadAssistants() { qDebug()<<"loading assistants..."; - QStringList assistantDirs; - for (const QString& dir : QCoreApplication::libraryPaths()) - assistantDirs << dir + QDir::separator() + QLatin1String("cantor/assistants"); + const QVector plugins = KPluginMetaData::findPlugins(QStringLiteral("cantor/assistants")); - QPluginLoader loader; - for (const QString& dir : assistantDirs) { + for (const KPluginMetaData &plugin : plugins) { - qDebug() << "dir: " << dir; - QStringList assistants; - QDir assistantDir = QDir(dir); + const auto result = KPluginFactory::instantiatePlugin(plugin, this); - assistants = assistantDir.entryList(); - - for (const QString& assistant : assistants) { - if (assistant == QLatin1String(".") || assistant == QLatin1String("..")) - continue; - - loader.setFileName(dir + QDir::separator() + assistant); - - if (!loader.load()){ - qDebug() << "Error while loading assistant: " << assistant; - continue; - } - - KPluginFactory* factory = KPluginLoader(loader.fileName()).factory(); - auto* plugin = factory->create(this); - auto* backend=worksheet()->session()->backend(); + if (!result) { + qDebug() << "Error while loading assistant plugin: " << result.errorText; + continue; + } - KPluginMetaData info(loader); - plugin->setPluginInfo(info); - plugin->setBackend(backend); + Cantor::Assistant *assistant = result.plugin; + auto* backend=worksheet()->session()->backend(); + assistant->setPluginInfo(plugin); + assistant->setBackend(backend); - bool supported=true; - for (const QString& req : plugin->requiredExtensions()) - supported = supported && backend->extensions().contains(req); + bool supported=true; + for (const QString& req : assistant->requiredExtensions()) + supported = supported && backend->extensions().contains(req); - if(supported) - { - qDebug() << "plugin " << info.name() << " is supported by " << backend->name() << ", requires extensions " << plugin->requiredExtensions(); - plugin->initActions(); - connect(plugin, &Cantor::Assistant::requested, this, &CantorPart::runAssistant); - }else - { - qDebug() << "plugin " << info.name() << " is not supported by "<name(); - removeChildClient(plugin); - plugin->deleteLater(); - } + if(supported) + { + qDebug() << "plugin " << plugin.name() << " is supported by " << backend->name() << ", requires extensions " << assistant->requiredExtensions(); + assistant->initActions(); + connect(assistant, &Cantor::Assistant::requested, this, &CantorPart::runAssistant); + }else + { + qDebug() << "plugin " << plugin.name() << " is not supported by "<name(); + removeChildClient(assistant); + assistant->deleteLater(); } } } diff --git a/src/lib/backend.cpp b/src/lib/backend.cpp index 15af75f2..289c71fe 100644 --- a/src/lib/backend.cpp +++ b/src/lib/backend.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -105,46 +106,24 @@ QList Backend::availableBackends() return backendCache; } - QStringList pluginDirs; - for (const QString& dir : QCoreApplication::libraryPaths()){ - pluginDirs << dir + QDir::separator() + QLatin1String("cantor/backends"); - } - - QPluginLoader loader; - for (const QString &dir : pluginDirs){ - qDebug() << "dir: " << dir; - QStringList plugins; - QDir pluginDir = QDir(dir); - - plugins = pluginDir.entryList(); + const QVector plugins = KPluginMetaData::findPlugins(QStringLiteral("cantor/backends")); - for (const QString &plugin : plugins){ - if (plugin==QLatin1String(".") || plugin==QLatin1String("..")) - continue; + for (const KPluginMetaData &plugin : plugins) { - loader.setFileName(dir + QDir::separator() + plugin); + const auto result = KPluginFactory::instantiatePlugin(plugin, QCoreApplication::instance()); - if (!loader.load()){ - qDebug() << "Error while loading plugin: " << plugin; - continue; - } - - KPluginFactory* factory = KPluginLoader(loader.fileName()).factory(); - Backend* backend = factory->create(QCoreApplication::instance()); + if (!result) { + qDebug() << "Error while loading backend: " << result.errorText; + continue; + } - if (!backend){ - qDebug() << "Error using plugin " << loader.fileName(); - qDebug() << "Error message: " << loader.errorString(); - continue; - } + Backend *backend = result.plugin; - KPluginMetaData info(loader); - backend->d->name=info.name(); - backend->d->comment=info.description(); - backend->d->icon=info.iconName(); - backend->d->url=info.website(); - backendCache<d->name = plugin.name(); + backend->d->comment = plugin.description(); + backend->d->icon = plugin.iconName(); + backend->d->url = plugin.website(); + backendCache << backend; } return backendCache; diff --git a/src/lib/cantor_macros.h b/src/lib/cantor_macros.h index c3d56687..9fcb2947 100644 --- a/src/lib/cantor_macros.h +++ b/src/lib/cantor_macros.h @@ -7,7 +7,6 @@ #define _CANTOR_MACROS_H #include -#include /** Exports Backend plugin. diff --git a/src/lib/panelpluginhandler.cpp b/src/lib/panelpluginhandler.cpp index 2604a2dc..4c9804e5 100644 --- a/src/lib/panelpluginhandler.cpp +++ b/src/lib/panelpluginhandler.cpp @@ -8,6 +8,8 @@ using namespace Cantor; #include #include + +#include #include #include @@ -33,34 +35,22 @@ PanelPluginHandler::~PanelPluginHandler() void PanelPluginHandler::loadPlugins() { - QStringList panelDirs; - for (const QString& path : QCoreApplication::libraryPaths()) { - const QString& dir = path + QDir::separator() + QLatin1String("cantor/panels"); - qDebug() << "dir: " << dir; - QDir panelDir = QDir(dir); + const QVector plugins = KPluginMetaData::findPlugins(QStringLiteral("cantor/panels")); - QPluginLoader loader; - const QStringList& panels = panelDir.entryList(); + for (const KPluginMetaData &plugin : plugins) { - for (const QString& panel : panels) - { - if (panel==QLatin1String(".") || panel==QLatin1String("..")) - continue; + const auto result = KPluginFactory::instantiatePlugin(plugin, QCoreApplication::instance()); - loader.setFileName(dir + QDir::separator() + panel); + if (!result) { + qDebug() << "Error while loading panel: " << result.errorText; + continue; + } - if (!loader.load()){ - qDebug() << "Error while loading panel" << panel << ": \"" << loader.errorString() << "\""; - continue; - } + PanelPlugin *panel = result.plugin; - KPluginFactory* factory = KPluginLoader(loader.fileName()).factory(); - PanelPlugin* plugin = factory->create(this); + panel->setPluginInfo(plugin); + d->plugins.append(panel); - KPluginMetaData info(loader); - plugin->setPluginInfo(info); - d->plugins.append(plugin); - } } } -- GitLab