diff --git a/kate/kateconfigplugindialogpage.cpp b/kate/kateconfigplugindialogpage.cpp index 03ee721ca..7516a6c3a 100644 --- a/kate/kateconfigplugindialogpage.cpp +++ b/kate/kateconfigplugindialogpage.cpp @@ -1,122 +1,125 @@ /* This file is part of the KDE project Copyright (C) 2001 Christoph Cullmann Copyright (C) 2002 Joseph Wenninger Copyright (C) 2007 Mirko Stocker 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. */ #include "kateconfigplugindialogpage.h" #include "kateapp.h" #include "katepluginmanager.h" #include "kateconfigdialog.h" #include #include class KatePluginListItem : public QTreeWidgetItem { public: KatePluginListItem(bool checked, KatePluginInfo *info); KatePluginInfo *info() const { return mInfo; } protected: void stateChange(bool); private: KatePluginInfo *mInfo; }; KatePluginListItem::KatePluginListItem(bool checked, KatePluginInfo *info) : QTreeWidgetItem() , mInfo(info) { setCheckState(0, checked ? Qt::Checked : Qt::Unchecked); } KatePluginListView::KatePluginListView(QWidget *parent) : QTreeWidget(parent) { setRootIsDecorated(false); connect(this, &KatePluginListView::itemChanged, this, &KatePluginListView::stateChanged); } void KatePluginListView::stateChanged(QTreeWidgetItem *item) { emit stateChange(static_cast(item), item->checkState(0) == Qt::Checked); } KateConfigPluginPage::KateConfigPluginPage(QWidget *parent, KateConfigDialog *dialog) : QFrame(parent) , myDialog(dialog) { QVBoxLayout *layout = new QVBoxLayout(this); layout->setSpacing(0); layout->setMargin(0); KatePluginListView *listView = new KatePluginListView(this); layout->addWidget(listView); QStringList headers; headers << i18n("Name") << i18n("Description"); listView->setHeaderLabels(headers); listView->setWhatsThis(i18n("Here you can see all available Kate plugins. Those with a check mark are loaded, and will be loaded again the next time Kate is started.")); KatePluginList &pluginList(KateApp::self()->pluginManager()->pluginList()); for (KatePluginList::iterator it = pluginList.begin(); it != pluginList.end(); ++it) { QTreeWidgetItem *item = new KatePluginListItem(it->load, &(*it)); item->setText(0, it->metaData.name()); item->setText(1, it->metaData.description()); listView->addTopLevelItem(item); } listView->resizeColumnToContents(0); listView->sortByColumn(0, Qt::AscendingOrder); connect(listView, &KatePluginListView::stateChange, this, &KateConfigPluginPage::stateChange); } void KateConfigPluginPage::stateChange(KatePluginListItem *item, bool b) { if (b) { loadPlugin(item); } else { unloadPlugin(item); } emit changed(); } void KateConfigPluginPage::loadPlugin(KatePluginListItem *item) { - KateApp::self()->pluginManager()->loadPlugin(item->info()); + const bool ok = KateApp::self()->pluginManager()->loadPlugin(item->info()); + if (!ok) { + return; + } KateApp::self()->pluginManager()->enablePluginGUI(item->info()); myDialog->addPluginPage(item->info()->plugin); item->setCheckState(0, Qt::Checked); } void KateConfigPluginPage::unloadPlugin(KatePluginListItem *item) { myDialog->removePluginPage(item->info()->plugin); KateApp::self()->pluginManager()->unloadPlugin(item->info()); item->setCheckState(0, Qt::Unchecked); } diff --git a/kate/katepluginmanager.cpp b/kate/katepluginmanager.cpp index 9fd3d7b18..a7aeec2bf 100644 --- a/kate/katepluginmanager.cpp +++ b/kate/katepluginmanager.cpp @@ -1,346 +1,348 @@ /* This file is part of the KDE project Copyright (C) 2001 Christoph Cullmann Copyright (C) 2001 Joseph Wenninger Copyright (C) 2001 Anders Lund 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. */ #include "config.h" #include "katepluginmanager.h" #include "kateapp.h" #include "katemainwindow.h" #include "katedebug.h" #include #include #include #include #include #include #include QString KatePluginInfo::saveName() const { return QFileInfo(metaData.fileName()).baseName(); } KatePluginManager::KatePluginManager(QObject *parent) : QObject(parent) { setupPluginList(); } KatePluginManager::~KatePluginManager() { // than unload the plugins unloadAllPlugins(); } void KatePluginManager::setupPluginList() { /** * get all KTextEditor/Plugins */ const QVector plugins = KPluginLoader::findPlugins(QStringLiteral("ktexteditor"), [](const KPluginMetaData & md) { return md.serviceTypes().contains(QStringLiteral("KTextEditor/Plugin")); }); /** * move them to our internal data structure * activate some plugins per default */ QSet defaultPlugins; defaultPlugins.insert (QLatin1String("katefiletreeplugin")); defaultPlugins.insert (QLatin1String("tabswitcherplugin")); defaultPlugins.insert (QLatin1String("kateprojectplugin")); defaultPlugins.insert (QLatin1String("katesearchplugin")); m_pluginList.clear(); QVectorIterator i(plugins); i.toBack(); QSet unique; while (i.hasPrevious()) { KatePluginInfo info; info.metaData = i.previous(); // only load plugins once, even if found multiple times! if (unique.contains(info.saveName())) continue; info.defaultLoad = defaultPlugins.contains(info.saveName()); info.load = false; info.plugin = nullptr; m_pluginList.push_back(info); unique.insert (info.saveName()); } /** * construct fast lookup map */ m_name2Plugin.clear(); for (int i = 0; i < m_pluginList.size(); ++i) { m_name2Plugin[m_pluginList[i].saveName()] = &(m_pluginList[i]); } } void KatePluginManager::loadConfig(KConfig *config) { // first: unload the plugins unloadAllPlugins(); /** * ask config object */ if (config) { KConfigGroup cg = KConfigGroup(config, QStringLiteral("Kate Plugins")); // disable all plugin if no config, beside the ones marked as default load for (int i = 0; i < m_pluginList.size(); ++i) { m_pluginList[i].load = cg.readEntry(m_pluginList[i].saveName(), m_pluginList[i].defaultLoad); } } /** * load plugins */ for (KatePluginList::iterator it = m_pluginList.begin(); it != m_pluginList.end(); ++it) { if (it->load) { loadPlugin(&(*it)); // restore config if (auto interface = qobject_cast (it->plugin)) { KConfigGroup group(config, QString::fromLatin1("Plugin:%1:").arg(it->saveName())); interface->readSessionConfig(group); } } } } void KatePluginManager::writeConfig(KConfig *config) { Q_ASSERT(config); KConfigGroup cg = KConfigGroup(config, QStringLiteral("Kate Plugins")); foreach(const KatePluginInfo & plugin, m_pluginList) { QString saveName = plugin.saveName(); cg.writeEntry(saveName, plugin.load); // save config if (auto interface = qobject_cast (plugin.plugin)) { KConfigGroup group(config, QString::fromLatin1("Plugin:%1:").arg(saveName)); interface->writeSessionConfig(group); } } } void KatePluginManager::unloadAllPlugins() { for (KatePluginList::iterator it = m_pluginList.begin(); it != m_pluginList.end(); ++it) { if (it->plugin) { unloadPlugin(&(*it)); } } } void KatePluginManager::enableAllPluginsGUI(KateMainWindow *win, KConfigBase *config) { for (KatePluginList::iterator it = m_pluginList.begin(); it != m_pluginList.end(); ++it) { if (it->plugin) { enablePluginGUI(&(*it), win, config); } } } void KatePluginManager::disableAllPluginsGUI(KateMainWindow *win) { for (KatePluginList::iterator it = m_pluginList.begin(); it != m_pluginList.end(); ++it) { if (it->plugin) { disablePluginGUI(&(*it), win); } } } -void KatePluginManager::loadPlugin(KatePluginInfo *item) +bool KatePluginManager::loadPlugin(KatePluginInfo *item) { /** * try to load the plugin */ auto factory = KPluginLoader(item->metaData.fileName()).factory(); if (factory) { item->plugin = factory->create(this, QVariantList() << item->saveName()); - item->load = item->plugin != nullptr; } + item->load = item->plugin != nullptr; /** * tell the world about the success */ if (item->plugin) { emit KateApp::self()->wrapper()->pluginCreated(item->saveName(), item->plugin); } + + return item->plugin != nullptr; } void KatePluginManager::unloadPlugin(KatePluginInfo *item) { disablePluginGUI(item); delete item->plugin; KTextEditor::Plugin *plugin = item->plugin; item->plugin = 0L; item->load = false; emit KateApp::self()->wrapper()->pluginDeleted(item->saveName(), plugin); } void KatePluginManager::enablePluginGUI(KatePluginInfo *item, KateMainWindow *win, KConfigBase *config) { // plugin around at all? if (!item->plugin) { return; } // lookup if there is already a view for it.. QObject *createdView = nullptr; if (!win->pluginViews().contains(item->plugin)) { // create the view + try to correctly load shortcuts, if it's a GUI Client createdView = item->plugin->createView(win->wrapper()); if (createdView) { win->pluginViews().insert(item->plugin, createdView); } } // load session config if needed if (config && win->pluginViews().contains(item->plugin)) { if (auto interface = qobject_cast (win->pluginViews().value(item->plugin))) { KConfigGroup group(config, QString::fromLatin1("Plugin:%1:MainWindow:0").arg(item->saveName())); interface->readSessionConfig(group); } } if (createdView) { emit win->wrapper()->pluginViewCreated(item->saveName(), createdView); } } void KatePluginManager::enablePluginGUI(KatePluginInfo *item) { // plugin around at all? if (!item->plugin) { return; } // enable the gui for all mainwindows... for (int i = 0; i < KateApp::self()->mainWindowsCount(); i++) { enablePluginGUI(item, KateApp::self()->mainWindow(i), 0); } } void KatePluginManager::disablePluginGUI(KatePluginInfo *item, KateMainWindow *win) { // plugin around at all? if (!item->plugin) { return; } // lookup if there is a view for it.. if (!win->pluginViews().contains(item->plugin)) { return; } // really delete the view of this plugin QObject *deletedView = win->pluginViews().value(item->plugin); delete deletedView; win->pluginViews().remove(item->plugin); emit win->wrapper()->pluginViewDeleted(item->saveName(), deletedView); } void KatePluginManager::disablePluginGUI(KatePluginInfo *item) { // plugin around at all? if (!item->plugin) { return; } // disable the gui for all mainwindows... for (int i = 0; i < KateApp::self()->mainWindowsCount(); i++) { disablePluginGUI(item, KateApp::self()->mainWindow(i)); } } KTextEditor::Plugin *KatePluginManager::plugin(const QString &name) { /** * name known? */ if (!m_name2Plugin.contains(name)) { return 0; } /** * real plugin instance, if any ;) */ return m_name2Plugin.value(name)->plugin; } bool KatePluginManager::pluginAvailable(const QString &name) { return m_name2Plugin.contains(name); } class KTextEditor::Plugin *KatePluginManager::loadPlugin(const QString &name, bool permanent) { /** * name known? */ if (!m_name2Plugin.contains(name)) { return 0; } /** * load, bail out on error */ loadPlugin(m_name2Plugin.value(name)); if (!m_name2Plugin.value(name)->plugin) { return 0; } /** * perhaps patch not load again back to "ok, load it once again on next loadConfig" */ m_name2Plugin.value(name)->load = permanent; return m_name2Plugin.value(name)->plugin; } void KatePluginManager::unloadPlugin(const QString &name, bool permanent) { /** * name known? */ if (!m_name2Plugin.contains(name)) { return; } /** * unload */ unloadPlugin(m_name2Plugin.value(name)); /** * perhaps patch load again back to "ok, load it once again on next loadConfig" */ m_name2Plugin.value(name)->load = !permanent; } diff --git a/kate/katepluginmanager.h b/kate/katepluginmanager.h index 942e38697..4274fdc5b 100644 --- a/kate/katepluginmanager.h +++ b/kate/katepluginmanager.h @@ -1,104 +1,104 @@ /* This file is part of the KDE project Copyright (C) 2001 Christoph Cullmann Copyright (C) 2001 Joseph Wenninger Copyright (C) 2001 Anders Lund 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. */ #ifndef __KATE_PLUGINMANAGER_H__ #define __KATE_PLUGINMANAGER_H__ #include #include #include #include #include #include class KConfig; class KateMainWindow; class KatePluginInfo { public: KatePluginInfo() : load(false) , defaultLoad(false) , plugin(nullptr) {} bool load; bool defaultLoad; KPluginMetaData metaData; KTextEditor::Plugin *plugin; QString saveName() const; }; typedef QList KatePluginList; class KatePluginManager : public QObject { Q_OBJECT public: KatePluginManager(QObject *parent); ~KatePluginManager(); void unloadAllPlugins(); void enableAllPluginsGUI(KateMainWindow *win, KConfigBase *config = 0); void disableAllPluginsGUI(KateMainWindow *win); void loadConfig(KConfig *); void writeConfig(KConfig *); - void loadPlugin(KatePluginInfo *item); + bool loadPlugin(KatePluginInfo *item); void unloadPlugin(KatePluginInfo *item); void enablePluginGUI(KatePluginInfo *item, KateMainWindow *win, KConfigBase *config = 0); void enablePluginGUI(KatePluginInfo *item); void disablePluginGUI(KatePluginInfo *item, KateMainWindow *win); void disablePluginGUI(KatePluginInfo *item); inline KatePluginList &pluginList() { return m_pluginList; } KTextEditor::Plugin *plugin(const QString &name); bool pluginAvailable(const QString &name); KTextEditor::Plugin *loadPlugin(const QString &name, bool permanent = true); void unloadPlugin(const QString &name, bool permanent = true); private: void setupPluginList(); /** * all known plugins */ KatePluginList m_pluginList; /** * fast access map from name => plugin info * uses the info stored in the plugin list */ QMap m_name2Plugin; }; #endif