File indexing completed on 2024-04-28 04:36:30
0001 /* 0002 SPDX-FileCopyrightText: 2002 Simon Hausmann <hausmann@kde.org> 0003 SPDX-FileCopyrightText: 2002 Matthias Hoelzer-Kluepfel <hoelzer@kde.org> 0004 SPDX-FileCopyrightText: 2002 Harald Fernengel <harry@kdevelop.org> 0005 SPDX-FileCopyrightText: 2002 Falk Brettschneider <falkbr@kdevelop.org> 0006 SPDX-FileCopyrightText: 2003 Julian Rockey <linux@jrockey.com> 0007 SPDX-FileCopyrightText: 2003 Roberto Raggi <roberto@kdevelop.org> 0008 SPDX-FileCopyrightText: 2003 Jens Dagerbo <jens.dagerbo@swipnet.se> 0009 SPDX-FileCopyrightText: 2003 Mario Scalas <mario.scalas@libero.it> 0010 SPDX-FileCopyrightText: 2003-2004, 2007 Alexander Dymo <adymo@kdevelop.org> 0011 SPDX-FileCopyrightText: 2006 Adam Treat <treat@kde.org> 0012 SPDX-FileCopyrightText: 2007 Andreas Pakulat <apaku@gmx.de> 0013 0014 SPDX-License-Identifier: LGPL-2.0-or-later 0015 */ 0016 0017 #include "iplugin.h" 0018 0019 #include <KActionCollection> 0020 #include <KMainWindow> 0021 #include <KXmlGuiWindow> 0022 #include <KXMLGUIFactory> 0023 0024 #include "icore.h" 0025 #include "iplugincontroller.h" 0026 #include "iprojectcontroller.h" 0027 #include "iproject.h" 0028 #include "contextmenuextension.h" 0029 0030 namespace KDevelop 0031 { 0032 0033 class IPluginPrivate 0034 { 0035 public: 0036 explicit IPluginPrivate(IPlugin *q) 0037 : q(q) 0038 {} 0039 0040 ~IPluginPrivate() 0041 { 0042 } 0043 0044 void guiClientAdded(KXMLGUIClient *client) 0045 { 0046 if (client != q) 0047 return; 0048 0049 q->initializeGuiState(); 0050 updateState(); 0051 } 0052 0053 void updateState() 0054 { 0055 const int projectCount = 0056 ICore::self()->projectController()->projectCount(); 0057 0058 IPlugin::ReverseStateChange reverse = IPlugin::StateNoReverse; 0059 if (! projectCount) 0060 reverse = IPlugin::StateReverse; 0061 0062 q->stateChanged(QStringLiteral("has_project"), reverse); 0063 } 0064 0065 IPlugin *q; 0066 ICore *core; 0067 QString m_errorDescription; 0068 }; 0069 0070 IPlugin::IPlugin( const QString &componentName, QObject *parent ) 0071 : QObject(parent) 0072 , KXMLGUIClient() 0073 , d_ptr(new IPluginPrivate(this)) 0074 { 0075 Q_D(IPlugin); 0076 0077 // The following cast is safe, there's no component in KDevPlatform that 0078 // creates plugins except the plugincontroller. The controller passes 0079 // Core::self() as parent to KServiceTypeTrader::createInstanceFromQuery 0080 // so we know the parent is always a Core* pointer. 0081 // This is the only way to pass the Core pointer to the plugin during its 0082 // creation so plugins have access to ICore during their creation. 0083 Q_ASSERT(qobject_cast<KDevelop::ICore*>(parent)); 0084 d->core = static_cast<KDevelop::ICore*>(parent); 0085 0086 auto metaData = core()->pluginController()->infoForPluginId(componentName); 0087 setComponentName(componentName, metaData.name()); 0088 0089 auto clientAdded = [this] (KXMLGUIClient* client) { 0090 Q_D(IPlugin); 0091 d->guiClientAdded(client); 0092 }; 0093 const auto mainWindows = KMainWindow::memberList(); 0094 for (KMainWindow* mw : mainWindows) { 0095 auto* guiWindow = qobject_cast<KXmlGuiWindow*>(mw); 0096 if (! guiWindow) 0097 continue; 0098 0099 connect(guiWindow->guiFactory(), &KXMLGUIFactory::clientAdded, 0100 this, clientAdded); 0101 } 0102 0103 auto updateState = [this] { 0104 Q_D(IPlugin); 0105 d->updateState(); 0106 }; 0107 connect(ICore::self()->projectController(), &IProjectController::projectOpened, 0108 this, updateState); 0109 connect(ICore::self()->projectController(), &IProjectController::projectClosed, 0110 this, updateState); 0111 } 0112 0113 IPlugin::~IPlugin() = default; 0114 0115 void IPlugin::unload() 0116 { 0117 } 0118 0119 ICore *IPlugin::core() const 0120 { 0121 Q_D(const IPlugin); 0122 0123 return d->core; 0124 } 0125 0126 } 0127 0128 KDevelop::ContextMenuExtension KDevelop::IPlugin::contextMenuExtension(KDevelop::Context* context, QWidget* parent) 0129 { 0130 Q_UNUSED(context); 0131 Q_UNUSED(parent); 0132 return KDevelop::ContextMenuExtension(); 0133 } 0134 0135 void KDevelop::IPlugin::initializeGuiState() 0136 { } 0137 0138 class CustomXmlGUIClient : public KXMLGUIClient 0139 { 0140 public: 0141 explicit CustomXmlGUIClient(const KDevelop::IPlugin* plugin) 0142 { 0143 // TODO KF5: Get rid off this 0144 setComponentName(plugin->componentName(), plugin->actionCollection()->componentDisplayName()); 0145 } 0146 using KXMLGUIClient::setXMLFile; 0147 }; 0148 0149 KXMLGUIClient* KDevelop::IPlugin::createGUIForMainWindow(Sublime::MainWindow* window) 0150 { 0151 QScopedPointer<CustomXmlGUIClient> ret(new CustomXmlGUIClient(this)); 0152 0153 QString file; 0154 createActionsForMainWindow(window, file, *ret->actionCollection()); 0155 if (ret->actionCollection()->isEmpty()) { 0156 return nullptr; 0157 } 0158 0159 Q_ASSERT(!file.isEmpty()); //A file must have been set 0160 ret->setXMLFile(file); 0161 return ret.take(); 0162 } 0163 0164 void KDevelop::IPlugin::createActionsForMainWindow( Sublime::MainWindow* /*window*/, QString& /*xmlFile*/, KActionCollection& /*actions*/ ) 0165 { 0166 } 0167 0168 bool KDevelop::IPlugin::hasError() const 0169 { 0170 Q_D(const IPlugin); 0171 0172 return !d->m_errorDescription.isEmpty(); 0173 } 0174 0175 void KDevelop::IPlugin::setErrorDescription(const QString& description) 0176 { 0177 Q_D(IPlugin); 0178 0179 d->m_errorDescription = description; 0180 } 0181 0182 0183 QString KDevelop::IPlugin::errorDescription() const 0184 { 0185 Q_D(const IPlugin); 0186 0187 return d->m_errorDescription; 0188 } 0189 0190 int KDevelop::IPlugin::configPages() const 0191 { 0192 return 0; 0193 } 0194 0195 KDevelop::ConfigPage* KDevelop::IPlugin::configPage (int, QWidget*) 0196 { 0197 return nullptr; 0198 } 0199 0200 int KDevelop::IPlugin::perProjectConfigPages() const 0201 { 0202 return 0; 0203 } 0204 0205 KDevelop::ConfigPage* KDevelop::IPlugin::perProjectConfigPage(int, const ProjectConfigOptions&, QWidget*) 0206 { 0207 return nullptr; 0208 } 0209 #include "moc_iplugin.cpp"