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

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 2006 Boudewijn Rempt (boud@valdyas.org)
0003  * SPDX-FileCopyrightText: 2006-2007, 2010 Thomas Zander <zander@kde.org>
0004  * SPDX-FileCopyrightText: 2006, 2008-2010 Thorsten Zachmann <zachmann@kde.org>
0005  * SPDX-FileCopyrightText: 2007 Jan Hambrecht <jaham@gmx.net>
0006  * SPDX-FileCopyrightText: 2010 Inge Wallin <inge@lysator.liu.se>
0007  *
0008  * SPDX-License-Identifier: LGPL-2.0-or-later
0009  */
0010 
0011 // Own
0012 #include "KoShapeRegistry.h"
0013 
0014 #include "KoSvgTextShape.h"
0015 #include "KoPathShapeFactory.h"
0016 #include "KoShapeLoadingContext.h"
0017 #include "KoShapeSavingContext.h"
0018 #include "KoShapeGroup.h"
0019 #include "KoShapeLayer.h"
0020 
0021 #include <KoPluginLoader.h>
0022 #include <KoXmlNS.h>
0023 
0024 #include <QString>
0025 #include <QHash>
0026 #include <QMultiMap>
0027 #include <QPainter>
0028 #include <QGlobalStatic>
0029 
0030 #include <FlakeDebug.h>
0031 
0032 Q_GLOBAL_STATIC(KoShapeRegistry, s_instance)
0033 
0034 class Q_DECL_HIDDEN KoShapeRegistry::Private
0035 {
0036 public:
0037     void insertFactory(KoShapeFactoryBase *factory);
0038     void init(KoShapeRegistry *q);
0039 
0040     // Map namespace,tagname to priority:factory
0041     QHash<QPair<QString, QString>, QMultiMap<int, KoShapeFactoryBase*> > factoryMap;
0042 };
0043 
0044 KoShapeRegistry::KoShapeRegistry()
0045         : d(new Private())
0046 {
0047 }
0048 
0049 KoShapeRegistry::~KoShapeRegistry()
0050 {
0051     qDeleteAll(doubleEntries());
0052     qDeleteAll(values());
0053     delete d;
0054 }
0055 
0056 void KoShapeRegistry::Private::init(KoShapeRegistry *q)
0057 {
0058     KoPluginLoader::PluginsConfig config;
0059     config.whiteList = "FlakePlugins";
0060     config.blacklist = "FlakePluginsDisabled";
0061     config.group = "krita";
0062     KoPluginLoader::instance()->load(QString::fromLatin1("Krita/Flake"),
0063                                      QString::fromLatin1("[X-Flake-PluginVersion] == 28"),
0064                                      config);
0065     config.whiteList = "ShapePlugins";
0066     config.blacklist = "ShapePluginsDisabled";
0067     KoPluginLoader::instance()->load(QString::fromLatin1("Krita/Shape"),
0068                                      QString::fromLatin1("[X-Flake-PluginVersion] == 28"),
0069                                      config);
0070 
0071     // Also add our hard-coded basic shapes
0072     q->add(new KoSvgTextShapeFactory());
0073     q->add(new KoPathShapeFactory(QStringList()));
0074 
0075     // Now all shape factories are registered with us, determine their
0076     // associated odf tagname & priority and prepare ourselves for
0077     // loading ODF.
0078 
0079     QList<KoShapeFactoryBase*> factories = q->values();
0080     for (int i = 0; i < factories.size(); ++i) {
0081         insertFactory(factories[i]);
0082     }
0083 }
0084 
0085 KoShapeRegistry* KoShapeRegistry::instance()
0086 {
0087     if (!s_instance.exists()) {
0088         s_instance->d->init(s_instance);
0089     }
0090     return s_instance;
0091 }
0092 
0093 void KoShapeRegistry::addFactory(KoShapeFactoryBase * factory)
0094 {
0095     add(factory);
0096     d->insertFactory(factory);
0097 }
0098 
0099 void KoShapeRegistry::Private::insertFactory(KoShapeFactoryBase *factory)
0100 {
0101     const QList<QPair<QString, QStringList> > odfElements(factory->odfElements());
0102 
0103     if (odfElements.isEmpty()) {
0104         debugFlake << "Shape factory" << factory->id() << " does not have OdfNamespace defined, ignoring";
0105     }
0106     else {
0107         int priority = factory->loadingPriority();
0108         for (QList<QPair<QString, QStringList> >::const_iterator it(odfElements.begin()); it != odfElements.end(); ++it) {
0109             foreach (const QString &elementName, (*it).second) {
0110                 QPair<QString, QString> p((*it).first, elementName);
0111 
0112                 QMultiMap<int, KoShapeFactoryBase*> & priorityMap = factoryMap[p];
0113 
0114                 priorityMap.insert(priority, factory);
0115 
0116                 debugFlake << "Inserting factory" << factory->id() << " for"
0117                     << p << " with priority "
0118                     << priority << " into factoryMap making "
0119                     << priorityMap.size() << " entries. ";
0120             }
0121         }
0122     }
0123 }
0124 
0125 #include "kis_debug.h"
0126 #include <QMimeDatabase>
0127 #include <KoUnit.h>
0128 #include <KoDocumentResourceManager.h>
0129 #include <KoShapeController.h>
0130 #include <KoShapeGroupCommand.h>
0131 
0132 
0133 QList<KoShapeFactoryBase*> KoShapeRegistry::factoriesForElement(const QString &nameSpace, const QString &elementName)
0134 {
0135     // Pair of namespace, tagname
0136     QPair<QString, QString> p = QPair<QString, QString>(nameSpace, elementName);
0137 
0138     QMultiMap<int, KoShapeFactoryBase*> priorityMap = d->factoryMap.value(p);
0139     QList<KoShapeFactoryBase*> shapeFactories;
0140     // sort list by priority
0141     Q_FOREACH (KoShapeFactoryBase *f, priorityMap.values()) {
0142         shapeFactories.prepend(f);
0143     }
0144 
0145     return shapeFactories;
0146 }