File indexing completed on 2024-05-12 16:29:09

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2010-2011 Carlos Licea <carlos@kdab.com>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Library General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2 of the License, or (at your option) any later version.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  * Library General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU Library General Public License
0015  * along with this library; see the file COPYING.LIB.  If not, write to
0016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018  */
0019 
0020 /**
0021  * This file deals with the tables designed for the DrawingML namespace
0022  * the table starts at tbl §21.1.3.13
0023  */
0024 
0025 #include "MsooXmlTableStyle.h"
0026 using namespace MSOOXML;
0027 
0028 #undef CURRENT_EL
0029 #define CURRENT_EL tbl
0030 //! tbl (Table) §21.1.3.13
0031 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tbl()
0032 {
0033     m_table = KoTable::create();
0034 
0035     READ_PROLOGUE
0036 
0037     bool tableSetByMe = false;
0038     if (!m_insideTable) {
0039         // Handling nested tables
0040         tableSetByMe = true;
0041         m_insideTable = true;
0042     }
0043 
0044     m_tableStyle = 0;
0045 
0046     if (!d->tableStyleList) {
0047         d->tableStyleList = new QMap<QString, MSOOXML::DrawingTableStyle*>;
0048 
0049         QString tableStylesFile;
0050         QString tableStylesPath;
0051         MSOOXML::Utils::splitPathAndFile(m_context->tableStylesFilePath, &tableStylesPath, &tableStylesFile);
0052 
0053         MSOOXML::MsooXmlDrawingTableStyleReader tableStyleReader(this);
0054         MSOOXML::MsooXmlDrawingTableStyleContext tableStyleReaderContext(m_context->import, tableStylesPath,
0055                                                                         tableStylesFile, &m_context->slideMasterProperties->theme,
0056                                                                         d->tableStyleList, m_context->colorMap);
0057         m_context->import->loadAndParseDocument(&tableStyleReader, m_context->tableStylesFilePath, &tableStyleReaderContext);
0058     }
0059 
0060     m_table->setName(QLatin1String("Table") + QString::number(m_currentTableNumber + 1));
0061     m_currentTableRowNumber = 0;
0062     m_currentTableColumnNumber = 0;
0063 
0064     while (!atEnd()) {
0065         readNext();
0066         BREAK_IF_END_OF(CURRENT_EL)
0067         if (isStartElement()) {
0068             TRY_READ_IF(tblPr)
0069             ELSE_TRY_READ_IF(tblGrid)
0070             ELSE_TRY_READ_IF(tr)
0071             SKIP_UNKNOWN
0072 //             ELSE_WRONG_FORMAT
0073         }
0074     }
0075 
0076     defineStyles();
0077 
0078     m_table->saveOdf(*body, *mainStyles);
0079 
0080     m_currentTableNumber++;
0081 
0082     if (tableSetByMe) {
0083         m_insideTable = false;
0084     }
0085 
0086     READ_EPILOGUE
0087 }
0088 
0089 void MSOOXML_CURRENT_CLASS::defineStyles()
0090 {
0091     const int rowCount = m_table->rowCount();
0092     const int columnCount = m_table->columnCount();
0093     QPair<int, int> spans;
0094 
0095     MSOOXML::DrawingTableStyleConverterProperties converterProperties;
0096     converterProperties.setRowCount(rowCount);
0097     converterProperties.setColumnCount(columnCount);
0098     converterProperties.setRoles(m_activeRoles);
0099     converterProperties.setLocalStyles(m_localTableStyles);
0100     // TODO: converterProperties.setLocalDefaulCelltStyle()
0101     MSOOXML::DrawingTableStyleConverter styleConverter(converterProperties, m_tableStyle);
0102     for(int row = 0; row < rowCount; ++row ) {
0103         for(int column = 0; column < columnCount; ++column ) {
0104             spans.first = m_table->cellAt(row, column)->rowSpan();
0105             spans.second = m_table->cellAt(row, column)->columnSpan();
0106             KoCellStyle::Ptr style = styleConverter.style(row, column, spans);
0107             m_table->cellAt(row, column)->setStyle(style);
0108         }
0109     }
0110 }
0111 
0112 #undef CURRENT_EL
0113 #define CURRENT_EL tblPr
0114 //! tblPr handler (Table Properties) §21.1.3.15
0115 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tblPr()
0116 {
0117     READ_PROLOGUE
0118 
0119     const QXmlStreamAttributes attrs(attributes());
0120     TRY_READ_ATTR_WITHOUT_NS(bandCol)
0121     if(MSOOXML::Utils::convertBooleanAttr(bandCol)) {
0122         m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::ColumnBanded;
0123     }
0124     TRY_READ_ATTR_WITHOUT_NS(bandRow)
0125     if(MSOOXML::Utils::convertBooleanAttr(bandRow)) {
0126         m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::RowBanded;
0127     }
0128     TRY_READ_ATTR_WITHOUT_NS(firstCol)
0129     if(MSOOXML::Utils::convertBooleanAttr(firstCol)) {
0130         m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::FirstCol;
0131     }
0132     TRY_READ_ATTR_WITHOUT_NS(firstRow)
0133     if(MSOOXML::Utils::convertBooleanAttr(firstRow)) {
0134         m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::FirstRow;
0135     }
0136     TRY_READ_ATTR_WITHOUT_NS(lastCol)
0137     if(MSOOXML::Utils::convertBooleanAttr(lastCol)) {
0138         m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::FirstCol;
0139     }
0140     TRY_READ_ATTR_WITHOUT_NS(lastRow)
0141     if(MSOOXML::Utils::convertBooleanAttr(lastCol)) {
0142         m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::LastCol;
0143     }
0144 //     TRY_READ_ATTR_WITHOUT_NS(rtl)
0145 
0146     while (!atEnd()) {
0147         readNext();
0148         BREAK_IF_END_OF(CURRENT_EL)
0149         if (isStartElement()) {
0150 //             TRY_READ_IF(blipFill)
0151 //             ELSE_TRY_READ_IF(effectDrag)
0152 //             ELSE_TRY_READ_IF(effectLst)
0153 //             ELSE_TRY_READ_IF(extLst)
0154 //             ELSE_TRY_READ_IF(gradFill)
0155 //             ELSE_TRY_READ_IF(grpFill)
0156 //             ELSE_TRY_READ_IF(noFill)
0157 //             ELSE_TRY_READ_IF(pattFill)
0158 //             ELSE_TRY_READ_IF(solidFill)
0159 //             ELSE_TRY_READ_IF(tableStyle)
0160             /*ELSE_*/TRY_READ_IF(tableStyleId)
0161 //             ELSE_WRONG_FORMAT
0162             SKIP_UNKNOWN
0163         }
0164     }
0165 
0166     READ_EPILOGUE
0167 }
0168 
0169 #undef CURRENT_EL
0170 #define CURRENT_EL tblGrid
0171 //! tblGrid handler (Table Grid) §21.1.3.14
0172 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tblGrid()
0173 {
0174     READ_PROLOGUE
0175     while (!atEnd()) {
0176         readNext();
0177         BREAK_IF_END_OF(CURRENT_EL)
0178         if (isStartElement()) {
0179             TRY_READ_IF(gridCol)
0180             ELSE_WRONG_FORMAT
0181         }
0182     }
0183     READ_EPILOGUE
0184 }
0185 
0186 #undef CURRENT_EL
0187 #define CURRENT_EL gridCol
0188 //! gridCol handler (Grid Column Definition) §21.1.3.2
0189 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_gridCol()
0190 {
0191     READ_PROLOGUE
0192     const QXmlStreamAttributes attrs(attributes());
0193 
0194     TRY_READ_ATTR_WITHOUT_NS(w)
0195 
0196     const qreal columnWidth = EMU_TO_POINT(w.toFloat());
0197 
0198     KoColumn* column = m_table->columnAt(m_currentTableColumnNumber++);
0199     KoColumnStyle::Ptr style = KoColumnStyle::create();
0200     style->setWidth(columnWidth);
0201     column->setStyle(style);
0202 
0203     while(!atEnd()) {
0204         readNext();
0205         BREAK_IF_END_OF(CURRENT_EL)
0206 //         if(isStartElement()) {
0207 //             TRY_READ_IF(extLst)
0208 //         }
0209     }
0210 
0211     READ_EPILOGUE
0212 }
0213 
0214 #undef CURRENT_EL
0215 #define CURRENT_EL tr
0216 //! tr handler (Table Row)§21.1.3.18
0217 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tr()
0218 {
0219     READ_PROLOGUE
0220 
0221     m_currentTableColumnNumber = 0;
0222 
0223     const QXmlStreamAttributes attrs(attributes());
0224     READ_ATTR_WITHOUT_NS(h)
0225     KoRow* row = m_table->rowAt(m_currentTableRowNumber);
0226     KoRowStyle::Ptr style = KoRowStyle::create();
0227     style->setHeight(EMU_TO_POINT(h.toFloat()));
0228     style->setHeightType(KoRowStyle::MinimumHeight);
0229     row->setStyle(style);
0230 
0231     while (!atEnd()) {
0232         readNext();
0233         BREAK_IF_END_OF(CURRENT_EL)
0234         if (isStartElement()) {
0235             TRY_READ_IF(tc)
0236 //             ELSE_TRY_READ_IF(extLst)
0237 //             ELSE_WRONG_FORMAT
0238             SKIP_UNKNOWN
0239         }
0240     }
0241 
0242     m_currentTableRowNumber++;
0243 
0244     READ_EPILOGUE
0245 }
0246 
0247 #undef CURRENT_EL
0248 #define CURRENT_EL tc
0249 //! tc handler (Table Cell) § 21.1.3.16
0250 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tc()
0251 {
0252     READ_PROLOGUE
0253     const QXmlStreamAttributes attrs(attributes());
0254 
0255     TRY_READ_ATTR_WITHOUT_NS(gridSpan)
0256     TRY_READ_ATTR_WITHOUT_NS(rowSpan)
0257 
0258     KoCell* cell = m_table->cellAt(m_currentTableRowNumber, m_currentTableColumnNumber);
0259 
0260     if (!gridSpan.isEmpty()) {
0261         cell->setColumnSpan(gridSpan.toInt());
0262     }
0263     if (!rowSpan.isEmpty()) {
0264         cell->setRowSpan(rowSpan.toInt());
0265     }
0266 
0267     TRY_READ_ATTR_WITHOUT_NS(vMerge)
0268     TRY_READ_ATTR_WITHOUT_NS(hMerge)
0269 
0270     if (vMerge == "1" || hMerge == "1") {
0271         cell->setCovered(true);
0272     }
0273 
0274     while (!atEnd()) {
0275         readNext();
0276         BREAK_IF_END_OF(CURRENT_EL)
0277         if (isStartElement()) {
0278             if (qualifiedName() == "a:txBody") {
0279                 QBuffer buffer;
0280 
0281                 KoXmlWriter* oldBody = body;
0282                 KoXmlWriter newBody(&buffer, oldBody->indentLevel()+1);
0283                 body = &newBody;
0284 
0285                 TRY_READ_IN_CONTEXT(DrawingML_txBody);
0286 
0287                 KoRawCellChild* textChild = new KoRawCellChild(buffer.data());
0288                 cell->appendChild(textChild);
0289 
0290                 body = oldBody;
0291             }
0292             // ELSE_TRY_READ_IF(extLst)
0293             ELSE_TRY_READ_IF(tcPr)
0294             SKIP_UNKNOWN
0295             // ELSE_WRONG_FORMAT
0296         }
0297     }
0298 
0299     m_currentTableColumnNumber++;
0300 
0301     READ_EPILOGUE
0302 }
0303 
0304 #undef CURRENT_EL
0305 #define CURRENT_EL tableStyleId
0306 //! tableStyleId (Table Style ID) §21.1.3.12
0307 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tableStyleId()
0308 {
0309     READ_PROLOGUE
0310 
0311     readNext();
0312     QString id = text().toString();
0313 
0314     QString predefinedTable = getPresetTable(id);
0315     if (!predefinedTable.isEmpty()) {
0316         predefinedTable.prepend("<a:tblStyleLst xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">");
0317         predefinedTable.prepend("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
0318         predefinedTable.append("</a:tblStyleLst>");
0319         QString tableStylesFile;
0320         QString tableStylesPath;
0321         QBuffer tempDevice;
0322         tempDevice.setData(predefinedTable.toLatin1());
0323         tempDevice.open(QIODevice::ReadOnly);
0324         MSOOXML::Utils::splitPathAndFile(m_context->tableStylesFilePath, &tableStylesPath, &tableStylesFile);
0325         MSOOXML::MsooXmlDrawingTableStyleReader tableStyleReader(this);
0326         MSOOXML::MsooXmlDrawingTableStyleContext tableStyleReaderContext(m_context->import, tableStylesPath,
0327                                                                          tableStylesFile, &m_context->slideMasterProperties->theme,
0328                                                                          d->tableStyleList, m_context->colorMap);
0329         m_context->import->loadAndParseFromDevice(&tableStyleReader, &tempDevice, &tableStyleReaderContext);
0330     }
0331 
0332     m_tableStyle = d->tableStyleList->value(text().toString());
0333     readNext();
0334 
0335     READ_EPILOGUE
0336 }
0337 
0338 // Local styles
0339 
0340 #undef CURRENT_EL
0341 #define CURRENT_EL tcPr
0342 //! tcPR (Table Cell Properties) §21.1.3.17
0343 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tcPr()
0344 {
0345     READ_PROLOGUE
0346 
0347     m_currentLocalStyleProperties = new MSOOXML::TableStyleProperties();
0348 
0349     while (!atEnd()) {
0350         readNext();
0351         BREAK_IF_END_OF(CURRENT_EL)
0352         if (isStartElement()) {
0353 //             TRY_READ_IF(blipFill)
0354 //             ELSE_TRY_READ_IF(cell3D)
0355 //             ELSE_TRY_READ_IF(extLst)
0356 //             ELSE_TRY_READ_IF(gradFill)
0357 //             ELSE_TRY_READ_IF(grpFill)
0358 //             ELSE_TRY_READ_IF(lnBlToTr)
0359 //             ELSE_TRY_READ_IF(lnTlToBr)
0360 //             ELSE_TRY_READ_IF(pattFill)
0361             if (QUALIFIED_NAME_IS(lnL)) {
0362                 TRY_READ(Table_lnL)
0363                 m_currentLocalStyleProperties->left = m_currentBorder;
0364                 m_currentLocalStyleProperties->setProperties |= TableStyleProperties::LeftBorder;
0365             }
0366             else if (QUALIFIED_NAME_IS(lnR)) {
0367                 TRY_READ(Table_lnR)
0368                 m_currentLocalStyleProperties->right = m_currentBorder;
0369                 m_currentLocalStyleProperties->setProperties |= TableStyleProperties::RightBorder;
0370             }
0371             else if (QUALIFIED_NAME_IS(lnT)) {
0372                 TRY_READ(Table_lnT)
0373                 m_currentLocalStyleProperties->top = m_currentBorder;
0374                 m_currentLocalStyleProperties->setProperties |= TableStyleProperties::TopBorder;
0375             }
0376             else if (QUALIFIED_NAME_IS(lnB)) {
0377                 TRY_READ(Table_lnB)
0378                 m_currentLocalStyleProperties->bottom = m_currentBorder;
0379                 m_currentLocalStyleProperties->setProperties |= TableStyleProperties::BottomBorder;
0380             }
0381             else if (QUALIFIED_NAME_IS(solidFill)) {
0382                 TRY_READ(solidFill)
0383                 m_currentLocalStyleProperties->backgroundColor = m_currentColor;
0384                 m_currentLocalStyleProperties->setProperties |= MSOOXML::TableStyleProperties::BackgroundColor;
0385                 if (m_currentAlpha > 0) {
0386                     m_currentLocalStyleProperties->backgroundOpacity = m_currentAlpha;
0387                     m_currentLocalStyleProperties->setProperties |= MSOOXML::TableStyleProperties::BackgroundOpacity;
0388                 }
0389             }
0390             SKIP_UNKNOWN // Added to make sure that solidfill eg inside 'lnT' does not mess with the color
0391         }
0392     }
0393 
0394     m_localTableStyles.setLocalStyle(m_currentLocalStyleProperties, m_currentTableRowNumber, m_currentTableColumnNumber);
0395 
0396     READ_EPILOGUE
0397 }