File indexing completed on 2024-05-12 15:56:48

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 2006 Boudewijn Rempt (boud@valdyas.org)
0003  * SPDX-FileCopyrightText: 2006-2007 Thomas Zander <zander@kde.org>
0004  * SPDX-FileCopyrightText: 2008 C. Boemann <cbo@boemann.dk>
0005  * SPDX-FileCopyrightText: 2008 Thorsten Zachmann <zachmann@kde.org>
0006  *
0007  * SPDX-License-Identifier: LGPL-2.0-or-later
0008  */
0009 
0010 #include "KoShapeFactoryBase.h"
0011 
0012 #include <QDebug>
0013 
0014 #include "KoDocumentResourceManager.h"
0015 #include "KoDeferredShapeFactoryBase.h"
0016 #include "KoShape.h"
0017 #include "KoShapeLoadingContext.h"
0018 
0019 #include <KoProperties.h>
0020 #include <KoJsonTrader.h>
0021 
0022 #include <KPluginFactory>
0023 #include <QPluginLoader>
0024 #include <QMutexLocker>
0025 #include <QMutex>
0026 #include <QPointer>
0027 
0028 
0029 #include <FlakeDebug.h>
0030 
0031 class Q_DECL_HIDDEN KoShapeFactoryBase::Private
0032 {
0033 public:
0034     Private(const QString &_id, const QString &_name, const QString &_deferredPluginName)
0035         : deferredFactory(0),
0036           deferredPluginName(_deferredPluginName),
0037           id(_id),
0038           name(_name),
0039           loadingPriority(0),
0040           hidden(false)
0041     {
0042     }
0043 
0044     ~Private() {
0045         Q_FOREACH (const KoShapeTemplate & t, templates)
0046             delete t.properties;
0047         templates.clear();
0048     }
0049 
0050     KoDeferredShapeFactoryBase *deferredFactory;
0051     QMutex pluginLoadingMutex;
0052     QString deferredPluginName;
0053     QList<KoShapeTemplate> templates;
0054     const QString id;
0055     const QString name;
0056     QString family;
0057     QString tooltip;
0058     QString iconName;
0059     int loadingPriority;
0060     QList<QPair<QString, QStringList> > xmlElements; // xml name space -> xml element names
0061     bool hidden;
0062     QList<QPointer<KoDocumentResourceManager> > resourceManagers;
0063 };
0064 
0065 
0066 KoShapeFactoryBase::KoShapeFactoryBase(const QString &id, const QString &name, const QString &deferredPluginName)
0067     : d(new Private(id, name, deferredPluginName))
0068 {
0069 }
0070 
0071 KoShapeFactoryBase::~KoShapeFactoryBase()
0072 {
0073     delete d;
0074 }
0075 
0076 QString KoShapeFactoryBase::toolTip() const
0077 {
0078     return d->tooltip;
0079 }
0080 
0081 QString KoShapeFactoryBase::iconName() const
0082 {
0083     return d->iconName;
0084 }
0085 
0086 QString KoShapeFactoryBase::name() const
0087 {
0088     return d->name;
0089 }
0090 
0091 QString KoShapeFactoryBase::family() const
0092 {
0093     return d->family;
0094 }
0095 
0096 int KoShapeFactoryBase::loadingPriority() const
0097 {
0098     return d->loadingPriority;
0099 }
0100 
0101 QList<QPair<QString, QStringList> > KoShapeFactoryBase::odfElements() const
0102 {
0103     return d->xmlElements;
0104 }
0105 
0106 void KoShapeFactoryBase::addTemplate(const KoShapeTemplate &params)
0107 {
0108     KoShapeTemplate tmplate = params;
0109     tmplate.id = d->id;
0110     d->templates.append(tmplate);
0111 }
0112 
0113 void KoShapeFactoryBase::setToolTip(const QString & tooltip)
0114 {
0115     d->tooltip = tooltip;
0116 }
0117 
0118 void KoShapeFactoryBase::setIconName(const char *iconName)
0119 {
0120     d->iconName = QLatin1String(iconName);
0121 }
0122 
0123 void KoShapeFactoryBase::setFamily(const QString & family)
0124 {
0125     d->family = family;
0126 }
0127 
0128 QString KoShapeFactoryBase::id() const
0129 {
0130     return d->id;
0131 }
0132 
0133 QList<KoShapeTemplate> KoShapeFactoryBase::templates() const
0134 {
0135     return d->templates;
0136 }
0137 
0138 void KoShapeFactoryBase::setLoadingPriority(int priority)
0139 {
0140     d->loadingPriority = priority;
0141 }
0142 
0143 void KoShapeFactoryBase::setXmlElementNames(const QString & nameSpace, const QStringList & names)
0144 {
0145     d->xmlElements.clear();
0146     d->xmlElements.append(QPair<QString, QStringList>(nameSpace, names));
0147 }
0148 
0149 void KoShapeFactoryBase::setXmlElements(const QList<QPair<QString, QStringList> > &elementNamesList)
0150 {
0151     d->xmlElements = elementNamesList;
0152 }
0153 
0154 bool KoShapeFactoryBase::hidden() const
0155 {
0156     return d->hidden;
0157 }
0158 
0159 void KoShapeFactoryBase::setHidden(bool hidden)
0160 {
0161     d->hidden = hidden;
0162 }
0163 
0164 void KoShapeFactoryBase::newDocumentResourceManager(KoDocumentResourceManager *manager) const
0165 {
0166     d->resourceManagers.append(manager);
0167     connect(manager, SIGNAL(destroyed(QObject*)), this, SLOT(pruneDocumentResourceManager(QObject*)));
0168 }
0169 
0170 KoShape *KoShapeFactoryBase::createDefaultShape(KoDocumentResourceManager *documentResources) const
0171 {
0172     if (!d->deferredPluginName.isEmpty()) {
0173         const_cast<KoShapeFactoryBase*>(this)->getDeferredPlugin();
0174         Q_ASSERT(d->deferredFactory);
0175         if (d->deferredFactory) {
0176             return d->deferredFactory->createDefaultShape(documentResources);
0177         }
0178     }
0179     return 0;
0180 }
0181 
0182 KoShape *KoShapeFactoryBase::createShape(const KoProperties* properties,
0183                                          KoDocumentResourceManager *documentResources) const
0184 {
0185     if (!d->deferredPluginName.isEmpty()) {
0186         const_cast<KoShapeFactoryBase*>(this)->getDeferredPlugin();
0187         Q_ASSERT(d->deferredFactory);
0188         if (d->deferredFactory) {
0189             return d->deferredFactory->createShape(properties, documentResources);
0190         }
0191     }
0192     return createDefaultShape(documentResources);
0193 }
0194 
0195 void KoShapeFactoryBase::getDeferredPlugin()
0196 {
0197     QMutexLocker(&d->pluginLoadingMutex);
0198     if (d->deferredFactory) return;
0199 
0200     const QList<KoJsonTrader::Plugin> offers =
0201         KoJsonTrader::instance()->query("Krita/Deferred", QString());
0202     Q_ASSERT(offers.size() > 0);
0203 
0204     Q_FOREACH (const KoJsonTrader::Plugin &pluginLoader, offers) {
0205         KPluginFactory *factory = qobject_cast<KPluginFactory *>(pluginLoader.instance());
0206         KoDeferredShapeFactoryBase *plugin = factory->create<KoDeferredShapeFactoryBase>(this, QVariantList());
0207 
0208         if (plugin && plugin->deferredPluginName() == d->deferredPluginName) {
0209             d->deferredFactory = plugin;
0210         }
0211     }
0212 }
0213 
0214 void KoShapeFactoryBase::pruneDocumentResourceManager(QObject *)
0215 {
0216     QList<QPointer<KoDocumentResourceManager> > rms;
0217     Q_FOREACH(QPointer<KoDocumentResourceManager> rm, d->resourceManagers) {
0218         if (rm) {
0219             rms << rm;
0220         }
0221     }
0222     d->resourceManagers = rms;
0223 }