Commit c0ba3d92 authored by Boudewijn Rempt's avatar Boudewijn Rempt

Save and load xml:id as well as text:id and draw:id where necessary

ODF 1.2 migrates from draw:id and text:id to xml:id in most cases. This
patch introduces a new class, KoElementReference, that makes handling
id's mostly transparent.

It also changes KoShapeSavingContext to manage references and id's in
a transparent manner when saving. Most filters, even those that are
currently useless, have also been updated.

BUG:288644
REVIEW: 104074
parent 605fc2e9
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include "kis_shape_layer.h" #include "kis_shape_layer.h"
#include <QPainter> #include <QPainter>
#include <QPainterPath> #include <QPainterPath>
#include <QRect> #include <QRect>
...@@ -39,6 +38,7 @@ ...@@ -39,6 +38,7 @@
#include <kicon.h> #include <kicon.h>
#include <kdebug.h> #include <kdebug.h>
#include <KoElementReference.h>
#include <KoColorSpace.h> #include <KoColorSpace.h>
#include <KoCompositeOp.h> #include <KoCompositeOp.h>
#include <KoDataCenterBase.h> #include <KoDataCenterBase.h>
...@@ -328,7 +328,10 @@ bool KisShapeLayer::saveLayer(KoStore * store) const ...@@ -328,7 +328,10 @@ bool KisShapeLayer::saveLayer(KoStore * store) const
shapeContext.xmlWriter().startElement("draw:page"); shapeContext.xmlWriter().startElement("draw:page");
shapeContext.xmlWriter().addAttribute("draw:name", ""); shapeContext.xmlWriter().addAttribute("draw:name", "");
shapeContext.xmlWriter().addAttribute("draw:id", "page1");
KoElementReference elementRef("page", 1);
elementRef.saveOdf(&shapeContext.xmlWriter(), KoElementReference::DrawId);
shapeContext.xmlWriter().addAttribute("draw:master-page-name", "Default"); shapeContext.xmlWriter().addAttribute("draw:master-page-name", "Default");
saveOdf(shapeContext); saveOdf(shapeContext);
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include <KoShapeSavingContext.h> #include <KoShapeSavingContext.h>
#include <KoStoreDevice.h> #include <KoStoreDevice.h>
#include <KoShapeTransformCommand.h> #include <KoShapeTransformCommand.h>
#include <KoElementReference.h>
#include "kis_painter.h" #include "kis_painter.h"
#include "kis_paint_device.h" #include "kis_paint_device.h"
...@@ -159,7 +160,10 @@ bool KisShapeSelection::saveSelection(KoStore * store) const ...@@ -159,7 +160,10 @@ bool KisShapeSelection::saveSelection(KoStore * store) const
shapeContext.xmlWriter().startElement("draw:page"); shapeContext.xmlWriter().startElement("draw:page");
shapeContext.xmlWriter().addAttribute("draw:name", ""); shapeContext.xmlWriter().addAttribute("draw:name", "");
shapeContext.xmlWriter().addAttribute("draw:id", "page1");
KoElementReference elementRef;
elementRef.saveOdf(&shapeContext.xmlWriter(), KoElementReference::DrawId);
shapeContext.xmlWriter().addAttribute("draw:master-page-name", "Default"); shapeContext.xmlWriter().addAttribute("draw:master-page-name", "Default");
saveOdf(shapeContext); saveOdf(shapeContext);
......
...@@ -345,7 +345,7 @@ void KoConnectionShape::saveOdf(KoShapeSavingContext & context) const ...@@ -345,7 +345,7 @@ void KoConnectionShape::saveOdf(KoShapeSavingContext & context) const
} }
if (d->shape1) { if (d->shape1) {
context.xmlWriter().addAttribute("draw:start-shape", context.drawId(d->shape1)); context.xmlWriter().addAttribute("draw:start-shape", context.xmlid(d->shape1, "shape", KoElementReference::Counter).toString());
context.xmlWriter().addAttribute("draw:start-glue-point", d->connectionPointId1); context.xmlWriter().addAttribute("draw:start-glue-point", d->connectionPointId1);
} else { } else {
QPointF p(shapeToDocument(d->handles[StartHandle]) * context.shapeOffset(this)); QPointF p(shapeToDocument(d->handles[StartHandle]) * context.shapeOffset(this));
...@@ -353,7 +353,7 @@ void KoConnectionShape::saveOdf(KoShapeSavingContext & context) const ...@@ -353,7 +353,7 @@ void KoConnectionShape::saveOdf(KoShapeSavingContext & context) const
context.xmlWriter().addAttributePt("svg:y1", p.y()); context.xmlWriter().addAttributePt("svg:y1", p.y());
} }
if (d->shape2) { if (d->shape2) {
context.xmlWriter().addAttribute("draw:end-shape", context.drawId(d->shape2)); context.xmlWriter().addAttribute("draw:end-shape", context.xmlid(d->shape2, "shape", KoElementReference::Counter).toString());
context.xmlWriter().addAttribute("draw:end-glue-point", d->connectionPointId2); context.xmlWriter().addAttribute("draw:end-glue-point", d->connectionPointId2);
} else { } else {
QPointF p(shapeToDocument(d->handles[EndHandle]) * context.shapeOffset(this)); QPointF p(shapeToDocument(d->handles[EndHandle]) * context.shapeOffset(this));
......
...@@ -218,8 +218,6 @@ void KoImageCollection::update(qint64 oldKey, qint64 newKey) ...@@ -218,8 +218,6 @@ void KoImageCollection::update(qint64 oldKey, qint64 newKey)
d->images.remove(oldKey); d->images.remove(oldKey);
d->images.insert(newKey, imageData); d->images.insert(newKey, imageData);
} }
Q_ASSERT(d->images.contains(newKey));
Q_ASSERT(!d->images.contains(oldKey));
} }
void KoImageCollection::removeOnKey(qint64 imageDataKey) void KoImageCollection::removeOnKey(qint64 imageDataKey)
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include "KoOdfWorkaround.h" #include "KoOdfWorkaround.h"
#include "KoFilterEffectStack.h" #include "KoFilterEffectStack.h"
#include <KoSnapData.h> #include <KoSnapData.h>
#include <KoElementReference.h>
#include <KoXmlReader.h> #include <KoXmlReader.h>
#include <KoXmlWriter.h> #include <KoXmlWriter.h>
...@@ -1381,11 +1382,10 @@ bool KoShape::loadOdfAttributes(const KoXmlElement &element, KoShapeLoadingConte ...@@ -1381,11 +1382,10 @@ bool KoShape::loadOdfAttributes(const KoXmlElement &element, KoShapeLoadingConte
} }
if (attributes & OdfId) { if (attributes & OdfId) {
if (element.hasAttributeNS(KoXmlNS::draw, "id")) { KoElementReference ref;
QString id = element.attributeNS(KoXmlNS::draw, "id"); ref.loadOdf(element);
if (!id.isNull()) { if (ref.isValid()) {
context.addShapeId(this, id); context.addShapeId(this, ref.toString());
}
} }
} }
...@@ -1571,6 +1571,9 @@ void KoShape::loadOdfGluePoints(const KoXmlElement &element, KoShapeLoadingConte ...@@ -1571,6 +1571,9 @@ void KoShape::loadOdfGluePoints(const KoXmlElement &element, KoShapeLoadingConte
if (child.localName() != "glue-point") if (child.localName() != "glue-point")
continue; continue;
// NOTE: this uses draw:id, but apparently while ODF 1.2 has deprecated
// all use of draw:id for xml:id, it didn't specify that here, so it
// doesn't support xml:id (and so, maybe, shouldn't use KoElementReference.
const QString id = child.attributeNS(KoXmlNS::draw, "id", QString()); const QString id = child.attributeNS(KoXmlNS::draw, "id", QString());
const int index = id.toInt(); const int index = id.toInt();
if(id.isEmpty() || index < 4 || d->connectors.contains(index)) { if(id.isEmpty() || index < 4 || d->connectors.contains(index)) {
...@@ -1748,8 +1751,8 @@ void KoShape::saveOdfAttributes(KoShapeSavingContext &context, int attributes) c ...@@ -1748,8 +1751,8 @@ void KoShape::saveOdfAttributes(KoShapeSavingContext &context, int attributes) c
if (attributes & OdfId) { if (attributes & OdfId) {
if (context.isSet(KoShapeSavingContext::DrawId)) { if (context.isSet(KoShapeSavingContext::DrawId)) {
context.xmlWriter().addAttribute("draw:id", context.drawId(this)); KoElementReference ref = context.xmlid(this, "shape", KoElementReference::Counter);
context.xmlWriter().addAttribute("xml:id", context.drawId(this)); ref.saveOdf(&context.xmlWriter(), KoElementReference::DrawId);
} }
} }
...@@ -1855,7 +1858,6 @@ void KoShape::saveOdfCommonChildElements(KoShapeSavingContext &context) const ...@@ -1855,7 +1858,6 @@ void KoShape::saveOdfCommonChildElements(KoShapeSavingContext &context) const
continue; continue;
context.xmlWriter().startElement("draw:glue-point"); context.xmlWriter().startElement("draw:glue-point");
context.xmlWriter().addAttribute("draw:id", QString("%1").arg(cp.key())); context.xmlWriter().addAttribute("draw:id", QString("%1").arg(cp.key()));
context.xmlWriter().addAttribute("xml:id", QString("%1").arg(cp.key()));
if (cp.value().alignment == KoConnectionPoint::AlignNone) { if (cp.value().alignment == KoConnectionPoint::AlignNone) {
// convert to percent from center // convert to percent from center
const qreal x = cp.value().position.x() * 100.0 - 50.0; const qreal x = cp.value().position.x() * 100.0 - 50.0;
......
...@@ -43,7 +43,8 @@ public: ...@@ -43,7 +43,8 @@ public:
Private(KoOdfLoadingContext &c, KoDocumentResourceManager *resourceManager) Private(KoOdfLoadingContext &c, KoDocumentResourceManager *resourceManager)
: context(c), : context(c),
zIndex(0), zIndex(0),
documentResources(resourceManager) documentResources(resourceManager),
documentRdf(0)
{ {
} }
~Private() { ~Private() {
...@@ -60,6 +61,7 @@ public: ...@@ -60,6 +61,7 @@ public:
QMap<QString, KoLoadingShapeUpdater*> updaterById; QMap<QString, KoLoadingShapeUpdater*> updaterById;
QMap<KoShape *, KoLoadingShapeUpdater*> updaterByShape; QMap<KoShape *, KoLoadingShapeUpdater*> updaterByShape;
KoDocumentResourceManager *documentResources; KoDocumentResourceManager *documentResources;
QObject *documentRdf;
}; };
KoShapeLoadingContext::KoShapeLoadingContext(KoOdfLoadingContext & context, KoDocumentResourceManager *documentResources) KoShapeLoadingContext::KoShapeLoadingContext(KoOdfLoadingContext & context, KoDocumentResourceManager *documentResources)
...@@ -191,3 +193,14 @@ KoDocumentResourceManager *KoShapeLoadingContext::documentResourceManager() cons ...@@ -191,3 +193,14 @@ KoDocumentResourceManager *KoShapeLoadingContext::documentResourceManager() cons
{ {
return d->documentResources; return d->documentResources;
} }
QObject *KoShapeLoadingContext::documentRdf() const
{
return d->documentRdf;
}
void KoShapeLoadingContext::setDocumentRdf(QObject *documentRdf)
{
d->documentRdf = documentRdf;
}
...@@ -176,6 +176,18 @@ public: ...@@ -176,6 +176,18 @@ public:
KoDocumentResourceManager *documentResourceManager() const; KoDocumentResourceManager *documentResourceManager() const;
/**
* @brief get the rdf document
* @return the rdf document, or 0 if there is none set/
*/
QObject *documentRdf() const;
/**
* @brief setDocumentRdf sets the rdf document for the loading context
* @param documentRdf the rdf document -- it needs to have been loaded already
*/
void setDocumentRdf(QObject *documentRdf);
private: private:
// to allow only the KoShapeRegistry access to the KoShapeBasedDocumentBase // to allow only the KoShapeRegistry access to the KoShapeBasedDocumentBase
class Private; class Private;
......
...@@ -31,10 +31,12 @@ ...@@ -31,10 +31,12 @@
#include <KoStore.h> #include <KoStore.h>
#include <KoStoreDevice.h> #include <KoStoreDevice.h>
#include <KoSharedSavingData.h> #include <KoSharedSavingData.h>
#include <KoElementReference.h>
#include <kmimetype.h> #include <kmimetype.h>
#include <kdebug.h> #include <kdebug.h>
#include <QMap> #include <QMap>
#include <QUuid>
class KoShapeSavingContextPrivate { class KoShapeSavingContextPrivate {
public: public:
...@@ -43,29 +45,31 @@ public: ...@@ -43,29 +45,31 @@ public:
KoXmlWriter *xmlWriter; KoXmlWriter *xmlWriter;
KoShapeSavingContext::ShapeSavingOptions savingOptions; KoShapeSavingContext::ShapeSavingOptions savingOptions;
QMap<const KoShape *, QString> drawIds;
QMap<const QTextBlockUserData*, QString> subIds;
QList<const KoShapeLayer*> layers; QList<const KoShapeLayer*> layers;
QSet<KoDataCenterBase *> dataCenters; QSet<KoDataCenterBase *> dataCenters;
int drawId;
int subId;
QMap<QString, KoSharedSavingData*> sharedData; QMap<QString, KoSharedSavingData*> sharedData;
QMap<qint64, QString> imageNames; QMap<qint64, QString> imageNames;
int imageId; int imageId;
QMap<QString, QImage> images; QMap<QString, QImage> images;
QHash<const KoShape *, QTransform> shapeOffsets; QHash<const KoShape *, QTransform> shapeOffsets;
QMap<const KoMarker *, QString> markerRefs; QMap<const KoMarker *, QString> markerRefs;
KoGenStyles& mainStyles; KoGenStyles& mainStyles;
KoEmbeddedDocumentSaver& embeddedSaver; KoEmbeddedDocumentSaver& embeddedSaver;
QMap<const void*, KoElementReference> references;
QMap<QString, int> referenceCounters;
QMap<QString, QList<const void*> > prefixedReferences;
}; };
KoShapeSavingContextPrivate::KoShapeSavingContextPrivate(KoXmlWriter &w, KoShapeSavingContextPrivate::KoShapeSavingContextPrivate(KoXmlWriter &w,
KoGenStyles &s, KoEmbeddedDocumentSaver &e) KoGenStyles &s, KoEmbeddedDocumentSaver &e)
: xmlWriter(&w), : xmlWriter(&w),
savingOptions(0), savingOptions(0),
drawId(0),
subId(0),
imageId(0), imageId(0),
mainStyles(s), mainStyles(s),
embeddedSaver(e) embeddedSaver(e)
...@@ -83,7 +87,7 @@ KoShapeSavingContext::KoShapeSavingContext(KoXmlWriter &xmlWriter, KoGenStyles & ...@@ -83,7 +87,7 @@ KoShapeSavingContext::KoShapeSavingContext(KoXmlWriter &xmlWriter, KoGenStyles &
KoEmbeddedDocumentSaver &embeddedSaver) KoEmbeddedDocumentSaver &embeddedSaver)
: d(new KoShapeSavingContextPrivate(xmlWriter, mainStyles, embeddedSaver)) : d(new KoShapeSavingContextPrivate(xmlWriter, mainStyles, embeddedSaver))
{ {
// by default allow saving of draw:id // by default allow saving of draw:id + xml:id
addOption(KoShapeSavingContext::DrawId); addOption(KoShapeSavingContext::DrawId);
} }
...@@ -138,36 +142,64 @@ void KoShapeSavingContext::removeOption(ShapeSavingOption option) ...@@ -138,36 +142,64 @@ void KoShapeSavingContext::removeOption(ShapeSavingOption option)
d->savingOptions = d->savingOptions ^ option; // xor to remove it. d->savingOptions = d->savingOptions ^ option; // xor to remove it.
} }
QString KoShapeSavingContext::drawId(const KoShape *shape, bool insert) KoElementReference KoShapeSavingContext::xmlid(const void *referent, const QString& prefix, KoElementReference::GenerationOption counter)
{ {
QMap<const KoShape *, QString>::iterator it(d->drawIds.find(shape)); Q_ASSERT(counter == KoElementReference::UUID || (counter == KoElementReference::Counter && !prefix.isEmpty()));
if (it == d->drawIds.end()) {
if (insert == true) { if (d->references.contains(referent)) {
it = d->drawIds.insert(shape, QString("shape%1").arg(++d->drawId)); return d->references[referent];
} else { }
return QString();
KoElementReference ref;
if (counter == KoElementReference::Counter) {
int referenceCounter = d->referenceCounters[prefix];
referenceCounter++;
ref = KoElementReference(prefix, referenceCounter);
d->references.insert(referent, ref);
d->referenceCounters[prefix] = referenceCounter;
}
else {
if (!prefix.isEmpty()) {
ref = KoElementReference(prefix);
d->references.insert(referent, ref);
}
else {
d->references.insert(referent, ref);
} }
} }
return it.value();
if (!prefix.isNull()) {
d->prefixedReferences[prefix].append(referent);
}
return ref;
} }
void KoShapeSavingContext::clearDrawIds() KoElementReference KoShapeSavingContext::existingXmlid(const void *referent)
{ {
d->drawIds.clear(); if (d->references.contains(referent)) {
d->drawId = 0; return d->references[referent];
}
else {
KoElementReference ref;
ref.invalidate();
return ref;
}
} }
QString KoShapeSavingContext::subId(const QTextBlockUserData *subItem, bool insert) void KoShapeSavingContext::clearXmlIds(const QString &prefix)
{ {
QMap<const QTextBlockUserData*, QString>::iterator it(d->subIds.find(subItem));
if (it == d->subIds.end()) { if (d->prefixedReferences.contains(prefix)) {
if (insert == true) { foreach(const void* ptr, d->prefixedReferences[prefix]) {
it = d->subIds.insert(subItem, QString("subitem%1").arg(++d->subId)); d->references.remove(ptr);
} else {
return QString();
} }
d->prefixedReferences.remove(prefix);
}
if (d->referenceCounters.contains(prefix)) {
d->referenceCounters[prefix] = 0;
} }
return it.value();
} }
void KoShapeSavingContext::addLayerForSaving(const KoShapeLayer *layer) void KoShapeSavingContext::addLayerForSaving(const KoShapeLayer *layer)
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <QImage> #include <QImage>
#include <QTransform> #include <QTransform>
#include <QTextBlockUserData> #include <QTextBlockUserData>
#include <KoElementReference.h>
class KoShape; class KoShape;
class KoXmlWriter; class KoXmlWriter;
...@@ -56,7 +57,8 @@ public: ...@@ -56,7 +57,8 @@ public:
*/ */
PresentationShape = 1, PresentationShape = 1,
/** /**
* Save the draw:id used for referencing the shape. * Save the draw:id used for referencing the shape. If draw:id is saved, xml:id is also
* saved.
* See OpenDocument 9.2.15 Common Drawing Shape Attributes / ID * See OpenDocument 9.2.15 Common Drawing Shape Attributes / ID
*/ */
DrawId = 2, DrawId = 2,
...@@ -139,39 +141,32 @@ public: ...@@ -139,39 +141,32 @@ public:
*/ */
ShapeSavingOptions options() const; ShapeSavingOptions options() const;
/** /**
* @brief Get the draw id for a shape * @brief xmlid returns an element reference that can be related to the given referent. If there is a
* * prefix given, this prefix will be used in addition to either the counter or the uuid.
* The draw:id is unique for all shapes. * @param referent the object we are referring to
* * @param prefix a prefix for the xml:id string
* @param shape for which the draw id should be returned * @param counter if counter is true, shapesavingcontext will use a counter to create the xml:id
* @param insert if true a new draw id will be generated if there is non yet * @return a KoElementReference; if insert is false and referent doesn't exist yet in the list, the elementrefence will be invalid.
* */
* @return the draw id for the shape or and empty string if it was not found KoElementReference xmlid(const void *referent, const QString& prefix = QString::null, KoElementReference::GenerationOption counter = KoElementReference::UUID);
/**
* @brief existingXmlid retrieve an existing xml id or invalid xml id if the referent object doesn't exist
*/ */
QString drawId(const KoShape *shape, bool insert = true); KoElementReference existingXmlid(const void *referent);
/** /**
* @brief Clear out all given draw ids * @brief Clear out all given draw ids
* @param prefix: removes all xml:id's that have the given prefix.
* *
* This is needed for checking if master pages are the same. In normal saving * This is needed for checking if master pages are the same. In normal saving
* this should not be called. * this should not be called.
* *
* @see KoPAPastePage::process * @see KoPAPastePage::process
*/ */
void clearDrawIds(); void clearXmlIds(const QString &prefix);
/**
* @brief Get the text id for a sub-item
*
* The text:id is unique for all sub-item.
*
* @param subitem for which the sub-item id should be returned
* @param insert if true a new sub-item id will be generated if there is non yet
*
* @return the sub-item id for the sub-item or and empty string if it was not found
*/
QString subId(const QTextBlockUserData *subItem, bool insert = true);
/** /**
* Adds a layer to save into a layer-set in styles.xml according to 9.1.2/9.1.3 odf spec * Adds a layer to save into a layer-set in styles.xml according to 9.1.2/9.1.3 odf spec
...@@ -256,7 +251,7 @@ public: ...@@ -256,7 +251,7 @@ public:
*/ */
KoSharedSavingData *sharedData(const QString &id) const; KoSharedSavingData *sharedData(const QString &id) const;
/* /**
* Add an offset that will be applied to the shape position when saved * Add an offset that will be applied to the shape position when saved
* *
* This is needed e.g. for shapes anchored to a text shape as the position is * This is needed e.g. for shapes anchored to a text shape as the position is
......
...@@ -277,7 +277,6 @@ QList<KoPAPageBase *> KoPADocument::loadOdfMasterPages( const QHash<QString, KoX ...@@ -277,7 +277,6 @@ QList<KoPAPageBase *> KoPADocument::loadOdfMasterPages( const QHash<QString, KoX
int count = 0; int count = 0;
for ( ; it != masterStyles.constEnd(); ++it ) for ( ; it != masterStyles.constEnd(); ++it )
{ {
kDebug(30010) << "Master:" << it.key();
KoPAMasterPage * masterPage = newMasterPage(); KoPAMasterPage * masterPage = newMasterPage();
masterPage->loadOdf( *( it.value() ), context ); masterPage->loadOdf( *( it.value() ), context );
masterPages.append( masterPage ); masterPages.append( masterPage );
...@@ -356,7 +355,7 @@ bool KoPADocument::saveOdfPages( KoPASavingContext &paContext, QList<KoPAPageBas ...@@ -356,7 +355,7 @@ bool KoPADocument::saveOdfPages( KoPASavingContext &paContext, QList<KoPAPageBas
// save master pages // save master pages
foreach( KoPAPageBase *page, masterPages ) { foreach( KoPAPageBase *page, masterPages ) {
if ( paContext.isSetClearDrawIds() ) { if ( paContext.isSetClearDrawIds() ) {
paContext.clearDrawIds(); paContext.clearXmlIds("shape");
} }
page->saveOdf( paContext ); page->saveOdf( paContext );
} }
......
...@@ -51,7 +51,6 @@ KoPAPage::~KoPAPage() ...@@ -51,7 +51,6 @@ KoPAPage::~KoPAPage()
void KoPAPage::saveOdf( KoShapeSavingContext & context ) const void KoPAPage::saveOdf( KoShapeSavingContext & context ) const
{ {
KoPASavingContext &paContext = static_cast<KoPASavingContext&>( context ); KoPASavingContext &paContext = static_cast<KoPASavingContext&>( context );
paContext.xmlWriter().startElement( "draw:page" ); paContext.xmlWriter().startElement( "draw:page" );
paContext.xmlWriter().addAttribute( "draw:name", paContext.pageName( this ) ); paContext.xmlWriter().addAttribute( "draw:name", paContext.pageName( this ) );
if (!name().isEmpty() && name() != paContext.pageName( this )) { if (!name().isEmpty() && name() != paContext.pageName( this )) {
......
...@@ -45,12 +45,13 @@ bool KoPAPastePage::process( const KoXmlElement & body, KoOdfReadStore & odfStor ...@@ -45,12 +45,13 @@ bool KoPAPastePage::process( const KoXmlElement & body, KoOdfReadStore & odfStor
KoOdfLoadingContext loadingContext( odfStore.styles(), odfStore.store(), m_doc->componentData() ); KoOdfLoadingContext loadingContext( odfStore.styles(), odfStore.store(), m_doc->componentData() );
KoPALoadingContext paContext(loadingContext, m_doc->resourceManager()); KoPALoadingContext paContext(loadingContext, m_doc->resourceManager());
QList<KoPAPageBase *> masterPages( m_doc->loadOdfMasterPages( odfStore.styles().masterPages(), paContext ) ); QList<KoPAPageBase *> newMasterPages( m_doc->loadOdfMasterPages( odfStore.styles().masterPages(), paContext ) );
QList<KoPAPageBase *> pages( m_doc->loadOdfPages( body, paContext ) ); QList<KoPAPageBase *> newPages( m_doc->loadOdfPages( body, paContext ) );
// Check where to start inserting pages
KoPAPageBase * insertAfterPage = 0; KoPAPageBase * insertAfterPage = 0;
KoPAPageBase * insertAfterMasterPage = 0; KoPAPageBase * insertAfterMasterPage = 0;
if ( dynamic_cast<KoPAMasterPage *>( m_activePage ) || ( m_activePage == 0 && pages.empty() ) ) { if ( dynamic_cast<KoPAMasterPage *>( m_activePage ) || ( m_activePage == 0 && newPages.empty() ) ) {
insertAfterMasterPage = m_activePage; insertAfterMasterPage = m_activePage;
insertAfterPage = m_doc->pages( false ).last(); insertAfterPage = m_doc->pages( false ).last();
} }
...@@ -59,7 +60,7 @@ bool KoPAPastePage::process( const KoXmlElement & body, KoOdfReadStore & odfStor ...@@ -59,7 +60,7 @@ bool KoPAPastePage::process( const KoXmlElement & body, KoOdfReadStore & odfStor
insertAfterMasterPage = m_doc->pages( true ).last(); insertAfterMasterPage = m_doc->pages( true ).last();
} }
if ( ! pages.empty() ) { if ( !newPages.empty() ) {
KoGenStyles mainStyles; KoGenStyles mainStyles;
QBuffer buffer; QBuffer buffer;
buffer.open( QIODevice::WriteOnly ); buffer.open( QIODevice::WriteOnly );
...@@ -87,10 +88,10 @@ bool KoPAPastePage::process( const KoXmlElement & body, KoOdfReadStore & odfStor ...@@ -87,10 +88,10 @@ bool KoPAPastePage::process( const KoXmlElement & body, KoOdfReadStore & odfStor
} }
m_doc->saveOdfPages( savingContext, emptyList, masterPages ); m_doc->saveOdfPages( savingContext, emptyList, newMasterPages );
QMap<KoPAMasterPage*, KoPAMasterPage*> updateMasterPage; QMap<KoPAMasterPage*, KoPAMasterPage*> masterPagesToUpdate;
foreach ( KoPAPageBase * page, masterPages ) foreach ( KoPAPageBase * page, newMasterPages )
{ {
KoPAMasterPage * masterPage = dynamic_cast<KoPAMasterPage*>( page ); KoPAMasterPage * masterPage = dynamic_cast<KoPAMasterPage*>( page );
Q_ASSERT( masterPage ); Q_ASSERT( masterPage );
...@@ -98,49 +99,49 @@ bool KoPAPastePage::process( const KoXmlElement & body, KoOdfReadStore & odfStor ...@@ -98,49 +99,49 @@ bool KoPAPastePage::process( const KoXmlElement & body, KoOdfReadStore & odfStor
QString masterPageName( savingContext.masterPageName( masterPage ) ); QString masterPageName( savingContext.masterPageName( masterPage ) );
QMap<QString, KoPAMasterPage*>::const_iterator existingMasterPage( masterPageNames.constFind( masterPageName ) ); QMap<QString, KoPAMasterPage*>::const_iterator existingMasterPage( masterPageNames.constFind( masterPageName ) );
if ( existingMasterPage != masterPageNames.constEnd() ) { if ( existingMasterPage != masterPageNames.constEnd() ) {
updateMasterPage.insert( masterPage, existingMasterPage.value() ); masterPagesToUpdate.insert( masterPage, existingMasterPage.value() );
} }
} }
} }
// update pages which have a duplicate master page // update pages which have a duplicate master page
foreach ( KoPAPageBase * page, pages ) foreach ( KoPAPageBase * page, newPages )
{ {
KoPAPage * p = dynamic_cast<KoPAPage*>( page ); KoPAPage * p = dynamic_cast<KoPAPage*>( page );
Q_ASSERT( p ); Q_ASSERT( p );
if ( p ) { if ( p ) {
KoPAMasterPage * masterPage( p->masterPage() ); KoPAMasterPage * masterPage( p->masterPage() );
QMap<KoPAMasterPage*, KoPAMasterPage*>::const_iterator pageIt( updateMasterPage.constFind( masterPage ) ); QMap<KoPAMasterPage*, KoPAMasterPage*>::const_iterator pageIt( masterPagesToUpdate.constFind( masterPage ) );
if ( pageIt != updateMasterPage.constEnd() ) { if ( pageIt != masterPagesToUpdate.constEnd() ) {
p->setMasterPage( pageIt.value() ); p->setMasterPage( pageIt.value() );
} }
} }
} }
// delete dumplicate master pages; // delete duplicate master pages;