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

0001 /* This file is part of the KDE project
0002    SPDX-FileCopyrightText: 2004-2006 David Faure <faure@kde.org>
0003    SPDX-FileCopyrightText: 2007-2009, 2011 Thorsten Zachmann <zachmann@kde.org>
0004    SPDX-FileCopyrightText: 2007 Jan Hambrecht <jaham@gmx.net>
0005    SPDX-FileCopyrightText: 2010 Benjamin Port <port.benjamin@gmail.com>
0006 
0007    SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #include "KoShapeSavingContext.h"
0011 
0012 #include "KoShapeLayer.h"
0013 #include "KoMarker.h"
0014 
0015 #include <KoXmlWriter.h>
0016 #include <KoStore.h>
0017 #include <KoStoreDevice.h>
0018 #include <KoSharedSavingData.h>
0019 
0020 #include <FlakeDebug.h>
0021 #include <QUuid>
0022 #include <QImage>
0023 #include <KisMimeDatabase.h>
0024 
0025 class KoShapeSavingContextPrivate {
0026 public:
0027     KoShapeSavingContextPrivate(KoXmlWriter&);
0028     ~KoShapeSavingContextPrivate();
0029 
0030     KoXmlWriter *xmlWriter;
0031     KoShapeSavingContext::ShapeSavingOptions savingOptions;
0032 
0033     QList<const KoShapeLayer*> layers;
0034     QMap<QString, KoSharedSavingData*> sharedData;
0035 
0036     QMap<qint64, QString> imageNames;
0037     int imageId;
0038     QMap<QString, QImage> images;
0039 
0040     QHash<const KoShape *, QTransform> shapeOffsets;
0041     QMap<const KoMarker *, QString> markerRefs;
0042 
0043     QMap<QString, int> referenceCounters;
0044     QMap<QString, QList<const void*> > prefixedReferences;
0045 
0046 };
0047 
0048 KoShapeSavingContextPrivate::KoShapeSavingContextPrivate(KoXmlWriter &w)
0049     : xmlWriter(&w)
0050     , imageId(0)
0051 {
0052 }
0053 
0054 KoShapeSavingContextPrivate::~KoShapeSavingContextPrivate()
0055 {
0056     Q_FOREACH (KoSharedSavingData * data, sharedData) {
0057         delete data;
0058     }
0059 }
0060 
0061 KoShapeSavingContext::KoShapeSavingContext(KoXmlWriter &xmlWriter)
0062     : d(new KoShapeSavingContextPrivate(xmlWriter))
0063 {
0064     // by default allow saving of draw:id + xml:id
0065     addOption(KoShapeSavingContext::DrawId);
0066 }
0067 
0068 KoShapeSavingContext::~KoShapeSavingContext()
0069 {
0070     delete d;
0071 }
0072 
0073 KoXmlWriter & KoShapeSavingContext::xmlWriter()
0074 {
0075     return *d->xmlWriter;
0076 }
0077 
0078 void KoShapeSavingContext::setXmlWriter(KoXmlWriter &xmlWriter)
0079 {
0080     d->xmlWriter = &xmlWriter;
0081 }
0082 
0083 bool KoShapeSavingContext::isSet(ShapeSavingOption option) const
0084 {
0085     return d->savingOptions & option;
0086 }
0087 
0088 void KoShapeSavingContext::setOptions(ShapeSavingOptions options)
0089 {
0090     d->savingOptions = options;
0091 }
0092 
0093 KoShapeSavingContext::ShapeSavingOptions KoShapeSavingContext::options() const
0094 {
0095     return d->savingOptions;
0096 }
0097 
0098 void KoShapeSavingContext::addOption(ShapeSavingOption option)
0099 {
0100     d->savingOptions = d->savingOptions | option;
0101 }
0102 
0103 void KoShapeSavingContext::removeOption(ShapeSavingOption option)
0104 {
0105     if (isSet(option))
0106         d->savingOptions = d->savingOptions ^ option; // xor to remove it.
0107 }
0108 
0109 void KoShapeSavingContext::addLayerForSaving(const KoShapeLayer *layer)
0110 {
0111     if (layer && ! d->layers.contains(layer))
0112         d->layers.append(layer);
0113 }
0114 
0115 void KoShapeSavingContext::saveLayerSet(KoXmlWriter &xmlWriter) const
0116 {
0117     xmlWriter.startElement("draw:layer-set");
0118     Q_FOREACH (const KoShapeLayer * layer, d->layers) {
0119         xmlWriter.startElement("draw:layer");
0120         xmlWriter.addAttribute("draw:name", layer->name());
0121         if (layer->isGeometryProtected())
0122             xmlWriter.addAttribute("draw:protected", "true");
0123         if (! layer->isVisible(false))
0124             xmlWriter.addAttribute("draw:display", "none");
0125         xmlWriter.endElement();  // draw:layer
0126     }
0127     xmlWriter.endElement();  // draw:layer-set
0128 }
0129 
0130 void KoShapeSavingContext::clearLayers()
0131 {
0132     d->layers.clear();
0133 }
0134 
0135 QMap<qint64, QString> KoShapeSavingContext::imagesToSave()
0136 {
0137     return d->imageNames;
0138 }
0139 
0140 QString KoShapeSavingContext::markerRef(const KoMarker */*marker*/)
0141 {
0142     return QString();
0143 }
0144 
0145 void KoShapeSavingContext::addSharedData(const QString &id, KoSharedSavingData * data)
0146 {
0147     QMap<QString, KoSharedSavingData*>::iterator it(d->sharedData.find(id));
0148     // data will not be overwritten
0149     if (it == d->sharedData.end()) {
0150         d->sharedData.insert(id, data);
0151     } else {
0152         warnFlake << "The id" << id << "is already registered. Data not inserted";
0153         Q_ASSERT(it == d->sharedData.end());
0154     }
0155 }
0156 
0157 KoSharedSavingData * KoShapeSavingContext::sharedData(const QString &id) const
0158 {
0159     KoSharedSavingData * data = 0;
0160     QMap<QString, KoSharedSavingData*>::const_iterator it(d->sharedData.constFind(id));
0161     if (it != d->sharedData.constEnd()) {
0162         data = it.value();
0163     }
0164     return data;
0165 }
0166 
0167 void KoShapeSavingContext::addShapeOffset(const KoShape *shape, const QTransform &m)
0168 {
0169     d->shapeOffsets.insert(shape, m);
0170 }
0171 
0172 void KoShapeSavingContext::removeShapeOffset(const KoShape *shape)
0173 {
0174     d->shapeOffsets.remove(shape);
0175 }
0176 
0177 QTransform KoShapeSavingContext::shapeOffset(const KoShape *shape) const
0178 {
0179     return d->shapeOffsets.value(shape, QTransform());
0180 }