KontactInterface

plugin.cpp
1/*
2 This file is part of the KDE Kontact Plugin Interface Library.
3
4 SPDX-FileCopyrightText: 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org>
5 SPDX-FileCopyrightText: 2002-2003 Daniel Molkentin <molkentin@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#include "plugin.h"
11#include "core.h"
12#include "kontactinterface_debug.h"
13#include "processes.h"
14
15#include <KAboutData>
16#include <KIO/CommandLauncherJob>
17#include <KXMLGUIFactory>
18
19#include <QDBusConnection>
20#include <QDir>
21#include <QDomDocument>
22#include <QFileInfo>
23
24#include <QCoreApplication>
25#include <QStandardPaths>
26
27using namespace KontactInterface;
28
29/**
30 PluginPrivate class that helps to provide binary compatibility between releases.
31 @internal
32*/
33//@cond PRIVATE
34class Q_DECL_HIDDEN Plugin::PluginPrivate
35{
36public:
37 void partDestroyed();
38 void setXmlFiles();
39 void removeInvisibleToolbarActions(Plugin *plugin);
40
41 Core *core = nullptr;
42 QList<QAction *> newActions;
43 QList<QAction *> syncActions;
44 QString identifier;
45 QString title;
46 QString icon;
47 QString executableName;
48 QString serviceName;
49 QByteArray partLibraryName;
50 QByteArray pluginName;
51 KParts::Part *part = nullptr;
52 bool hasPart = true;
53 bool disabled = false;
54};
55//@endcond
56Plugin::Plugin(Core *core, QObject *parent, const KPluginMetaData &, const char *appName, const char *pluginName)
57 : KXMLGUIClient(core)
58 , QObject(parent)
59 , d(new PluginPrivate)
60{
62 core->factory()->addClient(this);
63
64 d->pluginName = pluginName ? pluginName : appName;
65 d->core = core;
66}
67
69{
70 delete d->part;
71}
72
73void Plugin::setIdentifier(const QString &identifier)
74{
75 d->identifier = identifier;
76}
77
79{
80 return d->identifier;
81}
82
83void Plugin::setTitle(const QString &title)
84{
85 d->title = title;
86}
87
89{
90 return d->title;
91}
92
93void Plugin::setIcon(const QString &icon)
94{
95 d->icon = icon;
96}
97
99{
100 return d->icon;
101}
102
104{
105 d->executableName = bin;
106}
107
109{
110 return d->executableName;
111}
112
114{
115 d->partLibraryName = libName;
116}
117
119{
120 return false;
121}
122
124{
125 return core()->createPart(d->partLibraryName.constData());
126}
127
129{
130 return KAboutData();
131}
132
134{
135 if (!d->part) {
136 d->part = createPart();
137 if (d->part) {
138 connect(d->part, &KParts::Part::destroyed, this, [this]() {
139 d->partDestroyed();
140 });
141 d->removeInvisibleToolbarActions(this);
142 core()->partLoaded(this, d->part);
143 }
144 }
145 return d->part;
146}
147
149{
150 if (d->serviceName.isEmpty()) {
151 d->serviceName = QLatin1StringView("org.kde.") + QLatin1StringView(objectName().toLatin1());
152#ifdef Q_OS_WIN
154 d->serviceName.append(QLatin1StringView(".unique-") + pid);
155#endif
157 }
158 return d->serviceName;
159}
160
161int Plugin::weight() const
162{
163 return 0;
164}
165
167{
168 d->newActions.append(action);
169}
170
172{
173 d->syncActions.append(action);
174}
175
177{
178 return d->newActions;
179}
180
182{
183 return d->syncActions;
184}
185
187{
188 return {};
189}
190
192{
193 Q_UNUSED(data)
194 return false;
195}
196
200
202{
203}
204
208
210{
211 return d->core;
212}
213
215{
216 // Because the 3 korganizer plugins share the same part, we need to switch
217 // that part's XML files every time we are about to show its GUI...
218 d->setXmlFiles();
219
220 select();
221}
222
224{
225}
226
228{
229}
230
231//@cond PRIVATE
232void Plugin::PluginPrivate::partDestroyed()
233{
234 part = nullptr;
235}
236
237void Plugin::PluginPrivate::removeInvisibleToolbarActions(Plugin *plugin)
238{
239 if (pluginName.isEmpty()) {
240 return;
241 }
242
243 // Hide unwanted toolbar action by modifying the XML before createGUI, rather
244 // than doing it by calling removeAction on the toolbar after createGUI. Both
245 // solutions work visually, but only modifying the XML ensures that the
246 // actions don't appear in "edit toolbars". #207296
247 const QStringList hideActions = plugin->invisibleToolbarActions();
248 // qCDebug(KONTACTINTERFACE_LOG) << "Hiding actions" << hideActions << "from" << pluginName << part;
249 const QDomDocument doc = part->domDocument();
250 const QDomElement docElem = doc.documentElement();
251 // 1. Iterate over containers
252 for (QDomElement containerElem = docElem.firstChildElement(); !containerElem.isNull(); containerElem = containerElem.nextSiblingElement()) {
253 if (QString::compare(containerElem.tagName(), QLatin1StringView("ToolBar"), Qt::CaseInsensitive) == 0) {
254 // 2. Iterate over actions in toolbars
255 QDomElement actionElem = containerElem.firstChildElement();
256 while (!actionElem.isNull()) {
257 QDomElement nextActionElem = actionElem.nextSiblingElement();
258 if (QString::compare(actionElem.tagName(), QLatin1StringView("Action"), Qt::CaseInsensitive) == 0) {
259 // qCDebug(KONTACTINTERFACE_LOG) << "Looking at action" << actionElem.attribute("name");
260 if (hideActions.contains(actionElem.attribute(QStringLiteral("name")))) {
261 // qCDebug(KONTACTINTERFACE_LOG) << "REMOVING";
262 containerElem.removeChild(actionElem);
263 }
264 }
265 actionElem = nextActionElem;
266 }
267 }
268 }
269
270 // Possible optimization: we could do all the above and the writing below
271 // only when (newAppFile does not exist) or (version of domDocument > version of newAppFile) (*)
272 // This requires parsing newAppFile when it exists, though, and better use
273 // the fast kdeui code for that rather than a full QDomDocument.
274 // (*) or when invisibleToolbarActions() changes :)
275
277 + QLatin1StringView(pluginName) + QLatin1StringView(".rc");
278 const QFileInfo fileInfo(newAppFile);
279 QDir().mkpath(fileInfo.absolutePath());
280
281 QFile file(newAppFile);
282 if (!file.open(QFile::WriteOnly)) {
283 qCWarning(KONTACTINTERFACE_LOG) << "error writing to" << newAppFile;
284 return;
285 }
286 file.write(doc.toString().toUtf8());
287 file.flush();
288
289 setXmlFiles();
290}
291
292void Plugin::PluginPrivate::setXmlFiles()
293{
294 if (pluginName.isEmpty()) {
295 return;
296 }
298 + QLatin1StringView(pluginName) + QLatin1StringView(".rc");
300 + QLatin1StringView(pluginName) + QLatin1StringView(".rc");
301 if (!localFile.isEmpty() && !newAppFile.isEmpty()) {
302 if (part->xmlFile() != newAppFile || part->localXMLFile() != localFile) {
303 part->replaceXMLFile(newAppFile, localFile);
304 }
305 }
306}
307//@endcond
308
313
315{
316 if (d->executableName.isEmpty()) {
317 return;
318 }
319#ifdef Q_OS_WIN
320 activateWindowForProcess(d->executableName);
321#else
322 auto job = new KIO::CommandLauncherJob(d->executableName);
323 job->start();
324#endif
325}
326
328{
329 Q_UNUSED(parent)
330 return nullptr;
331}
332
334{
335 return d->hasPart;
336}
337
338void Plugin::setShowInSideBar(bool hasPart)
339{
340 d->hasPart = hasPart;
341}
342
344{
345 return true;
346}
347
348void Plugin::setDisabled(bool disabled)
349{
350 d->disabled = disabled;
351}
352
354{
355 return d->disabled;
356}
357
359{
360}
361
362void Plugin::virtual_hook(int, void *)
363{
364 // BASE::virtual_hook( id, data );
365}
366
367#include "moc_plugin.cpp"
KXMLGUIFactory * factory() const
virtual QAction * action(const QDomElement &element) const
void addClient(KXMLGUIClient *client)
The abstract interface that represents the Kontact core.
Definition core.h:27
virtual void partLoaded(Plugin *plugin, KParts::Part *part)=0
KParts::Part * createPart(const char *library)
Definition core.cpp:58
Base class for all Plugins in Kontact.
Definition plugin.h:66
void insertSyncAction(QAction *action)
Inserts a custom "Sync" action.
Definition plugin.cpp:171
void setIdentifier(const QString &identifier)
Sets the identifier of the plugin.
Definition plugin.cpp:73
void setIcon(const QString &icon)
Sets the icon name that is used for the plugin.
Definition plugin.cpp:93
Core * core() const
Returns a pointer to the kontact core object.
Definition plugin.cpp:209
void setShowInSideBar(bool hasPart)
Set if the plugin provides a part that should be shown in the sidebar.
Definition plugin.cpp:338
virtual KParts::Part * createPart()=0
Reimplement and return the part here.
virtual bool isRunningStandalone() const
Reimplement this method and return whether a standalone application is still running.
Definition plugin.cpp:118
QString registerClient()
Registers the client at DBus and returns the dbus identifier.
Definition plugin.cpp:148
virtual int weight() const
Return the weight of the plugin.
Definition plugin.cpp:161
QString icon() const
Returns the icon name that is used for the plugin.
Definition plugin.cpp:98
virtual void processDropEvent(QDropEvent *)
Process drop event.
Definition plugin.cpp:197
QList< QAction * > newActions() const
Returns the list of custom "New" actions.
Definition plugin.cpp:176
void setExecutableName(const QString &name)
Sets the name of executable (if existent).
Definition plugin.cpp:103
virtual const KAboutData aboutData()
Reimplement this method if you want to add your credits to the Kontact about dialog.
Definition plugin.cpp:128
virtual void readProperties(const KConfigGroup &)
Session management: read properties.
Definition plugin.cpp:201
Plugin(Core *core, QObject *parent, const KPluginMetaData &data, const char *appName, const char *pluginName=nullptr)
Creates a new plugin.
Definition plugin.cpp:56
virtual void bringToForeground()
Reimplement this method if your application needs a different approach to be brought in the foregroun...
Definition plugin.cpp:314
virtual QStringList invisibleToolbarActions() const
Returns a list of action names that shall be hidden in the main toolbar.
Definition plugin.cpp:186
void virtual_hook(int id, void *data) override
Virtual hook for BC extension.
Definition plugin.cpp:362
virtual Summary * createSummaryWidget(QWidget *parent)
Reimplement this method if you want to add a widget for your application to Kontact's summary page.
Definition plugin.cpp:327
QList< QAction * > syncActions() const
Returns the list of custom "Sync" actions.
Definition plugin.cpp:181
virtual void shortcutChanged()
Definition plugin.cpp:358
virtual void saveProperties(KConfigGroup &)
Session management: save properties.
Definition plugin.cpp:205
virtual void select()
This function is called when the plugin is selected by the user before the widget of the KPart belong...
Definition plugin.cpp:223
bool disabled() const
Returns whether the plugin is disabled.
Definition plugin.cpp:353
virtual bool queryClose() const
Reimplement this method if you want to add checks before closing the main kontact window.
Definition plugin.cpp:343
QString identifier() const
Returns the identifier of the plugin.
Definition plugin.cpp:78
void aboutToSelect()
Called by kontact when the plugin is selected by the user.
Definition plugin.cpp:214
virtual bool showInSideBar() const
Returns whether the plugin provides a part that should be shown in the sidebar.
Definition plugin.cpp:333
virtual bool canDecodeMimeData(const QMimeData *data) const
Returns whether the plugin can handle the drag object of the given mime type.
Definition plugin.cpp:191
void setPartLibraryName(const QByteArray &name)
Set name of library which contains the KPart used by this plugin.
Definition plugin.cpp:113
~Plugin() override
Destroys the plugin.
Definition plugin.cpp:68
void insertNewAction(QAction *action)
Inserts a custom "New" action.
Definition plugin.cpp:166
virtual void configUpdated()
This function is called whenever the config dialog has been closed successfully.
Definition plugin.cpp:227
QString executableName() const
Returns the name of the executable (if existent).
Definition plugin.cpp:108
KParts::Part * part()
You can use this method if you need to access the current part.
Definition plugin.cpp:133
QString title() const
Returns the localized title of the plugin.
Definition plugin.cpp:88
KParts::Part * loadPart()
Returns the loaded part.
Definition plugin.cpp:123
void setDisabled(bool value)
Sets whether the plugin shall be disabled.
Definition plugin.cpp:348
void setTitle(const QString &title)
Sets the localized title of the plugin.
Definition plugin.cpp:83
Base class for summary widgets in Kontact.
Definition summary.h:27
This file is part of the kpimutils library.
qint64 applicationPid()
bool registerService(const QString &serviceName)
QDBusConnection sessionBus()
bool mkpath(const QString &dirPath) const const
QDomElement documentElement() const const
QString toString(int indent) const const
QString attribute(const QString &name, const QString &defValue) const const
QString tagName() const const
QDomElement firstChildElement(const QString &tagName, const QString &namespaceURI) const const
bool isNull() const const
QDomElement nextSiblingElement(const QString &tagName, const QString &namespaceURI) const const
QDomNode removeChild(const QDomNode &oldChild)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void destroyed(QObject *obj)
QObject * parent() const const
void setObjectName(QAnyStringView name)
QString writableLocation(StandardLocation type)
int compare(QLatin1StringView s1, const QString &s2, Qt::CaseSensitivity cs)
bool isEmpty() const const
QString number(double n, char format, int precision)
QByteArray toUtf8() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
CaseInsensitive
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:21:21 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.