538 lines
19 KiB
C++
538 lines
19 KiB
C++
|
/****************************************************************************
|
||
|
** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
|
||
|
** All right reserved.
|
||
|
**
|
||
|
** Permission is hereby granted, free of charge, to any person obtaining
|
||
|
** a copy of this software and associated documentation files (the
|
||
|
** "Software"), to deal in the Software without restriction, including
|
||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||
|
** distribute, sublicense, and/or sell copies of the Software, and to
|
||
|
** permit persons to whom the Software is furnished to do so, subject to
|
||
|
** the following conditions:
|
||
|
**
|
||
|
** The above copyright notice and this permission notice shall be
|
||
|
** included in all copies or substantial portions of the Software.
|
||
|
**
|
||
|
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||
|
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||
|
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||
|
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||
|
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
**
|
||
|
****************************************************************************/
|
||
|
|
||
|
#include "xlsxdrawinganchor_p.h"
|
||
|
#include "xlsxdrawing_p.h"
|
||
|
#include "xlsxmediafile_p.h"
|
||
|
#include "xlsxchart.h"
|
||
|
#include "xlsxworkbook.h"
|
||
|
#include "xlsxutility_p.h"
|
||
|
|
||
|
#include <QXmlStreamReader>
|
||
|
#include <QXmlStreamWriter>
|
||
|
#include <QBuffer>
|
||
|
#include <QDir>
|
||
|
|
||
|
namespace QXlsx {
|
||
|
|
||
|
/*
|
||
|
The vertices that define the position of a graphical object
|
||
|
within the worksheet in pixels.
|
||
|
|
||
|
+------------+------------+
|
||
|
| A | B |
|
||
|
+-----+------------+------------+
|
||
|
| |(x1,y1) | |
|
||
|
| 1 |(A1)._______|______ |
|
||
|
| | | | |
|
||
|
| | | | |
|
||
|
+-----+----| OBJECT |-----+
|
||
|
| | | | |
|
||
|
| 2 | |______________. |
|
||
|
| | | (B2)|
|
||
|
| | | (x2,y2)|
|
||
|
+---- +------------+------------+
|
||
|
|
||
|
Example of an object that covers some of the area from cell A1 to B2.
|
||
|
|
||
|
Based on the width and height of the object we need to calculate 8 vars:
|
||
|
|
||
|
col_start, row_start, col_end, row_end, x1, y1, x2, y2.
|
||
|
|
||
|
We also calculate the absolute x and y position of the top left vertex of
|
||
|
the object. This is required for images.
|
||
|
|
||
|
The width and height of the cells that the object occupies can be
|
||
|
variable and have to be taken into account.
|
||
|
*/
|
||
|
|
||
|
// anchor
|
||
|
|
||
|
DrawingAnchor::DrawingAnchor(Drawing *drawing, ObjectType objectType)
|
||
|
: m_drawing(drawing)
|
||
|
, m_objectType(objectType)
|
||
|
{
|
||
|
m_drawing->anchors.append(this);
|
||
|
m_id = m_drawing->anchors.size(); // must be unique in one drawing{x}.xml file.
|
||
|
}
|
||
|
|
||
|
DrawingAnchor::~DrawingAnchor()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::setObjectPicture(const QImage &img)
|
||
|
{
|
||
|
QByteArray ba;
|
||
|
QBuffer buffer(&ba);
|
||
|
buffer.open(QIODevice::WriteOnly);
|
||
|
img.save(&buffer, "PNG");
|
||
|
|
||
|
m_pictureFile = QSharedPointer<MediaFile>(
|
||
|
new MediaFile(ba, QStringLiteral("png"), QStringLiteral("image/png")));
|
||
|
m_drawing->workbook->addMediaFile(m_pictureFile);
|
||
|
|
||
|
m_objectType = Picture;
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::setObjectGraphicFrame(QSharedPointer<Chart> chart)
|
||
|
{
|
||
|
m_chartFile = chart;
|
||
|
m_drawing->workbook->addChartFile(chart);
|
||
|
|
||
|
m_objectType = GraphicFrame;
|
||
|
}
|
||
|
|
||
|
QPoint DrawingAnchor::loadXmlPos(QXmlStreamReader &reader)
|
||
|
{
|
||
|
Q_ASSERT(reader.name() == QLatin1String("pos"));
|
||
|
|
||
|
QPoint pos;
|
||
|
QXmlStreamAttributes attrs = reader.attributes();
|
||
|
pos.setX(attrs.value(QLatin1String("x")).toString().toInt());
|
||
|
pos.setY(attrs.value(QLatin1String("y")).toString().toInt());
|
||
|
return pos;
|
||
|
}
|
||
|
|
||
|
QSize DrawingAnchor::loadXmlExt(QXmlStreamReader &reader)
|
||
|
{
|
||
|
Q_ASSERT(reader.name() == QLatin1String("ext"));
|
||
|
|
||
|
QSize size;
|
||
|
QXmlStreamAttributes attrs = reader.attributes();
|
||
|
size.setWidth(attrs.value(QLatin1String("cx")).toString().toInt());
|
||
|
size.setHeight(attrs.value(QLatin1String("cy")).toString().toInt());
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
XlsxMarker DrawingAnchor::loadXmlMarker(QXmlStreamReader &reader, const QString &node)
|
||
|
{
|
||
|
Q_ASSERT(reader.name() == node);
|
||
|
|
||
|
int col = 0;
|
||
|
int colOffset = 0;
|
||
|
int row = 0;
|
||
|
int rowOffset = 0;
|
||
|
while (!reader.atEnd()) {
|
||
|
reader.readNextStartElement();
|
||
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||
|
if (reader.name() == QLatin1String("col")) {
|
||
|
col = reader.readElementText().toInt();
|
||
|
} else if (reader.name() == QLatin1String("colOff")) {
|
||
|
colOffset = reader.readElementText().toInt();
|
||
|
} else if (reader.name() == QLatin1String("row")) {
|
||
|
row = reader.readElementText().toInt();
|
||
|
} else if (reader.name() == QLatin1String("rowOff")) {
|
||
|
rowOffset = reader.readElementText().toInt();
|
||
|
}
|
||
|
} else if (reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == node) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return XlsxMarker(row, col, rowOffset, colOffset);
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::loadXmlObject(QXmlStreamReader &reader)
|
||
|
{
|
||
|
if (reader.name() == QLatin1String("sp")) {
|
||
|
// Shape
|
||
|
m_objectType = Shape;
|
||
|
loadXmlObjectShape(reader);
|
||
|
} else if (reader.name() == QLatin1String("grpSp")) {
|
||
|
// Group Shape
|
||
|
m_objectType = GroupShape;
|
||
|
loadXmlObjectGroupShape(reader);
|
||
|
} else if (reader.name() == QLatin1String("graphicFrame")) {
|
||
|
// Graphic Frame
|
||
|
m_objectType = GraphicFrame;
|
||
|
loadXmlObjectGraphicFrame(reader);
|
||
|
} else if (reader.name() == QLatin1String("cxnSp")) {
|
||
|
// Connection Shape
|
||
|
m_objectType = ConnectionShape;
|
||
|
loadXmlObjectConnectionShape(reader);
|
||
|
} else if (reader.name() == QLatin1String("pic")) {
|
||
|
// Picture
|
||
|
m_objectType = Picture;
|
||
|
loadXmlObjectPicture(reader);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::loadXmlObjectConnectionShape(QXmlStreamReader &reader)
|
||
|
{
|
||
|
Q_UNUSED(reader)
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::loadXmlObjectGraphicFrame(QXmlStreamReader &reader)
|
||
|
{
|
||
|
Q_ASSERT(reader.name() == QLatin1String("graphicFrame"));
|
||
|
|
||
|
while (!reader.atEnd()) {
|
||
|
reader.readNextStartElement();
|
||
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||
|
if (reader.name() == QLatin1String("chart")) {
|
||
|
QString rId = reader.attributes().value(QLatin1String("r:id")).toString();
|
||
|
QString name = m_drawing->relationships()->getRelationshipById(rId).target;
|
||
|
QString path = QDir::cleanPath(splitPath(m_drawing->filePath())[0]
|
||
|
+ QLatin1String("/") + name);
|
||
|
|
||
|
bool exist = false;
|
||
|
QList<QSharedPointer<Chart>> cfs = m_drawing->workbook->chartFiles();
|
||
|
for (int i = 0; i < cfs.size(); ++i) {
|
||
|
if (cfs[i]->filePath() == path) {
|
||
|
// already exist
|
||
|
exist = true;
|
||
|
m_chartFile = cfs[i];
|
||
|
}
|
||
|
}
|
||
|
if (!exist) {
|
||
|
m_chartFile =
|
||
|
QSharedPointer<Chart>(new Chart(m_drawing->sheet, Chart::F_LoadFromExists));
|
||
|
m_chartFile->setFilePath(path);
|
||
|
m_drawing->workbook->addChartFile(m_chartFile);
|
||
|
}
|
||
|
}
|
||
|
} else if (reader.tokenType() == QXmlStreamReader::EndElement
|
||
|
&& reader.name() == QLatin1String("graphicFrame")) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::loadXmlObjectGroupShape(QXmlStreamReader &reader)
|
||
|
{
|
||
|
Q_UNUSED(reader)
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::loadXmlObjectPicture(QXmlStreamReader &reader)
|
||
|
{
|
||
|
Q_ASSERT(reader.name() == QLatin1String("pic"));
|
||
|
|
||
|
while (!reader.atEnd()) {
|
||
|
reader.readNextStartElement();
|
||
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||
|
if (reader.name() == QLatin1String("blip")) {
|
||
|
QString rId = reader.attributes().value(QLatin1String("r:embed")).toString();
|
||
|
QString name = m_drawing->relationships()->getRelationshipById(rId).target;
|
||
|
QString path = QDir::cleanPath(splitPath(m_drawing->filePath())[0]
|
||
|
+ QLatin1String("/") + name);
|
||
|
|
||
|
bool exist = false;
|
||
|
QList<QSharedPointer<MediaFile>> mfs = m_drawing->workbook->mediaFiles();
|
||
|
for (int i = 0; i < mfs.size(); ++i) {
|
||
|
if (mfs[i]->fileName() == path) {
|
||
|
// already exist
|
||
|
exist = true;
|
||
|
m_pictureFile = mfs[i];
|
||
|
}
|
||
|
}
|
||
|
if (!exist) {
|
||
|
m_pictureFile = QSharedPointer<MediaFile>(new MediaFile(path));
|
||
|
m_drawing->workbook->addMediaFile(m_pictureFile, true);
|
||
|
}
|
||
|
}
|
||
|
} else if (reader.tokenType() == QXmlStreamReader::EndElement
|
||
|
&& reader.name() == QLatin1String("pic")) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::loadXmlObjectShape(QXmlStreamReader &reader)
|
||
|
{
|
||
|
Q_UNUSED(reader)
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::saveXmlPos(QXmlStreamWriter &writer, const QPoint &pos) const
|
||
|
{
|
||
|
writer.writeEmptyElement(QStringLiteral("xdr:pos"));
|
||
|
writer.writeAttribute(QStringLiteral("x"), QString::number(pos.x()));
|
||
|
writer.writeAttribute(QStringLiteral("y"), QString::number(pos.y()));
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::saveXmlExt(QXmlStreamWriter &writer, const QSize &ext) const
|
||
|
{
|
||
|
writer.writeStartElement(QStringLiteral("xdr:ext"));
|
||
|
writer.writeAttribute(QStringLiteral("cx"), QString::number(ext.width()));
|
||
|
writer.writeAttribute(QStringLiteral("cy"), QString::number(ext.height()));
|
||
|
writer.writeEndElement(); // xdr:ext
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::saveXmlMarker(QXmlStreamWriter &writer, const XlsxMarker &marker,
|
||
|
const QString &node) const
|
||
|
{
|
||
|
writer.writeStartElement(node); // xdr:from or xdr:to
|
||
|
writer.writeTextElement(QStringLiteral("xdr:col"), QString::number(marker.col()));
|
||
|
writer.writeTextElement(QStringLiteral("xdr:colOff"), QString::number(marker.colOff()));
|
||
|
writer.writeTextElement(QStringLiteral("xdr:row"), QString::number(marker.row()));
|
||
|
writer.writeTextElement(QStringLiteral("xdr:rowOff"), QString::number(marker.rowOff()));
|
||
|
writer.writeEndElement();
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::saveXmlObject(QXmlStreamWriter &writer) const
|
||
|
{
|
||
|
if (m_objectType == Picture)
|
||
|
saveXmlObjectPicture(writer);
|
||
|
else if (m_objectType == ConnectionShape)
|
||
|
saveXmlObjectConnectionShape(writer);
|
||
|
else if (m_objectType == GraphicFrame)
|
||
|
saveXmlObjectGraphicFrame(writer);
|
||
|
else if (m_objectType == GroupShape)
|
||
|
saveXmlObjectGroupShape(writer);
|
||
|
else if (m_objectType == Shape)
|
||
|
saveXmlObjectShape(writer);
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::saveXmlObjectConnectionShape(QXmlStreamWriter &writer) const
|
||
|
{
|
||
|
Q_UNUSED(writer)
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::saveXmlObjectGraphicFrame(QXmlStreamWriter &writer) const
|
||
|
{
|
||
|
writer.writeStartElement(QStringLiteral("xdr:graphicFrame"));
|
||
|
writer.writeAttribute(QStringLiteral("macro"), QString());
|
||
|
|
||
|
writer.writeStartElement(QStringLiteral("xdr:nvGraphicFramePr"));
|
||
|
writer.writeEmptyElement(QStringLiteral("xdr:cNvPr"));
|
||
|
writer.writeAttribute(QStringLiteral("id"), QString::number(m_id));
|
||
|
writer.writeAttribute(QStringLiteral("name"), QStringLiteral("Chart %1").arg(m_id));
|
||
|
writer.writeEmptyElement(QStringLiteral("xdr:cNvGraphicFramePr"));
|
||
|
writer.writeEndElement(); // xdr:nvGraphicFramePr
|
||
|
|
||
|
writer.writeStartElement(QStringLiteral("xdr:xfrm"));
|
||
|
writer.writeEndElement(); // xdr:xfrm
|
||
|
|
||
|
writer.writeStartElement(QStringLiteral("a:graphic"));
|
||
|
writer.writeStartElement(QStringLiteral("a:graphicData"));
|
||
|
writer.writeAttribute(QStringLiteral("uri"),
|
||
|
QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/chart"));
|
||
|
|
||
|
int idx = m_drawing->workbook->chartFiles().indexOf(m_chartFile);
|
||
|
m_drawing->relationships()->addDocumentRelationship(
|
||
|
QStringLiteral("/chart"), QStringLiteral("../charts/chart%1.xml").arg(idx + 1));
|
||
|
|
||
|
writer.writeEmptyElement(QStringLiteral("c:chart"));
|
||
|
writer.writeAttribute(QStringLiteral("xmlns:c"),
|
||
|
QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/chart"));
|
||
|
writer.writeAttribute(
|
||
|
QStringLiteral("xmlns:r"),
|
||
|
QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
|
||
|
writer.writeAttribute(QStringLiteral("r:id"),
|
||
|
QStringLiteral("rId%1").arg(m_drawing->relationships()->count()));
|
||
|
|
||
|
writer.writeEndElement(); // a:graphicData
|
||
|
writer.writeEndElement(); // a:graphic
|
||
|
writer.writeEndElement(); // xdr:graphicFrame
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::saveXmlObjectGroupShape(QXmlStreamWriter &writer) const
|
||
|
{
|
||
|
Q_UNUSED(writer)
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::saveXmlObjectPicture(QXmlStreamWriter &writer) const
|
||
|
{
|
||
|
Q_ASSERT(m_objectType == Picture && !m_pictureFile.isNull());
|
||
|
|
||
|
writer.writeStartElement(QStringLiteral("xdr:pic"));
|
||
|
|
||
|
writer.writeStartElement(QStringLiteral("xdr:nvPicPr"));
|
||
|
writer.writeEmptyElement(QStringLiteral("xdr:cNvPr"));
|
||
|
writer.writeAttribute(QStringLiteral("id"), QString::number(m_id));
|
||
|
writer.writeAttribute(QStringLiteral("name"), QStringLiteral("Picture %1").arg(m_id));
|
||
|
|
||
|
writer.writeStartElement(QStringLiteral("xdr:cNvPicPr"));
|
||
|
writer.writeEmptyElement(QStringLiteral("a:picLocks"));
|
||
|
writer.writeAttribute(QStringLiteral("noChangeAspect"), QStringLiteral("1"));
|
||
|
writer.writeEndElement(); // xdr:cNvPicPr
|
||
|
|
||
|
writer.writeEndElement(); // xdr:nvPicPr
|
||
|
|
||
|
m_drawing->relationships()->addDocumentRelationship(QStringLiteral("/image"),
|
||
|
QStringLiteral("../media/image%1.%2")
|
||
|
.arg(m_pictureFile->index() + 1)
|
||
|
.arg(m_pictureFile->suffix()));
|
||
|
|
||
|
writer.writeStartElement(QStringLiteral("xdr:blipFill"));
|
||
|
writer.writeEmptyElement(QStringLiteral("a:blip"));
|
||
|
writer.writeAttribute(
|
||
|
QStringLiteral("xmlns:r"),
|
||
|
QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
|
||
|
writer.writeAttribute(QStringLiteral("r:embed"),
|
||
|
QStringLiteral("rId%1").arg(m_drawing->relationships()->count()));
|
||
|
writer.writeStartElement(QStringLiteral("a:stretch"));
|
||
|
writer.writeEmptyElement(QStringLiteral("a:fillRect"));
|
||
|
writer.writeEndElement(); // a:stretch
|
||
|
writer.writeEndElement(); // xdr:blipFill
|
||
|
|
||
|
writer.writeStartElement(QStringLiteral("xdr:spPr"));
|
||
|
|
||
|
writer.writeStartElement(QStringLiteral("a:prstGeom"));
|
||
|
writer.writeAttribute(QStringLiteral("prst"), QStringLiteral("rect"));
|
||
|
writer.writeEmptyElement(QStringLiteral("a:avLst"));
|
||
|
writer.writeEndElement(); // a:prstGeom
|
||
|
|
||
|
writer.writeEndElement(); // xdr:spPr
|
||
|
|
||
|
writer.writeEndElement(); // xdr:pic
|
||
|
}
|
||
|
|
||
|
void DrawingAnchor::saveXmlObjectShape(QXmlStreamWriter &writer) const { Q_UNUSED(writer) }
|
||
|
|
||
|
// absolute anchor
|
||
|
|
||
|
DrawingAbsoluteAnchor::DrawingAbsoluteAnchor(Drawing *drawing, ObjectType objectType)
|
||
|
: DrawingAnchor(drawing, objectType)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
bool DrawingAbsoluteAnchor::loadFromXml(QXmlStreamReader &reader)
|
||
|
{
|
||
|
Q_ASSERT(reader.name() == QLatin1String("absoluteAnchor"));
|
||
|
|
||
|
while (!reader.atEnd()) {
|
||
|
reader.readNextStartElement();
|
||
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||
|
if (reader.name() == QLatin1String("pos")) {
|
||
|
pos = loadXmlPos(reader);
|
||
|
} else if (reader.name() == QLatin1String("ext")) {
|
||
|
ext = loadXmlExt(reader);
|
||
|
} else {
|
||
|
loadXmlObject(reader);
|
||
|
}
|
||
|
} else if (reader.tokenType() == QXmlStreamReader::EndElement
|
||
|
&& reader.name() == QLatin1String("absoluteAnchor")) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void DrawingAbsoluteAnchor::saveToXml(QXmlStreamWriter &writer) const
|
||
|
{
|
||
|
writer.writeStartElement(QStringLiteral("xdr:absoluteAnchor"));
|
||
|
saveXmlPos(writer, pos);
|
||
|
saveXmlExt(writer, ext);
|
||
|
|
||
|
saveXmlObject(writer);
|
||
|
|
||
|
writer.writeEmptyElement(QStringLiteral("xdr:clientData"));
|
||
|
writer.writeEndElement(); // xdr:absoluteAnchor
|
||
|
}
|
||
|
|
||
|
// one cell anchor
|
||
|
|
||
|
DrawingOneCellAnchor::DrawingOneCellAnchor(Drawing *drawing, ObjectType objectType)
|
||
|
: DrawingAnchor(drawing, objectType)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
bool DrawingOneCellAnchor::loadFromXml(QXmlStreamReader &reader)
|
||
|
{
|
||
|
Q_ASSERT(reader.name() == QLatin1String("oneCellAnchor"));
|
||
|
while (!reader.atEnd()) {
|
||
|
reader.readNextStartElement();
|
||
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||
|
if (reader.name() == QLatin1String("from")) {
|
||
|
from = loadXmlMarker(reader, QLatin1String("from"));
|
||
|
} else if (reader.name() == QLatin1String("ext")) {
|
||
|
ext = loadXmlExt(reader);
|
||
|
} else {
|
||
|
loadXmlObject(reader);
|
||
|
}
|
||
|
} else if (reader.tokenType() == QXmlStreamReader::EndElement
|
||
|
&& reader.name() == QLatin1String("oneCellAnchor")) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void DrawingOneCellAnchor::saveToXml(QXmlStreamWriter &writer) const
|
||
|
{
|
||
|
writer.writeStartElement(QStringLiteral("xdr:oneCellAnchor"));
|
||
|
|
||
|
saveXmlMarker(writer, from, QStringLiteral("xdr:from"));
|
||
|
saveXmlExt(writer, ext);
|
||
|
|
||
|
saveXmlObject(writer);
|
||
|
|
||
|
writer.writeEmptyElement(QStringLiteral("xdr:clientData"));
|
||
|
writer.writeEndElement(); // xdr:oneCellAnchor
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Two cell anchor
|
||
|
|
||
|
This class specifies a two cell anchor placeholder for a group
|
||
|
, a shape, or a drawing element. It moves with
|
||
|
cells and its extents are in EMU units.
|
||
|
*/
|
||
|
DrawingTwoCellAnchor::DrawingTwoCellAnchor(Drawing *drawing, ObjectType objectType)
|
||
|
: DrawingAnchor(drawing, objectType)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
bool DrawingTwoCellAnchor::loadFromXml(QXmlStreamReader &reader)
|
||
|
{
|
||
|
Q_ASSERT(reader.name() == QLatin1String("twoCellAnchor"));
|
||
|
while (!reader.atEnd()) {
|
||
|
reader.readNextStartElement();
|
||
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||
|
if (reader.name() == QLatin1String("from")) {
|
||
|
from = loadXmlMarker(reader, QLatin1String("from"));
|
||
|
} else if (reader.name() == QLatin1String("to")) {
|
||
|
to = loadXmlMarker(reader, QLatin1String("to"));
|
||
|
} else {
|
||
|
loadXmlObject(reader);
|
||
|
}
|
||
|
} else if (reader.tokenType() == QXmlStreamReader::EndElement
|
||
|
&& reader.name() == QLatin1String("twoCellAnchor")) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void DrawingTwoCellAnchor::saveToXml(QXmlStreamWriter &writer) const
|
||
|
{
|
||
|
writer.writeStartElement(QStringLiteral("xdr:twoCellAnchor"));
|
||
|
writer.writeAttribute(QStringLiteral("editAs"), QStringLiteral("oneCell"));
|
||
|
|
||
|
saveXmlMarker(writer, from, QStringLiteral("xdr:from"));
|
||
|
saveXmlMarker(writer, to, QStringLiteral("xdr:to"));
|
||
|
|
||
|
saveXmlObject(writer);
|
||
|
|
||
|
writer.writeEmptyElement(QStringLiteral("xdr:clientData"));
|
||
|
writer.writeEndElement(); // xdr:twoCellAnchor
|
||
|
}
|
||
|
|
||
|
} // namespace QXlsx
|