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

0001 /* This file is part of the KDE project
0002    SPDX-FileCopyrightText: 2007-2009, 2011 Thorsten Zachmann <zachmann@kde.org>
0003    SPDX-FileCopyrightText: 2007 Jan Hambrecht <jaham@gmx.net>
0004    SPDX-FileCopyrightText: 2014-2015 Denis Kuplyakov <dener.kup@gmail.com>
0005 
0006    SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "KoShapeLoadingContext.h"
0010 #include "KoShape.h"
0011 #include "KoShapeContainer.h"
0012 #include "KoSharedLoadingData.h"
0013 #include "KoShapeControllerBase.h"
0014 #include "KoMarkerCollection.h"
0015 #include "KoDocumentResourceManager.h"
0016 #include "KoLoadingShapeUpdater.h"
0017 
0018 #include <FlakeDebug.h>
0019 
0020 uint qHash(const KoShapeLoadingContext::AdditionalAttributeData & attributeData)
0021 {
0022     return qHash(attributeData.name);
0023 }
0024 
0025 static QSet<KoShapeLoadingContext::AdditionalAttributeData> s_additionlAttributes;
0026 
0027 class Q_DECL_HIDDEN KoShapeLoadingContext::Private
0028 {
0029 public:
0030     Private(KoStore *store, KoDocumentResourceManager *resourceManager)
0031             : store(store)
0032             , zIndex(0)
0033             , documentResources(resourceManager)
0034             , sectionModel(0)
0035     {
0036     }
0037 
0038     ~Private() {
0039         Q_FOREACH (KoSharedLoadingData * data, sharedData) {
0040             delete data;
0041         }
0042     }
0043 
0044     KoStore *store;
0045 
0046     QMap<QString, KoShapeLayer*> layers;
0047     QMap<QString, KoShape*> drawIds;
0048     QMap<QString, QPair<KoShape *, QVariant> > subIds;
0049     QMap<QString, KoSharedLoadingData *> sharedData; //FIXME: use QScopedPointer here to auto delete in destructor
0050     int zIndex;
0051     QMap<QString, KoLoadingShapeUpdater*> updaterById;
0052     QMap<KoShape *, KoLoadingShapeUpdater*> updaterByShape;
0053     KoDocumentResourceManager *documentResources;
0054     KoSectionModel *sectionModel; };
0055 
0056 KoShapeLoadingContext::KoShapeLoadingContext(KoStore *store, KoDocumentResourceManager *documentResources)
0057         : d(new Private(store, documentResources))
0058 {
0059 }
0060 
0061 KoShapeLoadingContext::~KoShapeLoadingContext()
0062 {
0063     delete d;
0064 }
0065 
0066 KoStore *KoShapeLoadingContext::store() const
0067 {
0068     return d->store;
0069 }
0070 
0071 QString KoShapeLoadingContext::mimeTypeForPath(const QString &href, bool b)
0072 {
0073     Q_UNUSED(href);
0074     Q_UNUSED(b);
0075     return "image/svg+xml";
0076 }
0077 
0078 KoShapeLayer * KoShapeLoadingContext::layer(const QString & layerName)
0079 {
0080     return d->layers.value(layerName, 0);
0081 }
0082 
0083 void KoShapeLoadingContext::addLayer(KoShapeLayer * layer, const QString & layerName)
0084 {
0085     d->layers[ layerName ] = layer;
0086 }
0087 
0088 void KoShapeLoadingContext::clearLayers()
0089 {
0090     d->layers.clear();
0091 }
0092 
0093 void KoShapeLoadingContext::addShapeId(KoShape * shape, const QString & id)
0094 {
0095     d->drawIds.insert(id, shape);
0096     QMap<QString, KoLoadingShapeUpdater*>::iterator it(d->updaterById.find(id));
0097     while (it != d->updaterById.end() && it.key() == id) {
0098         d->updaterByShape.insertMulti(shape, it.value());
0099         it = d->updaterById.erase(it);
0100     }
0101 }
0102 
0103 KoShape * KoShapeLoadingContext::shapeById(const QString &id)
0104 {
0105     return d->drawIds.value(id, 0);
0106 }
0107 
0108 void KoShapeLoadingContext::addShapeSubItemId(KoShape *shape, const QVariant &subItem, const QString &id)
0109 {
0110     d->subIds.insert(id, QPair<KoShape *, QVariant>(shape, subItem));
0111 }
0112 
0113 QPair<KoShape *, QVariant> KoShapeLoadingContext::shapeSubItemById(const QString &id)
0114 {
0115     return d->subIds.value(id);
0116 }
0117 
0118 
0119 // TODO make sure to remove the shape from the loading context when loading for it failed and it was deleted. This can also happen when the parent is deleted
0120 void KoShapeLoadingContext::updateShape(const QString & id, KoLoadingShapeUpdater * shapeUpdater)
0121 {
0122     d->updaterById.insertMulti(id, shapeUpdater);
0123 }
0124 
0125 void KoShapeLoadingContext::shapeLoaded(KoShape * shape)
0126 {
0127     QMap<KoShape*, KoLoadingShapeUpdater*>::iterator it(d->updaterByShape.find(shape));
0128     while (it != d->updaterByShape.end() && it.key() == shape) {
0129         it.value()->update(shape);
0130         delete it.value();
0131         it = d->updaterByShape.erase(it);
0132     }
0133 }
0134 
0135 
0136 int KoShapeLoadingContext::zIndex()
0137 {
0138     return d->zIndex++;
0139 }
0140 
0141 void KoShapeLoadingContext::setZIndex(int index)
0142 {
0143     d->zIndex = index;
0144 }
0145 
0146 void KoShapeLoadingContext::addSharedData(const QString & id, KoSharedLoadingData * data)
0147 {
0148     QMap<QString, KoSharedLoadingData*>::iterator it(d->sharedData.find(id));
0149     // data will not be overwritten
0150     if (it == d->sharedData.end()) {
0151         d->sharedData.insert(id, data);
0152     } else {
0153         warnFlake << "The id" << id << "is already registered. Data not inserted";
0154         Q_ASSERT(it == d->sharedData.end());
0155     }
0156 }
0157 
0158 KoSharedLoadingData * KoShapeLoadingContext::sharedData(const QString & id) const
0159 {
0160     KoSharedLoadingData * data = 0;
0161     QMap<QString, KoSharedLoadingData*>::const_iterator it(d->sharedData.find(id));
0162     if (it != d->sharedData.constEnd()) {
0163         data = it.value();
0164     }
0165     return data;
0166 }
0167 
0168 void KoShapeLoadingContext::addAdditionalAttributeData(const AdditionalAttributeData & attributeData)
0169 {
0170     s_additionlAttributes.insert(attributeData);
0171 }
0172 
0173 QSet<KoShapeLoadingContext::AdditionalAttributeData> KoShapeLoadingContext::additionalAttributeData()
0174 {
0175     return s_additionlAttributes;
0176 }
0177 
0178 KoDocumentResourceManager *KoShapeLoadingContext::documentResourceManager() const
0179 {
0180     return d->documentResources;
0181 }
0182 
0183 KoSectionModel *KoShapeLoadingContext::sectionModel()
0184 {
0185     return d->sectionModel;
0186 }
0187 
0188 void KoShapeLoadingContext::setSectionModel(KoSectionModel *sectionModel)
0189 {
0190     d->sectionModel = sectionModel;
0191 }