File indexing completed on 2024-06-16 03:42:26

0001 // xlsxdrawinganchor.cpp
0002 
0003 #include <QtGlobal>
0004 #include <QDebug>
0005 #include <QXmlStreamReader>
0006 #include <QXmlStreamWriter>
0007 #include <QBuffer>
0008 #include <QDir>
0009 
0010 #include "xlsxdrawinganchor_p.h"
0011 #include "xlsxdrawing_p.h"
0012 #include "xlsxmediafile_p.h"
0013 #include "xlsxchart.h"
0014 #include "xlsxworkbook.h"
0015 #include "xlsxutility_p.h"
0016 
0017 QT_BEGIN_NAMESPACE_XLSX
0018 
0019 /*
0020      The vertices that define the position of a graphical object
0021      within the worksheet in pixels.
0022 
0023              +------------+------------+
0024              |     A      |      B     |
0025        +-----+------------+------------+
0026        |     |(x1,y1)     |            |
0027        |  1  |(A1)._______|______      |
0028        |     |    |              |     |
0029        |     |    |              |     |
0030        +-----+----|    OBJECT    |-----+
0031        |     |    |              |     |
0032        |  2  |    |______________.     |
0033        |     |            |        (B2)|
0034        |     |            |     (x2,y2)|
0035        +---- +------------+------------+
0036 
0037      Example of an object that covers some of the area from cell A1 to  B2.
0038 
0039      Based on the width and height of the object we need to calculate 8 vars:
0040 
0041          col_start, row_start, col_end, row_end, x1, y1, x2, y2.
0042 
0043      We also calculate the absolute x and y position of the top left vertex of
0044      the object. This is required for images.
0045 
0046      The width and height of the cells that the object occupies can be
0047      variable and have to be taken into account.
0048 */
0049 
0050 //anchor
0051 
0052 DrawingAnchor::DrawingAnchor(Drawing *drawing, ObjectType objectType)
0053     :m_drawing(drawing), m_objectType(objectType)
0054 {
0055     m_drawing->anchors.append(this);
0056     m_id = m_drawing->anchors.size();//must be unique in one drawing{x}.xml file.
0057 }
0058 
0059 DrawingAnchor::~DrawingAnchor()
0060 {
0061 
0062 }
0063 
0064 void DrawingAnchor::setObjectPicture(const QImage &img)
0065 {
0066     QByteArray ba;
0067     QBuffer buffer(&ba);
0068     buffer.open(QIODevice::WriteOnly);
0069     img.save(&buffer, "PNG");
0070 
0071     m_pictureFile = std::make_shared<MediaFile>(ba, QStringLiteral("png"), QStringLiteral("image/png"));
0072     m_drawing->workbook->addMediaFile(m_pictureFile);
0073 
0074     m_objectType = Picture;
0075 }
0076 
0077 bool DrawingAnchor::getObjectPicture(QImage &img)
0078 {
0079     if ( m_pictureFile == nullptr )
0080         return false;
0081 
0082     bool ret = img.loadFromData( m_pictureFile->contents() );
0083     return ret;
0084 }
0085 
0086 //{{ liufeijin
0087 void DrawingAnchor::setObjectShape(const QImage &img)
0088 {
0089     QByteArray ba;
0090     QBuffer buffer(&ba);
0091     buffer.open(QIODevice::WriteOnly);
0092     img.save(&buffer, "PNG");
0093 
0094     m_pictureFile = std::make_shared<MediaFile>(ba, QStringLiteral("png"), QStringLiteral("image/png"));
0095     m_drawing->workbook->addMediaFile(m_pictureFile);
0096 
0097     m_objectType = Shape;
0098 }
0099 //}}
0100 
0101 void DrawingAnchor::setObjectGraphicFrame(QSharedPointer<Chart> chart)
0102 {
0103     m_chartFile = chart;
0104     m_drawing->workbook->addChartFile(chart);
0105 
0106     m_objectType = GraphicFrame;
0107 }
0108 
0109 int DrawingAnchor::row() const
0110 {
0111     return -1;
0112 }
0113 
0114 int DrawingAnchor::col() const
0115 {
0116     return -1;
0117 }
0118 
0119 QPoint DrawingAnchor::loadXmlPos(QXmlStreamReader &reader)
0120 {
0121     Q_ASSERT(reader.name() == QLatin1String("pos"));
0122 
0123     QPoint pos;
0124     QXmlStreamAttributes attrs = reader.attributes();
0125     pos.setX(attrs.value(QLatin1String("x")).toInt());
0126     pos.setY(attrs.value(QLatin1String("y")).toInt());
0127     return pos;
0128 }
0129 
0130 QSize DrawingAnchor::loadXmlExt(QXmlStreamReader &reader)
0131 {
0132     Q_ASSERT(reader.name() == QLatin1String("ext"));
0133 
0134     QSize size;
0135     QXmlStreamAttributes attrs = reader.attributes();
0136     size.setWidth(attrs.value(QLatin1String("cx")).toInt());
0137     size.setHeight(attrs.value(QLatin1String("cy")).toInt());
0138     return size;
0139 }
0140 
0141 XlsxMarker DrawingAnchor::loadXmlMarker(QXmlStreamReader &reader, const QString &node)
0142 {
0143     Q_ASSERT(reader.name() == node);
0144 
0145     int col = 0;
0146     int colOffset = 0;
0147     int row = 0;
0148     int rowOffset = 0;
0149     while (!reader.atEnd())
0150     {
0151         reader.readNextStartElement();
0152         if (reader.tokenType() == QXmlStreamReader::StartElement)
0153         {
0154             if (reader.name() == QLatin1String("col"))
0155             {
0156                 col = reader.readElementText().toInt();
0157             }
0158             else if (reader.name() == QLatin1String("colOff"))
0159             {
0160                 colOffset = reader.readElementText().toInt();
0161             }
0162             else if (reader.name() == QLatin1String("row"))
0163             {
0164                 row = reader.readElementText().toInt();
0165             }
0166             else if (reader.name() == QLatin1String("rowOff"))
0167             {
0168                 rowOffset = reader.readElementText().toInt();
0169             }
0170         }
0171         else if (reader.tokenType() == QXmlStreamReader::EndElement
0172                    && reader.name() == node)
0173         {
0174             break;
0175         }
0176     }
0177 
0178     return XlsxMarker(row, col, rowOffset, colOffset);
0179 }
0180 
0181 void DrawingAnchor::loadXmlObject(QXmlStreamReader &reader)
0182 {
0183     /*
0184     <xsd:group name="EG_ObjectChoices">
0185         <xsd:sequence>
0186             <xsd:choice minOccurs="1" maxOccurs="1">
0187                 <xsd:element name="sp" type="CT_Shape"/>
0188                 <xsd:element name="grpSp" type="CT_GroupShape"/>
0189                 <xsd:element name="graphicFrame" type="CT_GraphicalObjectFrame"/>
0190                 <xsd:element name="cxnSp" type="CT_Connector"/>
0191                 <xsd:element name="pic" type="CT_Picture"/>
0192                 <xsd:element name="contentPart" type="CT_Rel"/>
0193             </xsd:choice>
0194         </xsd:sequence>
0195     </xsd:group>
0196     */
0197 
0198     if (reader.name() == QLatin1String("sp")) // <xsd:element name="sp" type="CT_Shape"/>
0199     {
0200         // Shape
0201         m_objectType = Shape;
0202 
0203         //{{ liufeijin
0204         sp_textlink = reader.attributes().value(QLatin1String("textlink")).toString();
0205         sp_macro = reader.attributes().value(QLatin1String("macro")).toString();
0206         //}} 
0207 
0208         // <xsd:attribute name="macro" type="xsd:string" use="optional"/>
0209         // <xsd:attribute name="textlink" type="xsd:string" use="optional"/>
0210         // <xsd:attribute name="fLocksText" type="xsd:boolean" use="optional" default="true"/>
0211         // <xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
0212 
0213         loadXmlObjectShape(reader); // CT_Shape
0214     }
0215     else if (reader.name() == QLatin1String("grpSp")) // <xsd:element name="grpSp" type="CT_GroupShape"/>
0216     {
0217         //Group Shape
0218         m_objectType = GroupShape;
0219         loadXmlObjectGroupShape(reader);
0220     }
0221     else if (reader.name() == QLatin1String("graphicFrame")) // <xsd:element name="graphicFrame" type="CT_GraphicalObjectFrame"/>
0222     {
0223         //Graphic Frame
0224         m_objectType = GraphicFrame;
0225         loadXmlObjectGraphicFrame(reader);
0226     }
0227     else if (reader.name() == QLatin1String("cxnSp")) // <xsd:element name="cxnSp" type="CT_Connector"/>
0228     {
0229         //Connection Shape
0230         m_objectType = ConnectionShape;
0231 
0232         // {{ liufeijin
0233         cxnSp_macro = reader.attributes().value(QLatin1String("macro")).toString();
0234         // }}
0235 
0236         loadXmlObjectConnectionShape(reader);
0237     }
0238     else if (reader.name() == QLatin1String("pic")) // <xsd:element name="pic" type="CT_Picture"/>
0239     {
0240         // Picture
0241         m_objectType = Picture;
0242         loadXmlObjectPicture(reader);
0243     }
0244     else if (reader.name() == QLatin1String("contentPart")) // <xsd:element name="contentPart" type="CT_Rel"/>
0245     {
0246         // contentPart
0247         /// TODO:
0248     }
0249 }
0250 
0251 void DrawingAnchor::loadXmlObjectConnectionShape(QXmlStreamReader &reader)
0252 {
0253     Q_ASSERT(reader.name() == QLatin1String("cxnSp"));
0254     bool hasoffext=false;
0255     while (!reader.atEnd()) {
0256         reader.readNextStartElement();
0257         if (reader.tokenType() == QXmlStreamReader::StartElement) {
0258             if (reader.name() == QLatin1String("cNvPr")){
0259                 xsp_cNvPR_name= reader.attributes().value(QLatin1String("name")).toString();
0260                 xsp_cNvPR_id= reader.attributes().value(QLatin1String("id")).toString();
0261              }else if(reader.name() == QLatin1String("spPr")){
0262                  xbwMode= reader.attributes().value(QLatin1String("bwMode")).toString();
0263             }else if(reader.name() == QLatin1String("xfrm")){
0264                 cxnSp_filpV= reader.attributes().value(QLatin1String("flipV")).toString();
0265             }else if (reader.name() == QLatin1String("off")) {
0266                posTA = loadXmlPos(reader);
0267                hasoffext=true;
0268             } else if (reader.name() == QLatin1String("ext")&&hasoffext) {
0269                extTA = loadXmlExt(reader);
0270                hasoffext=false;
0271             }else if(reader.name() == QLatin1String("prstGeom")){
0272                 xprstGeom_prst= reader.attributes().value(QLatin1String("prst")).toString().trimmed();
0273             }else if(reader.name() == QLatin1String("ln")){
0274                 xIn_algn= reader.attributes().value(QLatin1String("algn")).toString().trimmed();
0275                 xIn_cmpd= reader.attributes().value(QLatin1String("cmpd")).toString().trimmed();
0276                 xIn_cap= reader.attributes().value(QLatin1String("cap")).toString().trimmed();
0277                 xIn_w= reader.attributes().value(QLatin1String("w")).toString().trimmed();
0278             }else if(reader.name() == QLatin1String("headEnd")){
0279                 x_headEnd_w= reader.attributes().value(QLatin1String("w")).toString().trimmed();
0280                 x_headEnd_len= reader.attributes().value(QLatin1String("len")).toString().trimmed();
0281                 x_headEnd_tyep= reader.attributes().value(QLatin1String("type")).toString().trimmed();
0282             }else if(reader.name() == QLatin1String("tailEnd")){
0283                 x_tailEnd_w= reader.attributes().value(QLatin1String("w")).toString().trimmed();
0284                 x_tailEnd_len= reader.attributes().value(QLatin1String("len")).toString().trimmed();
0285                 x_tailEnd_tyep= reader.attributes().value(QLatin1String("type")).toString().trimmed();
0286             }else if(reader.name() == QLatin1String("lnRef")){
0287                 Style_inref_idx= reader.attributes().value(QLatin1String("idx")).toString().trimmed();
0288                 reader.readNextStartElement();
0289                 if (reader.tokenType() == QXmlStreamReader::StartElement) {
0290                     if(reader.name() == QLatin1String("schemeClr")){
0291                         Style_inref_val=reader.attributes().value(QLatin1String("val")).toString().trimmed();
0292                     }
0293                 }
0294             }else if(reader.name() == QLatin1String("fillRef")){
0295                 style_fillref_idx= reader.attributes().value(QLatin1String("idx")).toString().trimmed();
0296                 reader.readNextStartElement();
0297                 if (reader.tokenType() == QXmlStreamReader::StartElement) {
0298                     if(reader.name() == QLatin1String("schemeClr")){
0299                        style_fillref_val=reader.attributes().value(QLatin1String("val")).toString().trimmed();
0300                     }
0301                 }
0302             }else if(reader.name() == QLatin1String("effectRef")){
0303                 style_effectref_idx= reader.attributes().value(QLatin1String("idx")).toString().trimmed();
0304                 reader.readNextStartElement();
0305                 if (reader.tokenType() == QXmlStreamReader::StartElement) {
0306                     if(reader.name() == QLatin1String("schemeClr")){
0307                       style_effectref_val=reader.attributes().value(QLatin1String("val")).toString().trimmed();
0308                     }
0309                 }
0310             }else if(reader.name() == QLatin1String("fontRef")){
0311                 style_forntref_idx= reader.attributes().value(QLatin1String("idx")).toString().trimmed();
0312                 reader.readNextStartElement();
0313                 if (reader.tokenType() == QXmlStreamReader::StartElement) {
0314                     if(reader.name() == QLatin1String("schemeClr")){
0315                         style_forntref_val=reader.attributes().value(QLatin1String("val")).toString().trimmed();
0316                     }
0317                 }
0318             }
0319 
0320         } else if (reader.tokenType() == QXmlStreamReader::EndElement
0321                    && reader.name() == QLatin1String("cxnSp")) {
0322             break;
0323         }
0324     }
0325 
0326     return;
0327 
0328 }
0329 
0330 void DrawingAnchor::loadXmlObjectGraphicFrame(QXmlStreamReader &reader)
0331 {
0332     Q_ASSERT(reader.name() == QLatin1String("graphicFrame"));
0333 
0334     while (!reader.atEnd()) {
0335         reader.readNextStartElement();
0336         if (reader.tokenType() == QXmlStreamReader::StartElement) {
0337             if (reader.name() == QLatin1String("chart")) {
0338                 QString rId = reader.attributes().value(QLatin1String("r:id")).toString();
0339                 QString name = m_drawing->relationships()->getRelationshipById(rId).target;
0340 
0341                 const auto parts = splitPath(m_drawing->filePath());
0342                 QString path = QDir::cleanPath(parts.first() + QLatin1String("/") + name);
0343 
0344                 bool exist = false;
0345                 QList<QSharedPointer<Chart> > cfs = m_drawing->workbook->chartFiles();
0346                 for (int i=0; i<cfs.size(); ++i) {
0347                     if (cfs[i]->filePath() == path) {
0348                         //already exist
0349                         exist = true;
0350                         m_chartFile = cfs[i];
0351                     }
0352                 }
0353                 if (!exist) {
0354                     m_chartFile = QSharedPointer<Chart> (new Chart(m_drawing->sheet, Chart::F_LoadFromExists));
0355                     m_chartFile->setFilePath(path);
0356                     m_drawing->workbook->addChartFile(m_chartFile);
0357                 }
0358             }
0359         } else if (reader.tokenType() == QXmlStreamReader::EndElement
0360                    && reader.name() == QLatin1String("graphicFrame")) {
0361             break;
0362         }
0363     }
0364 
0365     return;
0366 }
0367 
0368 void DrawingAnchor::loadXmlObjectGroupShape(QXmlStreamReader &reader)
0369 {
0370     Q_UNUSED(reader)
0371 }
0372 
0373 void DrawingAnchor::loadXmlObjectPicture(QXmlStreamReader &reader)
0374 {
0375     Q_ASSERT(reader.name() == QLatin1String("pic"));
0376 
0377     while (!reader.atEnd()) {
0378         reader.readNextStartElement();
0379         if (reader.tokenType() == QXmlStreamReader::StartElement) {
0380             if (reader.name() == QLatin1String("blip")) {
0381                 QString rId = reader.attributes().value(QLatin1String("r:embed")).toString();
0382                 QString name = m_drawing->relationships()->getRelationshipById(rId).target;
0383 
0384                 const auto parts = splitPath(m_drawing->filePath());
0385                 QString path = QDir::cleanPath(parts.first() + QLatin1String("/") + name);
0386 
0387                 bool exist = false;
0388                 const auto mfs = m_drawing->workbook->mediaFiles();
0389                 for (const auto &mf : mfs) {
0390                     if (mf->fileName() == path) {
0391                         //already exist
0392                         exist = true;
0393                         m_pictureFile = mf;
0394                     }
0395                 }
0396                 if (!exist) {
0397                     m_pictureFile = std::make_shared<MediaFile>(path);
0398                     m_drawing->workbook->addMediaFile(m_pictureFile, true);
0399                 }
0400             }
0401         } else if (reader.tokenType() == QXmlStreamReader::EndElement
0402                    && reader.name() == QLatin1String("pic")) {
0403             break;
0404         }
0405     }
0406 
0407     return;
0408 }
0409 
0410 void DrawingAnchor::loadXmlObjectShape(QXmlStreamReader &reader)
0411 {
0412     /*
0413     <xsd:complexType name="CT_Shape">
0414         <xsd:sequence>
0415             <xsd:element name="nvSpPr" type="CT_ShapeNonVisual" minOccurs="1" maxOccurs="1"/>
0416             <xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="1" maxOccurs="1"/>
0417             <xsd:element name="style" type="a:CT_ShapeStyle" minOccurs="0" maxOccurs="1"/>
0418             <xsd:element name="txBody" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
0419         </xsd:sequence>
0420         <xsd:attribute name="macro" type="xsd:string" use="optional"/>
0421         <xsd:attribute name="textlink" type="xsd:string" use="optional"/>
0422         <xsd:attribute name="fLocksText" type="xsd:boolean" use="optional" default="true"/>
0423         <xsd:attribute name="fPublished" type="xsd:boolean" use="optional" default="false"/>
0424     </xsd:complexType>
0425     */
0426     /*
0427     <xsd:complexType name="CT_ShapeNonVisual">
0428         <xsd:sequence>
0429         <xsd:element name="cNvPr" type="a:CT_NonVisualDrawingProps" minOccurs="1" maxOccurs="1"/>
0430         <xsd:element name="cNvSpPr" type="a:CT_NonVisualDrawingShapeProps" minOccurs="1" maxOccurs="1"/>
0431         </xsd:sequence>
0432     </xsd:complexType>
0433     */
0434 
0435     Q_ASSERT(reader.name() == QLatin1String("sp"));
0436 
0437     while (!reader.atEnd())
0438     {
0439         reader.readNextStartElement();
0440 
0441         // qDebug() << __FUNCTION__ << reader.name().toString();
0442 
0443         if (reader.tokenType() == QXmlStreamReader::StartElement)
0444         {
0445             if (reader.name() == QLatin1String("nvSpPr"))
0446             {
0447 
0448             }
0449             else if (reader.name() == QLatin1String("spPr"))
0450             {
0451 
0452             }
0453             else if (reader.name() == QLatin1String("style"))
0454             {
0455 
0456             }
0457             else if (reader.name() == QLatin1String("txBody"))
0458             {
0459 
0460             }
0461         }
0462         else if (reader.tokenType() == QXmlStreamReader::EndElement
0463                    && reader.name() == QLatin1String("sp"))
0464         {
0465             break;
0466         }
0467     }
0468 
0469     /*
0470 
0471     bool hasoffext = false;
0472     while (!reader.atEnd())
0473     {
0474         reader.readNextStartElement();
0475 
0476         // qDebug() << __FUNCTION__ << reader.name().toString();
0477 
0478         if (reader.tokenType() == QXmlStreamReader::StartElement)
0479         {
0480             if (reader.name() == QLatin1String("blip"))
0481             {
0482                 QString rId;
0483                 sp_blip_rembed= reader.attributes().value(QLatin1String("r:embed")).toString();
0484                 sp_blip_cstate=reader.attributes().value(QLatin1String("cstate")).toString();
0485                 rId=sp_blip_rembed;
0486                 QString name = m_drawing->relationships()->getRelationshipById(rId).target;
0487                 QString path = QDir::cleanPath(splitPath(m_drawing->filePath())[0] + QLatin1String("/") + name);
0488                    bool exist = false;
0489                    QList<QSharedPointer<MediaFile> > mfs = m_drawing->workbook->mediaFiles();
0490                    for (int i=0; i<mfs.size(); ++i)
0491                    {
0492                        if (mfs[i]->fileName() == path)
0493                        {
0494                            //already exist
0495                            exist = true;
0496                            m_pictureFile = mfs[i];
0497                        }
0498                    }
0499                    if (!exist) {
0500                        m_pictureFile = QSharedPointer<MediaFile> (new MediaFile(path));
0501                        m_drawing->workbook->addMediaFile(m_pictureFile, true);
0502                    }
0503             }
0504             else if (reader.name() == QLatin1String("off"))
0505             {
0506                posTA = loadXmlPos(reader);
0507                hasoffext=true;
0508             }
0509             else if (reader.name() == QLatin1String("ext")&&hasoffext)
0510             {
0511                extTA = loadXmlExt(reader);
0512                hasoffext=false;
0513             }
0514             else if(reader.name() == QLatin1String("blipFill"))
0515             {
0516                 // dev24 : fixed for old Qt 5
0517 
0518                 rotWithShapeTA = reader.attributes().value(QLatin1String("rotWithShape")).toString().toInt();
0519                 dpiTA = reader.attributes().value(QLatin1String("dpi")).toString().toInt();
0520 
0521                 // rotWithShapeTA = reader.attributes().value(QLatin1String("rotWithShape")).toInt();
0522                 // dpiTA = reader.attributes().value(QLatin1String("dpi")).toInt();
0523 
0524             }else if(reader.name() == QLatin1String("cNvPr"))
0525             {
0526                xsp_cNvPR_name= reader.attributes().value(QLatin1String("name")).toString();
0527                xsp_cNvPR_id= reader.attributes().value(QLatin1String("id")).toString();
0528             }
0529             else if(reader.name() == QLatin1String("spPr"))
0530             {
0531                 xbwMode= reader.attributes().value(QLatin1String("bwMode")).toString();
0532             }
0533             else if(reader.name() == QLatin1String("prstGeom"))
0534             {
0535                 xprstGeom_prst= reader.attributes().value(QLatin1String("prst")).toString();
0536             }
0537             else if(reader.name() == QLatin1String("ln"))
0538             {
0539                 xIn_algn= reader.attributes().value(QLatin1String("algn")).toString();
0540                 xIn_cmpd= reader.attributes().value(QLatin1String("cmpd")).toString();
0541                 xIn_cap= reader.attributes().value(QLatin1String("cap")).toString();
0542                 xIn_w= reader.attributes().value(QLatin1String("w")).toString();
0543             }
0544             else if(reader.name() == QLatin1String("headEnd"))
0545             {
0546                 x_headEnd_w= reader.attributes().value(QLatin1String("w")).toString();
0547                 x_headEnd_len= reader.attributes().value(QLatin1String("len")).toString();
0548                 x_headEnd_tyep= reader.attributes().value(QLatin1String("type")).toString();
0549             }
0550             else if(reader.name() == QLatin1String("tailEnd"))
0551             {
0552                 x_tailEnd_w= reader.attributes().value(QLatin1String("w")).toString();
0553                 x_tailEnd_len= reader.attributes().value(QLatin1String("len")).toString();
0554                 x_tailEnd_tyep= reader.attributes().value(QLatin1String("type")).toString();
0555             }
0556             else if(reader.name() == QLatin1String("lnRef"))
0557             {
0558                 Style_inref_idx= reader.attributes().value(QLatin1String("idx")).toString().trimmed();
0559                 reader.readNextStartElement();
0560                 if (reader.tokenType() == QXmlStreamReader::StartElement) {
0561                     if(reader.name() == QLatin1String("schemeClr")){
0562                         Style_inref_val=reader.attributes().value(QLatin1String("val")).toString().trimmed();
0563                     }
0564                 }
0565             }
0566             else if(reader.name() == QLatin1String("fillRef"))
0567             {
0568                 style_fillref_idx= reader.attributes().value(QLatin1String("idx")).toString().trimmed();
0569                 reader.readNextStartElement();
0570                 if (reader.tokenType() == QXmlStreamReader::StartElement)
0571                 {
0572                     if(reader.name() == QLatin1String("schemeClr"))
0573                     {
0574                        style_fillref_val=reader.attributes().value(QLatin1String("val")).toString().trimmed();
0575                     }
0576                 }
0577             }
0578             else if(reader.name() == QLatin1String("effectRef"))
0579             {
0580                 style_effectref_idx= reader.attributes().value(QLatin1String("idx")).toString().trimmed();
0581                 reader.readNextStartElement();
0582                 if (reader.tokenType() == QXmlStreamReader::StartElement) {
0583                     if(reader.name() == QLatin1String("schemeClr")){
0584                       style_effectref_val=reader.attributes().value(QLatin1String("val")).toString().trimmed();
0585                     }
0586                 }
0587             }
0588             else if(reader.name() == QLatin1String("fontRef"))
0589             {
0590                 style_forntref_idx= reader.attributes().value(QLatin1String("idx")).toString().trimmed();
0591                 reader.readNextStartElement();
0592                 if (reader.tokenType() == QXmlStreamReader::StartElement) {
0593                     if(reader.name() == QLatin1String("schemeClr")){
0594                         style_forntref_val=reader.attributes().value(QLatin1String("val")).toString().trimmed();
0595                     }
0596                 }
0597             }
0598 
0599         }
0600         else if (reader.tokenType() == QXmlStreamReader::EndElement
0601                    && reader.name() == QLatin1String("sp"))
0602         {
0603             break;
0604         }
0605     }
0606 
0607     //*/
0608 
0609     return;
0610 }
0611 
0612 void DrawingAnchor::saveXmlPos(QXmlStreamWriter &writer, const QPoint &pos) const
0613 {
0614     writer.writeEmptyElement(QStringLiteral("xdr:pos"));
0615     writer.writeAttribute(QStringLiteral("x"), QString::number(pos.x()));
0616     writer.writeAttribute(QStringLiteral("y"), QString::number(pos.y()));
0617 }
0618 
0619 void DrawingAnchor::saveXmlExt(QXmlStreamWriter &writer, const QSize &ext) const
0620 {
0621     writer.writeStartElement(QStringLiteral("xdr:ext"));
0622     writer.writeAttribute(QStringLiteral("cx"), QString::number(ext.width()));
0623     writer.writeAttribute(QStringLiteral("cy"), QString::number(ext.height()));
0624     writer.writeEndElement(); //xdr:ext
0625 }
0626 
0627 void DrawingAnchor::saveXmlMarker(QXmlStreamWriter &writer, const XlsxMarker &marker, const QString &node) const
0628 {
0629     writer.writeStartElement(node); //xdr:from or xdr:to
0630     writer.writeTextElement(QStringLiteral("xdr:col"), QString::number(marker.col()));
0631     writer.writeTextElement(QStringLiteral("xdr:colOff"), QString::number(marker.colOff()));
0632     writer.writeTextElement(QStringLiteral("xdr:row"), QString::number(marker.row()));
0633     writer.writeTextElement(QStringLiteral("xdr:rowOff"), QString::number(marker.rowOff()));
0634     writer.writeEndElement();
0635 }
0636 
0637 void DrawingAnchor::saveXmlObject(QXmlStreamWriter &writer) const
0638 {
0639     if (m_objectType == Picture)
0640         saveXmlObjectPicture(writer);
0641     else if (m_objectType == ConnectionShape)
0642         saveXmlObjectConnectionShape(writer);
0643     else if (m_objectType == GraphicFrame)
0644         saveXmlObjectGraphicFrame(writer);
0645     else if (m_objectType == GroupShape)
0646         saveXmlObjectGroupShape(writer);
0647     else if (m_objectType == Shape)
0648         saveXmlObjectShape(writer);
0649 }
0650 
0651 void DrawingAnchor::saveXmlObjectConnectionShape(QXmlStreamWriter &writer) const
0652 {
0653     writer.writeStartElement(QStringLiteral("xdr:cxnSp"));  ///?
0654     writer.writeAttribute(QStringLiteral("macro"), cxnSp_macro);
0655 
0656         writer.writeStartElement(QStringLiteral("xdr:nvCxnSpPr"));
0657            writer.writeEmptyElement(QStringLiteral("xdr:cNvPr"));
0658            writer.writeAttribute(QStringLiteral("id"), xsp_cNvPR_id);
0659            writer.writeAttribute(QStringLiteral("name"), xsp_cNvPR_name);
0660            writer.writeEmptyElement(QStringLiteral("xdr:cNvCxnSpPr"));
0661         writer.writeEndElement(); //xdr:nvCxnSpPr
0662 
0663     writer.writeStartElement(QStringLiteral("xdr:spPr"));
0664     if(!xbwMode.isNull()){
0665          writer.writeAttribute(QStringLiteral("bwMode"), xbwMode);
0666     }
0667 
0668         writer.writeStartElement(QStringLiteral("a:xfrm"));
0669         if(!cxnSp_filpV.isEmpty()){
0670         writer.writeAttribute(QStringLiteral("flipV"), cxnSp_filpV);}
0671         writer.writeEmptyElement(QStringLiteral("a:off"));
0672         writer.writeAttribute(QStringLiteral("x"), QString::number(posTA.x()));
0673         writer.writeAttribute(QStringLiteral("y"), QString::number(posTA.y()));
0674         writer.writeEmptyElement(QStringLiteral("a:ext"));
0675         writer.writeAttribute(QStringLiteral("cx"), QString::number(extTA.width()));
0676         writer.writeAttribute(QStringLiteral("cy"), QString::number(extTA.height()));
0677         writer.writeEndElement(); //a:xfrm
0678 
0679         writer.writeStartElement(QStringLiteral("a:prstGeom"));
0680         writer.writeAttribute(QStringLiteral("prst"), xprstGeom_prst);
0681         writer.writeEmptyElement(QStringLiteral("a:avLst"));
0682         writer.writeEndElement(); //a:prstGeom
0683 
0684 
0685          writer.writeStartElement(QStringLiteral("a:ln"));
0686             if(!xIn_w.isEmpty()&&!xIn_cap.isEmpty()){
0687                 if(!xIn_w.isEmpty()){
0688                     writer.writeAttribute(QStringLiteral("w"), xIn_w);
0689                 }
0690                 if(!xIn_cap.isEmpty()){
0691                     writer.writeAttribute(QStringLiteral("cap"), xIn_cap);
0692                 }
0693                 if(!xIn_cmpd.isEmpty()){
0694                     writer.writeAttribute(QStringLiteral("cmpd"), xIn_cmpd);
0695                 }
0696                 if(!xIn_algn.isEmpty()){
0697                     writer.writeAttribute(QStringLiteral("algn"), xIn_algn);
0698                 }
0699             }
0700              if((!x_headEnd_tyep.isEmpty())||(!x_headEnd_w.isEmpty())||(!x_headEnd_len.isEmpty())){
0701                  writer.writeEmptyElement(QStringLiteral("a:headEnd"));
0702                  if(!x_headEnd_tyep.isEmpty()){
0703                     writer.writeAttribute(QStringLiteral("type"),x_headEnd_tyep);
0704                  }
0705                  if(!x_headEnd_w.isEmpty()){
0706                    writer.writeAttribute(QStringLiteral("w"),x_headEnd_w);
0707                  }
0708                  if(!x_headEnd_len.isEmpty()){
0709                    writer.writeAttribute(QStringLiteral("len"),x_headEnd_len);
0710                  }
0711              }
0712              if((!x_tailEnd_tyep.isEmpty())||(!x_tailEnd_w.isEmpty())||(!x_tailEnd_len.isEmpty())){
0713                   writer.writeEmptyElement(QStringLiteral("a:tailEnd"));
0714                   if(!x_tailEnd_tyep.isEmpty()){
0715                       writer.writeAttribute(QStringLiteral("type"),x_tailEnd_tyep);}
0716                   if(!x_tailEnd_w.isEmpty()){
0717                       writer.writeAttribute(QStringLiteral("w"),x_tailEnd_w);}
0718                   if(!x_tailEnd_len.isEmpty()){
0719                       writer.writeAttribute(QStringLiteral("len"),x_tailEnd_len);}
0720               }
0721 
0722          writer.writeEndElement();//a:ln
0723 
0724 
0725       writer.writeEndElement(); //xdr:spPr
0726       // writer style
0727 
0728       writer.writeStartElement(QStringLiteral("xdr:style"));// style
0729              writer.writeStartElement(QStringLiteral("a:lnRef"));//lnRef
0730              writer.writeAttribute(QStringLiteral("idx"),Style_inref_idx);
0731                 writer.writeStartElement(QStringLiteral("a:schemeClr"));//val
0732                 writer.writeAttribute(QStringLiteral("val"),Style_inref_val);
0733                 writer.writeEndElement(); // val
0734              writer.writeEndElement(); // lnRef
0735              writer.writeStartElement(QStringLiteral("a:fillRef"));//fillRef
0736              writer.writeAttribute(QStringLiteral("idx"),style_fillref_idx);
0737                 writer.writeStartElement(QStringLiteral("a:schemeClr"));//val
0738                 writer.writeAttribute(QStringLiteral("val"),style_fillref_val);
0739                 writer.writeEndElement(); // val
0740              writer.writeEndElement(); // fillRef
0741              writer.writeStartElement(QStringLiteral("a:effectRef"));//effectRef
0742              writer.writeAttribute(QStringLiteral("idx"),style_effectref_idx);
0743                 writer.writeStartElement(QStringLiteral("a:schemeClr"));//val
0744                 writer.writeAttribute(QStringLiteral("val"),style_effectref_val);
0745                 writer.writeEndElement(); // val
0746              writer.writeEndElement(); // effectRef
0747              writer.writeStartElement(QStringLiteral("a:fontRef"));//fontRef
0748              writer.writeAttribute(QStringLiteral("idx"),style_forntref_idx);
0749                 writer.writeStartElement(QStringLiteral("a:schemeClr"));//val
0750                 writer.writeAttribute(QStringLiteral("val"),style_forntref_val);
0751                 writer.writeEndElement(); // val
0752              writer.writeEndElement(); // fontRef
0753       writer.writeEndElement(); // style
0754 
0755       writer.writeEndElement(); //xdr:sp
0756 }
0757 
0758 void DrawingAnchor::saveXmlObjectGraphicFrame(QXmlStreamWriter &writer) const
0759 {
0760     writer.writeStartElement(QStringLiteral("xdr:graphicFrame"));
0761     writer.writeAttribute(QStringLiteral("macro"), QString());
0762 
0763     writer.writeStartElement(QStringLiteral("xdr:nvGraphicFramePr"));
0764     writer.writeEmptyElement(QStringLiteral("xdr:cNvPr"));
0765     writer.writeAttribute(QStringLiteral("id"), QString::number(m_id));
0766     writer.writeAttribute(QStringLiteral("name"), QStringLiteral("Chart %1").arg(m_id));
0767     writer.writeEmptyElement(QStringLiteral("xdr:cNvGraphicFramePr"));
0768     writer.writeEndElement();//xdr:nvGraphicFramePr
0769 
0770     writer.writeStartElement(QStringLiteral("xdr:xfrm"));
0771     writer.writeEndElement(); //xdr:xfrm
0772 
0773     writer.writeStartElement(QStringLiteral("a:graphic"));
0774     writer.writeStartElement(QStringLiteral("a:graphicData"));
0775     writer.writeAttribute(QStringLiteral("uri"), QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/chart"));
0776 
0777     int idx = m_drawing->workbook->chartFiles().indexOf(m_chartFile);
0778     m_drawing->relationships()->addDocumentRelationship(QStringLiteral("/chart"), QStringLiteral("../charts/chart%1.xml").arg(idx+1));
0779 
0780     writer.writeEmptyElement(QStringLiteral("c:chart"));
0781     writer.writeAttribute(QStringLiteral("xmlns:c"), QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/chart"));
0782     writer.writeAttribute(QStringLiteral("xmlns:r"), QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
0783     writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(m_drawing->relationships()->count()));
0784 
0785     writer.writeEndElement(); //a:graphicData
0786     writer.writeEndElement(); //a:graphic
0787     writer.writeEndElement(); //xdr:graphicFrame
0788 }
0789 
0790 void DrawingAnchor::saveXmlObjectGroupShape(QXmlStreamWriter &writer) const
0791 {
0792     Q_UNUSED(writer)
0793 }
0794 
0795 void DrawingAnchor::saveXmlObjectPicture(QXmlStreamWriter &writer) const
0796 {
0797     Q_ASSERT(m_objectType == Picture && m_pictureFile);
0798 
0799     writer.writeStartElement(QStringLiteral("xdr:pic"));
0800 
0801     writer.writeStartElement(QStringLiteral("xdr:nvPicPr"));
0802     writer.writeEmptyElement(QStringLiteral("xdr:cNvPr"));
0803     writer.writeAttribute(QStringLiteral("id"), QString::number(m_id+1)); // liufeijin
0804     writer.writeAttribute(QStringLiteral("name"), QStringLiteral("Picture %1").arg(m_id));
0805 
0806     writer.writeStartElement(QStringLiteral("xdr:cNvPicPr"));
0807     writer.writeEmptyElement(QStringLiteral("a:picLocks"));
0808     writer.writeAttribute(QStringLiteral("noChangeAspect"), QStringLiteral("1"));
0809     writer.writeEndElement(); //xdr:cNvPicPr
0810 
0811     writer.writeEndElement(); //xdr:nvPicPr
0812 
0813     m_drawing->relationships()->addDocumentRelationship(QStringLiteral("/image"), QStringLiteral("../media/image%1.%2")
0814                                                      .arg(m_pictureFile->index()+1)
0815                                                      .arg(m_pictureFile->suffix()));
0816 
0817     writer.writeStartElement(QStringLiteral("xdr:blipFill"));
0818     writer.writeEmptyElement(QStringLiteral("a:blip"));
0819     writer.writeAttribute(QStringLiteral("xmlns:r"), QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
0820     writer.writeAttribute(QStringLiteral("r:embed"), QStringLiteral("rId%1").arg(m_drawing->relationships()->count()));
0821     writer.writeStartElement(QStringLiteral("a:stretch"));
0822     writer.writeEmptyElement(QStringLiteral("a:fillRect"));
0823     writer.writeEndElement(); //a:stretch
0824     writer.writeEndElement();//xdr:blipFill
0825 
0826     writer.writeStartElement(QStringLiteral("xdr:spPr"));
0827 
0828     writer.writeStartElement(QStringLiteral("a:prstGeom"));
0829     writer.writeAttribute(QStringLiteral("prst"), QStringLiteral("rect"));
0830     writer.writeEmptyElement(QStringLiteral("a:avLst"));
0831     writer.writeEndElement(); //a:prstGeom
0832 
0833     writer.writeEndElement(); //xdr:spPr
0834 
0835     writer.writeEndElement(); //xdr:pic
0836 }
0837 
0838 int DrawingAnchor::getm_id()
0839 {
0840     return (this->m_id);
0841 }
0842 
0843 void DrawingAnchor::saveXmlObjectShape(QXmlStreamWriter &writer) const
0844 {
0845 //{{ liufeijin
0846     writer.writeStartElement(QStringLiteral("xdr:sp"));  //xdr:sp
0847         writer.writeAttribute(QStringLiteral("macro"), sp_macro);
0848         writer.writeAttribute(QStringLiteral("textlink"),sp_textlink);
0849 
0850     writer.writeStartElement(QStringLiteral("xdr:nvSpPr"));//xdr:nvSpPr
0851 
0852            writer.writeStartElement(QStringLiteral("xdr:cNvPr"));
0853               writer.writeAttribute(QStringLiteral("id"), xsp_cNvPR_id);
0854               writer.writeAttribute(QStringLiteral("name"), xsp_cNvPR_name);
0855               writer.writeStartElement(QStringLiteral("a:extLst"));
0856               writer.writeEndElement();
0857            writer.writeEndElement();//xdr:cNvPr
0858 
0859           writer.writeEmptyElement(QStringLiteral("xdr:cNvSpPr"));
0860 
0861     writer.writeEndElement(); //xdr:nvSpPr
0862 
0863     writer.writeStartElement(QStringLiteral("xdr:spPr"));
0864     if(!xbwMode.isNull()){
0865          writer.writeAttribute(QStringLiteral("bwMode"), xbwMode);
0866     }
0867         writer.writeStartElement(QStringLiteral("a:xfrm"));
0868         writer.writeEmptyElement(QStringLiteral("a:off"));
0869         writer.writeAttribute(QStringLiteral("x"), QString::number(posTA.x()));
0870         writer.writeAttribute(QStringLiteral("y"), QString::number(posTA.y()));
0871         writer.writeEmptyElement(QStringLiteral("a:ext"));
0872         writer.writeAttribute(QStringLiteral("cx"), QString::number(extTA.width()));
0873         writer.writeAttribute(QStringLiteral("cy"), QString::number(extTA.height()));
0874         writer.writeEndElement(); //a:xfrm
0875 
0876         writer.writeStartElement(QStringLiteral("a:prstGeom"));
0877         writer.writeAttribute(QStringLiteral("prst"), xprstGeom_prst);
0878         writer.writeEmptyElement(QStringLiteral("a:avLst"));
0879         writer.writeEndElement(); //a:prstGeom
0880 
0881     if(m_pictureFile){
0882         m_drawing->relationships()->addDocumentRelationship(QStringLiteral("/image"), QStringLiteral("../media/image%1.%2").arg(m_pictureFile->index()+1).arg(m_pictureFile->suffix()));
0883         writer.writeStartElement(QStringLiteral("a:blipFill"));
0884         writer.writeAttribute(QStringLiteral("dpi"), QString::number(dpiTA));
0885         writer.writeAttribute(QStringLiteral("rotWithShape"),QString::number(rotWithShapeTA));
0886 
0887          writer.writeStartElement(QStringLiteral("a:blip"));
0888            writer.writeAttribute(QStringLiteral("r:embed"), QStringLiteral("rId%1").arg(m_drawing->relationships()->count()));  //sp_blip_rembed  QStringLiteral("rId%1").arg(m_drawing->relationships()->count()) can't made new pic
0889            writer.writeAttribute(QStringLiteral("xmlns:r"), QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
0890            if(!sp_blip_cstate.isNull()){
0891              writer.writeAttribute(QStringLiteral("cstate"), sp_blip_cstate);
0892            }
0893           writer.writeEndElement();//a:blip
0894              writer.writeEmptyElement(QStringLiteral("a:srcRect"));
0895              writer.writeStartElement(QStringLiteral("a:stretch"));
0896                     writer.writeEmptyElement(QStringLiteral("a:fillRect"));
0897              writer.writeEndElement(); //a:stretch
0898          writer.writeEndElement();//a:blipFill
0899       }
0900     writer.writeStartElement(QStringLiteral("a:ln"));
0901        if(!xIn_w.isEmpty()&&!xIn_cap.isEmpty()){
0902            if(!xIn_w.isEmpty()){
0903                writer.writeAttribute(QStringLiteral("w"), xIn_w);
0904            }
0905            if(!xIn_cap.isEmpty()){
0906                writer.writeAttribute(QStringLiteral("cap"), xIn_cap);
0907            }
0908            if(!xIn_cmpd.isEmpty()){
0909                writer.writeAttribute(QStringLiteral("cmpd"), xIn_cmpd);
0910            }
0911            if(!xIn_algn.isEmpty()){
0912                writer.writeAttribute(QStringLiteral("algn"), xIn_algn);
0913            }
0914        }
0915         if((!x_headEnd_tyep.isEmpty())||(!x_headEnd_w.isEmpty())||(!x_headEnd_len.isEmpty())){
0916             writer.writeEmptyElement(QStringLiteral("a:headEnd"));
0917             if(!x_headEnd_tyep.isEmpty()){
0918                writer.writeAttribute(QStringLiteral("type"),x_headEnd_tyep);
0919             }
0920             if(!x_headEnd_w.isEmpty()){
0921               writer.writeAttribute(QStringLiteral("w"),x_headEnd_w);
0922             }
0923             if(!x_headEnd_len.isEmpty()){
0924               writer.writeAttribute(QStringLiteral("len"),x_headEnd_len);
0925             }
0926         }
0927         if((!x_tailEnd_tyep.isEmpty())||(!x_tailEnd_w.isEmpty())||(!x_tailEnd_len.isEmpty())){
0928              writer.writeEmptyElement(QStringLiteral("a:tailEnd"));
0929              if(!x_tailEnd_tyep.isEmpty()){
0930                  writer.writeAttribute(QStringLiteral("type"),x_tailEnd_tyep);}
0931              if(!x_tailEnd_w.isEmpty()){
0932                  writer.writeAttribute(QStringLiteral("w"),x_tailEnd_w);}
0933              if(!x_tailEnd_len.isEmpty()){
0934                  writer.writeAttribute(QStringLiteral("len"),x_tailEnd_len);}
0935          }
0936 
0937     writer.writeEndElement();//a:ln
0938 
0939 
0940  writer.writeEndElement(); //xdr:spPr
0941  // writer style
0942 
0943  writer.writeStartElement(QStringLiteral("xdr:style"));// style
0944         writer.writeStartElement(QStringLiteral("a:lnRef"));//lnRef
0945         writer.writeAttribute(QStringLiteral("idx"),Style_inref_idx);
0946            writer.writeStartElement(QStringLiteral("a:schemeClr"));//val
0947            writer.writeAttribute(QStringLiteral("val"),Style_inref_val);
0948            writer.writeEndElement(); // val
0949         writer.writeEndElement(); // lnRef
0950         writer.writeStartElement(QStringLiteral("a:fillRef"));//fillRef
0951         writer.writeAttribute(QStringLiteral("idx"),style_fillref_idx);
0952            writer.writeStartElement(QStringLiteral("a:schemeClr"));//val
0953            writer.writeAttribute(QStringLiteral("val"),style_fillref_val);
0954            writer.writeEndElement(); // val
0955         writer.writeEndElement(); // fillRef
0956         writer.writeStartElement(QStringLiteral("a:effectRef"));//effectRef
0957         writer.writeAttribute(QStringLiteral("idx"),style_effectref_idx);
0958            writer.writeStartElement(QStringLiteral("a:schemeClr"));//val
0959            writer.writeAttribute(QStringLiteral("val"),style_effectref_val);
0960            writer.writeEndElement(); // val
0961         writer.writeEndElement(); // effectRef
0962         writer.writeStartElement(QStringLiteral("a:fontRef"));//fontRef
0963         writer.writeAttribute(QStringLiteral("idx"),style_forntref_idx);
0964            writer.writeStartElement(QStringLiteral("a:schemeClr"));//val
0965            writer.writeAttribute(QStringLiteral("val"),style_forntref_val);
0966            writer.writeEndElement(); // val
0967         writer.writeEndElement(); // fontRef
0968  writer.writeEndElement(); // style
0969 
0970      writer.writeEndElement(); //xdr:sp
0971 
0972     //}} liufeijin
0973 }
0974 
0975 //absolute anchor
0976 
0977 DrawingAbsoluteAnchor::DrawingAbsoluteAnchor(Drawing *drawing, ObjectType objectType)
0978     :DrawingAnchor(drawing, objectType)
0979 {
0980 
0981 }
0982 
0983 // check point
0984 bool DrawingAbsoluteAnchor::loadFromXml(QXmlStreamReader &reader)
0985 {
0986     Q_ASSERT(reader.name() == QLatin1String("absoluteAnchor"));
0987 
0988     while (!reader.atEnd()) {
0989         reader.readNextStartElement();
0990         if (reader.tokenType() == QXmlStreamReader::StartElement) {
0991             if (reader.name() == QLatin1String("pos"))
0992             {
0993                 pos = loadXmlPos(reader);
0994             }
0995             else if (reader.name() == QLatin1String("ext"))
0996             {
0997                 ext = loadXmlExt(reader);
0998             }
0999             else
1000             {
1001                 loadXmlObject(reader);
1002             }
1003         }
1004         else if (reader.tokenType() == QXmlStreamReader::EndElement
1005                    && reader.name() == QLatin1String("absoluteAnchor"))
1006         {
1007             break;
1008         }
1009     }
1010     return true;
1011 }
1012 
1013 void DrawingAbsoluteAnchor::saveToXml(QXmlStreamWriter &writer) const
1014 {
1015     writer.writeStartElement(QStringLiteral("xdr:absoluteAnchor"));
1016     saveXmlPos(writer, pos);
1017     saveXmlExt(writer, ext);
1018 
1019     saveXmlObject(writer);
1020 
1021     writer.writeEmptyElement(QStringLiteral("xdr:clientData"));
1022     writer.writeEndElement(); //xdr:absoluteAnchor
1023 }
1024 
1025 //one cell anchor
1026 
1027 DrawingOneCellAnchor::DrawingOneCellAnchor(Drawing *drawing, ObjectType objectType)
1028     :DrawingAnchor(drawing, objectType)
1029 {
1030 
1031 }
1032 
1033 int DrawingOneCellAnchor::row() const
1034 {
1035     return from.row();
1036 }
1037 
1038 int DrawingOneCellAnchor::col() const
1039 {
1040     return from.col();
1041 }
1042 
1043 // check point
1044 bool DrawingOneCellAnchor::loadFromXml(QXmlStreamReader &reader)
1045 {
1046     Q_ASSERT(reader.name() == QLatin1String("oneCellAnchor"));
1047 
1048     while (!reader.atEnd())
1049     {
1050         reader.readNextStartElement();
1051         if (reader.tokenType() == QXmlStreamReader::StartElement)
1052         {
1053             if (reader.name() == QLatin1String("from"))
1054             {
1055                 from = loadXmlMarker(reader, QLatin1String("from"));
1056             }
1057             else if (reader.name() == QLatin1String("ext"))
1058             {
1059                 ext = loadXmlExt(reader);
1060             }
1061             else
1062             {
1063                 loadXmlObject(reader);
1064             }
1065         }
1066         else if (reader.tokenType() == QXmlStreamReader::EndElement
1067                    && reader.name() == QLatin1String("oneCellAnchor"))
1068         {
1069             break;
1070         }
1071     }
1072     return true;
1073 }
1074 
1075 void DrawingOneCellAnchor::saveToXml(QXmlStreamWriter &writer) const
1076 {
1077     writer.writeStartElement(QStringLiteral("xdr:oneCellAnchor"));
1078 
1079     saveXmlMarker(writer, from, QStringLiteral("xdr:from"));
1080     saveXmlExt(writer, ext);
1081 
1082     saveXmlObject(writer);
1083 
1084     writer.writeEmptyElement(QStringLiteral("xdr:clientData"));
1085     writer.writeEndElement(); //xdr:oneCellAnchor
1086 }
1087 
1088 /*
1089    Two cell anchor
1090 
1091    This class specifies a two cell anchor placeholder for a group
1092    , a shape, or a drawing element. It moves with
1093    cells and its extents are in EMU units.
1094 */
1095 DrawingTwoCellAnchor::DrawingTwoCellAnchor(Drawing *drawing, ObjectType objectType)
1096     :DrawingAnchor(drawing, objectType)
1097 {
1098 
1099 }
1100 
1101 int DrawingTwoCellAnchor::row() const
1102 {
1103     return from.row();
1104 }
1105 
1106 int DrawingTwoCellAnchor::col() const
1107 {
1108     return from.col();
1109 }
1110 
1111 // check point
1112 bool DrawingTwoCellAnchor::loadFromXml(QXmlStreamReader &reader)
1113 {
1114     Q_ASSERT(reader.name() == QLatin1String("twoCellAnchor"));
1115 
1116     /*
1117     <xsd:complexType name="CT_TwoCellAnchor">
1118         <xsd:sequence>
1119             <xsd:element name="from" type="CT_Marker"/>
1120             <xsd:element name="to" type="CT_Marker"/>
1121             <xsd:group ref="EG_ObjectChoices"/>
1122             <xsd:element name="clientData" type="CT_AnchorClientData" minOccurs="1" maxOccurs="1"/>
1123         </xsd:sequence>
1124         <xsd:attribute name="editAs" type="ST_EditAs" use="optional" default="twoCell"/>
1125     </xsd:complexType>
1126     */
1127 
1128     //{{ liufeijin
1129     QXmlStreamAttributes attrs = reader.attributes();  // for absolute twocell aadd by liufeijin 20181024
1130     editASName = attrs.value(QLatin1String("editAs")).toString();
1131     //}}
1132 
1133     while (!reader.atEnd())
1134     {
1135         reader.readNextStartElement();
1136 
1137         if (reader.tokenType() == QXmlStreamReader::StartElement)
1138         {
1139             if (reader.name() == QLatin1String("from"))
1140             {
1141                 from = loadXmlMarker(reader, QLatin1String("from"));
1142             }
1143             else if (reader.name() == QLatin1String("to"))
1144             {
1145                 to = loadXmlMarker(reader, QLatin1String("to"));
1146             }
1147             else if (reader.name() == QLatin1String("clientData"))
1148             {
1149                 // clientData
1150             }
1151             else
1152             {
1153                 /*
1154                 <xsd:group name="EG_ObjectChoices">
1155                     <xsd:sequence>
1156                         <xsd:choice minOccurs="1" maxOccurs="1">
1157                             <xsd:element name="sp" type="CT_Shape"/>
1158                             <xsd:element name="grpSp" type="CT_GroupShape"/>
1159                             <xsd:element name="graphicFrame" type="CT_GraphicalObjectFrame"/>
1160                             <xsd:element name="cxnSp" type="CT_Connector"/>
1161                             <xsd:element name="pic" type="CT_Picture"/>
1162                             <xsd:element name="contentPart" type="CT_Rel"/>
1163                         </xsd:choice>
1164                     </xsd:sequence>
1165                 </xsd:group>
1166                 */
1167 
1168                 loadXmlObject(reader);
1169             }
1170         }
1171         else if (reader.tokenType() == QXmlStreamReader::EndElement
1172                    && reader.name() == QLatin1String("twoCellAnchor"))
1173         {
1174             break;
1175         }
1176     }
1177     return true;
1178 }
1179 
1180 
1181    void DrawingTwoCellAnchor::saveToXml(QXmlStreamWriter &writer) const
1182 {
1183     writer.writeStartElement(QStringLiteral("xdr:twoCellAnchor"));
1184 
1185     //{{ liufeijin
1186     // writer.writeAttribute(QStringLiteral("editAs"), QStringLiteral("oneCell"));
1187    if(!editASName.isNull()){
1188        writer.writeAttribute(QStringLiteral("editAs"), editASName ); //QStringLiteral("oneCell")
1189    }
1190     // }}
1191 
1192     saveXmlMarker(writer, from, QStringLiteral("xdr:from"));
1193     saveXmlMarker(writer, to, QStringLiteral("xdr:to"));
1194 
1195     saveXmlObject(writer);
1196 
1197     writer.writeEmptyElement(QStringLiteral("xdr:clientData"));
1198     writer.writeEndElement(); //xdr:twoCellAnchor
1199 
1200 }
1201 
1202 
1203 QT_END_NAMESPACE_XLSX