diff --git a/filters/libmsooxml/MsooXmlDrawingReaderTableImpl.h b/filters/libmsooxml/MsooXmlDrawingReaderTableImpl.h index 52f53110ac5..856ffb3ec47 100644 --- a/filters/libmsooxml/MsooXmlDrawingReaderTableImpl.h +++ b/filters/libmsooxml/MsooXmlDrawingReaderTableImpl.h @@ -1,399 +1,397 @@ /* This file is part of the KDE project * Copyright (C) 2010-2011 Carlos Licea * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /** * This file deals with the tables designed for the DrawingML namespace * the table starts at tbl §21.1.3.13 */ #include "MsooXmlTableStyle.h" using namespace MSOOXML; #undef CURRENT_EL #define CURRENT_EL tbl //! tbl (Table) §21.1.3.13 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tbl() { + m_table = KoTable::create(); + READ_PROLOGUE bool tableSetByMe = false; if (!m_insideTable) { // Handling nested tables tableSetByMe = true; m_insideTable = true; } m_tableStyle = 0; if (!d->tableStyleList) { d->tableStyleList = new QMap; QString tableStylesFile; QString tableStylesPath; MSOOXML::Utils::splitPathAndFile(m_context->tableStylesFilePath, &tableStylesPath, &tableStylesFile); MSOOXML::MsooXmlDrawingTableStyleReader tableStyleReader(this); MSOOXML::MsooXmlDrawingTableStyleContext tableStyleReaderContext(m_context->import, tableStylesPath, tableStylesFile, &m_context->slideMasterProperties->theme, d->tableStyleList, m_context->colorMap); m_context->import->loadAndParseDocument(&tableStyleReader, m_context->tableStylesFilePath, &tableStyleReaderContext); } - m_table = new KoTable; - m_table->setName(QLatin1String("Table") + QString::number(m_currentTableNumber + 1)); m_currentTableRowNumber = 0; m_currentTableColumnNumber = 0; while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(tblPr) ELSE_TRY_READ_IF(tblGrid) ELSE_TRY_READ_IF(tr) SKIP_UNKNOWN // ELSE_WRONG_FORMAT } } defineStyles(); m_table->saveOdf(*body, *mainStyles); - delete m_table; - m_currentTableNumber++; if (tableSetByMe) { m_insideTable = false; } READ_EPILOGUE } void MSOOXML_CURRENT_CLASS::defineStyles() { const int rowCount = m_table->rowCount(); const int columnCount = m_table->columnCount(); QPair spans; MSOOXML::DrawingTableStyleConverterProperties converterProperties; converterProperties.setRowCount(rowCount); converterProperties.setColumnCount(columnCount); converterProperties.setRoles(m_activeRoles); converterProperties.setLocalStyles(m_localTableStyles); // TODO: converterProperties.setLocalDefaulCelltStyle() MSOOXML::DrawingTableStyleConverter styleConverter(converterProperties, m_tableStyle); for(int row = 0; row < rowCount; ++row ) { for(int column = 0; column < columnCount; ++column ) { spans.first = m_table->cellAt(row, column)->rowSpan(); spans.second = m_table->cellAt(row, column)->columnSpan(); KoCellStyle::Ptr style = styleConverter.style(row, column, spans); m_table->cellAt(row, column)->setStyle(style); } } } #undef CURRENT_EL #define CURRENT_EL tblPr //! tblPr handler (Table Properties) §21.1.3.15 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tblPr() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR_WITHOUT_NS(bandCol) if(MSOOXML::Utils::convertBooleanAttr(bandCol)) { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::ColumnBanded; } TRY_READ_ATTR_WITHOUT_NS(bandRow) if(MSOOXML::Utils::convertBooleanAttr(bandRow)) { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::RowBanded; } TRY_READ_ATTR_WITHOUT_NS(firstCol) if(MSOOXML::Utils::convertBooleanAttr(firstCol)) { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::FirstCol; } TRY_READ_ATTR_WITHOUT_NS(firstRow) if(MSOOXML::Utils::convertBooleanAttr(firstRow)) { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::FirstRow; } TRY_READ_ATTR_WITHOUT_NS(lastCol) if(MSOOXML::Utils::convertBooleanAttr(lastCol)) { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::FirstCol; } TRY_READ_ATTR_WITHOUT_NS(lastRow) if(MSOOXML::Utils::convertBooleanAttr(lastCol)) { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::LastCol; } // TRY_READ_ATTR_WITHOUT_NS(rtl) while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { // TRY_READ_IF(blipFill) // ELSE_TRY_READ_IF(effectDrag) // ELSE_TRY_READ_IF(effectLst) // ELSE_TRY_READ_IF(extLst) // ELSE_TRY_READ_IF(gradFill) // ELSE_TRY_READ_IF(grpFill) // ELSE_TRY_READ_IF(noFill) // ELSE_TRY_READ_IF(pattFill) // ELSE_TRY_READ_IF(solidFill) // ELSE_TRY_READ_IF(tableStyle) /*ELSE_*/TRY_READ_IF(tableStyleId) // ELSE_WRONG_FORMAT SKIP_UNKNOWN } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tblGrid //! tblGrid handler (Table Grid) §21.1.3.14 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tblGrid() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(gridCol) ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL gridCol //! gridCol handler (Grid Column Definition) §21.1.3.2 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_gridCol() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR_WITHOUT_NS(w) const qreal columnWidth = EMU_TO_POINT(w.toFloat()); KoColumn* column = m_table->columnAt(m_currentTableColumnNumber++); KoColumnStyle::Ptr style = KoColumnStyle::create(); style->setWidth(columnWidth); column->setStyle(style); while(!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) // if(isStartElement()) { // TRY_READ_IF(extLst) // } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tr //! tr handler (Table Row)§21.1.3.18 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tr() { READ_PROLOGUE m_currentTableColumnNumber = 0; const QXmlStreamAttributes attrs(attributes()); READ_ATTR_WITHOUT_NS(h) KoRow* row = m_table->rowAt(m_currentTableRowNumber); KoRowStyle::Ptr style = KoRowStyle::create(); style->setHeight(EMU_TO_POINT(h.toFloat())); style->setHeightType(KoRowStyle::MinimumHeight); row->setStyle(style); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(tc) // ELSE_TRY_READ_IF(extLst) // ELSE_WRONG_FORMAT SKIP_UNKNOWN } } m_currentTableRowNumber++; READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tc //! tc handler (Table Cell) § 21.1.3.16 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tc() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR_WITHOUT_NS(gridSpan) TRY_READ_ATTR_WITHOUT_NS(rowSpan) KoCell* cell = m_table->cellAt(m_currentTableRowNumber, m_currentTableColumnNumber); if (!gridSpan.isEmpty()) { cell->setColumnSpan(gridSpan.toInt()); } if (!rowSpan.isEmpty()) { cell->setRowSpan(rowSpan.toInt()); } TRY_READ_ATTR_WITHOUT_NS(vMerge) TRY_READ_ATTR_WITHOUT_NS(hMerge) if (vMerge == "1" || hMerge == "1") { cell->setCovered(true); } while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { if (qualifiedName() == "a:txBody") { QBuffer buffer; KoXmlWriter* oldBody = body; KoXmlWriter newBody(&buffer, oldBody->indentLevel()+1); body = &newBody; TRY_READ_IN_CONTEXT(DrawingML_txBody); KoRawCellChild* textChild = new KoRawCellChild(buffer.data()); cell->appendChild(textChild); body = oldBody; } // ELSE_TRY_READ_IF(extLst) ELSE_TRY_READ_IF(tcPr) SKIP_UNKNOWN // ELSE_WRONG_FORMAT } } m_currentTableColumnNumber++; READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tableStyleId //! tableStyleId (Table Style ID) §21.1.3.12 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tableStyleId() { READ_PROLOGUE readNext(); QString id = text().toString(); QString predefinedTable = getPresetTable(id); if (!predefinedTable.isEmpty()) { predefinedTable.prepend(""); predefinedTable.prepend(""); predefinedTable.append(""); QString tableStylesFile; QString tableStylesPath; QBuffer tempDevice; tempDevice.setData(predefinedTable.toLatin1()); tempDevice.open(QIODevice::ReadOnly); MSOOXML::Utils::splitPathAndFile(m_context->tableStylesFilePath, &tableStylesPath, &tableStylesFile); MSOOXML::MsooXmlDrawingTableStyleReader tableStyleReader(this); MSOOXML::MsooXmlDrawingTableStyleContext tableStyleReaderContext(m_context->import, tableStylesPath, tableStylesFile, &m_context->slideMasterProperties->theme, d->tableStyleList, m_context->colorMap); m_context->import->loadAndParseFromDevice(&tableStyleReader, &tempDevice, &tableStyleReaderContext); } m_tableStyle = d->tableStyleList->value(text().toString()); readNext(); READ_EPILOGUE } // Local styles #undef CURRENT_EL #define CURRENT_EL tcPr //! tcPR (Table Cell Properties) §21.1.3.17 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tcPr() { READ_PROLOGUE m_currentLocalStyleProperties = new MSOOXML::TableStyleProperties(); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { // TRY_READ_IF(blipFill) // ELSE_TRY_READ_IF(cell3D) // ELSE_TRY_READ_IF(extLst) // ELSE_TRY_READ_IF(gradFill) // ELSE_TRY_READ_IF(grpFill) // ELSE_TRY_READ_IF(lnBlToTr) // ELSE_TRY_READ_IF(lnTlToBr) // ELSE_TRY_READ_IF(pattFill) if (QUALIFIED_NAME_IS(lnL)) { TRY_READ(Table_lnL) m_currentLocalStyleProperties->left = m_currentBorder; m_currentLocalStyleProperties->setProperties |= TableStyleProperties::LeftBorder; } else if (QUALIFIED_NAME_IS(lnR)) { TRY_READ(Table_lnR) m_currentLocalStyleProperties->right = m_currentBorder; m_currentLocalStyleProperties->setProperties |= TableStyleProperties::RightBorder; } else if (QUALIFIED_NAME_IS(lnT)) { TRY_READ(Table_lnT) m_currentLocalStyleProperties->top = m_currentBorder; m_currentLocalStyleProperties->setProperties |= TableStyleProperties::TopBorder; } else if (QUALIFIED_NAME_IS(lnB)) { TRY_READ(Table_lnB) m_currentLocalStyleProperties->bottom = m_currentBorder; m_currentLocalStyleProperties->setProperties |= TableStyleProperties::BottomBorder; } else if (QUALIFIED_NAME_IS(solidFill)) { TRY_READ(solidFill) m_currentLocalStyleProperties->backgroundColor = m_currentColor; m_currentLocalStyleProperties->setProperties |= MSOOXML::TableStyleProperties::BackgroundColor; if (m_currentAlpha > 0) { m_currentLocalStyleProperties->backgroundOpacity = m_currentAlpha; m_currentLocalStyleProperties->setProperties |= MSOOXML::TableStyleProperties::BackgroundOpacity; } } SKIP_UNKNOWN // Added to make sure that solidfill eg inside 'lnT' does not mess with the color } } m_localTableStyles.setLocalStyle(m_currentLocalStyleProperties, m_currentTableRowNumber, m_currentTableColumnNumber); READ_EPILOGUE } diff --git a/filters/libmsooxml/MsooXmlDrawingReaderTableMethods.h b/filters/libmsooxml/MsooXmlDrawingReaderTableMethods.h index 0134ecbfe11..93912c129e9 100644 --- a/filters/libmsooxml/MsooXmlDrawingReaderTableMethods.h +++ b/filters/libmsooxml/MsooXmlDrawingReaderTableMethods.h @@ -1,49 +1,49 @@ /* This file is part of the KDE project * Copyright (C) 2010-2011 Carlos Licea * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ protected: KoFilter::ConversionStatus read_tbl(); KoFilter::ConversionStatus read_tblPr(); KoFilter::ConversionStatus read_tblGrid(); KoFilter::ConversionStatus read_tr(); KoFilter::ConversionStatus read_tableStyleId(); KoFilter::ConversionStatus read_gridCol(); KoFilter::ConversionStatus read_tc(); KoFilter::ConversionStatus read_tcPr(); KoFilter::ConversionStatus read_lnT(); KoFilter::ConversionStatus read_lnB(); KoFilter::ConversionStatus read_lnR(); KoFilter::ConversionStatus read_lnL(); void defineStyles(); uint m_currentTableNumber; //!< table counter, from 0 uint m_currentTableRowNumber; //!< row counter, from 0, initialized in read_tbl() uint m_currentTableColumnNumber; //!< column counter, from 0, initialized in read_tr() - KoTable* m_table; + KoTable::Ptr m_table; QString m_currentTableName; MSOOXML::DrawingTableStyle* m_tableStyle; MSOOXML::DrawingTableStyleConverterProperties::Roles m_activeRoles; MSOOXML::TableStyleProperties* m_currentLocalStyleProperties; MSOOXML::LocalTableStyles m_localTableStyles; #include "PresetDrawingMLTables.h" diff --git a/filters/libmsooxml/PresetDrawingMLTables.h b/filters/libmsooxml/PresetDrawingMLTables.h index 3879137454c..ecb71dcbb7b 100644 --- a/filters/libmsooxml/PresetDrawingMLTables.h +++ b/filters/libmsooxml/PresetDrawingMLTables.h @@ -1,11870 +1,11871 @@ /* * This file is part of Office 2007 Filters for Calligra * * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). * * Contact: Lassi Nieminen lassniem@gmail.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * */ QString getPresetTable(const QString& reference) { -QMap presetTables; -presetTables["{2D5ABB26-0587-4C30-8999-92F81FD0307C}"] = "\ +static const QMap presetTables = { +{ QStringLiteral("{2D5ABB26-0587-4C30-8999-92F81FD0307C}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{3C2FFA5D-87B4-456A-9821-1D502468CF0F}"] = "\ +") }, +{ QStringLiteral("{3C2FFA5D-87B4-456A-9821-1D502468CF0F}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{284E427A-3D55-4303-BF80-6455036E1DE7}"] = "\ +") }, +{ QStringLiteral("{284E427A-3D55-4303-BF80-6455036E1DE7}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{69C7853C-536D-4A76-A0AE-DD22124D55A5}"] = "\ +") }, +{ QStringLiteral("{69C7853C-536D-4A76-A0AE-DD22124D55A5}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{775DCB02-9BB8-47FD-8907-85C794F793BA}"] = "\ +") }, +{ QStringLiteral("{775DCB02-9BB8-47FD-8907-85C794F793BA}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{35758FB7-9AC5-4552-8A53-C91805E547FA}"] = "\ +") }, +{ QStringLiteral("{35758FB7-9AC5-4552-8A53-C91805E547FA}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{08FB837D-C827-4EFA-A057-4D05807E0F7C}"] = "\ +") }, +{ QStringLiteral("{08FB837D-C827-4EFA-A057-4D05807E0F7C}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{5940675A-B579-460E-94D1-54222C63F5DA}"] = "\ +") }, +{ QStringLiteral("{5940675A-B579-460E-94D1-54222C63F5DA}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{D113A9D2-9D6B-4929-AA2D-F23B5EE8CBE7}"] = "\ +") }, +{ QStringLiteral("{D113A9D2-9D6B-4929-AA2D-F23B5EE8CBE7}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{18603FDC-E32A-4AB5-989C-0864C3EAD2B8}"] = "\ +") }, +{ QStringLiteral("{18603FDC-E32A-4AB5-989C-0864C3EAD2B8}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{306799F8-075E-4A3A-A7F6-7FBC6576F1A4}"] = "\ +") }, +{ QStringLiteral("{306799F8-075E-4A3A-A7F6-7FBC6576F1A4}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{E269D01E-BC32-4049-B463-5C60D7B0CCD2}"] = "\ +") }, +{ QStringLiteral("{E269D01E-BC32-4049-B463-5C60D7B0CCD2}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{327F97BB-C833-4FB7-BDE5-3F7075034690}"] = "\ +") }, +{ QStringLiteral("{327F97BB-C833-4FB7-BDE5-3F7075034690}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{638B1855-1B75-4FBE-930C-398BA8C253C6}"] = "\ +") }, +{ QStringLiteral("{638B1855-1B75-4FBE-930C-398BA8C253C6}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{9D7B26C5-4107-4FEC-AEDC-1716B250A1EF}"] = "\ +") }, +{ QStringLiteral("{9D7B26C5-4107-4FEC-AEDC-1716B250A1EF}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{3B4B98B0-60AC-42C2-AFA5-B58CD77FA1E5}"] = "\ +") }, +{ QStringLiteral("{3B4B98B0-60AC-42C2-AFA5-B58CD77FA1E5}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{0E3FDE45-AF77-4B5C-9715-49D594BDF05E}"] = "\ +") }, +{ QStringLiteral("{0E3FDE45-AF77-4B5C-9715-49D594BDF05E}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{C083E6E3-FA7D-4D7B-A595-EF9225AFEA82}"] = "\ +") }, +{ QStringLiteral("{C083E6E3-FA7D-4D7B-A595-EF9225AFEA82}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{D27102A9-8310-4765-A935-A1911B00CA55}"] = "\ +") }, +{ QStringLiteral("{D27102A9-8310-4765-A935-A1911B00CA55}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{5FD0F851-EC5A-4D38-B0AD-8093EC10F338}"] = "\ +") }, +{ QStringLiteral("{5FD0F851-EC5A-4D38-B0AD-8093EC10F338}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{68D230F3-CF80-4859-8CE7-A43EE81993B5}"] = "\ +") }, +{ QStringLiteral("{68D230F3-CF80-4859-8CE7-A43EE81993B5}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{7E9639D4-E3E2-4D34-9284-5A2195B3D0D7}"] = "\ +") }, +{ QStringLiteral("{7E9639D4-E3E2-4D34-9284-5A2195B3D0D7}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{69012ECD-51FC-41F1-AA8D-1B2483CD663E}"] = "\ +") }, +{ QStringLiteral("{69012ECD-51FC-41F1-AA8D-1B2483CD663E}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{72833802-FEF1-4C79-8D5D-14CF1EAF98D9}"] = "\ +") }, +{ QStringLiteral("{72833802-FEF1-4C79-8D5D-14CF1EAF98D9}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{F2DE63D5-997A-4646-A377-4702673A728D}"] = "\ +") }, +{ QStringLiteral("{F2DE63D5-997A-4646-A377-4702673A728D}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{17292A2E-F333-43FB-9621-5CBBE7FDCDCB}"] = "\ +") }, +{ QStringLiteral("{17292A2E-F333-43FB-9621-5CBBE7FDCDCB}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{5A111915-BE36-4E01-A7E5-04B1672EAD32}"] = "\ +") }, +{ QStringLiteral("{5A111915-BE36-4E01-A7E5-04B1672EAD32}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{912C8C85-51F0-491E-9774-3900AFEF0FD7}"] = "\ +") }, +{ QStringLiteral("{912C8C85-51F0-491E-9774-3900AFEF0FD7}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{616DA210-FB5B-4158-B5E0-FEB733F419BA}"] = "\ +") }, +{ QStringLiteral("{616DA210-FB5B-4158-B5E0-FEB733F419BA}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{BC89EF96-8CEA-46FF-86C4-4CE0E7609802}"] = "\ +") }, +{ QStringLiteral("{BC89EF96-8CEA-46FF-86C4-4CE0E7609802}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{5DA37D80-6434-44D0-A028-1B22A696006F}"] = "\ +") }, +{ QStringLiteral("{5DA37D80-6434-44D0-A028-1B22A696006F}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{8799B23B-EC83-4686-B30A-512413B5E67A}"] = "\ +") }, +{ QStringLiteral("{8799B23B-EC83-4686-B30A-512413B5E67A}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{ED083AE6-46FA-4A59-8FB0-9F97EB10719F}"] = "\ +") }, +{ QStringLiteral("{ED083AE6-46FA-4A59-8FB0-9F97EB10719F}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{BDBED569-4797-4DF1-A0F4-6AAB3CD982D8}"] = "\ +") }, +{ QStringLiteral("{BDBED569-4797-4DF1-A0F4-6AAB3CD982D8}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{E8B1032C-EA38-4F05-BA0D-38AFFFC7BED3}"] = "\ +") }, +{ QStringLiteral("{E8B1032C-EA38-4F05-BA0D-38AFFFC7BED3}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{793D81CF-94F2-401A-BA57-92F5A7B2D0C5}"] = "\ +") }, +{ QStringLiteral("{793D81CF-94F2-401A-BA57-92F5A7B2D0C5}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{B301B821-A1FF-4177-AEE7-76D212191A09}"] = "\ +") }, +{ QStringLiteral("{B301B821-A1FF-4177-AEE7-76D212191A09}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{9DCAF9ED-07DC-4A11-8D7F-57B35C25682E}"] = "\ +") }, +{ QStringLiteral("{9DCAF9ED-07DC-4A11-8D7F-57B35C25682E}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{1FECB4D8-DB02-4DC6-A0A2-4F2EBAE1DC90}"] = "\ +") }, +{ QStringLiteral("{1FECB4D8-DB02-4DC6-A0A2-4F2EBAE1DC90}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{1E171933-4619-4E11-9A3F-F7608DF75F80}"] = "\ +") }, +{ QStringLiteral("{1E171933-4619-4E11-9A3F-F7608DF75F80}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{FABFCF23-3B69-468F-B69F-88F6DE6A72F2}"] = "\ +") }, +{ QStringLiteral("{FABFCF23-3B69-468F-B69F-88F6DE6A72F2}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{10A1B5D5-9B99-4C35-A422-299274C87663}"] = "\ +") }, +{ QStringLiteral("{10A1B5D5-9B99-4C35-A422-299274C87663}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{073A0DAA-6AF3-43AB-8588-CEC1D06C72B9}"] = "\ +") }, +{ QStringLiteral("{073A0DAA-6AF3-43AB-8588-CEC1D06C72B9}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}"] = "\ +") }, +{ QStringLiteral("{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{21E4AEA4-8DFA-4A89-87EB-49C32662AFE0}"] = "\ +") }, +{ QStringLiteral("{21E4AEA4-8DFA-4A89-87EB-49C32662AFE0}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{F5AB1C69-6EDB-4FF4-983F-18BD219EF322}"] = "\ +") }, +{ QStringLiteral("{F5AB1C69-6EDB-4FF4-983F-18BD219EF322}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{00A15C55-8517-42AA-B614-E9B94910E393}"] = "\ +") }, +{ QStringLiteral("{00A15C55-8517-42AA-B614-E9B94910E393}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{7DF18680-E054-41AD-8BC1-D1AEF772440D}"] = "\ +") }, +{ QStringLiteral("{7DF18680-E054-41AD-8BC1-D1AEF772440D}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{93296810-A885-4BE3-A3E7-6D5BEEA58F35}"] = "\ +") }, +{ QStringLiteral("{93296810-A885-4BE3-A3E7-6D5BEEA58F35}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{8EC20E35-A176-4012-BC5E-935CFFF8708E}"] = "\ +") }, +{ QStringLiteral("{8EC20E35-A176-4012-BC5E-935CFFF8708E}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{6E25E649-3F16-4E02-A733-19D2CDBF48F0}"] = "\ +") }, +{ QStringLiteral("{6E25E649-3F16-4E02-A733-19D2CDBF48F0}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{85BE263C-DBD7-4A20-BB59-AAB30ACAA65A}"] = "\ +") }, +{ QStringLiteral("{85BE263C-DBD7-4A20-BB59-AAB30ACAA65A}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{EB344D84-9AFB-497E-A393-DC336BA19D2E}"] = "\ +") }, +{ QStringLiteral("{EB344D84-9AFB-497E-A393-DC336BA19D2E}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{EB9631B5-78F2-41C9-869B-9F39066F8104}"] = "\ +") }, +{ QStringLiteral("{EB9631B5-78F2-41C9-869B-9F39066F8104}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{74C1A8A3-306A-4EB7-A6B1-4F7E0EB9C5D6}"] = "\ +") }, +{ QStringLiteral("{74C1A8A3-306A-4EB7-A6B1-4F7E0EB9C5D6}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{2A488322-F2BA-4B5B-9748-0D474271808F}"] = "\ +") }, +{ QStringLiteral("{2A488322-F2BA-4B5B-9748-0D474271808F}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{D7AC3CCA-C797-4891-BE02-D94E43425B78}"] = "\ +") }, +{ QStringLiteral("{D7AC3CCA-C797-4891-BE02-D94E43425B78}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{69CF1AB2-1976-4502-BF36-3FF5EA218861}"] = "\ +") }, +{ QStringLiteral("{69CF1AB2-1976-4502-BF36-3FF5EA218861}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{8A107856-5554-42FB-B03E-39F5DBC370BA}"] = "\ +") }, +{ QStringLiteral("{8A107856-5554-42FB-B03E-39F5DBC370BA}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{0505E3EF-67EA-436B-97B2-0124C06EBD24}"] = "\ +") }, +{ QStringLiteral("{0505E3EF-67EA-436B-97B2-0124C06EBD24}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{C4B1156A-380E-4F78-BDF5-A606A8083BF9}"] = "\ +") }, +{ QStringLiteral("{C4B1156A-380E-4F78-BDF5-A606A8083BF9}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{22838BEF-8BB2-4498-84A7-C5851F593DF1}"] = "\ +") }, +{ QStringLiteral("{22838BEF-8BB2-4498-84A7-C5851F593DF1}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{16D9F66E-5EB9-4882-86FB-DCBF35E3C3E4}"] = "\ +") }, +{ QStringLiteral("{16D9F66E-5EB9-4882-86FB-DCBF35E3C3E4}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{E8034E78-7F5D-4C2E-B375-FC64B27BC917}"] = "\ +") }, +{ QStringLiteral("{E8034E78-7F5D-4C2E-B375-FC64B27BC917}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{125E5076-3810-47DD-B79F-674D7AD40C01}"] = "\ +") }, +{ QStringLiteral("{125E5076-3810-47DD-B79F-674D7AD40C01}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{37CE84F3-28C3-443E-9E96-99CF82512B78}"] = "\ +") }, +{ QStringLiteral("{37CE84F3-28C3-443E-9E96-99CF82512B78}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{D03447BB-5D67-496B-8E87-E561075AD55C}"] = "\ +") }, +{ QStringLiteral("{D03447BB-5D67-496B-8E87-E561075AD55C}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{E929F9F4-4A8F-4326-A1B4-22849713DDAB}"] = "\ +") }, +{ QStringLiteral("{E929F9F4-4A8F-4326-A1B4-22849713DDAB}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{8FD4443E-F989-4FC4-A0C8-D5A2AF1F390B}"] = "\ +") }, +{ QStringLiteral("{8FD4443E-F989-4FC4-A0C8-D5A2AF1F390B}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{AF606853-7671-496A-8E4F-DF71F8EC918B}"] = "\ +") }, +{ QStringLiteral("{AF606853-7671-496A-8E4F-DF71F8EC918B}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{5202B0CA-FC54-4496-8BCA-5EF66A818D29}"] = "\ +") }, +{ QStringLiteral("{5202B0CA-FC54-4496-8BCA-5EF66A818D29}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{0660B408-B3CF-4A94-85FC-2B1E0A45F4A2}"] = "\ +") }, +{ QStringLiteral("{0660B408-B3CF-4A94-85FC-2B1E0A45F4A2}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{91EBBBCC-DAD2-459C-BE2E-F6DE35CF9A28}"] = "\ +") }, +{ QStringLiteral("{91EBBBCC-DAD2-459C-BE2E-F6DE35CF9A28}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; -presetTables["{46F890A9-2807-4EBB-B81D-B2AA78EC7F39}"] = "\ +") }, +{ QStringLiteral("{46F890A9-2807-4EBB-B81D-B2AA78EC7F39}"), QStringLiteral("\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -"; +") } +}; return presetTables.value(reference); } diff --git a/filters/libodf2/KoTable.cpp b/filters/libodf2/KoTable.cpp index a239e26aa43..88e969cb2fd 100644 --- a/filters/libodf2/KoTable.cpp +++ b/filters/libodf2/KoTable.cpp @@ -1,229 +1,231 @@ /* * Copyright (c) 2010 Carlos Licea * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "KoTable.h" #include "KoColumn.h" #include "KoRow.h" #include "KoCell.h" #include +KOSTYLE_DECLARE_SHARED_POINTER_IMPL(KoTable) + KoTable::KoTable() : m_columns() , m_rows() , m_cells() , m_rowCount() , m_columnCount() , m_style(0) , m_printable(true) , m_name() , m_protected(false) , m_protectionKey() { } KoTable::~KoTable() { } KoCell* KoTable::cellAt(int row, int column) { const QPair key(row,column); KoCell* cell = m_cells.value(key); if(!cell) { cell = new KoCell(); m_cells.insert(key, cell); m_columnCount = qMax(column+1, m_columnCount); m_rowCount = qMax(row+1, m_rowCount); } return cell; } KoColumn* KoTable::columnAt(int column) { KoColumn* columnAt = m_columns.value(column); if(!columnAt) { columnAt = new KoColumn(); if(column >= m_columns.size()) { m_columns.resize(column+1); } m_columns.insert(column, columnAt); m_columnCount = qMax(column+1, m_columnCount); } return columnAt; } KoRow* KoTable::rowAt(int row) { KoRow* rowAt = m_rows.value(row); if(!rowAt) { rowAt = new KoRow(); if(row >= m_rows.size()) { m_rows.resize(row+1); } m_rows.replace(row, rowAt); m_rowCount = qMax(row+1, m_rowCount); } return rowAt; } int KoTable::columnCount() const { return m_columnCount; } int KoTable::rowCount() const { return m_rowCount; } void KoTable::saveOdf(KoXmlWriter& writer, KoGenStyles& styles) { writer.startElement("table:table"); writer.addAttribute("table:name", m_name); writer.addAttribute("table:protected", m_protected ? "true" : "false" ); if(!m_protectionKey.isEmpty()) { writer.addAttribute("table:protection-key", m_protectionKey); } if(!m_protectionAlgorithm.isEmpty()) { writer.addAttribute("table:protection-key-digest-algorithm", m_protectionAlgorithm); } if(m_style) { m_style->setName(m_style->saveOdf(styles)); writer.addAttribute("table:style-name", m_style->name()); } { KoColumn defaultColumn; for(int c = 0; c < columnCount(); ++c) { KoColumn* column = m_columns.value(c); if(column) { column->saveOdf(writer, styles); } else { defaultColumn.saveOdf(writer, styles); } } } { KoRow defaultRow; for(int r = 0; r < rowCount(); ++r) { KoRow* row = m_rows.value(r); if(row) { row->saveOdf(writer, styles); KoCell defaultCell; for(int c = 0; c < columnCount(); ++c) { KoCell* cell = m_cells.value(QPair(r,c)); if(cell) { cell->saveOdf(writer, styles); } else { defaultCell.saveOdf(writer, styles); } } row->finishSaveOdf(writer, styles); } else { defaultRow.saveOdf(writer, styles); KoCell defaultCell; for(int c = 0; c < columnCount(); ++c) { KoCell* cell = m_cells.value(QPair(r,c)); if(cell) { cell->saveOdf(writer, styles); } else { defaultCell.saveOdf(writer, styles); } } defaultRow.finishSaveOdf(writer, styles); } } } writer.endElement();// table:table } void KoTable::setName(const QString& name) { m_name = name; } QString KoTable::name() const { return m_name; } void KoTable::setPrintable(bool printable) { m_printable = printable; } bool KoTable::printable() const { return m_printable; } void KoTable::setTableStyle(KoTblStyle::Ptr style) { m_style = style; } KoTblStyle::Ptr KoTable::tableStyle() { return m_style; } void KoTable::setProtected(bool isProtected) { m_protected = isProtected; } void KoTable::setProtectionKey(const QString &password, const QString &protectionAlgorithmUri) { m_protectionKey = password; m_protectionAlgorithm = protectionAlgorithmUri; } QString KoTable::protectionKey() const { return m_protectionKey; } QString KoTable::protectionalgorithm() const { return m_protectionAlgorithm; } bool KoTable::isPprotected() const { return m_protected; } diff --git a/filters/libodf2/KoTable.h b/filters/libodf2/KoTable.h index 5789e02773f..d0c946f33d8 100644 --- a/filters/libodf2/KoTable.h +++ b/filters/libodf2/KoTable.h @@ -1,111 +1,113 @@ /* * Copyright (c) 2010 Carlos Licea * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KOTABLE_H #define KOTABLE_H class KoColumn; class KoRow; class KoCell; #include "KoTblStyle.h" class KoXmlWriter; class KoGenStyles; #include "koodf2_export.h" #include #include #include /** * \class KoTable represents a table in an ODF element. * Note that, at least for now, the class is meant to be used * only to write tables and as such lacks much of the functionallity * needed to read written tables. * * All the pointers returned by this class are guaranteed to be not-null. * Do note, however, that there's no way to clear a cell, row or column. * * The \class KoTable owns all the pointer objects returned by * its methods. **/ class KOODF2_EXPORT KoTable { public: + KOSTYLE_DECLARE_SHARED_POINTER(KoTable) + KoTable(); ~KoTable(); KoRow* rowAt(int row); int rowCount() const; KoColumn* columnAt(int column); int columnCount() const; KoCell* cellAt(int row, int column); void saveOdf(KoXmlWriter& writer, KoGenStyles& styles); KoTblStyle::Ptr tableStyle(); void setTableStyle(KoTblStyle::Ptr style); // KoTableTemplate* tableTemplate(); // void setTableTemplate(KoTableTemplate* tableTemplate); // TableTemplateFlags templateFlags(); // void setTemplateFlags(TableTemplateFlags templateFlags); bool printable() const; void setPrintable(bool printable); // void setPrintRange(CellRange cellRange); // CellRange printRange() const; void setName(const QString& name); QString name() const; void setProtected(bool isProtected); bool isPprotected() const; void setProtectionKey(const QString &password, const QString &protectionAlgorithmUri = QLatin1String("http://www.w3.org/2000/09/xmldsig#sha1")); QString protectionKey() const; QString protectionalgorithm() const; private: QVector m_columns; QVector m_rows; QMap, KoCell*> m_cells; int m_rowCount; int m_columnCount; KoTblStyle::Ptr m_style; // KoTableTemplate* m_template; // TableTemplateFlags m_templateFlags; bool m_printable; // CellRange m_printRange; QString m_name; bool m_protected; QString m_protectionKey; QString m_protectionAlgorithm; }; #endif diff --git a/filters/stage/pptx/PptxXmlSlideReader.h b/filters/stage/pptx/PptxXmlSlideReader.h index ace827b623c..1f8faca1c5b 100644 --- a/filters/stage/pptx/PptxXmlSlideReader.h +++ b/filters/stage/pptx/PptxXmlSlideReader.h @@ -1,361 +1,360 @@ /* * This file is part of Office 2007 Filters for Calligra * * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). * * Contact: Suresh Chande suresh.chande@nokia.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * */ #ifndef PPTXXMLSLIDEREADER_H #define PPTXXMLSLIDEREADER_H #include #include #include #include #include +#include class KoXmlWriter; class PptxXmlSlideReaderContext; class PptxImport; namespace MSOOXML { class MsooXmlRelationships; class TableStyleList; } -class KoTable; - //! Data structure collecting information about single slide's shape (p:sp) class PptxShapeProperties { public: PptxShapeProperties(); PptxShapeProperties(const PptxShapeProperties &other); PptxShapeProperties& operator=(const PptxShapeProperties &other); //! p:spPr/a:xfrm/a:off@x value in EMU int x; //! p:spPr/a:xfrm/a:off@y value in EMU int y; //! p:spPr/a:xfrm/a:ext@cx value in EMU int width; //! p:spPr/a:xfrm/a:ext@cy value in EMU int height; //! p:spPr/a:xfrm@rot value in 1/60,000th of a degree. int rot; }; //! Styles valid for current slide class PptxActualSlideProperties { public: //! Map of paragraph-styles with the styleId as outer-key and the listlevel as inner-key. QMap > styles; //! Map of text-styles with the styleId as outer-key and the listlevel as inner-key. QMap > textStyles; //! Map of list-styles with the styleId as outer-key and the listlevel as inner-key. QMap > listStyles; }; //! Properties of a single placeholder for shapes defined by layouts class PptxPlaceholder { public: PptxPlaceholder(); explicit PptxPlaceholder(const PptxShapeProperties &other); ~PptxPlaceholder(); int x; int y; int width; int height; int rot; }; //! Data structure collecting information about single layout/master class PptxSlideProperties { public: PptxSlideProperties(); ~PptxSlideProperties(); //! geometry type QMap contentTypeMap; //! geometry type QMap contentEquations; //! geometry type QMap contentPath; //! The presentation:presentation-page-layout-name QString pageLayoutStyleName; //! Map of paragraph-styles with the styleId as outer-key and the listlevel as inner-key. QMap > styles; //! Map of text-styles with the styleId as outer-key and the listlevel as inner-key. QMap > textStyles; //! Map of list-styles with the styleId as outer-key and the listlevel as inner-key. QMap > listStyles; //! Map of spPr based graphicStyles, these contain fillColor & outline QMap graphicStyles; //! Position of the text QMap textShapePositions; //! Possible text shrinkage QMap m_textAutoFit; //! Borders in the frame QMap textLeftBorders; QMap textRightBorders; QMap textBottomBorders; QMap textTopBorders; KoGenStyle m_drawingPageProperties; // Layout specific // Extras frames such as pictures from layout, which should be put to the slide. QVector layoutFrames; // Name of the slidemaster to be used with this layout QString m_slideMasterName; // Master specific MSOOXML::DrawingMLTheme theme; //! Shapes map addressed by type QMap shapesMap; QMap colorMap; // Temporary attribute providing the info that the color mapping changed // compared to the slideMaster. bool overrideClrMapping; private: }; //! A class reading MSOOXML PPTX markup - ppt/slides/slide*.xml part. class PptxXmlSlideReader : public MSOOXML::MsooXmlCommonReader { public: //! Mode of operation. enum Type { Slide, SlideLayout, SlideMaster, NotesMaster, Notes }; explicit PptxXmlSlideReader(KoOdfWriters *writers); virtual ~PptxXmlSlideReader(); //! Reads/parses the XML. virtual KoFilter::ConversionStatus read(MSOOXML::MsooXmlReaderContext* context = 0); protected: KoFilter::ConversionStatus read_titleStyle(); KoFilter::ConversionStatus read_notesStyle(); KoFilter::ConversionStatus read_bodyStyle(); KoFilter::ConversionStatus read_otherStyle(); KoFilter::ConversionStatus read_txStyles(); KoFilter::ConversionStatus readInternal(); KoFilter::ConversionStatus read_sld(); KoFilter::ConversionStatus read_notes(); KoFilter::ConversionStatus read_sldInternal(); KoFilter::ConversionStatus read_notesMaster(); KoFilter::ConversionStatus read_sldMaster(); //!< For SlideMaster mode KoFilter::ConversionStatus read_sldLayout(); //!< For SlideLayout mode KoFilter::ConversionStatus read_cSld(); KoFilter::ConversionStatus read_bg(); KoFilter::ConversionStatus read_bgPr(); KoFilter::ConversionStatus read_bgRef(); KoFilter::ConversionStatus read_spTree(); KoFilter::ConversionStatus read_nvPr(); KoFilter::ConversionStatus read_ph(); KoFilter::ConversionStatus read_txBody(); KoFilter::ConversionStatus read_graphicFrame(); KoFilter::ConversionStatus read_nvGraphicFramePr(); KoFilter::ConversionStatus read_controls(); KoFilter::ConversionStatus read_control(); KoFilter::ConversionStatus read_xfrm_p(); KoFilter::ConversionStatus read_cNvPr_p(); KoFilter::ConversionStatus read_oleObj(); KoFilter::ConversionStatus read_clrMap(); KoFilter::ConversionStatus read_clrMapOvr(); PptxXmlSlideReaderContext* m_context; PptxShapeProperties* m_currentShapeProperties; KoGenStyle m_currentMasterPageStyle; //!< set by read_sp() KoGenStyle m_currentPresentationPageLayoutStyle; //!< set by read_sp() for placeholders (KoGenStyle::PresentationPageLayoutStyle) KoGenStyle m_currentPresentationStyle; //!< KoGenStyle::PresentationAutoStyle KoXmlWriter* m_placeholderElWriter; // Saves current text and paragraph styles to slide(layout/master) memory where they // can be used later for inheritance purposes void saveCurrentStyles(); // Saves current list styles void saveCurrentListStyles(); // Saves outline & fill style void saveCurrentGraphicStyles(); // Copies 9 lvls of text and paragraph styles to current styles void inheritAllTextAndParagraphStyles(); // Inherits liststyle to m_currentCombinedBulletProperties void inheritListStyles(); // Inherits default styles to m_currentCombinedBulletProperties void inheritDefaultListStyles(); // inherits default text style to target void inheritDefaultTextStyle(KoGenStyle& targetStyle); // Inherits correct textstyle to m_currentTextStyle // First from default, then from master, layout, slide using those lvls which are needed void inheritTextStyle(KoGenStyle& targetStyle); // Inherits default paragraphStyle void inheritDefaultParagraphStyle(KoGenStyle& targetStyle); // Inherits correct paragraph styles to m_currentParagraphStyle void inheritParagraphStyle(KoGenStyle& targetStyle); // Inherit correct body properties from slideMaster/slideLayout if needed void inheritBodyProperties(); // Saves current body properties void saveBodyProperties(); // Saves current shape position etc. so that they can be used by slide/slideLayout KoFilter::ConversionStatus generatePlaceHolderSp(); // Inherits shape x, y, width etc. from slideLayout/slideMaster void inheritShapePosition(); // Inherits shapes geometry, fill color etc. from slideLayout/slideMaster void inheritShapeGeometry(); /** * MS PowerPoint specific calculation of the paragraph margin. * @param spcAft/spcBef (paragraph spacing) as provided in pptx [%] * @param minimum font size detected in the paragraph [point] * @return paragraph margin [point] */ qreal processParagraphSpacing(const qreal margin, const qreal fontSize); private: void saveBodyPropertiesHelper(const QString &id, PptxSlideProperties* slideProperties); void inheritBodyPropertiesHelper(const QString &id, PptxSlideProperties* slideProperties); void init(); class Private; Private* const d; bool m_showSlideLayoutShapes; #include #include #include }; //! Context for PptxXmlSlideReader class PptxXmlSlideReaderContext : public MSOOXML::MsooXmlReaderContext { public: //! Creates the context object. /*! @param _slideProperties is written for SlideMaster type and read for Slide type. */ PptxXmlSlideReaderContext( PptxImport& _import, const QString& _path, const QString& _file, uint _slideNumber, MSOOXML::DrawingMLTheme* _themes, PptxXmlSlideReader::Type _type, PptxSlideProperties* _slideLayoutProperties, PptxSlideProperties* _slideMasterProperties, PptxSlideProperties* _notesMasterProperties, MSOOXML::MsooXmlRelationships& _relationships, QMap _commentAuthors, QMap masterColorMap, VmlDrawingReader& _vmlReader, QString _tableStylesFilePath = QString()); PptxImport* import; const QString path; const QString file; const uint slideNumber; MSOOXML::DrawingMLTheme* themes; PptxXmlSlideReader::Type type; PptxSlideProperties* slideLayoutProperties; PptxSlideProperties* slideMasterProperties; PptxSlideProperties* notesMasterProperties; PptxActualSlideProperties currentSlideStyles; PptxActualSlideProperties currentNotesStyles; // There could potentially be multiple of these...todo QString pageDrawStyleName; //!< written in read_sldInternal() QVector pageFrames; //! Frames which go to masterslide QMap commentAuthors; VmlDrawingReader& vmlReader; // Used to keep track, whether we should skip elements. At the moment we // need to read some slides twice because some elements from the later part // of the document are needed to fully understand cSld element. bool firstReadingRound; // Temporary attribute providing the info that the color mapping changed // compared to the slideMaster. bool overrideClrMapping; void initializeContext(const MSOOXML::DrawingMLTheme& theme, const QVector& _defaultParagraphStyles, const QVector& _defaultTextStyles, const QVector& _defaultListStyles, const QVector& _defaultBulletColors, const QVector& _defaultTextColors, const QVector& _defaultLatinFonts); // Must be in context, because each slide/layout/master may overwrite the // color mapping and the default text colors have to be re-interpreted. QVector defaultTextStyles; QVector defaultParagraphStyles; QVector defaultListStyles; QVector defaultBulletColors; QVector defaultTextColors; QVector defaultLatinFonts; // We need to know where to find the table styles when needed QString tableStylesFilePath; }; #endif diff --git a/filters/words/docx/import/DocxXmlDocumentReader.cpp b/filters/words/docx/import/DocxXmlDocumentReader.cpp index 760349f6ccf..090d9532680 100644 --- a/filters/words/docx/import/DocxXmlDocumentReader.cpp +++ b/filters/words/docx/import/DocxXmlDocumentReader.cpp @@ -1,7375 +1,7374 @@ /* * This file is part of Office 2007 Filters for Calligra * * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). * Copyright (C) 2010 KoGmbh (cbo@kogmbh.com). * * Contact: Suresh Chande suresh.chande@nokia.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * */ #include "DocxXmlDocumentReader.h" #include "DocxXmlHeaderReader.h" #include "DocxXmlFooterReader.h" #include "DocxImport.h" #include "DocxDebug.h" #include #include #include #include #include #include #include #include #include #include #include #define MSOOXML_CURRENT_NS "w" #define MSOOXML_CURRENT_CLASS DocxXmlDocumentReader #define BIND_READ_CLASS MSOOXML_CURRENT_CLASS #define DOCXXMLDOCREADER_CPP //#define DOCXXML_DEBUG_TABLES #include #include #include #include #include #include #include namespace { class BorderMap : public QMap { public: BorderMap() { insert(QString(), KoBorder::BorderNone); insert("nil", KoBorder::BorderNone); insert("none", KoBorder::BorderSolid); insert("single", KoBorder::BorderSolid); insert("thick", KoBorder::BorderSolid); //FIXME find a better representation insert("double", KoBorder::BorderDouble); insert("dotted", KoBorder::BorderDotted); insert("dashed", KoBorder::BorderDashed); insert("dotDash", KoBorder::BorderDashDot); insert("dotDotDash", KoBorder::BorderDashDotDot); insert("triple", KoBorder::BorderDouble); //FIXME insert("thinThickSmallGap", KoBorder::BorderSolid); //FIXME insert("thickThinSmallGap", KoBorder::BorderSolid); //FIXME insert("thinThickThinSmallGap", KoBorder::BorderSolid); //FIXME insert("thinThickMediumGap", KoBorder::BorderSolid); //FIXME insert("thickThinMediumGap", KoBorder::BorderSolid); //FIXME insert("thinThickThinMediumGap", KoBorder::BorderSolid); //FIXME insert("thinThickLargeGap", KoBorder::BorderSolid); //FIXME insert("thickThinLargeGap", KoBorder::BorderSolid); //FIXME insert("thinThickThinLargeGap", KoBorder::BorderSolid); //FIXME insert("wave", KoBorder::BorderSolid); //FIXME insert("dobleWave", KoBorder::BorderSolid); //FIXME insert("dashSmallGap", KoBorder::BorderSolid); //FIXME insert("dashDotStroked", KoBorder::BorderSolid); //FIXME insert("threeDEmboss", KoBorder::BorderSolid); //FIXME insert("threeDEngrave", KoBorder::BorderSolid); //FIXME insert("outset", KoBorder::BorderOutset); insert("inset", KoBorder::BorderInset); } } borderMap; } DocxXmlDocumentReaderContext::DocxXmlDocumentReaderContext( DocxImport& _import, const QString& _path, const QString& _file, MSOOXML::MsooXmlRelationships& _relationships, MSOOXML::DrawingMLTheme* _themes) : MSOOXML::MsooXmlReaderContext(&_relationships), import(&_import), path(_path), file(_file), themes(_themes) { } // --------------------------------------------------------------------- class DocxXmlDocumentReader::Private { public: Private() { } ~Private() { } }; DocxXmlDocumentReader::DocxXmlDocumentReader(KoOdfWriters *writers) : MSOOXML::MsooXmlCommonReader(writers) , m_pDocBkgImageWriter(0) , m_writers(writers) , d(new Private) { init(); } DocxXmlDocumentReader::~DocxXmlDocumentReader() { if (m_pDocBkgImageWriter) { delete m_pDocBkgImageWriter->device(); delete m_pDocBkgImageWriter; } doneInternal(); // MsooXmlCommonReaderImpl.h delete d; delete m_dropCapWriter; m_dropCapWriter = 0; } void DocxXmlDocumentReader::init() { initInternal(); // MsooXmlCommonReaderImpl.h initDrawingML(); m_defaultNamespace = QLatin1String(MSOOXML_CURRENT_NS ":"); m_complexCharType = NoComplexFieldCharType; m_complexCharStatus = NoneAllowed; m_dropCapStatus = NoDropCap; m_dropCapWriter = 0; m_currentTableNumber = 0; m_wasCaption = false; m_closeHyperlink = false; m_listFound = false; m_insideParagraph = false; m_createSectionStyle = false; m_createSectionToNext = false; m_currentVMLProperties.insideGroup = false; m_outputFrames = true; m_currentNumId.clear(); m_prevListLevel = 0; qsrand(QTime::currentTime().msec()); } KoFilter::ConversionStatus DocxXmlDocumentReader::read(MSOOXML::MsooXmlReaderContext* context) { m_context = dynamic_cast(context); Q_ASSERT(m_context); m_createSectionStyle = true; debugDocx << "============================="; readNext(); if (!isStartDocument()) { return KoFilter::WrongFormat; } //w:document readNext(); debugDocx << *this << namespaceUri(); if (!expectEl("w:document")) { return KoFilter::WrongFormat; } if (!expectNS(MSOOXML::Schemas::wordprocessingml)) { return KoFilter::WrongFormat; } /* const QXmlStreamAttributes attrs( attributes() ); for (int i=0; ipos() / device()->size(); m_context->import->reportProgress(progress); counter = 0; } ++counter; TRY_READ_IF(p) ELSE_TRY_READ_IF(del) ELSE_TRY_READ_IF(ins) ELSE_TRY_READ_IF(sdt) ELSE_TRY_READ_IF(sectPr) ELSE_TRY_READ_IF(tbl) ELSE_TRY_READ_IF(bookmarkStart) ELSE_TRY_READ_IF(bookmarkEnd) SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL sectPr //! w:sectPr handler (Section Properties) /*! ECMA-376, 17.6.17, p. 667. Parent elements: - [done] body (§17.2.2) - docPartBody (§17.12.6) Chils elements: - [done] bidi (Right to Left Section Layout) §17.6.1 - [done] cols (Column Definitions) §17.6.4 - docGrid (Document Grid) §17.6.5 - [done] endnotePr (Section-Wide Endnote Properties) §17.11.5 - [done] footerReference (Footer Reference) §17.10.2 - [done] footnotePr (Section-Wide Footnote Properties) §17.11.11 - formProt (Only Allow Editing of Form Fields) §17.6.6 - [done] headerReference (Header Reference) §17.10.5 - [done] lnNumType (Line Numbering Settings) §17.6.8 - noEndnote (Suppress Endnotes In Document) §17.11.16 - paperSrc (Paper Source Information) §17.6.9 - [done] pgBorders (Page Borders) §17.6.10 - [done] pgMar (Page Margins) §17.6.11 - pgNumType (Page Numbering Settings) §17.6.12 - [done] pgSz (Page Size) §17.6.13 - printerSettings (Reference to Printer Settings Data) §17.6.14 - rtlGutter (Gutter on Right Side of Page) §17.6.16 - sectPrChange (Revision Information for Section Properties) §17.13.5.32 - [done] textDirection (Text Flow Direction) §17.6.20 - titlePg (Different First Page Headers and Footers) §17.10.6 - type (Section Type) §17.6.22 - vAlign (Vertical Text Alignment on Page) §17.6.23 */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_sectPr() { READ_PROLOGUE m_footerActive = false; m_headerActive = false; m_currentPageStyle = KoGenStyle(KoGenStyle::PageLayoutStyle); m_currentPageStyle.setAutoStyleInStylesDotXml(true); m_currentPageStyle.addProperty("style:writing-mode", "lr-tb"); //! @todo handle all valued of style:print-orientation m_currentPageStyle.addProperty("style:print-orientation", "portrait"); if (m_backgroundColor.isValid()) m_currentPageStyle.addProperty("fo:background-color", m_backgroundColor.name()); if (m_pDocBkgImageWriter) { QString contents = QString::fromUtf8(((QBuffer*)m_pDocBkgImageWriter->device())->buffer(), ((QBuffer*)m_pDocBkgImageWriter->device())->buffer().size()); m_currentPageStyle.addChildElement("0", contents); } m_masterPageStyle = KoGenStyle(KoGenStyle::MasterPageStyle); m_footers.clear(); m_headers.clear(); m_pageMargins.clear(); m_pageBorderStyles.clear(); m_pageBorderPaddings.clear(); m_pageBorderOffsetFrom = "text"; while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(pgSz) ELSE_TRY_READ_IF(pgMar) ELSE_TRY_READ_IF(pgBorders) ELSE_TRY_READ_IF(textDirection) ELSE_TRY_READ_IF(headerReference) ELSE_TRY_READ_IF(footerReference) ELSE_TRY_READ_IF(cols) ELSE_TRY_READ_IF(footnotePr) ELSE_TRY_READ_IF(endnotePr) ELSE_TRY_READ_IF(lnNumType) else if (name() == "bidi") { m_currentPageStyle.addProperty("style:writing-mode", "rl-tb"); } SKIP_UNKNOWN } } applyPageBorders(m_currentPageStyle, m_pageMargins, m_pageBorderStyles, m_pageBorderPaddings, m_pageBorderOffsetFrom); // Currently if there are 3 header/footer styles, the one with 'first' is ignored bool useEvenAndOddHeaders = false; if (m_context->import->documentSettings().contains("evenAndOddHeaders")) { QString val = m_context->import->documentSettings()["evenAndOddHeaders"].toString(); useEvenAndOddHeaders = (val != "off" && val != "0" && val != "false"); } // the numbering in addChildElement is needed to correctly sort the element when writing out the values. if (!m_headers.isEmpty()) { bool odd = false; if (useEvenAndOddHeaders && !m_headers["even"].isEmpty()) { m_masterPageStyle.addChildElement("2 style:header-left", m_headers["even"]); } if (!m_headers["default"].isEmpty()) { odd = true; m_masterPageStyle.addChildElement("1 style:header", m_headers["default"]); } if (!odd) { m_masterPageStyle.addChildElement("1 style:header", m_headers["first"]); } } if (!m_footers.isEmpty()) { bool odd = false; if (useEvenAndOddHeaders && !m_footers["even"].isEmpty()) { m_masterPageStyle.addChildElement("4 style:footer-left", m_footers["even"]); } if (!m_footers["default"].isEmpty()) { odd = true; m_masterPageStyle.addChildElement("3 style:footer", m_footers["default"]); } if (!odd) { m_masterPageStyle.addChildElement("3 style:footer", m_footers["first"]); } } QString pageLayoutStyleName("Mpm"); pageLayoutStyleName = mainStyles->insert(m_currentPageStyle, pageLayoutStyleName); QString masterStyleName("Standard"); //! @todo style:display-name // masterStyle->addAttribute("style:display-name", masterStyleName); m_masterPageStyle.addAttribute("style:page-layout-name", pageLayoutStyleName); QString currentMasterPageName = mainStyles->insert(m_masterPageStyle, masterStyleName); // Because sectPr is always in the last bit of a section, it means that next paragraph/whatever // Needs to have a style which is modified by next sectPr m_createSectionToNext = true; KoGenStyle *sectionStyle = mainStyles->styleForModification(m_currentSectionStyleName, m_currentSectionStyleFamily); // There might not be a style to modify if the document is completely empty if (sectionStyle) { sectionStyle->addAttribute("style:master-page-name", currentMasterPageName); } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL pgSz //! w:pgSz handler (Page Size) /*! ECMA-376, 17.6.13, p. 655. Parent elements: - [done] sectPr (§17.6.17) - [done] sectPr (§17.6.18) - [done] sectPr (§17.6.19) No child elements. */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_pgSz() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(w) if (!w.isEmpty()) { const QString s(MSOOXML::Utils::TWIP_to_ODF(w)); if (!s.isEmpty()) { m_currentPageStyle.addProperty("fo:page-width", s); } } TRY_READ_ATTR(h) if (!h.isEmpty()) { const QString s(MSOOXML::Utils::TWIP_to_ODF(h)); if (!s.isEmpty()) { m_currentPageStyle.addProperty("fo:page-height", s); } } TRY_READ_ATTR(orient) if (!orient.isEmpty()) { m_currentPageStyle.addProperty("style:print-orientation", orient); } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL textDirection //! w:textDirection handler (Text Direction) /*! Parent elements: - [done] sectPr (§17.6.17) - [done] sectPr (§17.6.18) - [done] sectPr (§17.6.19) No child elements. */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_textDirection() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) if (!val.isEmpty() && val.size() == 4) { const QString left = val.left(2).toLower(); const QString right = val.right(2).toLower(); m_currentPageStyle.addProperty("style:writing-mode", left + '-' + right); } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL pgMar //! w:pgMar handler (Page Margins) /*! ECMA-376, 17.6.11, p. 649. Parent elements: - [done] sectPr (§17.6.17) - [done] sectPr (§17.6.18) - [done] sectPr (§17.6.19) No child elements. */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_pgMar() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(right) if (!right.isEmpty()) { int rightNum = 0; STRING_TO_INT(right, rightNum, QString("w:right")); m_pageMargins.insert(MarginRight,TWIP_TO_POINT(rightNum)); } TRY_READ_ATTR(left) if (!left.isEmpty()) { int leftNum = 0; STRING_TO_INT(left, leftNum, QString("w:left")); m_pageMargins.insert(MarginLeft,TWIP_TO_POINT(leftNum)); } TRY_READ_ATTR(footer) TRY_READ_ATTR(header) TRY_READ_ATTR(top) TRY_READ_ATTR(bottom) int topNum = 0; int bottomNum = 0; int headerNum = 0; int footerNum = 0; topNum = top.toInt(); bottomNum = bottom.toInt(); headerNum = header.toInt(); footerNum = footer.toInt(); if (!m_headerActive) { m_pageMargins.insert(MarginTop, TWIP_TO_POINT(topNum)); } else { m_pageMargins.insert(MarginTop, TWIP_TO_POINT(headerNum)); } if (!m_footerActive) { m_pageMargins.insert(MarginBottom, TWIP_TO_POINT(bottomNum)); } else { m_pageMargins.insert(MarginBottom, TWIP_TO_POINT(footerNum)); } QBuffer headerBuffer; headerBuffer.open( QIODevice::WriteOnly ); KoXmlWriter headerWriter(&headerBuffer, 3); headerWriter.startElement("style:header-style"); headerWriter.startElement("style:header-footer-properties"); headerWriter.addAttribute("style:dynamic-spacing", "true"); if (m_headerActive) { if (topNum > headerNum) { headerWriter.addAttributePt("fo:min-height", TWIP_TO_POINT(topNum - headerNum)); } } headerWriter.endElement(); // style:header-footer-properties headerWriter.endElement(); // style:header-style QString headerContents = QString::fromUtf8(headerBuffer.buffer(), headerBuffer.buffer().size() ); // the style elements need to be sorted correctly so that the created odf is valid // therefore we use footer-header-style-1 and footer-header-style-2 to sort header before footer m_currentPageStyle.addStyleChildElement("footer-header-style-1", headerContents); QBuffer footerBuffer; footerBuffer.open( QIODevice::WriteOnly ); KoXmlWriter footerWriter(&footerBuffer, 3); footerWriter.startElement("style:footer-style"); footerWriter.startElement("style:header-footer-properties"); footerWriter.addAttribute("style:dynamic-spacing", "true"); if (m_footerActive) { if (bottomNum > footerNum) { footerWriter.addAttributePt("fo:min-height", TWIP_TO_POINT(bottomNum - footerNum)); } } footerWriter.endElement(); // style:header-footer-properties footerWriter.endElement(); // style:footer-style QString footerContents = QString::fromUtf8(footerBuffer.buffer(), footerBuffer.buffer().size() ); m_currentPageStyle.addStyleChildElement("footer-header-style-2", footerContents); readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL pict //! pict handler (VML Object) /*! ECMA-376 Part 4, 9.2.2.2, p.31. This element specifies that an object is located at this position in the run’s contents. The layout properties of this object are specified using the VML syntax (§14.1). Parent elements: - r (Part 1, §22.1.2.87) - Shared ML - [done] r (Part 1, §17.3.2.25) - Shared ML Child elements: - control (Floating Embedded Control) §9.2.2.1 - movie (Embedded Video) Part 1, §17.3.3.17 - Any element in the urn:schemas-microsoft-com:vml namespace §14.1 - Any element in the urn:schemas-microsoft-com:office:office namespace §14.2 */ //! @todo support all elements KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_pict() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF_NS(v, rect) ELSE_TRY_READ_IF_NS(v, roundrect) ELSE_TRY_READ_IF_NS(v, shapetype) ELSE_TRY_READ_IF_NS(v, shape) ELSE_TRY_READ_IF_NS(v, group) ELSE_TRY_READ_IF_NS(v, oval) ELSE_TRY_READ_IF_NS(v, line) SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL footerReference //! w:footerReference handler (Footer Reference) /*! Parent elements: - [done] sectPr (§17.6.17) - [done] sectPr (§17.6.8) Child elements: - None */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_footerReference() { READ_PROLOGUE m_footerActive = true; const QXmlStreamAttributes attrs(attributes()); QString link_target; TRY_READ_ATTR_WITH_NS(r, id) if (r_id.isEmpty()) { link_target.clear(); } else { link_target = m_context->relationships->target(m_context->path, m_context->file, r_id); } DocxXmlFooterReader reader(this); QString errorMessage; MSOOXML::MsooXmlRelationships relationships(*m_context->import, m_writers, errorMessage); QString fileName = link_target; fileName.remove(0, m_context->path.length()); DocxXmlDocumentReaderContext context(*m_context->import, m_context->path, fileName, relationships, m_context->themes); context.m_tableStyles = m_context->m_tableStyles; context.m_bulletStyles = m_context->m_bulletStyles; context.m_namedDefaultStyles = m_context->m_namedDefaultStyles; const KoFilter::ConversionStatus status = m_context->import->loadAndParseDocument(&reader, link_target, errorMessage, &context); if (status != KoFilter::OK) { reader.raiseError(errorMessage); } QString footerContent; TRY_READ_ATTR(type) if (!type.isEmpty()) { if (type == "even") { footerContent = ""; footerContent.append(reader.content()); footerContent.append(""); } else { footerContent = ""; footerContent.append(reader.content()); footerContent.append(""); } m_footers[type] = footerContent; } else { footerContent = ""; footerContent.append(reader.content()); footerContent.append(""); m_footers["default"] = footerContent; } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL headerReference //! w:headerReference handler (Header Reference) /*! Parent elements: - [done] sectPr (§17.6.17) - [done] sectPr (§17.6.8) Child elements: - None */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_headerReference() { READ_PROLOGUE m_headerActive = true; const QXmlStreamAttributes attrs(attributes()); QString link_target; TRY_READ_ATTR_WITH_NS(r, id) if (r_id.isEmpty()) { link_target.clear(); } else { link_target = m_context->relationships->target(m_context->path, m_context->file, r_id); } DocxXmlHeaderReader reader(this); QString errorMessage; MSOOXML::MsooXmlRelationships relationships(*m_context->import, m_writers, errorMessage); QString fileName = link_target; fileName.remove(0, m_context->path.length()); DocxXmlDocumentReaderContext context(*m_context->import, m_context->path, fileName, relationships, m_context->themes); context.m_tableStyles = m_context->m_tableStyles; context.m_bulletStyles = m_context->m_bulletStyles; context.m_namedDefaultStyles = m_context->m_namedDefaultStyles; const KoFilter::ConversionStatus status = m_context->import->loadAndParseDocument(&reader, link_target, errorMessage, &context); if (status != KoFilter::OK) { reader.raiseError(errorMessage); } QString headerContent; TRY_READ_ATTR(type) if (!type.isEmpty()) { if (type == "even") { headerContent = ""; headerContent.append(reader.content()); headerContent.append(""); } else { headerContent = ""; headerContent.append(reader.content()); headerContent.append(""); } m_headers[type] = headerContent; } else { headerContent = ""; headerContent.append(reader.content()); headerContent.append(""); m_headers["default"] = headerContent; } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL lnNumType //! w:lnNumType handler (Line Numbering type) /* Parents elements: - [done] sectPr (§17.6.17) - [done] sectPr (§17.6.18) - [done] sectPr (§17.6.19) Child elements: - none */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_lnNumType() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(countBy) //TRY_READ_ATTR(restart) //TRY_READ_ATTR(start) QBuffer buffer; KoXmlWriter temp(&buffer); temp.startElement("text:linenumbering-configuration"); // These should maybe be somehow determined from attributes temp.addAttribute("text:number-position", "left"); temp.addAttribute("style:num-format", "1"); temp.addAttribute("text:offset", "0.1965in"); if (!countBy.isEmpty()) { temp.addAttribute("text:increment", countBy); } temp.endElement(); // text:linenumbering-configuration QString lineStyle = QString::fromUtf8(buffer.buffer(), buffer.buffer().size()); mainStyles->insertRawOdfStyles(KoGenStyles::DocumentStyles, lineStyle.toUtf8()); readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL endnotePr //! w:endonotePr handler (Endnote properties) /* Parent elements: - [done] sectPr (§17.6.17) - [done] sectPr (§17.6.18) - [done] sectPr (§17.6.19) Child elements: - [done] numFmt (Footnote Numbering Format) §17.11.18 - [done] numRestart (Footnote and Endnote Numbering Restart Location) §17.11.19 - [done] numStart (Footnote and Endnote Numbering Starting Value) §17.11.20 - pos (Footnote Placement) §17.11.21 */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_endnotePr() { READ_PROLOGUE MSOOXML::Utils::XmlWriteBuffer endBuf; body = endBuf.setWriter(body); body->startElement("text:notes-configuration"); body->addAttribute("text:note-class", "endnote"); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(numFmt) ELSE_TRY_READ_IF(numRestart) ELSE_TRY_READ_IF(numStart) SKIP_UNKNOWN } } body->endElement(); // text:notes-configuration QString endStyle; body = endBuf.releaseWriter(endStyle); mainStyles->insertRawOdfStyles(KoGenStyles::DocumentStyles, endStyle.toUtf8()); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL footnotePr //! w:footnotePr handler (Footnote properties) /* Parent elements: - [done] sectPr (§17.6.17) - [done] sectPr (§17.6.18) - [done] sectPr (§17.6.19) Child elements: - [done] numFmt (Footnote Numbering Format) §17.11.18 - [done] numRestart (Footnote and Endnote Numbering Restart Location) §17.11.19 - [done] numStart (Footnote and Endnote Numbering Starting Value) §17.11.20 - [done] pos (Footnote Placement) §17.11.21 */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_footnotePr() { READ_PROLOGUE MSOOXML::Utils::XmlWriteBuffer footBuf; body = footBuf.setWriter(body); body->startElement("text:notes-configuration"); body->addAttribute("text:note-class", "footnote"); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(numFmt) ELSE_TRY_READ_IF(numRestart) ELSE_TRY_READ_IF(numStart) ELSE_TRY_READ_IF(pos) SKIP_UNKNOWN } } body->endElement(); // text:notes-configuration QString footStyle; body = footBuf.releaseWriter(footStyle); mainStyles->insertRawOdfStyles(KoGenStyles::DocumentStyles, footStyle.toUtf8()); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL numFmt //! numFmt handler (Footnote Numbering format) /* Parent elements: - [done] endnotePr (§17.11.4) - [done] endnotePr (§17.11.5) - [done] footnotePr (§17.11.12) - [done] footnotePr (§17.11.11) Child elements: - none */ //! @todo support all attributes KoFilter::ConversionStatus DocxXmlDocumentReader::read_numFmt() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) if (!val.isEmpty()) { if (val == "upperLetter") { body->addAttribute("style:num-format", "A"); } else if (val == "lowerLetter") { body->addAttribute("style:num-format", "a"); } else if (val == "upperRoman") { body->addAttribute("style:num-format", "I"); } else if (val == "lowerRoman") { body->addAttribute("style:num-format", "i"); } else if (val == "none") { body->addAttribute("style:num-format", ""); } else { body->addAttribute("style:num-format", "1"); } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL numRestart //! numRestart (Footnote and Endnote Numbering Restart Location) /* Parent elements: - [done] endnotePr (§17.11.4) - [done] endnotePr (§17.11.5) - [done] footnotePr (§17.11.12) - [done] footnotePr (§17.11.11) Child elements: - none */ //! @todo support all attributes KoFilter::ConversionStatus DocxXmlDocumentReader::read_numRestart() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) if (!val.isEmpty()) { if (val == "eachPage") { body->addAttribute("text:start-numbering-at", "page"); } else if (val == "eachSect") { body->addAttribute("text:start-numbering-at", "chapter"); } else { //continuous body->addAttribute("text:start-numbering-at", "document"); } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL numStart //! numStart (Footnote and Endnote Numbering Starting Value) /* Parent elements: - [done] endnotePr (§17.11.4) - [done] endnotePr (§17.11.5) - [done] footnotePr (§17.11.12) - [done] footnotePr (§17.11.11) Child elements: - none */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_numStart() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) if (!val.isEmpty()) { body->addAttribute("text:start-value", val); } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL pos //! pos (Footnote Placement) /* Parent elements: - [not applicable] endnotePr (§17.11.4) - [not applicable] endnotePr (§17.11.5) - [done] footnotePr (§17.11.12) - [done] footnotePr (§17.11.11) Child elements: - none */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_pos() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) if (!val.isEmpty()) { if (val == "beneathText") { body->addAttribute("text:footnotes-position", "text"); } else if (val == "docEnd") { body->addAttribute("text:footnotes-position", "document"); } else if (val == "sectEnd") { body->addAttribute("text:footnotes-position", "section"); } else { // pageBottom body->addAttribute("text:footnotes-position", "page"); } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL cols //! w:cols handler (Column definitions) /* Parents elements: - [done] sectPr (§17.6.17) - [done] sectPr (§17.6.18) - [done] sectPr (§17.6.19) Child Elements: - col (Single Column Definition) §17.6.3 */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_cols() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(num) TRY_READ_ATTR(space) QBuffer columnBuffer; KoXmlWriter columnWriter(&columnBuffer); columnWriter.startElement("style:columns"); if (!num.isEmpty()) { columnWriter.addAttribute("fo:column-count", num); } if (!space.isEmpty()) { bool ok; const qreal distance = qreal(TWIP_TO_POINT(space.toDouble(&ok))); if (ok) { columnWriter.addAttributePt("fo:column-gap", distance); } } while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { } } columnWriter.endElement(); // style:columns; const QString elementContents = QString::fromUtf8(columnBuffer.buffer(), columnBuffer.buffer().size()); if (!num.isEmpty()) { m_currentPageStyle.addChildElement("style:columns", elementContents); } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL pgBorders //! w:pgBorders handler (Page Borders) /*! ECMA-376, 17.6.10, p. 646. Parent elements: - [done] sectPr (§17.6.17) - [done] sectPr (§17.6.18) - [done] sectPr (§17.6.19) Child elements: - [done] bottom (Bottom Border) §17.6.2 - [done] left (Left Border) §17.6.7 - [done] right (Right Border) §17.6.15 - [done] top (Top Border) §17.6.21 */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_pgBorders() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(offsetFrom) m_pageBorderOffsetFrom = offsetFrom; while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { if (QUALIFIED_NAME_IS(top)) { RETURN_IF_ERROR(readBorderElement(TopBorder, "top", m_pageBorderStyles, m_pageBorderPaddings)); } else if (QUALIFIED_NAME_IS(left)) { RETURN_IF_ERROR(readBorderElement(LeftBorder, "left", m_pageBorderStyles, m_pageBorderPaddings)); } else if (QUALIFIED_NAME_IS(bottom)) { RETURN_IF_ERROR(readBorderElement(BottomBorder, "bottom", m_pageBorderStyles, m_pageBorderPaddings)); } else if (QUALIFIED_NAME_IS(right)) { RETURN_IF_ERROR(readBorderElement(RightBorder, "right", m_pageBorderStyles, m_pageBorderPaddings)); } ELSE_WRONG_FORMAT } } READ_EPILOGUE } void DocxXmlDocumentReader::applyBorders(KoGenStyle *style, QMap sourceBorder, QMap sourcePadding) { const QString topBorder = sourceBorder.value(TopBorder,QString()); const QString leftBorder = sourceBorder.value(LeftBorder,QString()); const QString bottomBorder = sourceBorder.value(BottomBorder,QString()); const QString rightBorder = sourceBorder.value(RightBorder,QString()); if (!topBorder.isEmpty() && leftBorder == topBorder && bottomBorder == topBorder && rightBorder == topBorder) { style->addProperty("fo:border", topBorder); // all sides the same } else { if (!topBorder.isEmpty()) { style->addProperty("fo:border-top", topBorder); } if (!leftBorder.isEmpty()) { style->addProperty("fo:border-left", leftBorder); } if (!bottomBorder.isEmpty()) { style->addProperty("fo:border-bottom", bottomBorder); } if (!rightBorder.isEmpty()) { style->addProperty("fo:border-right", rightBorder); } } sourceBorder.clear(); const qreal topPadding = sourcePadding.value(TopBorder); const qreal leftPadding = sourcePadding.value(LeftBorder); const qreal bottomPadding = sourcePadding.value(BottomBorder); const qreal rightPadding = sourcePadding.value(RightBorder); if (sourcePadding.contains(TopBorder) && leftPadding == topPadding && bottomPadding == topPadding && rightPadding == topPadding) { style->addPropertyPt("fo:padding", topPadding); // all sides the same } else { if (sourcePadding.contains(TopBorder)) { style->addPropertyPt("fo:padding-top", topPadding); } if (sourcePadding.contains(LeftBorder)) { style->addPropertyPt("fo:padding-left", leftPadding); } if (sourcePadding.contains(BottomBorder)) { style->addPropertyPt("fo:padding-bottom", bottomPadding); } if (sourcePadding.contains(RightBorder)) { style->addPropertyPt("fo:padding-right", rightPadding); } } sourcePadding.clear(); } void DocxXmlDocumentReader::applyPageBorders(KoGenStyle &style, QMap &pageMargins, QMap &pageBorder, QMap &pagePadding, QString & offsetFrom) { if (pageMargins.contains(MarginTop)) { if (pagePadding.contains(TopBorder)) { qreal margin = pageMargins.value(MarginTop); qreal padding = pagePadding.value(TopBorder); if(offsetFrom == "page") { style.addPropertyPt("fo:margin-top", padding); style.addPropertyPt("fo:padding-top", margin - padding); } else { style.addPropertyPt("fo:margin-top", margin - padding); style.addPropertyPt("fo:padding-top", padding); } } else { style.addPropertyPt("fo:margin-top", pageMargins.value(MarginTop)); } } if (pageMargins.contains(MarginBottom)) { if (pagePadding.contains(BottomBorder)) { qreal margin = pageMargins.value(MarginBottom); qreal padding = pagePadding.value(BottomBorder); if(offsetFrom == "page") { style.addPropertyPt("fo:margin-bottom", padding); style.addPropertyPt("fo:padding-bottom", margin - padding); } else { style.addPropertyPt("fo:margin-bottom", margin - padding); style.addPropertyPt("fo:padding-bottom", padding); } } else { style.addPropertyPt("fo:margin-bottom", pageMargins.value(MarginBottom)); } } if (pageMargins.contains(MarginLeft)) { if (pagePadding.contains(LeftBorder)) { qreal margin = pageMargins.value(MarginLeft); qreal padding = pagePadding.value(LeftBorder); if(offsetFrom == "page") { style.addPropertyPt("fo:margin-left", padding); style.addPropertyPt("fo:padding-left", margin - padding); } else { style.addPropertyPt("fo:margin-left", margin - padding); style.addPropertyPt("fo:padding-left", padding); } } else { style.addPropertyPt("fo:margin-left", pageMargins.value(MarginLeft)); } } if (pageMargins.contains(MarginRight)) { if (pagePadding.contains(RightBorder)) { qreal margin = pageMargins.value(MarginRight); qreal padding = pagePadding.value(RightBorder); if(offsetFrom == "page") { style.addPropertyPt("fo:margin-right", padding); style.addPropertyPt("fo:padding-right", margin - padding); } else { style.addPropertyPt("fo:margin-right", margin - padding); style.addPropertyPt("fo:padding-right", padding); } } else { style.addPropertyPt("fo:margin-right", pageMargins.value(MarginRight)); } } pageMargins.clear(); pagePadding.clear(); const QString topBorder = pageBorder.value(TopBorder,QString()); const QString leftBorder = pageBorder.value(LeftBorder,QString()); const QString bottomBorder = pageBorder.value(BottomBorder,QString()); const QString rightBorder = pageBorder.value(RightBorder,QString()); if (!topBorder.isEmpty() && leftBorder == topBorder && bottomBorder == topBorder && rightBorder == topBorder) { style.addProperty("fo:border", topBorder); // all sides the same } else { if (!topBorder.isEmpty()) { style.addProperty("fo:border-top", topBorder); } if (!leftBorder.isEmpty()) { style.addProperty("fo:border-left", leftBorder); } if (!bottomBorder.isEmpty()) { style.addProperty("fo:border-bottom", bottomBorder); } if (!rightBorder.isEmpty()) { style.addProperty("fo:border-right", rightBorder); } } pageBorder.clear(); } //! Converts 17.18.2 ST_Border (Border Styles, p. 1462, 4357) value to W3C CSS2 border-style value //! @see http://www.w3.org/TR/CSS2/box.html#value-def-border-style //! @see http://www.w3.org/TR/CSS2/box.html#value-def-border-width static QString ST_Border_to_ODF(const QString& s) { if (s == "nil" || s == "none" || s.isEmpty()) return QString(); else if (s == "thick") return QLatin1String("solid thick"); else if (s == "single") return QLatin1String("solid"); else if (s == "dashed" || s == "dotted" || s == "double") return s; return QLatin1String("solid"); } KoFilter::ConversionStatus DocxXmlDocumentReader::readBorderElement(BorderSide borderSide, const char *borderSideName, QMap &sourceBorder, QMap &sourcePadding) { const QXmlStreamAttributes attrs(attributes()); READ_ATTR(val) TRY_READ_ATTR(sz) TRY_READ_ATTR(color) createBorderStyle(sz, color, val, borderSide, sourceBorder); TRY_READ_ATTR(space) if (!space.isEmpty()) { int sp; STRING_TO_INT(space, sp, QString("w:%1@space").arg(borderSideName)); sourcePadding.insertMulti(borderSide, sp); } readNext(); return KoFilter::OK; } void DocxXmlDocumentReader::createBorderStyle(const QString& size, const QString& color, const QString& lineStyle, BorderSide borderSide, QMap &sourceBorder) { const QString odfLineStyle(ST_Border_to_ODF(lineStyle)); if (odfLineStyle.isEmpty()) return; QString border; if (!size.isEmpty()) border += MSOOXML::Utils::ST_EighthPointMeasure_to_ODF(size) + ' '; border.append(odfLineStyle + ' '); if (!color.isEmpty()) { if (color == "auto") { // The documentation for auto value says that it leaves the color up to the application // to decide, here we make a decision to use window color text MSOOXML::DrawingMLColorSchemeItemBase *colorItem = 0; colorItem = m_context->themes->colorScheme.value("dk1"); QColor col = Qt::black; if (colorItem) { col = colorItem->value(); } border.append(col.name()); } else { border.append('#'); border.append(color); } } else { border.append(QLatin1String("#000000")); } sourceBorder.insertMulti(borderSide,border); } #undef CURRENT_EL #define CURRENT_EL object //! object handler (Embedded Object) /*! ECMA-376, 17.3.3.19, p.371. */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_object() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(dxaOrig) m_currentObjectWidthCm = MSOOXML::Utils::ST_TwipsMeasure_to_cm(dxaOrig); TRY_READ_ATTR(dyaOrig) m_currentObjectHeightCm = MSOOXML::Utils::ST_TwipsMeasure_to_cm(dyaOrig); // Protecting in case the object is inside a textbox inside a shape VMLShapeProperties oldProperties = m_currentVMLProperties; while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF_NS(v, shapetype) else if (name() == "shape") { m_outputFrames = false; TRY_READ(shape) m_outputFrames = true; } ELSE_TRY_READ_IF_NS(o, OLEObject) ELSE_TRY_READ_IF(control) SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } m_currentVMLProperties = oldProperties; READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL commentRangeStart //! commentRangeStart handler /*! Parent elements: - bdo (§17.3.2.3) - body (§17.2.2) - comment (§17.13.4.2) - customXml (§17.5.1.6) - customXml (§17.5.1.4) - customXml (§17.5.1.5) - customXml (§17.5.1.3) - deg (§22.1.2.26) - del (§17.13.5.14) - den (§22.1.2.28) - dir (§17.3.2.8) - docPartBody (§17.12.6) - e (§22.1.2.32) - endnote (§17.11.2) - fldSimple (§17.16.19) - fName (§22.1.2.37) - footnote (§17.11.10) - ftr (§17.10.3) - hdr (§17.10.4) - hyperlink (§17.16.22) - ins (§17.13.5.18) - lim (§22.1.2.52) - moveFrom (§17.13.5.22) - moveTo (§17.13.5.25) - num (§22.1.2.75) - oMath (§22.1.2.77) - [done] p (§17.3.1.22) - rt (§17.3.3.24) - rubyBase (§17.3.3.27) - sdtContent (§17.5.2.34) - sdtContent (§17.5.2.33) - sdtContent (§17.5.2.35) - sdtContent (§17.5.2.36) - [done] smartTag (§17.5.1.9) - sub (§22.1.2.112) - sup (§22.1.2.114) - tbl (§17.4.38) - tc (§17.4.66) - tr (§17.4.79) Child elements: - none */ //! @todo support all attributes etc. KoFilter::ConversionStatus DocxXmlDocumentReader::read_commentRangeStart() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); READ_ATTR(id) body->startElement("office:annotation"); body->addCompleteElement(m_context->m_comments[id].toUtf8()); body->endElement(); // office:annotation readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL endnoteReference //! endnoteReference handler /*! Parent elements: - [done] r (§17.3.2.25) - [done] r (§22.1.2.87) Child elements: - none */ //! @todo support all attributes etc. KoFilter::ConversionStatus DocxXmlDocumentReader::read_endnoteReference() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); READ_ATTR(id) // # example endnote from odt document converted with OpenOffice // // 1 // // // studies // // // body->startElement("text:note"); body->addAttribute("text:id", QString("endn").append(id)); body->addAttribute("text:note-class", "endnote"); body->startElement("text:note-citation"); // NOTE: This line is meaningless in the sense that office // programs are supposed to autogenerate the value based on the // footnote style, it is hardcoded for the moment as calligra has // no support for it. body->addTextSpan(id); body->endElement(); // text:note-citation body->startElement("text:note-body"); body->addCompleteElement(m_context->m_endnotes[id].toUtf8()); body->endElement(); // text:note-body body->endElement(); // text:note readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL footnoteReference //! footnoteReference handler /*! Parent elements: - [done] r (§17.3.2.25) - [done] r (§22.1.2.87) Child elements: - none */ //! @todo support all attributes etc. KoFilter::ConversionStatus DocxXmlDocumentReader::read_footnoteReference() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); READ_ATTR(id) // # example endnote from odt document converted with OpenOffice // // 1 // // // studies // // // body->startElement("text:note"); body->addAttribute("text:id", QString("ftn").append(id)); body->addAttribute("text:note-class", "footnote"); body->startElement("text:note-citation"); // NOTE: This line is meaningless in the sense that office // programs are supposed to autogenerate the value based on the // footnote style, it is hardcoded for the moment as calligra has // no support for it. body->addTextSpan(id); body->endElement(); // text:note-citation body->startElement("text:note-body"); body->addCompleteElement(m_context->m_footnotes[id].toUtf8()); body->endElement(); // text:note-body body->endElement(); // text:note readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL fldChar //! fldChar handler /*! Complex field character Parent elements: - [done] r (§17.3.2.25) - [done] r (§22.1.2.87) Child elements: - ffData (Form Field Properties) §17.16.17 */ //! @todo support all attributes etc. KoFilter::ConversionStatus DocxXmlDocumentReader::read_fldChar() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(fldCharType) if (!fldCharType.isEmpty()) { if (fldCharType == "begin") { m_complexCharStatus = InstrAllowed; } else if (fldCharType == "separate") { m_complexCharStatus = InstrExecute; } else if (fldCharType == "end") { m_complexCharStatus = NoneAllowed; m_complexCharType = NoComplexFieldCharType; m_complexCharValue.clear(); } } while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL); } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL br //! br handler /* Parent elements: - [done] r (§17.3.2.25) - [done] r (§22.1.2.87) */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_br() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(type) if (type == "column") { m_currentParagraphStyle.addProperty("fo:break-before", "column"); } else if (type == "page") { m_currentParagraphStyle.addProperty("fo:break-before", "page"); } else { body->startElement("text:line-break"); body->endElement(); } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL lastRenderedPageBreak //! lastRenderedPageBreak handler /* Parent elements: - [done] r (§17.3.2.25) - [done] r (§22.1.2.87) */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_lastRenderedPageBreak() { READ_PROLOGUE body->startElement("text:soft-page-break"); body->endElement(); // text:soft-page-break readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL instrText //! instrText handler /* Parent elements: - [done] r (§17.3.2.25) - [done] r (§22.1.2.87) */ //! @todo support all attributes etc. KoFilter::ConversionStatus DocxXmlDocumentReader::read_instrText() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (m_complexCharStatus == InstrAllowed) { QString instruction = text().toString().trimmed(); if (instruction.startsWith(QLatin1String("HYPERLINK"))) { // Removes hyperlink, spaces and extra " chars instruction.remove(0, 11); instruction.truncate(instruction.size() - 1); m_complexCharType = HyperlinkComplexFieldCharType; m_complexCharValue = instruction; } else if (instruction.startsWith(QLatin1String("PAGEREF"))) { instruction.remove(0, 8); // removes PAGEREF m_complexCharType = ReferenceComplexFieldCharType; m_complexCharValue = instruction.left(instruction.indexOf(' ')); } else if (instruction.startsWith(QLatin1String("GOTOBUTTON"))) { instruction.remove(0, 12); // removes GOTOBUTTON m_complexCharType = InternalHyperlinkComplexFieldCharType; m_complexCharValue = instruction; } else if (instruction.startsWith(QLatin1String("MACROBUTTON"))) { m_complexCharType = MacroButtonFieldCharType; m_complexCharValue = '['; } else { m_complexCharValue = instruction; } } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL hyperlink //! hyperlink handler (Hyperlink) /*! ECMA-376, 17.3.3.31, p.1431. Parent elements: - bdo (§17.3.2.3) - customXml (§17.5.1.3) - dir (§17.3.2.8) - [done] fldSimple (§17.16.19) - [done] hyperlink (§17.16.22) - [done] p (§17.3.1.22) - [done] sdtContent (§17.5.2.36) - [done] smartTag (§17.5.1.9) Child elements: - bdo (Bidirectional Override) §17.3.2.3 - [done] bookmarkEnd (Bookmark End) §17.13.6.1 - [done] bookmarkStart (Bookmark Start) §17.13.6.2 - commentRangeEnd (Comment Anchor Range End) §17.13.4.3 - commentRangeStart (Comment Anchor Range Start) §17.13.4.4 - customXml (Inline-Level Custom XML Element) §17.5.1.3 - customXmlDelRangeEnd (Custom XML Markup Deletion End) §17.13.5.4 - customXmlDelRangeStart (Custom XML Markup Deletion Start) §17.13.5.5 - customXmlInsRangeEnd (Custom XML Markup Insertion End) §17.13.5.6 - customXmlInsRangeStart (Custom XML Markup Insertion Start) §17.13.5.7 - customXmlMoveFromRangeEnd (Custom XML Markup Move Source End) §17.13.5.8 - customXmlMoveFromRangeStart (Custom XML Markup Move Source Start) §17.13.5.9 - customXmlMoveToRangeEnd (Custom XML Markup Move Destination Location End) §17.13.5.10 - customXmlMoveToRangeStart (Custom XML Markup Move Destination Location Start) §17.13.5.11 - [done] del (Deleted Run Content) §17.13.5.14 - dir (Bidirectional Embedding Level) §17.3.2.8 - [done] fldSimple (Simple Field) §17.16.19 - [done] hyperlink (Hyperlink) §17.16.22 - [done] ins (Inserted Run Content) §17.13.5.18 - moveFrom (Move Source Run Content) §17.13.5.22 - moveFromRangeEnd (Move Source Location Container - End) §17.13.5.23 - moveFromRangeStart (Move Source Location Container - Start) §17.13.5.24 - moveTo (Move Destination Run Content) §17.13.5.25 - moveToRangeEnd (Move Destination Location Container - End) §17.13.5.27 - moveToRangeStart (Move Destination Location Container - Start) §17.13.5.28 - oMath (Office Math) §22.1.2.77 - oMathPara (Office Math Paragraph) §22.1.2.78 - permEnd (Range Permission End) §17.13.7.1 - permStart (Range Permission Start) §17.13.7.2 - proofErr (Proofing Error Anchor) §17.13.8.1 - [done] r (Text Run) §17.3.2.25 - [done] sdt (Inline-Level Structured Document Tag) §17.5.2.31 - [done] smartTag (Inline-Level Smart Tag) §17.5.1.9 - subDoc (Anchor for Subdocument Location) §17.17.1.1 */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_hyperlink() { READ_PROLOGUE QString link_target; const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR_WITH_NS(r, id) if (r_id.isEmpty()) { link_target.clear(); } else { link_target = m_context->relationships->target(m_context->path, m_context->file, r_id); // The return value also contains the path in the start and directory separator, we need to remove them link_target.remove(0, m_context->path.size() + 1); } bool closeTag = false; TRY_READ_ATTR(anchor) MSOOXML::Utils::XmlWriteBuffer hlinkBuffer; body = hlinkBuffer.setWriter(body); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(r) ELSE_TRY_READ_IF(sdt) ELSE_TRY_READ_IF(hyperlink) ELSE_TRY_READ_IF(bookmarkStart) ELSE_TRY_READ_IF(bookmarkEnd) ELSE_TRY_READ_IF(fldSimple) ELSE_TRY_READ_IF(del) ELSE_TRY_READ_IF(ins) ELSE_TRY_READ_IF(smartTag) SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } body = hlinkBuffer.originalWriter(); //NOTE: Workaround until text:display="none" support. if ((m_currentParagraphStyle.property("text:display", KoGenStyle::TextType) == "none") && hlinkBuffer.isEmpty()) { READ_EPILOGUE } if (!link_target.isEmpty() || !anchor.isEmpty()) { body->startElement("text:a", false); body->addAttribute("xlink:type", "simple"); closeTag = true; if (!anchor.isEmpty()) { body->addAttribute("xlink:href", QString("#%1").arg(anchor)); } else { body->addAttribute("xlink:href", QUrl(link_target).toEncoded()); } } hlinkBuffer.releaseWriter(); if (closeTag) { body->endElement(); // text:bookmark, text:a } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL del //! del (Deleted Run Content) /*! ECMA-376, 17.13.5.18, p.959. This element specifies that the inline-level content contained within it shall be treated as deleted content which has been tracked as a revision. Parent elements, Child elements: sync to ins (Inserted Run Content) */ //! @todo: read more attributes and child emenets KoFilter::ConversionStatus DocxXmlDocumentReader::read_del() { READ_PROLOGUE m_changeTrackingState.push(DeletedRunContent); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(r) ELSE_TRY_READ_IF(bookmarkStart) ELSE_TRY_READ_IF(bookmarkEnd) ELSE_TRY_READ_IF(del) ELSE_TRY_READ_IF(ins) ELSE_TRY_READ_IF_NS(m, oMath) ELSE_TRY_READ_IF_NS(m, oMathPara) ELSE_TRY_READ_IF(sdt) ELSE_TRY_READ_IF(smartTag) SKIP_UNKNOWN } } if (m_changeTrackingState.isEmpty()) { warnDocx << "Error: ChangeTrackingState stack is corrupt!"; } else { m_changeTrackingState.pop(); } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL ins //! ins (Inserted Run Content) /*! ECMA-376, 17.13.5.18, p.959. This element specifies that the inline-level content contained within it shall be treated as inserted content which has been tracked as a revision. Parent elements: - bdo (§17.3.2.3) - [done] body (§17.2.2) - comment (§17.13.4.2) - customXml (§17.5.1.3) - deg (§22.1.2.26) - del (§17.13.5.14) - den (§22.1.2.28) - dir (§17.3.2.8) - docPartBody (§17.12.6) - e (§22.1.2.32) - [done] endnote (§17.11.2) - [done] fldSimple (§17.16.19) - fName (§22.1.2.37) - [done] footnote (§17.11.10) - [done] ftr (§17.10.3) - [done] hdr (§17.10.4) - [done] hyperlink (§17.16.22) - lim (§22.1.2.52 - moveFrom (§17.13.5.22) - moveTo (§17.13.5.25) - num (§22.1.2.75) - [done] oMath (§22.1.2.77) - [done] p (§17.3.1.22) - rt (§17.3.3.24 - rubyBase (§17.3.3.27) - sdtContent (§17.5.2.36) - [done] smartTag (§17.5.1.9) - sub (§22.1.2.112) - sup (§22.1.2.114) - tbl (§17.4.38) - tc (§17.4.66) - tr (§17.4.79) Child elements: - acc (Accent) §22.1.2.1 - bar (Bar) §22.1.2.7 - bdo (Bidirectional Override) §17.3.2.3 - [done] bookmarkEnd (Bookmark End) §17.13.6.1 - [done] bookmarkStart (Bookmark Start) §17.13.6.2 - borderBox (Border-Box Object) §22.1.2.11 - box (Box Object) §22.1.2.13 - commentRangeEnd (Comment Anchor Range End) §17.13.4.3 - commentRangeStart (Comment Anchor Range Start) §17.13.4.4 - customXml (Inline-Level Custom XML Element) §17.5.1.3 - customXmlDelRangeEnd (Custom XML Markup Deletion End) §17.13.5.4 - customXmlDelRangeStart (Custom XML Markup Deletion Start) §17.13.5.5 - customXmlInsRangeEnd (Custom XML Markup Insertion End) §17.13.5.6 - customXmlInsRangeStart (Custom XML Markup Insertion Start) §17.13.5.7 - customXmlMoveFromRangeEnd (Custom XML Markup Move Source End) §17.13.5.8 - customXmlMoveFromRangeStart (Custom XML Markup Move Source Start) §17.13.5.9 - customXmlMoveToRangeEnd (Custom XML Markup Move Destination Location End) §17.13.5.10 - customXmlMoveToRangeStart (Custom XML Markup Move Destination Location Start) §17.13.5.11 - d (Delimiter Object) §22.1.2.24 - [done] del (Deleted Run Content) §17.13.5.14 - dir (Bidirectional Embedding Level) §17.3.2.8 - eqArr (Array Object) §22.1.2.34 - f (Fraction Object) §22.1.2.36 - func (Function Apply Object) §22.1.2.39 - groupChr (Group-Character Object) §22.1.2.41 - [done] ins (Inserted Run Content) §17.13.5.18 - limLow (Lower-Limit Object) §22.1.2.54 - limUpp (Upper-Limit Object) §22.1.2.56 - m (Matrix Object) §22.1.2.60 - moveFrom (Move Source Run Content) §17.13.5.22 - moveFromRangeEnd (Move Source Location Container - End) §17.13.5.23 - moveFromRangeStart (Move Source Location Container - Start) §17.13.5.24 - moveTo (Move Destination Run Content) §17.13.5.25 - moveToRangeEnd (Move Destination Location Container - End) §17.13.5.27 - moveToRangeStart (Move Destination Location Container - Start) §17.13.5.28 - nary (n-ary Operator Object) §22.1.2.70 - [done] oMath (Office Math) §22.1.2.77 - [done] oMathPara (Office Math Paragraph) §22.1.2.78 - permEnd (Range Permission End) §17.13.7.1 - permStart (Range Permission Start) §17.13.7.2 - phant (Phantom Object) §22.1.2.81 - proofErr (Proofing Error Anchor) §17.13.8.1 - [done] r (Run) §22.1.2.87 - [done] r (Text Run) §17.3.2.25 - rad (Radical Object) §22.1.2.88 - [done] sdt (Inline-Level Structured Document Tag) §17.5.2.31 - [done] smartTag (Inline-Level Smart Tag) §17.5.1.9 - sPre (Pre-Sub-Superscript Object) §22.1.2.99 - sSub (Subscript Object) §22.1.2.101 - sSubSup (Sub-Superscript Object) §22.1.2.103 - sSup (Superscript Object) §22.1.2.105 */ //! @todo: read more attributes and child emenets KoFilter::ConversionStatus DocxXmlDocumentReader::read_ins() { READ_PROLOGUE m_changeTrackingState.push(InsertedRunContent); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(r) ELSE_TRY_READ_IF(bookmarkStart) ELSE_TRY_READ_IF(bookmarkEnd) ELSE_TRY_READ_IF(del) ELSE_TRY_READ_IF(ins) ELSE_TRY_READ_IF_NS(m, oMath) ELSE_TRY_READ_IF_NS(m, oMathPara) ELSE_TRY_READ_IF(sdt) ELSE_TRY_READ_IF(smartTag) SKIP_UNKNOWN } } if (m_changeTrackingState.isEmpty()) { warnDocx << "Error: ChangeTrackingState stack is corrupt!"; } else { m_changeTrackingState.pop(); } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL sdtContent /*! sdt handler //! @todo support properly */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_sdtContent() { READ_PROLOGUE // FIXME: This is not properly supported at all atm. while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(p) ELSE_TRY_READ_IF(tbl) ELSE_TRY_READ_IF(sdt) ELSE_TRY_READ_IF(fldSimple) ELSE_TRY_READ_IF(hyperlink) ELSE_TRY_READ_IF_NS(m, oMath) ELSE_TRY_READ_IF_NS(m, oMathPara) ELSE_TRY_READ_IF(r) ELSE_TRY_READ_IF(bookmarkStart) ELSE_TRY_READ_IF(bookmarkEnd) ELSE_TRY_READ_IF(smartTag) ELSE_TRY_READ_IF(tc) SKIP_UNKNOWN } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL sdt /*! sdt handler //! @todo support properly */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_sdt() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL); if (isStartElement()) { TRY_READ_IF(sdtContent) SKIP_UNKNOWN } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL txbxContent /*! txbxContent handler (Textbox content) Parent elements: - [done] textbox (§14.1.2.19) */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_txbxContent() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(p) ELSE_TRY_READ_IF(tbl) ELSE_TRY_READ_IF(sdt) SKIP_UNKNOWN } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL p //! [1] p handler (Paragraph) ECMA-376, WML 17.3.1.22, p. 251, //! This element specifies a paragraph of content in the document. //! [2] p handler (Text Paragraphs) ECMA-376, DrawingML 21.1.2.2.6, p. 3587. //! This element specifies the presence of a paragraph of text within the containing text body. /*! Parent elements: - [done] body (§17.2.2) - [done] comment (§17.13.4.2) - customXml (§17.5.1.6) - docPartBody (§17.12.6) - [done] endnote (§17.11.2) - [done] footnote (§17.11.10) - [done] ftr (§17.10.3) - [done] hdr (§17.10.4) - [done] sdtContent (§17.5.2.34) - [done] tc (§17.4.66) - [done] p (§17.3.1.22) Child elements: - bdo (Bidirectional Override) §17.3.2.3 - [done] bookmarkEnd (Bookmark End) §17.13.6.1 - [done] bookmarkStart (Bookmark Start) §17.13.6.2 - commentRangeEnd (Comment Anchor Range End) §17.13.4.3 - [done] commentRangeStart (Comment Anchor Range Start) §17.13.4.4 - WML only - customXml (Inline-Level Custom XML Element) §17.5.1.3 - customXmlDelRangeEnd (Custom XML Markup Deletion End) §17.13.5.4 - customXmlDelRangeStart (Custom XML Markup Deletion Start) §17.13.5.5 - customXmlInsRangeEnd (Custom XML Markup Insertion End) §17.13.5.6 - customXmlInsRangeStart (Custom XML Markup Insertion Start) §17.13.5.7 - customXmlMoveFromRangeEnd (Custom XML Markup Move Source End) §17.13.5.8 - customXmlMoveFromRangeStart (Custom XML Markup Move Source Start) §17.13.5.9 - customXmlMoveToRangeEnd (Custom XML Markup Move Destination Location End) §17.13.5.10 - customXmlMoveToRangeStart (Custom XML Markup Move Destination Location Start) §17.13.5.11 - [done] del (Deleted Run Content) §17.13.5.14 - dir (Bidirectional Embedding Level) §17.3.2.8 - [done] fldSimple (Simple Field) §17.16.19 - [done] hyperlink (Hyperlink) §17.16.22 - WML only - [done] ins (Inserted Run Content) §17.13.5.18 - moveFrom (Move Source Run Content) §17.13.5.22 - moveFromRangeEnd (Move Source Location Container - End) §17.13.5.23 - moveFromRangeStart (Move Source Location Container - Start) §17.13.5.24 - moveTo (Move Destination Run Content) §17.13.5.25 - moveToRangeEnd (Move Destination Location Container - End) §17.13.5.27 - moveToRangeStart (Move Destination Location Container - Start) §17.13.5.28 - [done] oMath (Office Math) §22.1.2.77 - [done] oMathPara (Office Math Paragraph) §22.1.2.78 - permEnd (Range Permission End) §17.13.7.1 - permStart (Range Permission Start) §17.13.7.2 - [done] pPr (Paragraph Properties) §17.3.1.26 - proofErr (Proofing Error Anchor) §17.13.8.1 - [done] r (Text Run) §17.3.2.25 - [done] sdt (Inline-Level Structured Document Tag) §17.5.2.31 - [done] smartTag (Inline-Level Smart Tag) §17.5.1.9 - subDoc (Anchor for Subdocument Location) §17.17.1.1 */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_p() { READ_PROLOGUE m_insideParagraph = true; m_paragraphStyleNameWritten = false; m_currentStyleName.clear(); m_listFound = false; m_closeHyperlink = false; // It is possible that one of the child elements of p has p element // Therefore we push the current style to vector and pop it out when we // come out To make sure in that case we don't lose the previous style QVector activeStyles; activeStyles.push_back(m_currentParagraphStyle); MSOOXML::Utils::XmlWriteBuffer textPBuf; bool oldWasCaption = m_wasCaption; m_wasCaption = false; if (oldWasCaption) { debugDocx << "SKIP!"; } else { body = textPBuf.setWriter(body); m_currentParagraphStyle = KoGenStyle(KoGenStyle::ParagraphAutoStyle, "paragraph"); if (m_moveToStylesXml) { m_currentParagraphStyle.setAutoStyleInStylesDotXml(true); } // MS2007 has a different way of marking drop cap, it divides them to // two paragraphs here we apply the status to current paragraph if // previous one had dropCap if (m_dropCapStatus == DropCapDone) { QBuffer frameBuffer; frameBuffer.open(QIODevice::WriteOnly); KoXmlWriter elementWriter(&frameBuffer); elementWriter.startElement("style:drop-cap"); elementWriter.addAttribute("style:lines", m_dropCapLines); elementWriter.addAttributePt("style:distance", m_dropCapDistance); elementWriter.endElement(); // style-drop-cap QString drop = QString::fromUtf8(frameBuffer.buffer(), frameBuffer.buffer().size()); m_currentParagraphStyle.addChildElement("style:tab-stops", drop); } } // Whether section starts from this paragraph bool sectionAdded = false; if (m_createSectionStyle) { // To avoid the style to become a duplicate or being duplicated. m_currentParagraphStyle.addAttribute("style:master-page-name", "placeholder"); m_createSectionStyle = false; sectionAdded = true; } while (!atEnd()) { readNext(); debugDocx << *this; BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { //ELSE_TRY_READ_IF(commentRangeEnd) TRY_READ_IF(sdt) ELSE_TRY_READ_IF(hyperlink) ELSE_TRY_READ_IF(del) ELSE_TRY_READ_IF(ins) ELSE_TRY_READ_IF(commentRangeStart) ELSE_TRY_READ_IF(bookmarkStart) ELSE_TRY_READ_IF(bookmarkEnd) ELSE_TRY_READ_IF(pPr) // CASE #400.1 ELSE_TRY_READ_IF(r) // CASE #400.2 ELSE_TRY_READ_IF(fldSimple) ELSE_TRY_READ_IF_NS(m, oMathPara) ELSE_TRY_READ_IF_NS(m, oMath) ELSE_TRY_READ_IF(smartTag) SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } //--------------------------------------------- // Prepare for List Style //--------------------------------------------- if (m_listFound && m_currentBulletList.size() > m_currentListLevel) { m_currentBulletProperties = m_currentBulletList.at(m_currentListLevel); KoGenStyle textStyle = KoGenStyle(KoGenStyle::TextStyle, "text"); KoGenStyle::copyPropertiesFromStyle(m_currentParagraphStyle, textStyle, KoGenStyle::TextType); if (!textStyle.isEmpty()) { //MSWord: A bullet/picture label does not inherit font information //from the paragraph mark. if (m_currentBulletProperties.m_type != MSOOXML::Utils::ParagraphBulletProperties::NumberType) { textStyle.removeProperty("style:font-name"); textStyle.removeProperty("style:font-name-complex"); } //MSWord: A label does NOT inherit Underline from text-properties //of the paragraph style. A bullet/picture does not inherit //{Italics, Bold}. if (m_currentBulletProperties.m_type != MSOOXML::Utils::ParagraphBulletProperties::NumberType) { textStyle.removeProperty("fo:font-style"); textStyle.removeProperty("fo:font-weight"); } textStyle.removeProperty("style:text-underline-color"); textStyle.removeProperty("style:text-underline-mode"); textStyle.removeProperty("style:text-underline-style"); textStyle.removeProperty("style:text-underline-type"); textStyle.removeProperty("style:text-underline-width"); KoGenStyle::copyPropertiesFromStyle(m_currentBulletProperties.textStyle(), textStyle); m_currentBulletProperties.setTextStyle(textStyle); } } //--------------------------------------------- // Fine-tune Paragraph Style //--------------------------------------------- if (m_currentParagraphStyle.parentName().isEmpty()) { if (m_context->m_namedDefaultStyles.contains("paragraph")) { m_currentParagraphStyle.setParentName(m_context->m_namedDefaultStyles.value("paragraph")); } } // take outline level from style's default-outline-level, // there is no text:outline-level equivalent in OOXML QString outlineLevelAttribute; const KoGenStyle* pstyle = &m_currentParagraphStyle; do { outlineLevelAttribute = pstyle->attribute("style:default-outline-level"); // use isNull, empty string value is valid here if (! outlineLevelAttribute.isNull()) { break; } // next in hierarchy pstyle = mainStyles->style(pstyle->parentName(), "paragraph"); } while (pstyle); const uint outlineLevel = outlineLevelAttribute.toUInt(); //NOTE: Workaround until text:display="none" support. bool isHidden = (m_currentParagraphStyle.property("text:display", KoGenStyle::TextType) == "none"); // rPr (Run Properties for the Paragraph Mark), ECMA-376, 17.3.1.29, p.253 // This element specifies the set of run properties applied to the // glyph used to represent the physical location of the paragraph // mark for this paragraph. ODF: The paragraph mark formatting // does not affect other runs of text so it can NOT be saved into // text-properties of the paragraph style. // if (!textPBuf.isEmpty()) { m_currentParagraphStyle.removeAllProperties(KoGenStyle::TextType); } //--------------------------------------------- // Process Paragraph Content //--------------------------------------------- if (oldWasCaption || (isHidden && textPBuf.isEmpty())) { //nothing body = textPBuf.originalWriter(); } else { if (m_dropCapStatus == DropCapRead) { body = textPBuf.releaseWriter(); // If we read a drop cap but there was no text there might as well // be no drop cap m_dropCapStatus = NoDropCap; } else if (m_dropCapStatus == DropCapDone) { // In case of drop cap, we do not wish there to be a paragraph at // this point, this because two ooxml paragraphs with drop cap in // first, trasnfer to one paragraph in odt with drop cap as style. body = textPBuf.releaseWriter(); } else { body = textPBuf.originalWriter(); // In ooxml it seems that nothing should be created if sectPr was present if (!m_createSectionToNext) { if (m_listFound) { // update the size of a bullet picture if ((m_currentBulletProperties.m_type == MSOOXML::Utils::ParagraphBulletProperties::PictureType) && (m_currentBulletProperties.bulletSizePt() == "UNUSED")) { int percent = 100; if (m_currentBulletProperties.bulletRelativeSize() != "UNUSED") { STRING_TO_INT(m_currentBulletProperties.bulletRelativeSize(), percent, QString("PictureType: processing bulletRelativeSize")); } QString fontSize = m_currentParagraphStyle.property("fo:font-size",KoGenStyle::TextType); // Using the default font size at the moment if (fontSize.isEmpty()) { fontSize = m_context->m_defaultFontSizePt; } qreal base = 10; //fair enough if (!fontSize.isEmpty() && fontSize.endsWith(QLatin1String("pt"))) { fontSize.chop(2); STRING_TO_QREAL(fontSize, base, QString("PictureType: processing font-size")); } m_currentBulletProperties.setBulletSizePt(percent * base / 100); } // update automatic numbering info if (m_currentBulletProperties.m_type == MSOOXML::Utils::ParagraphBulletProperties::NumberType) { bool listOpen = false; if (m_continueListNum.contains(m_currentNumId)) { listOpen = true; } else if (!m_currentBulletProperties.startOverride()) { // TODO: The most recent one is required to check // against the correct prevListLevel. // // Check if any of the lists that inherit numbering // from the abstract numbering definition was opened. QStringList numIDs = m_context->m_abstractNumIDs.keys(m_context->m_abstractNumIDs[m_currentNumId]); QStringList::const_iterator i; for (i = numIDs.constBegin(); i != numIDs.constEnd(); ++i) { if (m_continueListNum.contains(*i)) { listOpen = true; m_currentNumId = *i; break; } } } if (listOpen) { if (m_currentListLevel <= m_continueListNum[m_currentNumId].first) { m_continueListNum[m_currentNumId].second = true; } else { m_continueListNum[m_currentNumId].second = false; QString key; int i = m_continueListNum[m_currentNumId].first; while (i > m_currentListLevel) { key = m_currentNumId; key.append(QString(".lvl%1").arg(i)); m_numIdXmlId.remove(key); --i; } } } } m_currentListStyle = KoGenStyle(KoGenStyle::ListAutoStyle); if (m_moveToStylesXml) { m_currentListStyle.setAutoStyleInStylesDotXml(true); } m_currentListStyle.addChildElement("list-style-properties", m_currentBulletProperties.convertToListProperties(*mainStyles, MSOOXML::Utils::DocxFilter)); QString listStyleName = mainStyles->insert(m_currentListStyle, QString()); Q_ASSERT(!listStyleName.isEmpty()); //TODO: continue an opened list based on this information // m_usedListStyles.insertMulti(m_currentNumId, listStyleName); // Start a new list body->startElement("text:list"); body->addAttribute("text:style-name", listStyleName); // continue numbering if applicable if (m_currentBulletProperties.m_type == MSOOXML::Utils::ParagraphBulletProperties::NumberType) { QString key = m_currentNumId; key.append(QString(".lvl%1").arg(m_currentListLevel)); // Keeping the id readable for debugging purpose QString xmlId = key; xmlId.append(QString("_%1").arg(m_numIdXmlId[key].first)).prepend("lst"); xmlId.append(QString("_%1").arg(qrand())); body->addAttribute("xml:id", xmlId); if (m_continueListNum.contains(m_currentNumId)) { if (m_continueListNum[m_currentNumId].second) { body->addAttribute("text:continue-list", m_numIdXmlId[key].second); } } m_numIdXmlId[key].first++; m_numIdXmlId[key].second = xmlId; } body->startElement("text:list-item"); for (int i = 0; i < m_currentListLevel; ++i) { body->startElement("text:list"); body->startElement("text:list-item"); } // restart numbering if applicable if (m_currentBulletProperties.m_type == MSOOXML::Utils::ParagraphBulletProperties::NumberType) { if (!m_continueListNum.contains(m_currentNumId) || (m_continueListNum.contains(m_currentNumId) && !m_continueListNum[m_currentNumId].second)) { body->addAttribute("text:start-value", m_currentBulletProperties.startValue()); } m_continueListNum[m_currentNumId] = qMakePair(m_currentListLevel, false); } m_currentParagraphStyle.addAttribute("style:list-style-name", listStyleName); } body->startElement((outlineLevel > 0) ? "text:h" : "text:p", false); if (outlineLevel > 0) { body->addAttribute("text:outline-level", outlineLevel); } if (m_currentStyleName.isEmpty()) { QString currentParagraphStyleName; currentParagraphStyleName = (mainStyles->insert(m_currentParagraphStyle)); if (sectionAdded) { m_currentSectionStyleName = currentParagraphStyleName; m_currentSectionStyleFamily = m_currentParagraphStyle.familyName(); } body->addAttribute("text:style-name", currentParagraphStyleName); } else { body->addAttribute("text:style-name", m_currentStyleName); if (m_currentStyleName == "Caption") { m_wasCaption = true; } } //insert the bookmark-start/bookmark-end XML snippet if (!m_bookmarkSnippet.isEmpty()) { body->addCompleteElement(m_bookmarkSnippet.toUtf8()); } //insert the floating table XML snippet if (!m_floatingTable.isEmpty()) { body->addCompleteElement(m_floatingTable.toUtf8()); m_floatingTable.clear(); } (void)textPBuf.releaseWriter(); body->endElement(); //text:p or text:h if (m_listFound) { for (int i = 0; i <= m_currentListLevel; ++i) { body->endElement(); //text:list-item body->endElement(); //text:list } } debugDocx << "/text:p"; } } } // True if this was last paragraph of the section, if we were then it means // that next paragraph/table should have a new section identifier if (m_createSectionToNext) { m_createSectionStyle = true; m_createSectionToNext = false; } m_currentStyleName.clear(); m_insideParagraph = false; m_currentParagraphStyle = activeStyles.last(); activeStyles.pop_back(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL smartTag //! smartTag Handler (Smart Tag) /* Parent elements: - bdo (§17.3.2.3); - customXml (§17.5.1.3); - del (§17.13.5.14); dir (§17.3.2.8); - [done] fldSimple (§17.16.19); - [done] hyperlink (§17.16.22); - ins (§17.13.5.18); - moveFrom (§17.13.5.22); - moveTo (§17.13.5.25); - [done] p (§17.3.1.22); - [done] sdtContent (§17.5.2.36); - [done] smartTag (§17.5.1.9) Child elements: - bdo (Bidirectional Override) §17.3.2.3 - [done] bookmarkEnd (Bookmark End) §17.13.6.1 - [done] bookmarkStart (Bookmark Start) §17.13.6.2 - commentRangeEnd (Comment Anchor Range End) §17.13.4.3 - [done] commentRangeStart (Comment Anchor Range Start) §17.13.4.4 - customXml (Inline-Level Custom XML Element) §17.5.1.3 - customXmlDelRangeEnd (Custom XML Markup Deletion End) §17.13.5.4 - customXmlDelRangeStart (Custom XML Markup Deletion Start) §17.13.5.5 - customXmlInsRangeEnd (Custom XML Markup Insertion End) §17.13.5.6 - customXmlInsRangeStart (Custom XML Markup Insertion Start) §17.13.5.7 - customXmlMoveFromRangeEnd (Custom XML Markup Move Source End) §17.13.5.8 - customXmlMoveFromRangeStart (Custom XML Markup Move Source Start) §17.13.5.9 - customXmlMoveToRangeEnd (Custom XML Markup Move Destination Location End) §17.13.5.10 - customXmlMoveToRangeStart (Custom XML Markup Move Destination Location Start) §17.13.5.11 - [done] del (Deleted Run Content) §17.13.5.14 - dir (Bidirectional Embedding Level) §17.3.2.8 - [done] fldSimple (Simple Field) §17.16.19 - [done] hyperlink (Hyperlink) §17.16.22 - [done] ins (Inserted Run Content) §17.13.5.18 - moveFrom (Move Source Run Content) §17.13.5.22 - moveFromRangeEnd (Move Source Location Container - End) §17.13.5.23 - moveFromRangeStart (Move Source Location Container - Start) §17.13.5.24 - moveTo (Move Destination Run Content) §17.13.5.25 - moveToRangeEnd (Move Destination Location Container - End) §17.13.5.27 - moveToRangeStart (Move Destination Location Container - Start) §17.13.5.28 - [done] oMath (Office Math) §22.1.2.77 - [done] oMathPara (Office Math Paragraph) §22.1.2.78 - permEnd (Range Permission End) §17.13.7.1 - permStart (Range Permission Start) §17.13.7.2 - proofErr (Proofing Error Anchor) §17.13.8.1 - [done] r (Text Run) §17.3.2.25 - [done] sdt (Inline-Level Structured Document Tag) §17.5.2.31 - [done] smartTag (Inline-Level Smart Tag) §17.5.1.9 - smartTagPr (Smart Tag Properties) §17.5.1.10 - subDoc (Anchor for Subdocument Location) §17.17.1.1 */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_smartTag() { READ_PROLOGUE // todo, use as RDF info? while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(r) ELSE_TRY_READ_IF(smartTag) ELSE_TRY_READ_IF(bookmarkStart) ELSE_TRY_READ_IF(bookmarkEnd) ELSE_TRY_READ_IF(fldSimple) ELSE_TRY_READ_IF(hyperlink) ELSE_TRY_READ_IF(commentRangeStart) ELSE_TRY_READ_IF(r) ELSE_TRY_READ_IF_NS(m, oMathPara) ELSE_TRY_READ_IF_NS(m, oMath) ELSE_TRY_READ_IF(del) ELSE_TRY_READ_IF(ins) ELSE_TRY_READ_IF(sdt) SKIP_UNKNOWN } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL r //! r handler (Text Run) /*! ECMA-376, 17.3.2.25, p.320. Parent elements: - bdo (§17.3.2.3) - customXml (§17.5.1.3) - del (§17.13.5.14) - dir (§17.3.2.8) - [done] fldSimple (§17.16.19) - [done] hyperlink (§17.16.22) - ins (§17.13.5.18) - moveFrom (§17.13.5.22) - moveTo (§17.13.5.25) - [done] p (§17.3.1.22) - rt (§17.3.3.24) - rubyBase (§17.3.3.27) - [done] sdtContent (§17.5.2.36) - [done] smartTag (§17.5.1.9) Child elements: - annotationRef (Comment Information Block) §17.13.4.1 - [done] br (Break) §17.3.3.1 - commentReference (Comment Content Reference Mark) §17.13.4.5 - contentPart (Content Part) §17.3.3.2 - continuationSeparator (Continuation Separator Mark) §17.11.1 - cr (Carriage Return) §17.3.3.4 - dayLong (Date Block - Long Day Format) §17.3.3.5 - dayShort (Date Block - Short Day Format) §17.3.3.6 - delInstrText (Deleted Field Code) §17.16.13 - [done] delText (Deleted Text) §17.3.3.7 - [done] drawing (DrawingML Object) §17.3.3.9 - endnoteRef (Endnote Reference Mark) §17.11.6 - [done] endnoteReference (Endnote Reference) §17.11.7 - [done] fldChar (Complex Field Character) §17.16.18 - footnoteRef (Footnote Reference Mark) §17.11.13 - [done] footnoteReference (Footnote Reference) §17.11.14 - [done] instrText (Field Code) §17.16.23 - [done] lastRenderedPageBreak (Position of Last Calculated Page Break) §17.3.3.13 - monthLong (Date Block - Long Month Format) §17.3.3.15 - monthShort (Date Block - Short Month Format) §17.3.3.16 - noBreakHyphen (Non Breaking Hyphen Character) §17.3.3.18 - [done] object (Embedded Object) §17.3.3.19 - pgNum (Page Number Block) §17.3.3.22 - [done] ptab (Absolute Position Tab Character) §17.3.3.23 - [done] rPr (Run Properties) §17.3.2.28 - ruby (Phonetic Guide) §17.3.3.25 - separator (Footnote/Endnote Separator Mark) §17.11.23 - softHyphen (Optional Hyphen Character) §17.3.3.29 - sym (Symbol Character) §17.3.3.30 - [done] t (Text) §17.3.3.31 - [done] tab (Tab Character) §17.3.3.32 - yearLong (Date Block - Long Year Format) §17.3.3.33 - yearShort (Date Block - Short Year Format) §17.3.3.34 VML child elements (see Part 4): - [done] pict (VML Object) §9.2.2.2 */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_r() { READ_PROLOGUE m_currentTextStyle = KoGenStyle(KoGenStyle::TextAutoStyle, "text"); if (m_moveToStylesXml) { m_currentTextStyle.setAutoStyleInStylesDotXml(true); } KoXmlWriter* oldWriter = body; // DropCapRead means we have read the w:dropCap attribute on this // paragraph and now have to save the text. // DropCapDone means we are in the next paragraph and want to add // the saved text to this paragraph. if (m_dropCapStatus == DropCapRead) { m_dropCapStatus = DropCapDone; m_dropCapBuffer = new QBuffer; m_dropCapBuffer->open(QIODevice::ReadWrite); m_dropCapWriter = new KoXmlWriter(m_dropCapBuffer); body = m_dropCapWriter; } else if (m_dropCapStatus == DropCapDone) { body->addCompleteElement(m_dropCapBuffer); delete m_dropCapWriter; delete m_dropCapBuffer; m_dropCapBuffer = 0; m_dropCapWriter = 0; m_dropCapStatus = NoDropCap; } MSOOXML::Utils::XmlWriteBuffer buffer; body = buffer.setWriter(body); while (!atEnd()) { readNext(); debugDocx << *this; BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(rPr) ELSE_TRY_READ_IF(t) ELSE_TRY_READ_IF(ptab) ELSE_TRY_READ_IF(delText) ELSE_TRY_READ_IF(drawing) ELSE_TRY_READ_IF(endnoteReference) ELSE_TRY_READ_IF(footnoteReference) ELSE_TRY_READ_IF(object) else if (name() == "pict") { // Protecting in case the object is inside a textbox inside a shape VMLShapeProperties oldProperties = m_currentVMLProperties; TRY_READ(pict) m_currentVMLProperties = oldProperties; } ELSE_TRY_READ_IF(instrText) ELSE_TRY_READ_IF(fldChar) ELSE_TRY_READ_IF(lastRenderedPageBreak) ELSE_TRY_READ_IF(br) ELSE_TRY_READ_IF_NS(mc, AlternateContent) else if (qualifiedName() == "w:tab") { body->startElement("text:tab"); body->endElement(); // text:tab } SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } //NOTE: Workaround until text:display="none" support. if (m_currentTextStyle.property("text:display") == "none") { body = buffer.originalWriter(); READ_EPILOGUE } if (m_currentTextStyle.parentName().isEmpty()) { if (m_context->m_namedDefaultStyles.contains("text")) { m_currentTextStyle.setParentName(m_context->m_namedDefaultStyles.value("text")); } } // inserted/deleted run content, use a different color and // underline/line-through if (!m_changeTrackingState.isEmpty()) { if (m_changeTrackingState.top() == InsertedRunContent) { m_currentTextStyle.addProperty("style:text-underline-mode", "continuous"); m_currentTextStyle.addProperty("style:text-underline-style", "solid"); m_currentTextStyle.addProperty("style:text-underline-type", "single"); m_currentTextStyle.addProperty("style:text-underline-width", "auto"); } else { m_currentTextStyle.addProperty("style:text-line-through-mode", "continuous"); m_currentTextStyle.addProperty("style:text-line-through-style", "solid"); m_currentTextStyle.addProperty("style:text-line-through-type", "single"); m_currentTextStyle.addProperty("style:text-line-through-width", "auto"); } m_currentTextStyle.addProperty("style:text-underline-color", "#800080"); m_currentTextStyle.addProperty("fo:color", "#800080"); } // We want to write to the higher body level body = buffer.originalWriter(); QString currentTextStyleName; if (!m_currentTextStyle.isEmpty() || !m_currentTextStyle.parentName().isEmpty()) { currentTextStyleName = mainStyles->insert(m_currentTextStyle); } if (m_complexCharStatus == ExecuteInstrNow || m_complexCharType == InternalHyperlinkComplexFieldCharType) { if (m_complexCharType == HyperlinkComplexFieldCharType || m_complexCharType == InternalHyperlinkComplexFieldCharType) { body->startElement("text:a", false); body->addAttribute("xlink:type", "simple"); if (m_complexCharType == HyperlinkComplexFieldCharType) { body->addAttribute("xlink:href", QUrl(m_complexCharValue).toEncoded()); } else { int spacePosition = m_complexCharValue.indexOf(' '); QString textValue(QLatin1Char('#')); textValue.append(m_complexCharValue.left(spacePosition)); m_complexCharValue.remove(0, textValue.length()); body->addAttribute("xlink:href", QUrl(textValue).toEncoded()); } } } if (!currentTextStyleName.isEmpty()) { body->startElement("text:span", false); body->addAttribute("text:style-name", currentTextStyleName); } m_closeHyperlink = handleSpecialField(); if (m_complexCharStatus == ExecuteInstrNow) { if (m_complexCharType == ReferenceNextComplexFieldCharType) { body->startElement("text:bookmark-ref"); body->addAttribute("text:reference-format", "page"); body->addAttribute("text:ref-name", m_complexCharValue); m_closeHyperlink = true; } else { m_specialCharacters = m_complexCharValue; m_closeHyperlink = handleSpecialField(); } } if (m_complexCharType == InternalHyperlinkComplexFieldCharType || m_complexCharType == MacroButtonFieldCharType) { body->addTextSpan(m_complexCharValue); } // Writing the internal body of read_t now body = buffer.releaseWriter(); if (m_closeHyperlink) { body->endElement(); //either text:bookmark-ref or text:a or text:page-number etc. m_closeHyperlink = false; } if (!currentTextStyleName.isEmpty()) { body->endElement(); //text:span } if (m_complexCharStatus == InstrExecute) { if (m_complexCharType == ReferenceComplexFieldCharType) { m_complexCharType = ReferenceNextComplexFieldCharType; } } if (m_complexCharStatus == ExecuteInstrNow && m_complexCharType == HyperlinkComplexFieldCharType) { body->endElement(); // text:a } else if (m_complexCharType == InternalHyperlinkComplexFieldCharType) { body->endElement(); // text:a } // Case where there's hyperlink with read_instrText, we only want to use the link // with the next r element, not this. if (m_complexCharStatus == InstrExecute) { m_complexCharStatus = ExecuteInstrNow; } if (m_dropCapStatus == DropCapDone) { body = oldWriter; } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL rPr //! [1] rPr handler (Run Properties for the Paragraph Mark) WML ECMA-376, 17.3.1.29, p.263, //! This element specifies a set of run properties which shall be applied to the contents //! of the parent run after all style formatting has been applied to the text. //! [2] rPr handler (Run Properties) WML ECMA-376, 17.3.2.28, p.331, //! This element specifies a set of run properties which shall be applied to the contents //! of the parent run after all style formatting has been applied to the text. /*! Parent elements: - [1] pPr (§17.3.1.26) - [2] ctrlPr (§22.1.2.23) - [2] r (§22.1.2.87) - Shared ML - [2] r (§17.3.2.25) Child elements: - [done] b (Bold) §17.3.2.1 - bCs (Complex Script Bold) §17.3.2.2 - [done] bdr (Text Border) §17.3.2.4 - [done] caps (Display All Characters As Capital Letters) §17.3.2.5 - [done] color (Run Content Color) §17.3.2.6 - cs (Use Complex Script Formatting on Run) §17.3.2.7 - del (Deleted Paragraph) §17.13.5.15 - [done] dstrike (Double Strikethrough) §17.3.2.9 - eastAsianLayout (East Asian Typography Settings) §17.3.2.10 - effect (Animated Text Effect) §17.3.2.11 - em (Emphasis Mark) §17.3.2.12 - emboss (Embossing) §17.3.2.13 - fitText (Manual Run Width) §17.3.2.14 - [done] highlight (Text Highlighting) §17.3.2.15 - [done] i (Italics) §17.3.2.16 - iCs (Complex Script Italics) §17.3.2.17 - imprint (Imprinting) §17.3.2.18 - ins (Inserted Paragraph) §17.13.5.20 - kern (Font Kerning) §17.3.2.19 - [done] lang (Languages for Run Content) §17.3.2.20 - moveFrom (Move Source Paragraph) §17.13.5.21 - moveTo (Move Destination Paragraph) §17.13.5.26 - noProof (Do Not Check Spelling or Grammar) §17.3.2.21 - oMath (Office Open XML Math) §17.3.2.22 - [done] outline (Display Character Outline) §17.3.2.23 - position (Vertically Raised or Lowered Text) §17.3.2.24 - [done] rFonts (Run Fonts) §17.3.2.26 - rPrChange (Revision Information for Run Properties on the Paragraph Mark) §17.13.5.30 - [done] rStyle (Referenced Character Style) §17.3.2.29 - rtl (Right To Left Text) §17.3.2.30 - shadow (Shadow) §17.3.2.31 - [done] shd (Run Shading) §17.3.2.32 - [done] smallCaps (Small Caps) §17.3.2.33 - snapToGrid (Use Document Grid Settings For Inter-Character Spacing) §17.3.2.34 - [done] spacing (Character Spacing Adjustment) §17.3.2.35 - specVanish (Paragraph Mark Is Always Hidden) §17.3.2.36 - [done] strike (Single Strikethrough) §17.3.2.37 - [done] sz (Non-Complex Script Font Size) §17.3.2.38 - szCs (Complex Script Font Size) §17.3.2.39 - [done] u (Underline) §17.3.2.40 - [done] vanish (Hidden Text) §17.3.2.41 - [done] vertAlign (Subscript/Superscript Text) §17.3.2.42 - [done] w (Expanded/Compressed Text) §17.3.2.43 - [done] webHidden (Web Hidden Text) §17.3.2.44 */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_rPr() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); Q_ASSERT(m_currentTextStyleProperties == 0); m_currentTextStyleProperties = new KoCharacterStyle(); while (!atEnd()) { readNext(); debugDocx << *this; BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(b) ELSE_TRY_READ_IF(i) ELSE_TRY_READ_IF(u) ELSE_TRY_READ_IF(sz) ELSE_TRY_READ_IF(strike) ELSE_TRY_READ_IF(dstrike) ELSE_TRY_READ_IF(rStyle) ELSE_TRY_READ_IF(color) ELSE_TRY_READ_IF(highlight) ELSE_TRY_READ_IF(lang) ELSE_TRY_READ_IF_IN_CONTEXT(shd) ELSE_TRY_READ_IF(vertAlign) ELSE_TRY_READ_IF(rFonts) ELSE_TRY_READ_IF(spacing) ELSE_TRY_READ_IF(outline) ELSE_TRY_READ_IF(caps) ELSE_TRY_READ_IF(smallCaps) ELSE_TRY_READ_IF(w) ELSE_TRY_READ_IF(webHidden) ELSE_TRY_READ_IF(bdr) ELSE_TRY_READ_IF(vanish) SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } m_currentTextStyleProperties->saveOdf(m_currentTextStyle); delete m_currentTextStyleProperties; m_currentTextStyleProperties = 0; READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL pPr //! pPr handler (Paragraph Properties) /*! 1. pPr (Paragraph Properties) 17.3.1.26, p.259. Parent elements: - [done] p (§17.3.1.22) - common reader 2. pPr (Paragraph Properties) 17.7.5.2, p.725. Parent elements: - [done] pPrDefault - DocxXmlStylesReader 3. pPr (Table Style Conditional Formatting Paragraph Properties) 17.7.6.1, p.733. Parent elements: - tblStylePr (§17.7.6.6) 4. pPr (Style Paragraph Properties) 17.7.8.2, p.752. Parent elements: - [done] style (§17.7.4.17) - DocxXmlStylesReader 5. pPr (Numbering Level Associated Paragraph Properties) 17.9.23, p.818. Parent elements: - lvl (§17.9.6) - lvl (§17.9.7) Child elements: - adjustRightInd (Automatically Adjust Right Indent When Using Document Grid) §17.3.1.1 - autoSpaceDE (Automatically Adjust Spacing of Latin and East Asian Text) §17.3.1.2 - autoSpaceDN (Automatically Adjust Spacing of East Asian Text and Numbers) §17.3.1.3 - bidi (Right to Left Paragraph Layout) §17.3.1.6 - cnfStyle (Paragraph Conditional Formatting) §17.3.1.8 - contextualSpacing (Ignore Spacing Above and Below When Using Identical Styles) §17.3.1.9 - divId (Associated HTML div ID) §17.3.1.10 - [done] framePr (Text Frame Properties) §17.3.1.11 - ind (Paragraph Indentation) §17.3.1.12 - [done] jc (Paragraph Alignment) §17.3.1.13 - keepLines (Keep All Lines On One Page) §17.3.1.14 - keepNext (Keep Paragraph With Next Paragraph) §17.3.1.15 - kinsoku (Use East Asian Typography Rules for First and Last Character per Line) §17.3.1.16 - mirrorIndents (Use Left/Right Indents as Inside/Outside Indents) §17.3.1.18 - [done] numPr (Numbering Definition Instance Reference) §17.3.1.19 - [done] outlineLvl (Associated Outline Level) §17.3.1.20 - overflowPunct (Allow Punctuation to Extend Past Text Extents) §17.3.1.21 - pageBreakBefore (Start Paragraph on Next Page) §17.3.1.23 - [done] pBdr (Paragraph Borders) §17.3.1.24 - pPrChange (Revision Information for Paragraph Properties) §17.13.5.29 - [done] pStyle (Referenced Paragraph Style) §17.3.1.27 - [done] rPr (Run Properties for the Paragraph Mark) §17.3.1.29 - [done] sectPr (Section Properties) §17.6.18 - [done] shd (Paragraph Shading) §17.3.1.31 - snapToGrid (Use Document Grid Settings for Inter-Line Paragraph Spacing) §17.3.1.32 - [done] spacing (Spacing Between Lines and Above/Below Paragraph) §17.3.1.33 - suppressAutoHyphens (Suppress Hyphenation for Paragraph) §17.3.1.34 - [done] suppressLineNumbers (Suppress Line Numbers for Paragraph) §17.3.1.35 - suppressOverlap (Prevent Text Frames From Overlapping) §17.3.1.36 - [done] tabs (Set of Custom Tab Stops) §17.3.1.38 - textAlignment (Vertical Character Alignment on Line) §17.3.1.39 - textboxTightWrap (Allow Surrounding Paragraphs to Tight Wrap to Text Box Contents) §17.3.1.40 - textDirection (Paragraph Text Flow Direction) §17.3.1.41 - topLinePunct (Compress Punctuation at Start of a Line) §17.3.1.43 - widowControl (Allow First/Last Line to Display on a Separate Page) §17.3.1.44 - wordWrap (Allow Line Breaking At Character Level) §17.3.1.45 */ //! CASE #850 -> CASE #853 //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_pPr() { READ_PROLOGUE while (!atEnd()) { readNext(); debugDocx << *this; BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { if (name() == "rPr") { m_currentTextStyle = KoGenStyle(KoGenStyle::TextAutoStyle, "text"); TRY_READ(rPr) KoGenStyle::copyPropertiesFromStyle(m_currentTextStyle, m_currentParagraphStyle, KoGenStyle::TextType); } ELSE_TRY_READ_IF_IN_CONTEXT(shd) ELSE_TRY_READ_IF_IN_CONTEXT(jc) ELSE_TRY_READ_IF(tabs) ELSE_TRY_READ_IF(spacing) ELSE_TRY_READ_IF(pStyle) ELSE_TRY_READ_IF(numPr) ELSE_TRY_READ_IF(pBdr) ELSE_TRY_READ_IF(framePr) ELSE_TRY_READ_IF(ind) ELSE_TRY_READ_IF(suppressLineNumbers) ELSE_TRY_READ_IF(sectPr) ELSE_TRY_READ_IF(outlineLvl) SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL webHidden //! webHidden handler (Web Hidden Text) /*! Parent elements: - [done] rPr (§17.3.1.29) - [done] rPr (§17.3.1.30) - [done] rPr (§17.5.2.28) - [done] rPr (§17.9.25) - [done] rPr (§17.7.9.1) - [done] rPr (§17.7.5.4) - [done] rPr (§17.3.2.28) - [done] rPr (§17.5.2.27) - [done] rPr (§17.7.6.2) - [done] rPr (§17.3.2.27) Child elements: - none */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_webHidden() { READ_PROLOGUE //! TODO: implement hidden readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL bookmarkStart //! bookmarkStart handler (Bookmark Start) /*! Parent elements: - bdo (§17.3.2.3) - body (§17.2.2) - comment (§17.13.4.2) - customXml (§17.5.1.6) - customXml (§17.5.1.4) - customXml (§17.5.1.5) - customXml (§17.5.1.3) - deg (§22.1.2.26) - del (§17.13.5.14) - den (§22.1.2.28) - dir (§17.3.2.8) - docPartBody (§17.12.6) - e (§22.1.2.32) - [done] endnote (§17.11.2) - fldSimple (§17.16.19) - fName (§22.1.2.37) - [done] footnote (§17.11.10) - [done] ftr (§17.10.3) - [done] hdr (§17.10.4) - [done] hyperlink (§17.16.22) - ins (§17.13.5.18) - lim (§22.1.2.52) - moveFrom (§17.13.5.22) - moveTo (§17.13.5.25) - num (§22.1.2.75) - oMath (§22.1.2.77) - [done p (§17.3.1.22) - rt (§17.3.3.24) - rubyBase (§17.3.3.27) - sdtContent (§17.5.2.34) - sdtContent (§17.5.2.33) - sdtContent (§17.5.2.35) - sdtContent (§17.5.2.36) - [done] smartTag (§17.5.1.9) - sub (§22.1.2.112) - sup (§22.1.2.114) - tbl (§17.4.38) - tc (§17.4.66) - tr (§17.4.79) Child elements: - none */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_bookmarkStart() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(name) TRY_READ_ATTR(id) if (!name.isEmpty() && !id.isEmpty()) { MSOOXML::Utils::XmlWriteBuffer buffer; //bookmark presence limitation by ODF 1.2 if (!m_insideParagraph) { body = buffer.setWriter(body); } body->startElement("text:bookmark-start"); body->addAttribute("text:name", name); body->endElement(); // text:bookmark-start m_bookmarks[id] = name; if (!m_insideParagraph) { body = buffer.releaseWriter(m_bookmarkSnippet); } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL bookmarkEnd //! bookmarkEnd handler (Bookmark End) /*! Parent elements: - bdo (§17.3.2.3) - body (§17.2.2) - comment (§17.13.4.2) - customXml (§17.5.1.6) - customXml (§17.5.1.4) - customXml (§17.5.1.5) - customXml (§17.5.1.3) - deg (§22.1.2.26) - del (§17.13.5.14) - den (§22.1.2.28) - dir (§17.3.2.8) - docPartBody (§17.12.6) - e (§22.1.2.32) - [done] endnote (§17.11.2) - fldSimple (§17.16.19) - fName (§22.1.2.37) - [done] footnote (§17.11.10) - [done] ftr (§17.10.3) - [done] hdr (§17.10.4) - [done] hyperlink (§17.16.22) - ins (§17.13.5.18) - lim (§22.1.2.52) - moveFrom (§17.13.5.22) - moveTo (§17.13.5.25) - num (§22.1.2.75) - oMath (§22.1.2.77) - [done p (§17.3.1.22) - rt (§17.3.3.24) - rubyBase (§17.3.3.27) - sdtContent (§17.5.2.34) - sdtContent (§17.5.2.33) - sdtContent (§17.5.2.35) - sdtContent (§17.5.2.36) - [done] smartTag (§17.5.1.9) - sub (§22.1.2.112) - sup (§22.1.2.114) - tbl (§17.4.38) - tc (§17.4.66) - tr (§17.4.79) Child elements: - none */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_bookmarkEnd() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(id) if (!id.isEmpty()) { MSOOXML::Utils::XmlWriteBuffer buffer; //bookmark presence limitation by ODF 1.2 if (!m_insideParagraph) { body = buffer.setWriter(body); } body->startElement("text:bookmark-end"); body->addAttribute("text:name", m_bookmarks[id]); body->endElement(); // text:bookmark-end if (!m_insideParagraph) { body = buffer.releaseWriter(m_bookmarkSnippet); } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL numPr //! numPr handler (Numbering Definition Instance Reference) /*! This element specifies that the current paragraph references a numbering definition instance in the current document. The presence of this element specifies that the paragraph will inherit the properties specified by the numbering definition in the num element (§2.9.16) at the level specified by the level specified in the lvl element (§2.9.7) and shall have an associated number positioned before the beginning of the text flow in this paragraph. When this element appears as part of the paragraph formatting for a paragraph style, then any numbering level defined using the ilvl element shall be ignored, and the pStyle element (§2.9.25) on the associated abstract numbering definition shall be used instead. Parent elements: - [done] pPr (§17.3.1.26); - [done] pPr (§17.3.1.25); - [done] pPr (§17.7.5.2); - [done] pPr (§17.7.6.1); - [done] pPr (§17.9.23); - [done] pPr (§17.7.8.2) Child elements: - [done] ilvl (Numbering Level Reference) §17.9.3 - ins (Inserted Numbering Properties) §17.13.5.19 - [done] numId (Numbering Definition Instance Reference) §17.9.19 */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_numPr() { READ_PROLOGUE m_listFound = true; m_currentListLevel = 0; while (!atEnd()) { readNext(); debugDocx << *this; BREAK_IF_END_OF(CURRENT_EL); if (isStartElement()) { TRY_READ_IF(numId) ELSE_TRY_READ_IF(ilvl) SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL ilvl //! ilvl handler (Numbering Level Reference) /*! This element specifies the numbering level of the numbering definition instance which shall be applied to the parent paragraph. This numbering level is specified on either the abstract numbering definition's lvl element (§2.9.7), and may be overridden by a numbering definition instance level override's lvl element (§2.9.6). */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_ilvl() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) if (!val.isEmpty()) { bool ok = false; uint listValue = val.toUInt(&ok); if (ok) { m_currentListLevel = listValue; } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL numId //! numPr handler (Numbering Definition Instance Reference) /*! This element specifies that the current paragraph references a numbering definition instance in the current document. The presence of this element specifies that the paragraph will inherit the properties specified by the numbering definition in the num element (§2.9.16) at the level specified by the level specified in the lvl element (§2.9.7) and shall have an associated number positioned before the beginning of the text flow in this paragraph. When this element appears as part of the paragraph formatting for a paragraph style, then any numbering level defined using the ilvl element shall be ignored, and the pStyle element (§2.9.25) on the associated abstract numbering definition shall be used instead. Parent elements: - [done] numPr (§17.3.1.19) Child elements: - none */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_numId() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) // In docx, this value defines a predetermined style from numbering xml, // The styles from numbering have to be given some name, NumStyle has been // chosen here if (!val.isEmpty()) { if (val == "0") { m_listFound = false; // spec says that this means deleted list } else { m_currentBulletList = m_context->m_bulletStyles[val]; m_currentNumId = val; } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL delText //! delText (Deleted Text) /*! ECMA-376, 17.3.3.7, p.351. This element specifies that this run contains literal text which shall be displayed in the document. The delText element shall be used for all text runs which are part of a region of text that is contained in a deleted region using the del element. Parent Elements: - [done] r (§22.1.2.87) - [done] r (§17.3.2.25) @todo: attribute xml:space */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_delText() { READ_PROLOGUE while (!atEnd()) { readNext(); if (isCharacters()) { body->addTextSpan(text().toString()); } BREAK_IF_END_OF(CURRENT_EL) } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL drawing //! drawing handler (DrawingML Object) /*! ECMA-376, 17.3.3.9, p.362. This element specifies that a DrawingML object is located at this position in the run’s contents. The layout properties of this DrawingML object are specified using the WordprocessingML Drawing syntax (§20.4, p. 3466). Parent elements: - background (§17.2.1) - numPicBullet (§17.9.21) - object (§17.3.3.19) - r (§22.1.2.87) - Shared ML - [done] r (§17.3.2.25) Child elements: - [done] anchor (Anchor for Floating DrawingML Object) §20.4.2.3 - [done] inline (Inline DrawingML Object) §20.4.2.8 */ //! CASE #1300 //! CASE #1301 //! CASE #1380 KoFilter::ConversionStatus DocxXmlDocumentReader::read_drawing() { READ_PROLOGUE m_hyperLink = false; m_hasPosOffsetH = false; m_hasPosOffsetV = false; m_rot = 0; m_z_index = 0; pushCurrentDrawStyle(new KoGenStyle(KoGenStyle::GraphicAutoStyle, "graphic")); if (m_moveToStylesXml) { m_currentDrawStyle->setAutoStyleInStylesDotXml(true); } applyBorders(m_currentDrawStyle, m_textBorderStyles, m_textBorderPaddings); m_drawing_anchor = false; m_drawing_inline = false; MSOOXML::Utils::XmlWriteBuffer buffer; body = buffer.setWriter(body); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF_NS(wp, anchor) ELSE_TRY_READ_IF_NS(wp, inline) ELSE_WRONG_FORMAT } } body = buffer.originalWriter(); if (m_hyperLink) { body->startElement("text:a"); body->addAttribute("xlink:type", "simple"); body->addAttribute("xlink:href", QUrl(m_hyperLinkTarget).toEncoded()); } if (m_context->graphicObjectIsGroup) { body->startElement("draw:g"); } else { body->startElement("draw:frame"); body->addAttribute("draw:layer", "layout"); if (m_hasPosOffsetH) { debugDocx << "m_posOffsetH" << m_posOffsetH; m_svgX += m_posOffsetH; } if (m_hasPosOffsetV) { debugDocx << "m_posOffsetV" << m_posOffsetV; m_svgY += m_posOffsetV; } if (!m_docPrName.isEmpty()) { // from docPr/@name body->addAttribute("draw:name", m_docPrName); } if (m_rot == 0) { body->addAttribute("svg:x", EMU_TO_CM_STRING(m_svgX)); body->addAttribute("svg:y", EMU_TO_CM_STRING(m_svgY)); } else { // m_rot is in 1/60,000th of a degree qreal angle, xDiff, yDiff; MSOOXML::Utils::rotateString(m_rot, m_svgWidth, m_svgHeight, angle, xDiff, yDiff); QString rotString = QString("rotate(%1) translate(%2cm %3cm)") .arg(angle).arg((m_svgX + xDiff)/360000).arg((m_svgY + yDiff)/360000); body->addAttribute("draw:transform", rotString); } body->addAttribute("svg:width", EMU_TO_CM_STRING(m_svgWidth)); body->addAttribute("svg:height", EMU_TO_CM_STRING(m_svgHeight)); } //! @todo add more cases for text:anchor-type! use m_drawing_inline and see CASE #1343 if (m_drawing_inline) { body->addAttribute("text:anchor-type", "as-char"); m_currentDrawStyle->addProperty("style:vertical-rel", "baseline"); } else { body->addAttribute("draw:z-index", m_z_index); if (m_alignH.isEmpty()) { m_currentDrawStyle->addProperty("style:horizontal-pos", "from-left"); } else { m_currentDrawStyle->addProperty("style:horizontal-pos", m_alignH); } if (m_alignV.isEmpty()) { m_currentDrawStyle->addProperty("style:vertical-pos", "from-top"); } else if (m_alignV == "center") { m_currentDrawStyle->addProperty("style:vertical-pos", "middle"); } else if (m_alignV == "bottom") { m_currentDrawStyle->addProperty("style:vertical-pos", "bottom"); } else if (m_alignV == "top") { m_currentDrawStyle->addProperty("style:vertical-pos", "top"); } else if (m_alignV == "outside") { m_currentDrawStyle->addProperty("style:vertical-pos", "bottom"); } else if (m_alignV == "inside") { m_currentDrawStyle->addProperty("style:vertical-pos", "top"); } if (m_relativeFromV == "column") { m_currentDrawStyle->addProperty("style:vertical-rel", "paragraph"); } else if (m_relativeFromV == "bottomMargin") { // Not supported propery by ODF, making a best guess m_currentDrawStyle->addProperty("style:vertical-rel", "page"); m_currentDrawStyle->addProperty("style:vertical-pos", "bottom"); } else if (m_relativeFromV == "insideMargin") { // Not supported propery by ODF, making a best guess m_currentDrawStyle->addProperty("style:vertical-rel", "page"); m_currentDrawStyle->addProperty("style:vertical-pos", "top"); } else if (m_relativeFromV == "line") { m_currentDrawStyle->addProperty("style:vertical-rel", "paragraph"); } else if (m_relativeFromV == "margin") { if (m_headerActive || m_footerActive) { m_currentDrawStyle->addProperty("style:vertical-rel", "frame-content"); } else { m_currentDrawStyle->addProperty("style:vertical-rel", "page-content"); } } else if (m_relativeFromV == "outsideMargin") { // Not supported propery by ODF, making a best guess m_currentDrawStyle->addProperty("style:vertical-rel", "page"); m_currentDrawStyle->addProperty("style:vertical-pos", "bottom"); } else if (m_relativeFromV == "page") { if (m_headerActive || m_footerActive) { m_currentDrawStyle->addProperty("style:vertical-rel", "frame"); } else { m_currentDrawStyle->addProperty("style:vertical-rel", "page"); } } else if (m_relativeFromV == "paragraph") { m_currentDrawStyle->addProperty("style:vertical-rel", "paragraph"); } else if (m_relativeFromV == "topMargin") { m_currentDrawStyle->addProperty("style:vertical-rel", "page"); m_currentDrawStyle->addProperty("style:vertical-pos", "top"); } if (m_relativeFromH == "character") { m_currentDrawStyle->addProperty("style:horizontal-rel", "char"); body->addAttribute("text:anchor-type", "char"); } else if (m_relativeFromH == "column") { m_currentDrawStyle->addProperty("style:horizontal-rel", "paragraph"); body->addAttribute("text:anchor-type", "paragraph"); } else if (m_relativeFromH == "insideMargin") { m_currentDrawStyle->addProperty("style:horizontal-rel", "page-start-margin"); body->addAttribute("text:anchor-type", "paragraph"); } else if (m_relativeFromH == "leftMargin") { m_currentDrawStyle->addProperty("style:horizontal-rel", "page-start-margin"); body->addAttribute("text:anchor-type", "paragraph"); } else if (m_relativeFromH == "margin") { m_currentDrawStyle->addProperty("style:horizontal-rel", "page-content"); body->addAttribute("text:anchor-type", "paragraph"); } else if (m_relativeFromH == "outsideMargin") { m_currentDrawStyle->addProperty("style:horizontal-rel", "page-end-margin"); body->addAttribute("text:anchor-type", "paragraph"); } else if (m_relativeFromH == "page") { m_currentDrawStyle->addProperty("style:horizontal-rel", "page"); body->addAttribute("text:anchor-type", "paragraph"); } else if (m_relativeFromH == "rightMargin") { m_currentDrawStyle->addProperty("style:horizontal-rel", "page-end-margin"); body->addAttribute("text:anchor-type", "paragraph"); } } const QString styleName(mainStyles->insert(*m_currentDrawStyle, "gr")); body->addAttribute("draw:style-name", styleName); popCurrentDrawStyle(); (void)buffer.releaseWriter(); body->endElement(); // draw:frame/draw:g if (m_hyperLink) { body->endElement(); // text:a } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL framePr //! framePr handler (Text Frame Properties) /*! Parent elements: - [done] pPr (§17.3.1.26) - [done] pPr (§17.3.1.25) - [done] pPr (§17.7.5.2) - [done] pPr (§17.7.6.1) - [done] pPr (§17.9.23) - [done] pPr (§17.7.8.2) No child elements. */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_framePr() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(dropCap) TRY_READ_ATTR(lines) TRY_READ_ATTR(hSpace) // MS 2007 behaves so that it ignores text and paragraph styles in // case of drop cap for the first letter(s), here we set a // variable to show we have encountered a drop cap. if (!dropCap.isEmpty()) { m_dropCapStatus = DropCapRead; m_dropCapDistance = 0; m_dropCapLines.clear(); if (!lines.isEmpty()) { m_dropCapLines = lines; } if (!hSpace.isEmpty()) { bool ok; const qreal distance = qreal(TWIP_TO_POINT(hSpace.toDouble(&ok))); if (ok) { m_dropCapDistance = distance; } } } //! @todo more attributes readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL suppressLineNumbers //! w:suppressLineNumbers handler /* Parent elements: - [done] pPr (§17.3.1.26) - [done] pPr (§17.3.1.25) - [done] pPr (§17.7.5.2) - [done] pPr (§17.7.6.1) - [done] pPr (§17.9.23) - [done] pPr (§17.7.8.2) */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_suppressLineNumbers() { READ_PROLOGUE m_currentParagraphStyle.addProperty("text:number-lines", "false"); readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL ind //! ind handler //! CASE KoFilter::ConversionStatus DocxXmlDocumentReader::read_ind() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(left) bool ok = false; const qreal leftInd = qreal(TWIP_TO_POINT(left.toDouble(&ok))); if (ok) { m_currentParagraphStyle.addPropertyPt("fo:margin-left", leftInd); } // TODO: Values in {none, first-line, hanging) are from the // "Special" field of the Paragraph dialog in MS Word. The // tab-stop position in case of a list item and the implicit // tab-stop for a paragraph with hanging indent depend on this. // Check the MsooXmlUtils::convertToListProperties function. TRY_READ_ATTR(firstLine) TRY_READ_ATTR(hanging) if (!hanging.isEmpty()) { const qreal firstInd = qreal(TWIP_TO_POINT(hanging.toDouble(&ok))); if (ok) { m_currentParagraphStyle.addPropertyPt("fo:text-indent", -firstInd); } } else if (!firstLine.isEmpty()) { const qreal firstInd = qreal(TWIP_TO_POINT(firstLine.toDouble(&ok))); if (ok) { m_currentParagraphStyle.addPropertyPt("fo:text-indent", firstInd); } } TRY_READ_ATTR(right) const int rightInd = qreal(TWIP_TO_POINT(right.toDouble(&ok))); if (ok) { m_currentParagraphStyle.addPropertyPt("fo:margin-right", rightInd); } //! @todo more attributes readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL outlineLvl //! ind handler //! CASE KoFilter::ConversionStatus DocxXmlDocumentReader::read_outlineLvl() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) if (!val.isEmpty()) { bool ok = false; const uint outlineLevelValue = val.toUInt(&ok); if (ok && outlineLevelValue <= 9) { // ooxml's levels starts at 0, odf's at 1, ooxml 9 means: no level // Set non-null QString for no level, to allow seeing the difference // between non-set and set-but-empty value with KoGenStyle::attribute // ODF §19.470 style:default-outline-level says: // The style:default-outline-level attribute value can be empty. // If empty, this attribute does not inherit a list style value from a parent style. const QString odfOutlineLevelValue = (outlineLevelValue == 9) ? QString("") : QString::number(outlineLevelValue + 1); m_currentParagraphStyle.addAttribute("style:default-outline-level", odfOutlineLevelValue); } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL b //! b handler //! CASE #1112 KoFilter::ConversionStatus DocxXmlDocumentReader::read_b() { READ_PROLOGUE if (READ_BOOLEAN_VAL) { m_currentTextStyle.addProperty("fo:font-weight", "bold"); } else { m_currentTextStyle.addProperty("fo:font-weight", "normal"); } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL i //! i handler //! CASE #1112 KoFilter::ConversionStatus DocxXmlDocumentReader::read_i() { READ_PROLOGUE if (READ_BOOLEAN_VAL) { m_currentTextStyle.addProperty("fo:font-style", "italic"); } else { m_currentTextStyle.addProperty("fo:font-style", "normal"); } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL u //! u handler //! CASE #1149 KoFilter::ConversionStatus DocxXmlDocumentReader::read_u() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) //! @todo more styles MSOOXML::Utils::setupUnderLineStyle(val, m_currentTextStyleProperties); TRY_READ_ATTR(color) QColor c(MSOOXML::Utils::ST_HexColorRGB_to_QColor(color)); if (c.isValid()) { m_currentTextStyleProperties->setUnderlineColor(c); } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL sz //! sz handler (Non-Complex Script Font Size) ECMA-376, 17.3.2.38, p.342 /*! This element specifies the font size which shall be applied to all non complex script characters in the contents of this run when displayed. */ /*! Parent elements: - [done] rPr (§17.3.1.29) - rPr (§17.3.1.30) - rPr (§17.5.2.28) - rPr (§17.9.25) - [done] rPr (§17.7.9.1) - [done] rPr (§17.7.5.4) (within style) - [done] rPr (§17.3.2.28) - [done] rPr (§17.5.2.27) - [done] rPr (§17.7.6.2) - [done] rPr (§17.3.2.27) No child elements. */ //! @todo support all elements //! CASE #1162 KoFilter::ConversionStatus DocxXmlDocumentReader::read_sz() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); READ_ATTR(val) bool ok; const qreal pointSize = qreal(val.toUInt(&ok)) / 2.0; /* half-points */ if (ok) { // In case of drop cap, text size should not be read if (m_dropCapStatus != DropCapDone) { m_currentTextStyleProperties->setFontPointSize(pointSize); } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL jc //! Paragraph Alignment /*! ECMA-376, 17.3.1.13, p.239 */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_jc(jcCaller caller) { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); READ_ATTR(val) // Does ODF support high/low/medium kashida ? val = val.toLower(); if ((val == "both") || (val == "distribute")) { if (caller == jc_pPr) { m_currentParagraphStyle.addProperty("fo:text-align", "justify"); } else { m_tableMainStyle->setHorizontalAlign(KoTblStyle::CenterAlign); } } else if (val == "center") { if (caller == jc_pPr) { m_currentParagraphStyle.addProperty("fo:text-align", val); } else { m_tableMainStyle->setHorizontalAlign(KoTblStyle::CenterAlign); } } else if ((val == "start") || (val == "left")) { if (caller == jc_pPr) { m_currentParagraphStyle.addProperty("fo:text-align", "start"); } else { m_tableMainStyle->setHorizontalAlign(KoTblStyle::LeftAlign); } } else if ((val == "right") || (val == "end")) { if (caller == jc_pPr) { m_currentParagraphStyle.addProperty("fo:text-align", "end"); } else { m_tableMainStyle->setHorizontalAlign(KoTblStyle::RightAlign); } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL spacing //! spacing handler (Spacing Between Lines and Above/Below Paragraph) /*! ECMA-376, 17.3.1.33, p.269. This element specifies the inter-line and inter-paragraph spacing which shall be applied to the contents of this paragraph when it is displayed by a consumer. Parent elements: - [done] pPr (§17.3.1.26) - [done] pPr (§17.3.1.25) - [done] pPr (§17.7.5.2) - [done] pPr (§17.7.6.1) - [done] pPr (§17.9.23) - [done] pPr (§17.7.8.2) No child elements. @todo support all elements */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_spacing() { //TODO: afterLines, beforeLines are critical. READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); bool ok = true; int marginBottom = 10; bool afterAutospacing = MSOOXML::Utils::convertBooleanAttr(attrs.value("w:afterAutospacing").toString()); if (!afterAutospacing) { TRY_READ_ATTR(after) marginBottom = TWIP_TO_POINT(after.toDouble(&ok)); } if (ok) { m_currentParagraphStyle.addPropertyPt("fo:margin-bottom", marginBottom); } ok = true; int marginTop = 5; bool beforeAutospacing = MSOOXML::Utils::convertBooleanAttr(attrs.value("w:beforeAutospacing").toString()); if (!beforeAutospacing) { TRY_READ_ATTR(before) marginTop = TWIP_TO_POINT(before.toDouble(&ok)); } if (ok) { m_currentParagraphStyle.addPropertyPt("fo:margin-top", marginTop); } // for rPr TRY_READ_ATTR(val) const qreal pointSize = (TWIP_TO_POINT(val.toDouble(&ok))); if (ok) { m_currentTextStyle.addPropertyPt("fo:letter-spacing", qreal(pointSize) / 100.0); } TRY_READ_ATTR(lineRule) TRY_READ_ATTR(line) qreal lineSpace = line.toDouble(&ok); if (ok) { if (lineRule == "atLeast") { lineSpace = TWIP_TO_POINT(lineSpace); m_currentParagraphStyle.addPropertyPt("style:line-height-at-least", lineSpace); } else if (lineRule == "exact") { lineSpace = TWIP_TO_POINT(lineSpace); m_currentParagraphStyle.addPropertyPt("fo:line-height", lineSpace); } else { lineSpace = lineSpace / 2.4; // converting to percentage QString space = "%1"; space = space.arg(lineSpace); space.append('%'); m_currentParagraphStyle.addProperty("fo:line-height", space); } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL shd //! Shading handler (object's shading attributes) /*! ECMA-376, 17.3.5, p.399 Parent Elements: - [done] pPr (Paragraph Properties) §17.3.1.26 - [done] tcPr (Table Cell Properties) §17.4.70 Attributes: - color (Shading Pattern Color) - fill (Shading Background Color) - themeColor (Shading Pattern Theme Color) - themeFill (Shading Background Theme Color) - themeFillShade (Shading Background Theme Color Shade) - themeFillTint (Shading Background Theme Color Tint) - themeShade (Shading Pattern Theme Color Shade) - themeTint (Shading Pattern Theme Color Tint) - [done] val (Shading Pattern) */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_shd(shdCaller caller) { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); READ_ATTR(val) val = val.toLower(); TRY_READ_ATTR(color) //debugDocx << m_callsNames; if (!color.isEmpty() && color != MsooXmlReader::constAuto) { QColor clr(MSOOXML::Utils::ST_HexColorRGB_to_QColor(color)); if (caller == shd_rPr && clr.isValid() && val == "solid") { m_currentTextStyleProperties->setBackground(clr); } } TRY_READ_ATTR(fill) QString fillColor = fill.toLower(); if (!fillColor.isEmpty() && fillColor != MsooXmlReader::constAuto) { fillColor.prepend("#"); if (caller == shd_pPr) { m_currentParagraphStyle.addProperty("fo:background-color", fillColor); } if (caller == shd_tcPr) { m_currentTableStyleProperties->backgroundColor = fillColor; m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::BackgroundColor; } if (caller == shd_rPr && val == "clear") { if (m_currentTextStyleProperties->background() == QBrush()) { QColor clr(fillColor); m_currentTextStyleProperties->setBackground(clr); } } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL rFonts //! w:lang handler (Run Fonts) /*! ECMA-376, 17.3.2.26, p.323. Parent elements: - rPr (§17.3.1.29) (within p) - rPr (§17.3.1.30) - rPr (§17.5.2.28) - rPr (§17.9.25) - rPr (§17.7.9.1) - rPr (§17.7.5.4) (within style) - rPr (§17.3.2.28) - rPr (§17.5.2.27) - rPr (§17.7.6.2) - rPr (§17.3.2.27) No child elements. CASE #850 -> CASE #858 -> CASE #861 -> CASE #1150 @todo support all elements */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_rFonts() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); // CASE #1153 TRY_READ_ATTR(ascii) if (!ascii.isEmpty()) { m_currentTextStyle.addProperty("style:font-name", ascii, KoGenStyle::TextType); } // CASE #1152 if (ascii.isEmpty()) { TRY_READ_ATTR(asciiTheme) if (!asciiTheme.isEmpty()) { QString font = asciiTheme; if (font.startsWith(QLatin1String("major"))) { font = m_context->themes->fontScheme.majorFonts.latinTypeface; } else if (font.startsWith(QLatin1String("minor"))) { font = m_context->themes->fontScheme.minorFonts.latinTypeface; } m_currentTextStyle.addProperty("style:font-name", font); } } // CASE #1155 TRY_READ_ATTR(cs) if (!cs.isEmpty()) { m_currentTextStyle.addProperty("style:font-name-complex", cs, KoGenStyle::TextType); } // CASE #1154 if (cs.isEmpty()) { TRY_READ_ATTR(cstheme) if (!cstheme.isEmpty()) { //! @todo } } // CASE #1157 TRY_READ_ATTR(eastAsia) if (!eastAsia.isEmpty()) { m_currentTextStyle.addProperty("style:font-name-asian", eastAsia, KoGenStyle::TextType); } // CASE #1156 if (eastAsia.isEmpty()) { TRY_READ_ATTR(eastAsiaTheme) if (!eastAsiaTheme.isEmpty()) { //! @todo } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL pStyle //! pStyle handler (Referenced Paragraph Style) /*! ECMA-376, WML, 17.3.1.27, p.260. This element specifies the style ID of the paragraph style which shall be used to format the contents of this paragraph. This formatting is applied at the following location in the style hierarchy: - Document defaults - Table styles - Numbering styles - Paragraph styles (this element) - Character styles - Direct Formatting This means that all properties specified in the style element (§17.7.4.17) with a styleId which corresponds to the value in this element's val attribute are applied to the paragraph at the appropriate level in the hierarchy. Parent elements: - [done] pPr (§17.3.1.26) - [done] pPr (§17.3.1.25) - [done] pPr (§17.7.5.2) - [done] pPr (§17.7.6.1) - [done] pPr (§17.9.23) - [done] pPr (§17.7.8.2) No child elements. */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_pStyle() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) m_currentParagraphStyle.setParentName(val); readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tcMar //! tcMar (cell margin) /*! Parent elements: - .... Child elements: - ... @todo support all elements */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_tcMar() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { const QXmlStreamAttributes attrs(attributes()); if (QUALIFIED_NAME_IS(top)) { READ_ATTR(w) m_currentTableStyleProperties->topMargin = TWIP_TO_POINT(w.toDouble()); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::TopMargin; } else if (QUALIFIED_NAME_IS(left)) { READ_ATTR(w) m_currentTableStyleProperties->leftMargin = TWIP_TO_POINT(w.toDouble()); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::LeftMargin; } else if (QUALIFIED_NAME_IS(bottom)) { READ_ATTR(w) m_currentTableStyleProperties->bottomMargin = TWIP_TO_POINT(w.toDouble()); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::BottomMargin; } else if (QUALIFIED_NAME_IS(right)) { READ_ATTR(w) m_currentTableStyleProperties->rightMargin = TWIP_TO_POINT(w.toDouble()); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::RightMargin; } } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tblCellMar //! tblCellMar (cell margin defaults) /*! Parent elements: - [done] tblPr (§17.4.60) - [done] tblPr (§17.4.59) - [done] tblPr (§17.7.6.4) - [done] tblPr (§17.7.6.3) Child elements: - ... @todo support all elements */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_tblCellMar() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { const QXmlStreamAttributes attrs(attributes()); if (QUALIFIED_NAME_IS(top)) { READ_ATTR(w) m_currentTableStyleProperties->topMargin = TWIP_TO_POINT(w.toDouble()); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::TopMargin; } else if (QUALIFIED_NAME_IS(left)) { READ_ATTR(w) m_currentTableStyleProperties->leftMargin = TWIP_TO_POINT(w.toDouble()); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::LeftMargin; } else if (QUALIFIED_NAME_IS(bottom)) { READ_ATTR(w) m_currentTableStyleProperties->bottomMargin = TWIP_TO_POINT(w.toDouble()); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::BottomMargin; } else if (QUALIFIED_NAME_IS(right)) { READ_ATTR(w) m_currentTableStyleProperties->rightMargin = TWIP_TO_POINT(w.toDouble()); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::RightMargin; } } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tblBorders //! tblBorders handler (Table borders) /*! Parent elements: - [done] tblPr (§17.4.60) - [done] tblPr (§17.4.59) - [done] tblPr (§17.7.6.4) - [done] tblPr (§17.7.6.3) Child elements: - [done] bottom (Table Bottom Border) §17.4.4 - [done] end (Table Trailing Edge Border) §17.4.13 - [done] insideH (Table Inside Horizontal Edges Border) §17.4.23 - [done] insideV (Table Inside Vertical Edges Border) §17.4.25 - [done] start (Table Leading Edge Border) §17.4.37 - [done] top (Table Top Border) §17.4.77 */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_tblBorders() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { if (QUALIFIED_NAME_IS(top)) { m_currentTableStyleProperties->top = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::TopBorder; } else if (QUALIFIED_NAME_IS(bottom)) { m_currentTableStyleProperties->bottom = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::BottomBorder; } else if (QUALIFIED_NAME_IS(left)) { m_currentTableStyleProperties->left = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::LeftBorder; } else if (QUALIFIED_NAME_IS(right)) { m_currentTableStyleProperties->right = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::RightBorder; } else if (QUALIFIED_NAME_IS(insideV)) { m_currentTableStyleProperties->insideV = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::InsideVBorder; } else if (QUALIFIED_NAME_IS(insideH)) { m_currentTableStyleProperties->insideH = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::InsideHBorder; } } } READ_EPILOGUE } KoBorder::BorderData DocxXmlDocumentReader::getBorderData() { const QXmlStreamAttributes attrs(attributes()); KoBorder::BorderData borderData; TRY_READ_ATTR(val) borderData.style = borderMap.value(val); TRY_READ_ATTR(themeColor) TRY_READ_ATTR(color) if (!color.isEmpty()) { QString colorString = QString("#").append(color); borderData.innerPen.setColor(QColor(colorString)); borderData.outerPen.setColor(QColor(colorString)); } // Fallback to theme if (!borderData.innerPen.color().isValid() && !themeColor.isEmpty()) { MSOOXML::DrawingMLColorSchemeItemBase *colorItem = 0; colorItem = m_context->themes->colorScheme.value(themeColor); if (colorItem) { borderData.innerPen.setColor(colorItem->value()); borderData.outerPen.setColor(colorItem->value()); } } TRY_READ_ATTR(sz) borderData.outerPen.setWidthF(sz.toDouble() / 8.0); return borderData; } #undef CURRENT_EL #define CURRENT_EL tblpPr //! tblpPr handler (Floating Table Positioning) /*! ECMA-376, 17.4.58, p. 475. Parent elements: - [done] tblPr (§17.4.60) - [done] tblPr (§17.4.59) - [done] tblPr (§17.7.6.4) - [done] tblPr (§17.7.6.3) Child elements: - none */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_tblpPr() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(bottomFromText) TRY_READ_ATTR(leftFromText) TRY_READ_ATTR(rightFromText) TRY_READ_ATTR(topFromText) TRY_READ_ATTR(horzAnchor) TRY_READ_ATTR(vertAnchor) TRY_READ_ATTR(tblpX) TRY_READ_ATTR(tblpXSpec) TRY_READ_ATTR(tblpY) TRY_READ_ATTR(tblpYSpec) //If the tblpYSpecX/tblpYSpec attribute is also specified, then tblpX/tblpY //value is ignored. m_svgX = m_svgY = 0; if (tblpXSpec.isEmpty()) { STRING_TO_INT(tblpX, m_svgX, QString("w:tblpX")); } if (tblpYSpec.isEmpty()) { STRING_TO_INT(tblpY, m_svgY, QString("w:tblpY")); } int bottom = 0, left =0, right = 0, top = 0; STRING_TO_INT(bottomFromText, bottom, QString("w:bottomFromText")); STRING_TO_INT(leftFromText, left, QString("w:leftFromText")); STRING_TO_INT(rightFromText, right, QString("w:rightFromText")); STRING_TO_INT(topFromText, top, QString("w:topFromText")); pushCurrentDrawStyle(new KoGenStyle(KoGenStyle::GraphicAutoStyle, "graphic")); if (m_moveToStylesXml) { m_currentDrawStyle->setAutoStyleInStylesDotXml(true); } //fo:margin m_currentDrawStyle->addPropertyPt("fo:margin-bottom", TWIP_TO_POINT(bottom)); m_currentDrawStyle->addPropertyPt("fo:margin-left", TWIP_TO_POINT(left)); m_currentDrawStyle->addPropertyPt("fo:margin-right", TWIP_TO_POINT(right)); m_currentDrawStyle->addPropertyPt("fo:margin-top", TWIP_TO_POINT(top)); //style:horizontal-rel if (horzAnchor.isEmpty()) { m_currentDrawStyle->addProperty("style:horizontal-rel", "page"); } else if (horzAnchor == "margin") { m_currentDrawStyle->addProperty("style:horizontal-rel", "page-content"); } else if (horzAnchor == "page") { m_currentDrawStyle->addProperty("style:horizontal-rel", "page"); } else if (horzAnchor == "text") { m_currentDrawStyle->addProperty("style:horizontal-rel", "paragraph"); } //style:vertical-rel if (vertAnchor.isEmpty()) { if (m_headerActive || m_footerActive) { m_currentDrawStyle->addProperty("style:vertical-rel", "frame"); } else { m_currentDrawStyle->addProperty("style:vertical-rel", "page"); } } else if (vertAnchor == "margin") { m_currentDrawStyle->addProperty("style:vertical-rel", "page-content"); } else if (vertAnchor == "page") { if (m_headerActive || m_footerActive) { m_currentDrawStyle->addProperty("style:vertical-rel", "frame"); } else { m_currentDrawStyle->addProperty("style:vertical-rel", "page"); } } else if (vertAnchor == "text") { m_currentDrawStyle->addProperty("style:vertical-rel", "paragraph"); } //style:horizontal-pos if (tblpXSpec.isEmpty()) { m_currentDrawStyle->addProperty("style:horizontal-pos", "from-left"); } else { m_currentDrawStyle->addProperty("style:horizontal-pos", tblpXSpec); } //style:vertical-pos if (tblpYSpec.isEmpty()) { m_currentDrawStyle->addProperty("style:vertical-pos", "from-top"); } else if (tblpYSpec == "center") { m_currentDrawStyle->addProperty("style:vertical-pos", "middle"); } else if (tblpYSpec == "top") { m_currentDrawStyle->addProperty("style:vertical-pos", "top"); } else if (tblpYSpec == "inside") { m_currentDrawStyle->addProperty("style:vertical-pos", "top"); } else if (tblpYSpec == "bottom") { m_currentDrawStyle->addProperty("style:vertical-pos", "bottom"); } else if (tblpYSpec == "outside") { m_currentDrawStyle->addProperty("style:vertical-pos", "bottom"); } //style:wrap if (tblpXSpec.isEmpty() || (tblpXSpec == "left")) { m_currentDrawStyle->addProperty("style:wrap", "right"); } else if (tblpXSpec == "right") { m_currentDrawStyle->addProperty("style:wrap", "left"); } else { m_currentDrawStyle->addProperty("style:wrap", "parallel"); } m_currentDrawStyle->addProperty("style:number-wrapped-paragraphs", "no-limit"); //draw:auto-grow-height m_currentDrawStyle->addProperty("draw:auto-grow-height", "true"); m_currentDrawStyleName = mainStyles->insert(*m_currentDrawStyle); popCurrentDrawStyle(); readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tblStyle //! tblStyle handler (Referenced table style) /*! Parent elements: - [done] tblPr (§17.4.60) - [done] tblPr (§17.4.59) - [done] tblPr (§17.7.6.4) - [done] tblPr (§17.7.6.3) Child elements: - none */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_tblStyle() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) m_currentTableStyleName = val; //Inheriting values from the defined style MSOOXML::DrawingTableStyle* tableStyle = m_context->m_tableStyles.value(m_currentTableStyleName); Q_ASSERT(tableStyle); if (tableStyle) { m_tableMainStyle->setHorizontalAlign(tableStyle->mainStyle->horizontalAlign()); } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL rStyle //! rStyle handler (Referenced run Style) /*! Parent elements: - rPr (§17.3.1.29) - rPr (§17.3.1.30) - rPr (§17.5.2.28) - rPr (§17.9.25) - rPr (§17.7.9.1) - rPr (§17.7.5.4) - rPr (§17.3.2.28) - rPr (§17.5.2.27) - rPr (§17.7.6.2) - rPr (§17.3.2.27) No child elements. */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_rStyle() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) m_currentTextStyle.setParentName(val); readNext(); READ_EPILOGUE } bool DocxXmlDocumentReader::handleSpecialField() { if (m_specialCharacters.isEmpty()) { return false; } QString instr = m_specialCharacters.trimmed(); m_specialCharacters.clear(); QVector instructions; while (instr.indexOf(' ') > 0) { int place = instr.indexOf(' '); instructions.push_back(instr.left(place)); instr.remove(0, place + 1); } instructions.push_back(instr); QString command = instructions.at(0); bool returnTrue = true; if (command == "AUTHOR") { body->startElement("text:author-name"); } else if (command == "CREATEDATE") { body->startElement("text:creation-date"); } else if (command == "DATE") { body->startElement("text:date"); } else if (command == "EDITIME") { body->startElement("text:modification-time"); } else if (command == "FILENAME") { body->startElement("text:file-name"); } else if (command == "NUMPAGES") { body->startElement("text:page-count"); } else if (command == "NUMWORDS") { body->startElement("text:word-count"); } else if (command == "PAGE") { body->startElement("text:page-number"); body->addAttribute("text:select-page", "current"); } else if (command == "PRINTDATE") { body->startElement("text:print-date"); } else if (command == "REF") { if ((instructions.size() > 3) && instructions.contains("\\h")) { body->startElement("text:bookmark-ref"); body->addAttribute("text:reference-format", "page"); body->addAttribute("text:ref-name", instructions.at(1)); } else { returnTrue = false; } } else if (command == "TIME") { body->startElement("text:time"); } else if (command == "SAVEDATE") { body->startElement("text:modification-date"); } else { returnTrue = false; } return returnTrue; } #undef CURRENT_EL #define CURRENT_EL fldSimple //! fldSimple handler (Simple Field) /*! Parent elements: - bdo (§17.3.2.3) - customXml (§17.5.1.3) - dir (§17.3.2.8) - [done] fldSimple (§17.16.19) - hyperlink (§17.16.22) - [done] p (§17.3.1.22) - [done] sdtContent (§17.5.2.36) - [done] smartTag (§17.5.1.9) Child elements: - bdo (Bidirectional Override) §17.3.2.3 - [done] bookmarkEnd (Bookmark End) §17.13.6.1 - [done] bookmarkStart (Bookmark Start) §17.13.6.2 - commentRangeEnd (Comment Anchor Range End) §17.13.4.3 - commentRangeStart (Comment Anchor Range Start) §17.13.4.4 - customXml (Inline-Level Custom XML Element) §17.5.1.3 - customXmlDelRangeEnd (Custom XML Markup Deletion End) §17.13.5.4 - customXmlDelRangeStart (Custom XML Markup Deletion Start) §17.13.5.5 - customXmlInsRangeEnd (Custom XML Markup Insertion End) §17.13.5.6 - customXmlInsRangeStart (Custom XML Markup Insertion Start) §17.13.5.7 - customXmlMoveFromRangeEnd (Custom XML Markup Move Source End) §17.13.5.8 - customXmlMoveFromRangeStart (Custom XML Markup Move Source Start) §17.13.5.9 - customXmlMoveToRangeEnd (Custom XML Markup Move Destination Location End) §17.13.5.10 - customXmlMoveToRangeStart (Custom XML Markup Move Destination Location Start) §17.13.5.11 - [done] del (Deleted Run Content) §17.13.5.14 - dir (Bidirectional Embedding Level) §17.3.2.8 - [done] fldSimple (Simple Field) §17.16.19 - [done] hyperlink (Hyperlink) §17.16.22 - [done] ins (Inserted Run Content) §17.13.5.18 - moveFrom (Move Source Run Content) §17.13.5.22 - moveFromRangeEnd (Move Source Location Container - End) §17.13.5.23 - moveFromRangeStart (Move Source Location Container - Start) §17.13.5.24 - moveTo (Move Destination Run Content) §17.13.5.25 - moveToRangeEnd (Move Destination Location Container - End) §17.13.5.27 - moveToRangeStart (Move Destination Location Container - Start) §17.13.5.28 - [done] oMath (Office Math) §22.1.2.77 - [done] oMathPara (Office Math Paragraph) §22.1.2.78 - permEnd (Range Permission End) §17.13.7.1 - permStart (Range Permission Start) §17.13.7.2 - proofErr (Proofing Error Anchor) §17.13.8.1 - [done] r (Text Run) §17.3.2.25 - [done] sdt (Inline-Level Structured Document Tag) §17.5.2.31 - [done] smartTag (Inline-Level Smart Tag) §17.5.1.9 - subDoc (Anchor for Subdocument Location) §17.17.1.1 @todo support all elements */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_fldSimple() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(instr) m_specialCharacters = instr; // @todo support all attributes while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(fldSimple) ELSE_TRY_READ_IF(r) ELSE_TRY_READ_IF(sdt) ELSE_TRY_READ_IF(hyperlink) ELSE_TRY_READ_IF(del) ELSE_TRY_READ_IF(ins) ELSE_TRY_READ_IF(bookmarkStart) ELSE_TRY_READ_IF(bookmarkEnd) ELSE_TRY_READ_IF_NS(m, oMathPara) ELSE_TRY_READ_IF_NS(m, oMath) ELSE_TRY_READ_IF(smartTag) SKIP_UNKNOWN } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tabs //! tabs handler (Set of Custom Tab Stops) /*! ECMA-376, 17.3.1.38, p.269 This element specifies a sequence of custom tab stops which shall be used for any tab characters in the current paragraph. If this element is omitted on a given paragraph, its value is determined by the setting previously set at any level of the style hierarchy (i.e. that previous setting remains unchanged). If this setting is never specified in the style hierarchy, then no custom tab stops shall be used for this paragraph. As well, this property is additive - tab stops at each level in the style hierarchy are added to each other to determine the full set of tab stops for the paragraph. A hanging indent specified via the hanging attribute on the ind element (§17.3.1.12) shall also always implicitly create a custom tab stop at its location. Parent elements: - [done] pPr (§17.3.1.26) - [done] pPr (§17.3.1.25) - [done] pPr (§17.7.5.2) - [done] pPr (§17.7.6.1) - [done] pPr (§17.9.23) - [done] pPr (§17.7.8.2) Child elements: - [done] tab (§17.3.137) */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_tabs() { READ_PROLOGUE QBuffer tabs; tabs.open(QIODevice::WriteOnly); KoXmlWriter elementWriter(&tabs, 4 /*proper indentation*/); elementWriter.startElement("style:tab-stops"); QBuffer buffer; buffer.open(QIODevice::WriteOnly); KoXmlWriter *oldBody = body; body = new KoXmlWriter(&buffer); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(tab) ELSE_WRONG_FORMAT } } elementWriter.addCompleteElement(&buffer); delete body; body = oldBody; elementWriter.endElement(); // style-tab-stops QString tabStops = QString::fromUtf8(tabs.buffer(), tabs.buffer().size()); debugDocx << tabStops; m_currentParagraphStyle.addChildElement("style:tab-stops", tabStops); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tab //! tab (Custom Tab Stop) /*! ECMA-376, 17.3.1.37, p.267 Specifies a single custom tab stop defined within a set of paragraph properties in a document. A tab stop location shall always be measured relative to the leading edge of the paragraph in which it is used (that is, the left edge for a left-to-right paragraph, and the right edge for a right-to-left paragraph). Parent elements: - [done] tabs (§17.3.1.38) Child elements: - None */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_tab() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(leader) TRY_READ_ATTR(pos) TRY_READ_ATTR(val) // "clear" - Specifies that the current tab stop is cleared and // shall be removed and ignored when processing the contents of // this document. // // NOTE: This is a workaround! The correct approach would be to // clear the tab-stop inherited from the parent named style at the // specified position. But this must be done during ODF loading // and it's not supported by ODF. The solution for a viewer would // be to not save tab-stop elements to the named style and only // save the final set into each "child" style. if (val == "clear") { readNext(); READ_EPILOGUE } body->startElement("style:tab-stop"); // ST_TabJc (Custom Tab Stop Type) in {bar, center, clear, // decimal, end, num, start} - there's (left, right) instead of // (start, end) according to test files. // // ODF: The default value for this attribute is left. if (!val.isEmpty()) { if (val == "center") { body->addAttribute("style:type", "center"); } else if (val == "decimal") { body->addAttribute("style:type", "char"); body->addAttribute("style:char", "." ); } else if (val == "end" || val == "right") { body->addAttribute("style:type", "right"); } else if (val == "bar" || val == "num") { debugDocx << "Unhandled tab justification code:" << val; } } bool ok = false; const qreal value = qreal(TWIP_TO_POINT(pos.toDouble(&ok))); if (ok) { body->addAttributePt("style:position", value); } // ST_TabTlc (Custom Tab Stop Leader Character) in {dot, heavy, // hyphen, middleDot, none, underscore} // // ODF: The default value for this attribute is “ “ (U+0020). QChar text; if (!leader.isEmpty()) { if (leader == "dot" || leader == "middleDot") { text = QChar('.'); } else if (leader == "hyphen") { text = QChar('-'); } else if (leader == "underscore" || leader == "heavy") { text = QChar('_'); } else if (leader == "none") { text = QChar(); } } if (!text.isNull()) { body->addAttribute("style:leader-text", text); } body->endElement(); // style:tab-stop readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL ptab //! ptab handler (absolute tab) /*! Parent elements: - [done] r (§22.1.2.87); - [done] r (§17.3.2.25) Child elements: - none @todo support all attributes */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_ptab() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); //! @todo: support all attributes properly body->startElement("text:tab"); body->endElement(); // text:tab readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL pBdr //! pBdr handler (Paragraph Borders) /*! ECMA-376, WML, 17.3.1.24, p.256. This element specifies the borders for the parent paragraph. Each child element shall specify a specific kind of border (left, right, bottom, top, and between). Parent elements: - [done] pPr (§17.3.1.26) - [done] pPr (§17.3.1.25) - [done] pPr (§17.7.5.2) - [done] pPr (§17.7.6.1) - [done] pPr (§17.9.23) - [done] pPr (§17.7.8.2) Child elements: - bar (Paragraph Border Between Facing Pages) §17.3.1.4 - between (Paragraph Border Between Identical Paragraphs) §17.3.1.5 - [done] bottom (Paragraph Border Below Identical Paragraphs) §17.3.1.7 - [done] left (Left Paragraph Border) §17.3.1.17 - [done] right (Right Paragraph Border) §17.3.1.28 - [done] top (Paragraph Border Above Identical Paragraphs) §17.3.1.42 @todo support all elements */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_pBdr() { READ_PROLOGUE m_borderStyles.clear(); m_borderPaddings.clear(); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { if (QUALIFIED_NAME_IS(top)) { RETURN_IF_ERROR(readBorderElement(TopBorder, "top", m_borderStyles, m_borderPaddings)); } else if (QUALIFIED_NAME_IS(left)) { RETURN_IF_ERROR(readBorderElement(LeftBorder, "left", m_borderStyles, m_borderPaddings)); } else if (QUALIFIED_NAME_IS(bottom)) { RETURN_IF_ERROR(readBorderElement(BottomBorder, "bottom", m_borderStyles, m_borderPaddings)); } else if (QUALIFIED_NAME_IS(right)) { RETURN_IF_ERROR(readBorderElement(RightBorder, "right", m_borderStyles, m_borderPaddings)); } SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } applyBorders(&m_currentParagraphStyle, m_borderStyles, m_borderPaddings); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL bdr //! bbdr handler (Text Border) /*! Parent elements: - [done] rPr (§17.3.1.29); - [done] rPr (§17.3.1.30); - [done] rPr (§17.5.2.28); - [done] rPr (§17.9.25); - [done] rPr (§17.7.9.1); - [done] rPr (§17.7.5.4); - [done] rPr (§17.3.2.28); - [done] rPr (§17.5.2.27); - [done] rPr (§17.7.6.2); - [done] rPr (§17.3.2.27) Child elements: - none (?) @todo support all elements */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_bdr() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); m_textBorderStyles.clear(); m_textBorderPaddings.clear(); READ_ATTR(val) TRY_READ_ATTR(sz) TRY_READ_ATTR(color) createBorderStyle(sz, color, val, TopBorder, m_textBorderStyles); createBorderStyle(sz, color, val, LeftBorder, m_textBorderStyles); createBorderStyle(sz, color, val, BottomBorder, m_textBorderStyles); createBorderStyle(sz, color, val, RightBorder, m_textBorderStyles); TRY_READ_ATTR(space) if (!space.isEmpty()) { bool ok = false; const qreal sp = qreal(TWIP_TO_POINT(space.toDouble(&ok))); if (ok) { m_textBorderPaddings.insertMulti(TopBorder, sp); m_textBorderPaddings.insertMulti(LeftBorder, sp); m_textBorderPaddings.insertMulti(RightBorder, sp); m_textBorderPaddings.insertMulti(BottomBorder, sp); } } // Note that styles are not applied to anything, odf does not support // border around normal text run, but ooxml uses this element also to determine // borders for example to pictures readNext(); READ_EPILOGUE } void DocxXmlDocumentReader::readStrikeElement(KoCharacterStyle::LineType type) { const QXmlStreamAttributes attrs(attributes()); if (READ_BOOLEAN_VAL) { m_currentTextStyleProperties->setStrikeOutType(type); m_currentTextStyleProperties->setStrikeOutStyle(KoCharacterStyle::SolidLine); //! @todo m_currentTextStyleProperties->strikeOutWidth() ?? //! @todo m_currentTextStyleProperties->setStrikeOutColor() ?? //! @todo m_currentTextStyleProperties->setStrikeOutMode() ?? //! @todo m_currentTextStyleProperties->setStrikeOutText() ?? } } #undef CURRENT_EL #define CURRENT_EL strike //! strike handler //! CASE #1050 KoFilter::ConversionStatus DocxXmlDocumentReader::read_strike() { READ_PROLOGUE readStrikeElement(KoCharacterStyle::SingleLine); readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL dstrike //! dstrike handler //! CASE #1051 KoFilter::ConversionStatus DocxXmlDocumentReader::read_dstrike() { READ_PROLOGUE readStrikeElement(KoCharacterStyle::DoubleLine); readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL caps //! caps handler /*! Parent elements: - [done] rPr (many) */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_caps() { READ_PROLOGUE if (READ_BOOLEAN_VAL) { m_currentTextStyleProperties->setFontCapitalization(QFont::AllUppercase); } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL outline //! outline handler /*! Parent Elements: - [done] rPr (many) */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_outline() { READ_PROLOGUE m_currentTextStyleProperties->setTextOutline(QPen(Qt::SolidLine)); readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL smallCaps //! smallCaps handler /*! Parent elements: - [done] rPr (many) */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_smallCaps() { READ_PROLOGUE if (READ_BOOLEAN_VAL) { m_currentTextStyleProperties->setFontCapitalization(QFont::SmallCaps); } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL w //! w handler (Expanded/Compressed Text) /*! ECMA-376, 17.3.2.43, p.350 This element specifies the amount by which each character shall be expanded or when the character is rendered in the document. Parent elements: - [done] rPr (§17.3.1.29) - rPr (§17.3.1.30) - rPr (§17.5.2.28) - rPr (§17.9.25) - rPr (§17.7.9.1) - rPr (§17.7.5.4) - [done] rPr (§17.3.2.28) - rPr (§17.5.2.27) - rPr (§17.7.6.2) - rPr (§17.3.2.27) No child elements. */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_w() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); READ_ATTR(val) if (!val.isEmpty()) { int wNumber; STRING_TO_INT(val, wNumber, "w@val") m_currentTextStyleProperties->setTextScale(wNumber); } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL vanish //! vanish handler (Hidden text) /* Parent elements: - [done] rPr (§17.3.1.29); - [done] rPr (§17.3.1.30); - [done] rPr (§17.5.2.28); - [done] rPr (§17.9.25); . [done] rPr (§17.7.9.1); - [done] rPr (§17.7.5.4); - [done] rPr (§17.3.2.28); - [done] rPr (§17.5.2.27); - [done] rPr (§17.7.6.2); - [done] rPr (§17.3.2.27) No child elements */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_vanish() { READ_PROLOGUE m_currentTextStyle.addProperty("text:display", "none"); readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL color //! color handler //! CASE #1158 KoFilter::ConversionStatus DocxXmlDocumentReader::read_color() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); READ_ATTR(val) //! @todo more styles if (val == MsooXmlReader::constAuto) { m_currentTextStyle.addProperty("style:use-window-font-color", "true"); } else { QColor color(MSOOXML::Utils::ST_HexColorRGB_to_QColor(val)); if (color.isValid()) { m_currentTextStyleProperties->setForeground(QBrush(color)); } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL highlight //! highlight handler (Text Highlighting) /*! ECMA-376, 17.3.2.15, p.310 */ //! CASE #1158 KoFilter::ConversionStatus DocxXmlDocumentReader::read_highlight() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); READ_ATTR(val) m_currentTextStyleProperties->setBackground(MSOOXML::Utils::ST_HighlightColor_to_QColor(val)); readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL vertAlign //! vertAlign handler (Subscript/Superscript Text) ECMA-376, 17.3.2.42, p.349 /*! This element specifies the alignment which shall be applied to the contents of this run when displayed. */ /*! Parent elements: - [done] rPr No child elements. */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_vertAlign() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) val = val.toLower(); if (val == "superscript") { m_currentTextStyleProperties->setVerticalAlignment(QTextCharFormat::AlignSuperScript); } else if (val == "subscript") { m_currentTextStyleProperties->setVerticalAlignment(QTextCharFormat::AlignSubScript); } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL lang //! w:lang handler (Languages for Run Content) /*! ECMA-376, 17.3.2.20, p.314. Parent elements: - [done] rPr (§17.3.1.29) (within pPr §17.3.1.26) - rPr (§17.3.1.30) (within rPrChange §17.13.5.30) - rPr (§17.3.2.27) (within del §17.13.5.13, ins §17.13.5.16, rPrChange §17.13.5.31) - [done] rPr (§17.3.2.28) (witin ctrlPr §22.1.2.23, r §22.1.2.87, r §17.3.2.25) - rPr (§17.5.2.27) (within sdtPr §17.5.2.38) - rPr (§17.5.2.28) (within sdtEndPr §17.5.2.37) - [done] rPr (§17.7.9.1) (within style §17.7.4.17 - styles) - [done] rPr (§17.7.5.4) (within rPrDefault §17.7.5.5 - styles) - rPr (§17.7.6.2) (within tblStylePr §17.7.6.6 - styles) - rPr (§17.9.25) (within lvl §17.9.6, lvl §17.9.7 - numbering) No child elements. CASE #850 -> CASE #858 -> CASE #861 -> CASE #1100 @todo support all elements */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_lang() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); // CASE #1100 TRY_READ_ATTR(bidi) QString language, country; if (!bidi.isEmpty()) { if (MSOOXML::Utils::ST_Lang_to_languageAndCountry(bidi, language, country)) { m_currentTextStyle.addProperty("style:language-complex", language, KoGenStyle::TextType); m_currentTextStyle.addProperty("style:country-complex", country, KoGenStyle::TextType); } else { warnDocx << "invalid value of \"bidi\" attribute:" << bidi << " - skipping"; } } TRY_READ_ATTR(val) if (MSOOXML::Utils::ST_Lang_to_languageAndCountry(val, language, country)) { m_currentTextStyle.addProperty("fo:language", language, KoGenStyle::TextType); m_currentTextStyle.addProperty("fo:country", country, KoGenStyle::TextType); } else { warnDocx << "invalid value of \"val\" attribute:" << val << " - skipping"; } TRY_READ_ATTR(eastAsia) if (!eastAsia.isEmpty()) { if (MSOOXML::Utils::ST_Lang_to_languageAndCountry(eastAsia, language, country)) { m_currentTextStyle.addProperty("style:language-asian", language, KoGenStyle::TextType); m_currentTextStyle.addProperty("style:country-asian", country, KoGenStyle::TextType); } else { warnDocx << "invalid value of \"eastAsia\" attribute:" << eastAsia << " - skipping"; } } debugDocx << "bidi:" << bidi << "val:" << val << "eastAsia:" << eastAsia; readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL background //! w:background handler (Document Background) /*! ECMA-376, 17.2.1, p. 189. This element specifies the background for every page of the document containing the background element. Child element: - [done] drawing (§17.3.3.9) Attributes: - [done] color (Background Color) - themeColor (Background Theme Color) - themeTint (Border Theme Color Tint) - themeShade (Border Theme Color Shade) */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_background() { READ_PROLOGUE // The specs say that the background will not be shown in the default view but only in the fullscreen-view except the // displayBackgroundShape is defined. Since we cannot (and don't want to) make such assumptions about the available // views we only take over whatever is displayed in that default view. That's inline with what OO.org does too. bool displayBackgroundShape = m_context->import->documentSettings().contains("displayBackgroundShape"); if (displayBackgroundShape) { QString val = m_context->import->documentSetting("displayBackgroundShape").toString(); displayBackgroundShape = (val != "off" && val != "0" && val != "false"); } if (displayBackgroundShape) { const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(color) QColor tmpColor(MSOOXML::Utils::ST_HexColorRGB_to_QColor(color)); if (tmpColor.isValid()) m_backgroundColor = tmpColor; while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { if (qualifiedName() == "v:background") { TRY_READ(VML_background) } ELSE_TRY_READ_IF(drawing) SKIP_UNKNOWN } } } else { while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tbl //! tbl handler (Table) /*! ECMA-376, 17.4.38, p. 460. This element specifies the contents of a table present in the document. A table is a set of paragraphs (and other block-level content) arranged in rows and columns. Parent elements: - [done] body (§17.2.2) - comment (§17.13.4.2) - customXml (§17.5.1.6) - docPartBody (§17.12.6) - [done] endnote (§17.11.2); - [done] footnote (§17.11.10) - [done] ftr (§17.10.3) - [done] hdr (§17.10.4) - sdtContent (§17.5.2.34) - [done] tc (§17.4.66) Child elements: - [done] bookmarkEnd (Bookmark End) §17.13.6.1 - [done] bookmarkStart (Bookmark Start) §17.13.6.2 - commentRangeEnd (Comment Anchor Range End) §17.13.4.3 - commentRangeStart (Comment Anchor Range Start) §17.13.4.4 - customXml (Row-Level Custom XML Element) §17.5.1.5 - customXmlDelRangeEnd (Custom XML Markup Deletion End) §17.13.5.4 - customXmlDelRangeStart (Custom XML Markup Deletion Start) §17.13.5.5 - customXmlInsRangeEnd (Custom XML Markup Insertion End) §17.13.5.6 - customXmlInsRangeStart (Custom XML Markup Insertion Start) §17.13.5.7 - customXmlMoveFromRangeEnd (Custom XML Markup Move Source End) §17.13.5.8 - customXmlMoveFromRangeStart (Custom XML Markup Move Source Start) §17.13.5.9 - customXmlMoveToRangeEnd (Custom XML Markup Move Destination Location End) §17.13.5.10 - customXmlMoveToRangeStart (Custom XML Markup Move Destination Location Start) §17.13.5.11 - del (Deleted Run Content) §17.13.5.14 - ins (Inserted Run Content) §17.13.5.18 - moveFrom (Move Source Run Content) §17.13.5.22 - moveFromRangeEnd (Move Source Location Container - End) §17.13.5.23 - moveFromRangeStart (Move Source Location Container - Start) §17.13.5.24 - moveTo (Move Destination Run Content) §17.13.5.25 - moveToRangeEnd (Move Destination Location Container - End) §17.13.5.27 - moveToRangeStart (Move Destination Location Container - Start) §17.13.5.28 - oMath (Office Math) §22.1.2.77 - oMathPara (Office Math Paragraph) §22.1.2.78 - permEnd (Range Permission End) §17.13.7.1 - permStart (Range Permission Start) §17.13.7.2 - proofErr (Proofing Error Anchor) §17.13.8.1 - sdt (Row-Level Structured Document Tag) §17.5.2.30 - [done] tblGrid (Table Grid) §17.4.49 - [done] tblPr (Table Properties) §17.4.60 - [done] tr (Table Row) §17.4.79 */ //! @todo support all child elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_tbl() { + m_table = KoTable::create(); + READ_PROLOGUE // save current state of lists processing saveState(); - KoTable table; - m_table = &table; - m_table->setName(QLatin1String("Table") + QString::number(++m_currentTableNumber)); m_currentTableRowNumber = 0; m_currentTableColumnNumber = 0; m_currentDefaultCellStyle = 0; m_currentTableStyleProperties = 0; m_currentLocalTableStyles = new MSOOXML::LocalTableStyles; m_currentTableStyleName.clear(); m_currentDrawStyleName.clear(); m_tableMainStyle = KoTblStyle::create(); if (m_moveToStylesXml) { m_tableMainStyle->setAutoStyleInStylesDotXml(true); } //Disable to get a style of type TableAutoStyle. // m_tableMainStyle->setName("TableMainStyle" + QString::number(m_currentTableNumber - 1)); bool sectionAdded = false; if (m_createSectionStyle) { m_createSectionStyle = false; sectionAdded = true; // To avoid the style to become a duplicate or being duplicated. m_tableMainStyle->setMasterPageName("placeholder"); } // Fix me, for tables inside tables this might not work m_activeRoles = 0; MSOOXML::Utils::XmlWriteBuffer buffer; body = buffer.setWriter(body); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { if(QUALIFIED_NAME_IS(tblPr)) { //tblPr/tblBorders m_currentTableStyleProperties = new MSOOXML::TableStyleProperties; TRY_READ(tblPr) m_currentDefaultCellStyle = m_currentTableStyleProperties; m_currentTableStyleProperties = 0; //debug border information #ifdef DOCXXML_DEBUG_TABLES debugDocx << "==> [tblBorders] information: <===================="; debugDocx << "top:" << m_currentDefaultCellStyle->top.style; debugDocx << "bottom:" << m_currentDefaultCellStyle->bottom.style; debugDocx << "left:" << m_currentDefaultCellStyle->left.style; debugDocx << "right:" << m_currentDefaultCellStyle->right.style; debugDocx << "insideH:" << m_currentDefaultCellStyle->insideH.style; debugDocx << "insideV:" << m_currentDefaultCellStyle->insideV.style; #endif } ELSE_TRY_READ_IF(tblGrid) ELSE_TRY_READ_IF(tr) SKIP_UNKNOWN // ELSE_TRY_READ_IF(bookmarkStart) // ELSE_TRY_READ_IF(bookmarkEnd) // ELSE_WRONG_FORMAT } } //reference to the default parent style from styles.xml if (m_currentTableStyleName.isEmpty() && m_context->m_namedDefaultStyles.contains("table")) { m_currentTableStyleName = m_context->m_namedDefaultStyles.value("table"); MSOOXML::DrawingTableStyle* tableStyle = m_context->m_tableStyles.value(m_currentTableStyleName); Q_ASSERT(tableStyle); if (tableStyle) { m_tableMainStyle->setHorizontalAlign(tableStyle->mainStyle->horizontalAlign()); } } //Floating Table if (!m_currentDrawStyleName.isEmpty()) { body->startElement("draw:frame"); body->addAttribute("draw:style-name", m_currentDrawStyleName.toUtf8()); body->addAttribute("text:anchor-type", "paragraph"); body->addAttributePt("svg:width", TWIP_TO_POINT(m_svgWidth)); if (m_svgX != 0) { body->addAttributePt("svg:x", TWIP_TO_POINT(m_svgX)); } if (m_svgY != 0) { body->addAttributePt("svg:y", TWIP_TO_POINT(m_svgY)); } body->startElement("draw:text-box"); } m_table->setTableStyle(m_tableMainStyle); defineTableStyles(); #ifdef DOCXXML_DEBUG_TABLES debugDocx << "----------------------------------------"; #endif m_table->saveOdf(*body, *mainStyles); if (sectionAdded) { m_currentSectionStyleName = m_table->tableStyle()->name(); m_currentSectionStyleFamily = "table"; } delete m_currentLocalTableStyles; //Floating Table if (!m_currentDrawStyleName.isEmpty()) { body->endElement(); //draw:text-box body->endElement(); //draw:frame body = buffer.releaseWriter(m_floatingTable); } else { body = buffer.releaseWriter(); } // restore previous state of lists processing restoreState(); READ_EPILOGUE } void DocxXmlDocumentReader::defineTableStyles() { const int rowCount = m_table->rowCount(); const int columnCount = m_table->columnCount(); MSOOXML::DrawingTableStyleConverterProperties converterProperties; converterProperties.setRowCount(rowCount); converterProperties.setColumnCount(columnCount); converterProperties.setRoles(m_activeRoles); converterProperties.setLocalStyles(*m_currentLocalTableStyles); converterProperties.setLocalDefaulCelltStyle(m_currentDefaultCellStyle); MSOOXML::DrawingTableStyle* tableStyle = m_context->m_tableStyles.value(m_currentTableStyleName); MSOOXML::DrawingTableStyleConverter styleConverter(converterProperties, tableStyle); QPair spans; for(int row = 0; row < rowCount; ++row ) { #ifdef DOCXXML_DEBUG_TABLES debugDocx << "----- [ROW" << row +1 << "] ----------"; #endif for(int column = 0; column < columnCount; ++column ) { #ifdef DOCXXML_DEBUG_TABLES debugDocx << "----- [COLUMN" << column +1 << "] ----------"; #endif spans.first = m_table->cellAt(row, column)->rowSpan(); spans.second = m_table->cellAt(row, column)->columnSpan(); KoCellStyle::Ptr style = styleConverter.style(row, column, spans); if (m_moveToStylesXml) { style->setAutoStyleInStylesDotXml(true); } m_table->cellAt(row, column)->setStyle(style); #ifdef DOCXXML_DEBUG_TABLES style = m_table->cellAt(row, column)->style(); debugDocx << "[check] top:" << style->borders()->topBorderData().style; debugDocx << "[check] bottom:" << style->borders()->bottomBorderData().style; debugDocx << "[check] left:" << style->borders()->leftBorderData().style; debugDocx << "[check] right:" << style->borders()->rightBorderData().style; #endif } } } #undef CURRENT_EL #define CURRENT_EL tblPr //! tblPr handler (Table Properties) /*! ECMA-376, 17.4.60, p. 492. This element specifies the set of table-wide properties applied to the current table. These properties affect the appearance of all rows and cells within the parent table, but can be overridden by individual table-level exception, row, and cell level properties as defined by each property. Parent elements: - [done] tbl (§17.4.38) Child elements: - bidiVisual (Visually Right to Left Table) §17.4.1 - [done] jc (Table Alignment) §17.4.29 - shd (Table Shading) §17.4.32 - [done] tblBorders (Table Borders) §17.4.39 - tblCaption (Table Caption) §17.4.41 - [done] tblCellMar (Table Cell Margin Defaults) §17.4.43 - tblCellSpacing (Table Cell Spacing Default) §17.4.46 - tblDescription (Table Description) §17.4.47 - tblInd (Table Indent from Leading Margin) §17.4.51 - tblLayout (Table Layout) §17.4.53 - tblLook (Table Style Conditional Formatting Settings) §17.4.56 - tblOverlap (Floating Table Allows Other Tables to Overlap) §17.4.57 - [done] tblpPr (Floating Table Positioning) §17.4.58 - tblPrChange (Revision Information for Table Properties) §17.13.5.34 - [done] tblStyle (Referenced Table Style) §17.4.63 - tblStyleColBandSize (Number of Columns in Column Band) §17.7.6.5 - tblStyleRowBandSize (Number of Rows in Row Band) §17.7.6.7 - tblW (Preferred Table Width) §17.4.64 */ //! @todo support all child elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_tblPr() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(tblStyle) ELSE_TRY_READ_IF(tblpPr) ELSE_TRY_READ_IF(tblBorders) ELSE_TRY_READ_IF(tblCellMar) ELSE_TRY_READ_IF_IN_CONTEXT(jc) SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tblPrEx //! tblPrEx (Table-Level Property Exceptions) /*! ECMA-376, 17.4.61, p. 484. Parent elements: - [done] tr (§17.4.79) Child elements - jc (Table Alignment Exception) §17.4.27 - shd (Table Shading Exception) §17.4.31 - [done] tblBorders (Table Borders Exceptions) §17.4.40 - tblCellMar (Table Cell Margin Exceptions) §17.4.42 - tblCellSpacing (Table Cell Spacing Exception) §17.4.45 - tblInd (Table Indent from Leading Margin Exception) §17.4.52 - tblLayout (Table Layout Exception) §17.4.54 - tblLook (Table Style Conditional Formatting Settings Exception) §17.4.55 - tblPrExChange (Revision Information for Table-Level Property Exceptions) §17.13.5.35 - tblW (Preferred Table Width Exception) §17.4.65 */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_tblPrEx() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { if (QUALIFIED_NAME_IS(tblBorders)) { m_currentTableStyleProperties = new MSOOXML::TableStyleProperties; TRY_READ_IF(tblBorders) m_currentTableStyleProperties->target = MSOOXML::TableStyleProperties::TableRow; m_currentLocalTableStyles->setLocalStyle(m_currentTableStyleProperties, m_currentTableRowNumber, -1); #ifdef DOCXXML_DEBUG_TABLES debugDocx << "====> [Row" << m_currentTableRowNumber << " Column (-1)" << "] Border information:"; debugDocx << "top:" << m_currentTableStyleProperties->top.style; debugDocx << "bottom:" << m_currentTableStyleProperties->bottom.style; debugDocx << "left:" << m_currentTableStyleProperties->left.style; debugDocx << "right:" << m_currentTableStyleProperties->right.style; #endif m_currentTableStyleProperties = 0; } SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tblGrid //! tblGrid handler (Table Grid) /*! ECMA-376, 17.4.49, p. 474. This element specifies the table grid for the current table. The table grid is a definition of the set of grid columns which define all of the shared vertical edges of the table, as well as default widths for each of these grid columns. These grid column widths are then used to determine the size of the table based on the table layout algorithm used (§17.4.53;§17.4.54). Parent elements: - [done] tbl (§17.4.38) Child elements: - [done] gridCol (Grid Column Definition) §17.4.16 - tblGridChange (Revision Information for Table Grid Column Definitions) §17.13.5.33 */ //! @todo support all child elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_tblGrid() { READ_PROLOGUE m_currentTableColumnNumber = 0; m_svgWidth = 0; while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(gridCol) SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL gridCol //! gridCol handler (Grid Column Definition) /*! ECMA-376, 17.4.16, p. 433. This element specifies the presence and details about a single grid column within a table grid. A grid column is a logical column in a table used to specify the presence of a shared vertical edge in the table. When table cells are then added to this table, these shared edges (or grid columns, looking at the column between those shared edges) determine how table cells are placed into the table grid. Parent elements: - tblGrid (§17.4.48) - [done] tblGrid (§17.4.49) No child elements. */ //! @todo support all child elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_gridCol() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(w) int width = 0; STRING_TO_INT(w, width, QString("w:w")); m_svgWidth += width; const qreal columnWidth = width / 20.0; KoColumn* column = m_table->columnAt(m_currentTableColumnNumber++); KoColumnStyle::Ptr style = KoColumnStyle::create(); if (m_moveToStylesXml) { style->setAutoStyleInStylesDotXml(true); } style->setWidth(columnWidth); column->setStyle(style); readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tr //! tr handler (Table Row) /*! ECMA-376, 17.4.79, p. 492. This element specifies a single table row, which contains the table’s cells. Table rows in WordprocessingML are analogous to HTML tr elements. Parent elements: - customXml (§17.5.1.5) - sdtContent (§17.5.2.35) - [done] tbl (§17.4.38) Child elements: - [done] bookmarkEnd (Bookmark End) §17.13.6.1 - [done] bookmarkStart (Bookmark Start) §17.13.6.2 - commentRangeEnd (Comment Anchor Range End) §17.13.4.3 - commentRangeStart (Comment Anchor Range Start) §17.13.4.4 - customXml (Cell-Level Custom XML Element) §17.5.1.4 - customXmlDelRangeEnd (Custom XML Markup Deletion End) §17.13.5.4 - customXmlDelRangeStart (Custom XML Markup Deletion Start) §17.13.5.5 - customXmlInsRangeEnd (Custom XML Markup Insertion End) §17.13.5.6 - customXmlInsRangeStart (Custom XML Markup Insertion Start) §17.13.5.7 - customXmlMoveFromRangeEnd (Custom XML Markup Move Source End) §17.13.5.8 - customXmlMoveFromRangeStart (Custom XML Markup Move Source Start) §17.13.5.9 - customXmlMoveToRangeEnd (Custom XML Markup Move Destination Location End) §17.13.5.10 - customXmlMoveToRangeStart (Custom XML Markup Move Destination Location Start) §17.13.5.11 - del (Deleted Run Content) §17.13.5.14 - ins (Inserted Run Content) §17.13.5.18 - moveFrom (Move Source Run Content) §17.13.5.22 - moveFromRangeEnd (Move Source Location Container - End) §17.13.5.23 - moveFromRangeStart (Move Source Location Container - Start) §17.13.5.24 - moveTo (Move Destination Run Content) §17.13.5.25 - moveToRangeEnd (Move Destination Location Container - End) §17.13.5.27 - moveToRangeStart (Move Destination Location Container - Start) §17.13.5.28 - oMath (Office Math) §22.1.2.77 - oMathPara (Office Math Paragraph) §22.1.2.78 - permEnd (Range Permission End) §17.13.7.1 - permStart (Range Permission Start) §17.13.7.2 - proofErr (Proofing Error Anchor) §17.13.8.1 - [done] sdt (Cell-Level Structured Document Tag) §17.5.2.32 - [done] tblPrEx (Table-Level Property Exceptions) §17.4.61 - tc (Table Cell) §17.4.66 - [done]trPr (Table Row Properties) §17.4.82 */ //! @todo support all child elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_tr() { READ_PROLOGUE m_currentTableColumnNumber = 0; while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(tc) ELSE_TRY_READ_IF(trPr) ELSE_TRY_READ_IF(bookmarkStart) ELSE_TRY_READ_IF(bookmarkEnd) ELSE_TRY_READ_IF(sdt) ELSE_TRY_READ_IF(tblPrEx) SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } m_currentTableRowNumber++; READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL trPr /* Parent elements: - [done] tr (§17.4.79) child elements: - cantSplit (Table Row Cannot Break Across Pages) §17.4.6 - [done] cnfStyle (Table Row Conditional Formatting) §17.4.7 - del (Deleted Table Row)§17.13.5.12 - divId (Associated HTML div ID)§17.4.9 - gridAfter (Grid Columns After Last Cell)§17.4.14 - gridBefore (Grid Columns Before First Cell) §17.4.15 - hidden (Hidden Table Row Marker)§17.4.20 - ins (Inserted Table Row) §17.13.5.17 - jc (Table Row Alignment) §17.4.28 - tblCellSpacing (Table Row Cell Spacing) §17.4.44 - tblHeader (Repeat Table Row on Every New Page) §17.4.50 - [done] trHeight (Table Row Height) §17.4.81 - trPrChange (Revision Information for Table Row Properties) §17.13.5.37 - wAfter (Preferred Width After Table Row) §17.4.86 - wBefore (Preferred Width Before Table Row) §17.4.87 */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_trPr() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(trHeight) ELSE_TRY_READ_IF(cnfStyle) SKIP_UNKNOWN } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL cnfStyle /* Parent elements: - many, eg. tr, tc, ppr child elements: - none */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_cnfStyle() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); // Note this parameter does not follow ooxml spec at all at least in office2007 but // produces values from office 2003 ie. val with binary // FirstRow, LastRow, FirstColumn, LastColumn, Band1Vertical, Band2Vertical, // Band1Horizontal, Band2Horizontal, NE Cell, NW Cell, SE Cell, SW Cell. TRY_READ_ATTR(val) if (val.length() == 12) { if (val.at(0) == '1') { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::FirstRow; } if (val.at(1) == '1') { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::LastRow; } if (val.at(2) == '1') { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::FirstCol; } if (val.at(3) == '1') { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::LastCol; } if (val.at(4) == '1') { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::ColumnBanded; } if (val.at(5) == '1') { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::ColumnBanded; } if (val.at(6) == '1') { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::RowBanded; } if (val.at(7) == '1') { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::RowBanded; } if (val.at(8) == '1') { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::NeCell; } if (val.at(9) == '1') { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::NwCell; } if (val.at(10) == '1') { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::SeCell; } if (val.at(11) == '1') { m_activeRoles |= MSOOXML::DrawingTableStyleConverterProperties::SwCell; } } readNext(); READ_EPILOGUE } /* Parent elements: - [done]trPr (§17.4.82) - trPr (§17.7.6.10) - trPr (§17.7.6.11) - trPr (§17.4.83) */ #undef CURRENT_EL #define CURRENT_EL trHeight KoFilter::ConversionStatus DocxXmlDocumentReader::read_trHeight() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) TRY_READ_ATTR(hRule) KoRow* row = m_table->rowAt(m_currentTableRowNumber); KoRowStyle::Ptr style = KoRowStyle::create(); if (m_moveToStylesXml) { style->setAutoStyleInStylesDotXml(true); } style->setHeight(TWIP_TO_POINT(val.toFloat())); if (hRule == QLatin1String("exact")) { style->setHeightType(KoRowStyle::ExactHeight); } else if (hRule == QLatin1String("atLeast")) { style->setHeightType(KoRowStyle::MinimumHeight); } else { style->setHeightType(KoRowStyle::MinimumHeight); } row->setStyle(style); readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tc //! tc handler (Table Cell) /*! ECMA-376, 17.4.66, p. 502. This element specifies a single cell in a table row, which contains the table’s content. Table cells in WordprocessingML are analogous to HTML td elements. Parent elements: - customXml (§17.5.1.4) - sdtContent (§17.5.2.33) - [done] tr (§17.4.79) Child elements: - altChunk (Anchor for Imported External Content) §17.17.2.1 - [done] bookmarkEnd (Bookmark End) §17.13.6.1 - [done] bookmarkStart (Bookmark Start) §17.13.6.2 - commentRangeEnd (Comment Anchor Range End) §17.13.4.3 - commentRangeStart (Comment Anchor Range Start) §17.13.4.4 - customXml (Block-Level Custom XML Element) §17.5.1.6 - customXmlDelRangeEnd (Custom XML Markup Deletion End) §17.13.5.4 - customXmlDelRangeStart (Custom XML Markup Deletion Start) §17.13.5.5 - customXmlInsRangeEnd (Custom XML Markup Insertion End) §17.13.5.6 - customXmlInsRangeStart (Custom XML Markup Insertion Start) §17.13.5.7 - customXmlMoveFromRangeEnd (Custom XML Markup Move Source End) §17.13.5.8 - customXmlMoveFromRangeStart (Custom XML Markup Move Source Start) §17.13.5.9 - customXmlMoveToRangeEnd (Custom XML Markup Move Destination Location End) §17.13.5.10 - customXmlMoveToRangeStart (Custom XML Markup Move Destination Location Start) §17.13.5.11 - del (Deleted Run Content) §17.13.5.14 - ins (Inserted Run Content) §17.13.5.18 - moveFrom (Move Source Run Content) §17.13.5.22 - moveFromRangeEnd (Move Source Location Container - End) §17.13.5.23 - moveFromRangeStart (Move Source Location Container - Start) §17.13.5.24 - moveTo (Move Destination Run Content) §17.13.5.25 - moveToRangeEnd (Move Destination Location Container - End) §17.13.5.27 - moveToRangeStart (Move Destination Location Container - Start) §17.13.5.28 - oMath (Office Math) §22.1.2.77 - oMathPara (Office Math Paragraph) §22.1.2.78 - [done] p (Paragraph) §17.3.1.22 - permEnd (Range Permission End) §17.13.7.1 - permStart (Range Permission Start) §17.13.7.2 - proofErr (Proofing Error Anchor) §17.13.8.1 - sdt (Block-Level Structured Document Tag) §17.5.2.29 - [done] tbl (Table) §17.4.38 - [done] tcPr (Table Cell Properties) §17.4.70 */ //! @todo support all child elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_tc() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { if(qualifiedName() == "w:p") { KoCell* cell = m_table->cellAt(m_currentTableRowNumber, m_currentTableColumnNumber); QBuffer buffer; KoXmlWriter* oldBody = body; KoXmlWriter newBody(&buffer, oldBody->indentLevel()+1); body = &newBody; TRY_READ(p) KoRawCellChild* textChild = new KoRawCellChild(buffer.data()); cell->appendChild(textChild); body = oldBody; } else if(QUALIFIED_NAME_IS(tbl)) { - KoTable* currentTable = m_table; + KoTable::Ptr currentTable = m_table; int currentRow = m_currentTableRowNumber; int currentColumn = m_currentTableColumnNumber; MSOOXML::TableStyleProperties* currentDefaultCellStyle = m_currentDefaultCellStyle; MSOOXML::TableStyleProperties* currentStyleProperties = m_currentTableStyleProperties; MSOOXML::LocalTableStyles* currentLocalStyles = m_currentLocalTableStyles; QString currentTableStyle = m_currentTableStyleName; KoCell* cell = m_table->cellAt(m_currentTableRowNumber, m_currentTableColumnNumber); QBuffer buffer; KoXmlWriter* oldBody = body; KoXmlWriter newBody(&buffer, oldBody->indentLevel()+1); body = &newBody; TRY_READ(tbl) KoRawCellChild* textChild = new KoRawCellChild(buffer.data()); cell->appendChild(textChild); body = oldBody; m_table = currentTable; m_currentTableRowNumber = currentRow; m_currentTableColumnNumber = currentColumn; m_currentDefaultCellStyle = currentDefaultCellStyle; m_currentTableStyleProperties = currentStyleProperties; m_currentLocalTableStyles = currentLocalStyles; m_currentTableStyleName = currentTableStyle; } else if(QUALIFIED_NAME_IS(tcPr)) { m_currentTableStyleProperties = new MSOOXML::TableStyleProperties; TRY_READ(tcPr) m_currentTableStyleProperties->target = MSOOXML::TableStyleProperties::TableCell; m_currentLocalTableStyles->setLocalStyle(m_currentTableStyleProperties, m_currentTableRowNumber, m_currentTableColumnNumber); #ifdef DOCXXML_DEBUG_TABLES debugDocx << "====> [Row" << m_currentTableRowNumber << " Column" << m_currentTableColumnNumber << "] Border information:"; debugDocx << "top:" << m_currentTableStyleProperties->top.style; debugDocx << "bottom:" << m_currentTableStyleProperties->bottom.style; debugDocx << "left:" << m_currentTableStyleProperties->left.style; debugDocx << "right:" << m_currentTableStyleProperties->right.style; #endif m_currentTableStyleProperties = 0; } // ELSE_TRY_READ_IF(bookmarkStart) // ELSE_TRY_READ_IF(bookmarkEnd) //! @todo add ELSE_WRONG_FORMAT } } // Setting cell covers in case of cell span in horizontal KoCell* const cell = m_table->cellAt(m_currentTableRowNumber, m_currentTableColumnNumber); int columnSpan = cell->columnSpan(); if (columnSpan > 1) { int columnIndex = 1; while (columnIndex < columnSpan) { ++m_currentTableColumnNumber; KoCell* coveredCell = m_table->cellAt(m_currentTableRowNumber, m_currentTableColumnNumber); coveredCell->setCovered(true); ++columnIndex; } } m_currentTableColumnNumber++; return KoFilter::OK; } #undef CURRENT_EL #define CURRENT_EL tcPr //! tcPr handler (Table Cell Properties) /*! ECMA-376, 17.4.70, p. 510. This element specifies the set of properties which shall be applied a specific table cell. Each unique property is specified by a child element of this element. In any instance where there is a conflict between the table level, table-level exception, or row level properties with a corresponding table cell property, these properties shall overwrite the table or row wide properties. Parent elements: - [done] tc (§17.4.66) Child elements: - cellDel (Table Cell Deletion) §17.13.5.1 - cellIns (Table Cell Insertion) §17.13.5.2 - cellMerge (Vertically Merged/Split Table Cells) §17.13.5.3 - [done] cnfStyle (Table Cell Conditional Formatting) §17.4.8 - [done] gridSpan (Grid Columns Spanned by Current Table Cell) §17.4.17 - headers (Header Cells Associated With Table Cell) §17.4.19 - hideMark (Ignore End Of Cell Marker In Row Height Calculation) §17.4.21 - hMerge (Horizontally Merged Cell) §17.4.22 - noWrap (Don't Wrap Cell Content) §17.4.30 - [done] shd (Table Cell Shading) §17.4.33 - [done] tcBorders (Table Cell Borders) §17.4.67 - tcFitText (Fit Text Within Cell) §17.4.68 - [done] tcMar (Single Table Cell Margins) §17.4.69 - tcPrChange (Revision Information for Table Cell Properties) §17.13.5.36 - tcW (Preferred Table Cell Width) §17.4.72 - [done] textDirection (Table Cell Text Flow Direction) §17.4.73 - [done] vAlign (Table Cell Vertical Alignment) §17.4.84 - [done] vMerge (Vertically Merged Cell) §17.4.85 */ //! @todo support all child elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_tcPr() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(gridSpan) ELSE_TRY_READ_IF(cnfStyle) ELSE_TRY_READ_IF_IN_CONTEXT(shd) ELSE_TRY_READ_IF(tcBorders) ELSE_TRY_READ_IF(tcMar) ELSE_TRY_READ_IF(vMerge) ELSE_TRY_READ_IF(vAlign) else if (name() == "textDirection") { TRY_READ(textDirectionTc) } SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL vAlign //! vAlign Handler (Table Cell Vertical Alignment) /*! ECMA-376, 17.4.84, p. 519. Parent elements: - [done] tcPr (§17.7.6.8); - [done] tcPr (§17.7.6.9); - [done] tcPr (§17.4.70); - [done] tcPr (§17.4.71) Child elements: - none */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_vAlign() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) if (!val.isEmpty()) { if (val == "both" || val == "center") { m_currentTableStyleProperties->verticalAlign = "middle"; } else if (val == "top" || val == "bottom") { m_currentTableStyleProperties->verticalAlign = val; } else { m_currentTableStyleProperties->verticalAlign = "automatic"; } m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::VerticalAlign; } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL textDirection //! textDirection Handler (Table Cell Text Flow Direction) /* Parent elements: - [done] tcPr (§17.7.6.8); - [done] tcPr (§17.7.6.9); - [done] tcPr (§17.4.70); - [done] tcPr (§17.4.71) Child elements: - none */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_textDirectionTc() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) if (!val.isEmpty()) { m_currentTableStyleProperties->glyphOrientation = false; m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::GlyphOrientation; } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL vMerge //! vMerge Handler (vertically merged cell) /* Parent elements: - [done] tcPr (§17.7.6.8); - [done] tcPr (§17.7.6.9); - [done] tcPr (§17.4.70); - [done] tcPr (§17.4.71) Child elements: - none */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_vMerge() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) if (!val.isEmpty()) { // Not empty value marks the start of the vertical merging KoCell* cell = m_table->cellAt(m_currentTableRowNumber, m_currentTableColumnNumber); cell->setRowSpan(1); } else { // In this case, it should continue from which ever cell above was the starter KoCell* cell = m_table->cellAt(m_currentTableRowNumber, m_currentTableColumnNumber); cell->setCovered(true); int previousRow = m_currentTableRowNumber - 1; while (previousRow > -1) { KoCell* previousRowCell = m_table->cellAt(previousRow, m_currentTableColumnNumber); if (!previousRowCell->isCovered()) { previousRowCell->setRowSpan(previousRowCell->rowSpan() + 1); // This current cell should be replaced with cell->setCovered(true); break; } --previousRow; } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL tcBorders //! tcBorders handlers (table cell borders) /*! ECMA-376, 17.4.67, p.494. Parent elements: - [done] tcPr (§17.7.6.8); - [done] tcPr (§17.7.6.9); - [done] tcPr (§17.4.70); - [done] tcPr (§17.4.71) Child elements: - [done] bottom (Table Cell Bottom Border) §17.4.3 - [done] end (Table Cell Trailing Edge Border) §17.4.12 - [done] insideH (Table Cell Inside Horizontal Edges Border) §17.4.24 - [done] insideV (Table Cell Inside Vertical Edges Border) §17.4.26 - [done] start (Table Cell Leading Edge Border) §17.4.34 - [done] tl2br (Table Cell Top Left to Bottom Right Diagonal Border) §17.4.74 - [done] top (Table Cell Top Border) §17.4.75 - [done] tr2bl (Table Cell Top Right to Bottom Left Diagonal Border) §17.4.80 */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_tcBorders() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { if (QUALIFIED_NAME_IS(top)) { m_currentTableStyleProperties->top = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::TopBorder; } else if (QUALIFIED_NAME_IS(bottom)) { m_currentTableStyleProperties->bottom = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::BottomBorder; } else if (QUALIFIED_NAME_IS(left)) { m_currentTableStyleProperties->left = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::LeftBorder; } else if (QUALIFIED_NAME_IS(right)) { m_currentTableStyleProperties->right = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::RightBorder; } else if (QUALIFIED_NAME_IS(insideV)) { m_currentTableStyleProperties->insideV = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::InsideVBorder; } else if (QUALIFIED_NAME_IS(insideH)) { m_currentTableStyleProperties->insideH = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::InsideHBorder; } else if (QUALIFIED_NAME_IS(tl2br)) { m_currentTableStyleProperties->tl2br = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::Tl2brBorder; } else if (QUALIFIED_NAME_IS(tr2bl)) { m_currentTableStyleProperties->tr2bl = getBorderData(); m_currentTableStyleProperties->setProperties |= MSOOXML::TableStyleProperties::Tr2blBorder; } SKIP_UNKNOWN } } m_currentTableStyleProperties->target = MSOOXML::TableStyleProperties::TableCell; READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL gridSpan //! gridSpan handler (Grid Columns Spanned by Current Table Cell) /*! Parent elements: - [done]tcPr (§17.7.6.8); - [done] tcPr (§17.7.6.9); - [done] tcPr (§17.4.70); - [done] tcPr (§17.4.71) Child elements: - none */ //! @todo support all child elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_gridSpan() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) if (!val.isEmpty()) { int span = 0; STRING_TO_INT(val, span, "gridSpan"); KoCell* const cell = m_table->cellAt(m_currentTableRowNumber, m_currentTableColumnNumber); cell->setColumnSpan(span); } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL control //! Reads a activeX control object /* Parent elements: - [done] object (§17.3.3.19) Child elements: - none */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_control() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); body->startElement("draw:frame"); body->addAttribute("svg:width", m_currentObjectWidthCm); body->addAttribute("svg:height", m_currentObjectHeightCm); body->addAttribute("text:anchor-type", "as-char"); // default for these // Do we even want to try anything with activeX controls? /* TRY_READ_ATTR_WITH_NS(r, id) const QString oleName(m_context->relationships->target(m_context->path, m_context->file, r_id)); debugDocx << "oleName:" << oleName; */ // Replacement image body->startElement("draw:image"); body->addAttribute("xlink:type", "simple"); body->addAttribute("xlink:show", "embed"); body->addAttribute("xlink:actuate", "onLoad"); body->addAttribute("xlink:href", m_currentVMLProperties.imagedataPath); body->endElement(); // draw:image body->endElement(); // draw:frame readNext(); READ_EPILOGUE } // --------------------------------------------------------------------------- #include // this adds w:p, w:pPr, w:t, w:r, etc. // --------------------------------------------------------------------------- #undef MSOOXML_CURRENT_NS #define MSOOXML_CURRENT_NS "o" // urn:schemas-microsoft-com:office:office #undef CURRENT_EL #define CURRENT_EL OLEObject //! Reads an OLE object KoFilter::ConversionStatus DocxXmlDocumentReader::read_OLEObject() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); // example: // body->startElement("draw:frame"); body->addAttribute("svg:width", m_currentObjectWidthCm); body->addAttribute("svg:height", m_currentObjectHeightCm); body->addAttribute("text:anchor-type", "as-char"); // default for these TRY_READ_ATTR_WITH_NS(r, id) const QString oleName(m_context->relationships->target(m_context->path, m_context->file, r_id)); debugDocx << "oleName:" << oleName; QString destinationName = oleName.mid(oleName.lastIndexOf('/') + 1); KoFilter::ConversionStatus stat = m_context->import->copyFile(oleName, destinationName, false); if (stat == KoFilter::OK) { body->startElement("draw:object-ole"); addManifestEntryForFile(destinationName); body->addAttribute("xlink:href", destinationName); body->addAttribute("xlink:type", "simple"); body->endElement(); // draw:object-ole } // Replacement image body->startElement("draw:image"); body->addAttribute("xlink:type", "simple"); body->addAttribute("xlink:show", "embed"); body->addAttribute("xlink:actuate", "onLoad"); body->addAttribute("xlink:href", m_currentVMLProperties.imagedataPath); body->endElement(); // draw:image while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) } body->endElement(); // draw:frame READ_EPILOGUE } #undef MSOOXML_CURRENT_NS #define MSOOXML_CURRENT_NS "wp" #undef CURRENT_EL #define CURRENT_EL anchor //! anchor handler (Anchor for Floating DrawingML Object) /*! ECMA-376, 20.4.2.3, p.3469. This element specifies that the DrawingML object located at this position in the document is a floating object. Within a WordprocessingML document, drawing objects can exist in two states: - Inline - The drawing object is in line with the text, and affects the line height and layout of its line (like a character glyph of similar size). - Floating - The drawing object is anchored within the text, but can be absolutely positioned in the document relative to the page. When this element encapsulates the DrawingML object's information, then all child elements shall dictate the positioning of this object as a floating object on the page. Parent elements: - [done] drawing (§17.3.3.9) Child elements: - cNvGraphicFramePr (Common DrawingML Non-Visual Properties) §20.4.2.4 - [done] docPr (Drawing Object Non-Visual Properties) §20.4.2.5 - effectExtent (Object Extents Including Effects) §20.4.2.6 - extent (Drawing Object Size) §20.4.2.7 - [done] graphic (Graphic Object) §20.1.2.2.16 - [done] positionH (Horizontal Positioning) §20.4.2.10 - [done] positionV (Vertical Positioning) §20.4.2.11 - simplePos (Simple Positioning Coordinates) §20.4.2.13 - [done] wrapNone (No Text Wrapping) §20.4.2.15 - [done] wrapSquare (Square Wrapping) §20.4.2.17 - [done] wrapThrough (Through Wrapping) §20.4.2.18 - [done] wrapTight (Tight Wrapping) §20.4.2.19 - [done] wrapTopAndBottom (Top and Bottom Wrapping) §20.4.2.20 Attributes: - [done] allowOverlap (Allow Objects to Overlap) - [done] behindDoc (Display Behind Document Text) - [done] distB (Distance From Text on Bottom Edge) (see also: inline) - [done] distL (Distance From Text on Left Edge) (see also: inline) - [done] distR (Distance From Text on Right Edge) (see also: inline) - [done] distT (Distance From Text on Top Edge) (see also: inline) - hidden (Hidden) - [done] layoutInCell (Layout In Table Cell) - locked (Lock Anchor) - [done] relativeHeight (Relative Z-Ordering Position) - simplePos (Page Positioning) */ //! @todo support all elements //! CASE #1340 //! CASE #1410 //! CASE #1420 KoFilter::ConversionStatus DocxXmlDocumentReader::read_anchor() { READ_PROLOGUE m_docPrName.clear(); m_docPrDescr.clear(); m_drawing_anchor = true; // for pic:pic bool behindDoc = false; bool allowOverlap = false; m_alignH.clear(); m_alignV.clear(); const QXmlStreamAttributes attrs(attributes()); //! @todo parse 20.4.3.4 ST_RelFromH (Horizontal Relative Positioning), p. 3511 READ_ATTR_WITHOUT_NS(distT) distToODF("fo:margin-top", distT); READ_ATTR_WITHOUT_NS(distB) distToODF("fo:margin-bottom", distB); READ_ATTR_WITHOUT_NS(distL) distToODF("fo:margin-left", distL); READ_ATTR_WITHOUT_NS(distR) distToODF("fo:margin-right", distR); TRY_READ_ATTR_WITHOUT_NS(relativeHeight) if (!relativeHeight.isEmpty()) { m_z_index = relativeHeight.toInt(); } TRY_READ_ATTR_WITHOUT_NS(layoutInCell) m_currentDrawStyle->addProperty("style:flow-with-text", MSOOXML::Utils::convertBooleanAttr(layoutInCell, false)); behindDoc = MSOOXML::Utils::convertBooleanAttr(attrs.value("behindDoc").toString()); allowOverlap = MSOOXML::Utils::convertBooleanAttr(attrs.value("allowOverlap").toString()); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF_NS(a, graphic) ELSE_TRY_READ_IF(positionH) ELSE_TRY_READ_IF(positionV) ELSE_TRY_READ_IF(docPr) ELSE_TRY_READ_IF(wrapSquare) ELSE_TRY_READ_IF(wrapTight) ELSE_TRY_READ_IF(wrapThrough) else if (QUALIFIED_NAME_IS(wrapNone)) { // wrapNone (No Text Wrapping), ECMA-376, 20.4.2.15 // This element specifies that the parent DrawingML object shall // not cause any text wrapping within the contents of the host // WordprocessingML document based on its display location. // CASE #1410 readNext(); if (!expectElEnd(QUALIFIED_NAME(wrapNone))) { return KoFilter::WrongFormat; } if (allowOverlap) { m_currentDrawStyle->addProperty("style:wrap", "run-through"); if (behindDoc) { m_currentDrawStyle->addProperty("style:run-through", "background"); } else { m_currentDrawStyle->addProperty("style:run-through", "foreground"); } } else { m_currentDrawStyle->addProperty("style:wrap", "none"); } } else if (QUALIFIED_NAME_IS(wrapTopAndBottom)) { // 20.4.2.20 wrapTopAndBottom (Top and Bottom Wrapping) // This element specifies that text shall wrap around the top // and bottom of this object, but not its left or right edges. // CASE #1410 readNext(); if (!expectElEnd(QUALIFIED_NAME(wrapTopAndBottom))) { return KoFilter::WrongFormat; } m_currentDrawStyle->addProperty("style:wrap", "none"); } SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL inline //! inline handler (Inline DrawingML Object) /*! ECMA-376, 20.4.2.8, p.3485. This element specifies that the DrawingML object located at this position in the document is a floating object. Within a WordprocessingML document, drawing objects can exist in two states: - Inline - The drawing object is in line with the text, and affects the line height and layout of its line (like a character glyph of similar size). - Floating - The drawing object is anchored within the text, but can be absolutely positioned in the document relative to the page. When this element encapsulates the DrawingML object's information, then all child elements shall dictate the positioning of this object as a floating object on the page. Parent elements: - [done] drawing (§17.3.3.9) Child elements: - cNvGraphicFramePr (Common DrawingML Non-Visual Properties) §20.4.2.4 - [done] docPr (Drawing Object Non-Visual Properties) §20.4.2.5 - effectExtent (Object Extents Including Effects) §20.4.2.6 - [done] extent (Drawing Object Size) §20.4.2.7 - [done] graphic (Graphic Object) §20.1.2.2.16 Attributes: - distB (Distance From Text on Bottom Edge) - distL (Distance From Text on Left Edge) - distR (Distance From Text on Right Edge) - distT (Distance From Text on Top Edge) */ //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_inline() { READ_PROLOGUE m_docPrName.clear(); m_docPrDescr.clear(); m_drawing_inline = true; // for pic m_svgX = m_svgY = m_svgWidth = m_svgHeight = 0; while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF_NS(wp, extent) ELSE_TRY_READ_IF(docPr) ELSE_TRY_READ_IF_NS(a, graphic) SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL extent KoFilter::ConversionStatus DocxXmlDocumentReader::read_extent() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); READ_ATTR_WITHOUT_NS(cx) STRING_TO_INT(cx, m_svgWidth, "ext@cx") READ_ATTR_WITHOUT_NS(cy) STRING_TO_INT(cy, m_svgHeight, "ext@cy") while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL docPr //! docPr handler (Drawing Object Non-Visual Properties) /*! ECMA-376, 20.4.2.5, p.3478. This element specifies non-visual object properties for the parent DrawingML object. These properties are specified as child elements of this element. Parent elements: - [done] anchor (§20.4.2.3) - [done] inline (§20.4.2.8) Child elements: - extLst (Extension List) §20.1.2.2.15 - [done] hlinkClick (Click Hyperlink) §21.1.2.3.5 - hlinkHover (Hyperlink for Hover) §20.1.2.2.23 Attributes: - [done] descr (Alternative Text for Object) - hidden (Hidden) - id (Unique Identifier) - [done] name (Name) */ //! CASE #1340 //! @todo support all elements KoFilter::ConversionStatus DocxXmlDocumentReader::read_docPr() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR_WITHOUT_NS_INTO(name, m_docPrName) TRY_READ_ATTR_WITHOUT_NS_INTO(descr, m_docPrDescr) //! @todo support docPr/@hidden (maybe to style:text-properties/@text:display) while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF_NS(a, hlinkClick) SKIP_UNKNOWN //! @todo add ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL positionH //! positionH handler (Horizontal Positioning) /*! ECMA-376, 20.4.2.10, p.3490. This element specifies the horizontal positioning of a floating DrawingML object within a WordprocessingML document. This positioning is specified in two parts: - Positioning Base - The relativeFrom attribute on this element specifies the part of the document from which the positioning shall be calculated. - Positioning - The child element of this element (align or posOffset) specifies how the object is positioned relative to that base. Parent elements: - [done] anchor (§20.4.2.3) Child elements: - [done] align (Relative Horizontal Alignment) §20.4.2.1 - [done] posOffset (Absolute Position Offset) §20.4.2.12 Attributes: - [done] relativeFrom (Horizontal Position Relative Base) */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_positionH() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); //! @todo parse 20.4.3.4 ST_RelFromH (Horizontal Relative Positioning), p. 3511 READ_ATTR_WITHOUT_NS_INTO(relativeFrom, m_relativeFromH) while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF_IN_CONTEXT(align) ELSE_TRY_READ_IF_IN_CONTEXT(posOffset) ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL positionV //! positionV handler (Vertical Positioning) /*! ECMA-376, 20.4.2.11, p.3491. This element specifies the vertical positioning of a floating DrawingML object within a WordprocessingML document. This positioning is specified in two parts: - Positioning Base - The relativeFrom attribute on this element specifies the part of the document from which the positioning shall be calculated. - Positioning - The child element of this element (align or posOffset) specifies how the object is positioned relative to that base. Parent elements: - [done] anchor (§20.4.2.3) Child elements: - [done] align (Relative Vertical Alignment) §20.4.2.2 - [done] posOffset (Absolute Position Offset) §20.4.2.12 Attributes: - [done] relativeFrom (Horizontal Position Relative Base) */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_positionV() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); //! @todo parse 20.4.3.5 ST_RelFromV (Vertical Relative Positioning), p. 3512 READ_ATTR_WITHOUT_NS_INTO(relativeFrom, m_relativeFromV) while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF_IN_CONTEXT(align) ELSE_TRY_READ_IF_IN_CONTEXT(posOffset) ELSE_WRONG_FORMAT } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL posOffset //! posOffset handler (Absolute Position Offset) /*! ECMA-376, 20.4.2.12, p.3492. This element specifies an absolute measurement for the positioning of a floating DrawingML object within a WordprocessingML document. This measurement shall be calculated relative to the top left edge of the positioning base specified by the parent element's relativeFrom attribute. Parent elements: - [done] positionH (§20.4.2.10) - [done] positionV (§20.4.2.11) No child elements. */ //! CASE #1360 KoFilter::ConversionStatus DocxXmlDocumentReader::read_posOffset(posOffsetCaller caller) { READ_PROLOGUE readNext(); if (isCharacters()) { switch (caller) { case posOffset_positionH: STRING_TO_INT(text().toString(), m_posOffsetH, "positionH/posOffset text") m_hasPosOffsetH = true; break; case posOffset_positionV: STRING_TO_INT(text().toString(), m_posOffsetV, "positionV/posOffset text") m_hasPosOffsetV = true; break; default: return KoFilter::WrongFormat; } } ELSE_WRONG_FORMAT readNext(); READ_EPILOGUE } #undef CURRENT_EL void DocxXmlDocumentReader::readWrapAttrs() { if (QUALIFIED_NAME_IS(wrapTight)) { m_currentDrawStyle->addProperty("style:wrap-contour", "true"); m_currentDrawStyle->addProperty("style:wrap-contour-mode", "outside"); } else if (QUALIFIED_NAME_IS(wrapThrough)) { m_currentDrawStyle->addProperty("style:wrap-contour", "true"); m_currentDrawStyle->addProperty("style:wrap-contour-mode", "full"); } m_currentDrawStyle->addProperty("style:number-wrapped-paragraphs", "no-limit"); const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR_WITHOUT_NS(wrapText) if (wrapText == "bothSides") { m_currentDrawStyle->addProperty("style:wrap", "parallel"); } else if (wrapText == "largest") { m_currentDrawStyle->addProperty("style:wrap", "biggest"); } else { m_currentDrawStyle->addProperty("style:wrap", wrapText); } } #define CURRENT_EL wrapPolygon //! wrapPolygon (Wrapping Polygon) /*! ECMA-376, 20.4.2.16, p.3495 This element specifies the wrapping polygon which shall be used to determine the extents to which text can wrap around the specified object in the document. This polygon shall be defined by the following: - The start element defines the coordinates of the origin of the wrap polygon - Two or more lineTo elements define the point of the wrap polygon TODO: If the set of child elements does not result in a closed polygon (the last lineTo element does not return to the position specified by the start element), then a single additional line shall be inferred as needed to close the wrapping polygon. Parent elements: - [done] wrapThrough (§20.4.2.18) - [done] wrapTight (§20.4.2.19) Child elements: - lineTo (Wrapping Polygon Line End Position) - start (Wrapping Polygon Start) Attributes: - edited (Wrapping Points Modified) */ KoFilter::ConversionStatus DocxXmlDocumentReader::read_wrapPolygon() { READ_PROLOGUE QString points; while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { if (QUALIFIED_NAME_IS(start) || QUALIFIED_NAME_IS(lineTo)) { const QXmlStreamAttributes attrs(attributes()); READ_ATTR_WITHOUT_NS(x) READ_ATTR_WITHOUT_NS(y) bool ok; int _x = x.toInt(&ok); int _y = y.toInt(&ok); // EMUs - TODO: Which units do I have to use? if (ok) { // x = QString::number(PT_TO_PX(EMU_TO_POINT(_x)), 'f'); // y = QString::number(PT_TO_PX(EMU_TO_POINT(_y)), 'f'); x = QString::number(EMU_TO_POINT(_x), 'f'); y = QString::number(EMU_TO_POINT(_y), 'f'); } //TODO: else a number followed immediately by a unit identifier. //TODO: find max and min to set svg:width, svg:height and svg:viewBox points.append(x); points.append(","); points.append(y); points.append(" "); skipCurrentElement(); } SKIP_UNKNOWN } } if (!points.isEmpty()) { points.chop(1); //remove last space body->startElement("draw:contour-polygon"); body->addAttribute("draw:points", points); body->endElement(); //draw:contour-polygon } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL wrapSquare //! wrapSquare handler (Square Wrapping) /*! ECMA-376, 20.4.2.17, p.3496. This element specifies that text shall wrap around a virtual rectangle bounding this object. The bounds of the wrapping rectangle shall be dictated by the extents including the addition of the effectExtent element as a child of this element (if present) or the effectExtent present on the parent element. Parent elements: - [done] anchor (§20.4.2.3) Child elements: - effectExtent (Object Extents Including Effects) Attributes: - distB (Distance From Text on Bottom Edge) - distL (Distance From Text on Left Edge) - distR (Distance From Text on Right Edge) - distT (Distance From Text (Top)) - [done] wrapText (Text Wrapping Location) */ //! CASE #1410 KoFilter::ConversionStatus DocxXmlDocumentReader::read_wrapSquare() { READ_PROLOGUE readWrapAttrs(); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) // if (isStartElement()) { //! @todo effectExtent // } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL wrapTight //! wrapTight handler (Tight Wrapping) /*! ECMA-376, 20.4.2.17, p.3497. This element specifies that text shall wrap around the wrapping polygon bounding this object as defined by the child wrapPolygon element. When this element specifies a wrapping polygon, it shall not allow text to wrap within the object's maximum left and right extents. Parent elements: - [done] anchor (§20.4.2.3) Child elements: - wrapPolygon (Wrapping Polygon) Attributes: - distL (Distance From Text on Left Edge) - distR (Distance From Text on Right Edge) - [done] wrapText (Text Wrapping Location) */ //! CASE #1410 KoFilter::ConversionStatus DocxXmlDocumentReader::read_wrapTight() { READ_PROLOGUE readWrapAttrs(); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL); // if (isStartElement()) { // TRY_READ_IF(wrapPolygon) // SKIP_UNKNOWN // } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL wrapThrough //! wrapThrough handler (Through Wrapping) /*! ECMA-376, 20.4.2.18, p.3500. This element specifies that text shall wrap around the wrapping polygon bounding this object as defined by the child wrapPolygon element. When this element specifies a wrapping polygon, it shall allow text to wrap within the object's maximum left and right extents. Parent elements: - [done] anchor (§20.4.2.3) Child elements: - wrapPolygon (Wrapping Polygon) Attributes: - distL (Distance From Text on Left Edge) - distR (Distance From Text on Right Edge) - [done] wrapText (Text Wrapping Location) */ //! CASE #1410 KoFilter::ConversionStatus DocxXmlDocumentReader::read_wrapThrough() { READ_PROLOGUE readWrapAttrs(); // NOTE: The name wrapThrough is misleading, it does not mean run-through it // just means that wrapping happens potentially inside of the container. while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) // if (isStartElement()) { // TRY_READ_IF(wrapPolygon) // SKIP_UNKNOWN // } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL align //! align handler (Relative Horizontal Alignment, Relative Vertical Alignment) /*! ECMA-376, 20.4.2.1, 20.4.2.2, p.3468, 3469. This element specifies how a DrawingML object shall be horizontally/vertically aligned relative to the horizontal alignment base defined by the parent element. Once an alignment base is defined, this element shall determine how the DrawingML object shall be aligned relative to that location. Parent elements: - [done] positionH (§20.4.2.10) - [done] positionV (§20.4.2.11) No child elements. */ //! CASE #1340 KoFilter::ConversionStatus DocxXmlDocumentReader::read_align(alignCaller caller) { READ_PROLOGUE readNext(); if (!isEndElement()) {// was text switch (caller) { case align_positionH: //! 20.4.3.1 ST_AlignH (Relative Horizontal Alignment Positions), p. 3508. /*center inside left outside right*/ m_alignH = text().toString(); break; case align_positionV: //! 20.4.3.2 ST_AlignV (Vertical Alignment Definition), p. 3509. /*bottom center inside outside top*/ m_alignV = text().toString(); break; } readNext(); } READ_EPILOGUE } #undef MSOOXML_CURRENT_NS #define MSOOXML_CURRENT_NS "m" #undef CURRENT_EL #define CURRENT_EL oMathPara //! oMathPara handler // @todo implement... KoFilter::ConversionStatus DocxXmlDocumentReader::read_oMathPara() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF(oMath) ELSE_TRY_READ_IF(oMathParaPr) SKIP_UNKNOWN } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL oMathParaPr //! oMathParaPr handler (paragraph properties) // @todo support fully KoFilter::ConversionStatus DocxXmlDocumentReader::read_oMathParaPr() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { if (qualifiedName() == "m:jc") { TRY_READ(jc_m) } } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL oMath //! oMath handler // @todo implement... KoFilter::ConversionStatus DocxXmlDocumentReader::read_oMath() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { if (qualifiedName() == "m:r") { TRY_READ(r_m) } ELSE_TRY_READ_IF(del) ELSE_TRY_READ_IF(ins) SKIP_UNKNOWN } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL jc //! jc handler for math // @todo implement.. KoFilter::ConversionStatus DocxXmlDocumentReader::read_jc_m() { READ_PROLOGUE const QXmlStreamAttributes attrs(attributes()); TRY_READ_ATTR(val) if (!val.isEmpty()) { if (val == "centerGroup") { m_currentParagraphStyle.addProperty("fo:text-align", "center"); } else { // Fix this based on possible values, m_currentParagraphStyle.addProperty("fo:text-align", "left"); } } readNext(); READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL t //! t handler for math // @todo implement... KoFilter::ConversionStatus DocxXmlDocumentReader::read_t_m() { READ_PROLOGUE while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) debugDocx << *this; if (isCharacters()) { body->addTextSpan(text().toString()); } } READ_EPILOGUE } #undef CURRENT_EL #define CURRENT_EL r //! r handler in math // @todo implement fully. KoFilter::ConversionStatus DocxXmlDocumentReader::read_r_m() { READ_PROLOGUE m_currentTextStyle = KoGenStyle(KoGenStyle::TextAutoStyle, "text"); if (m_moveToStylesXml) { m_currentTextStyle.setAutoStyleInStylesDotXml(true); } MSOOXML::Utils::XmlWriteBuffer buffer; body = buffer.setWriter(body); while (!atEnd()) { readNext(); BREAK_IF_END_OF(CURRENT_EL) if (isStartElement()) { TRY_READ_IF_NS(w, rPr) else if (qualifiedName() == "m:t") { TRY_READ(t_m) } SKIP_UNKNOWN } } body = buffer.originalWriter(); QString currentTextStyleName = mainStyles->insert(m_currentTextStyle); body->startElement("text:span", false); body->addAttribute("text:style-name", currentTextStyleName); bool closeHyperLink = handleSpecialField(); // Writing the internal body of read_t now body = buffer.releaseWriter(); if (closeHyperLink) { body->endElement(); // some special field } body->endElement(); //text:span READ_EPILOGUE } // ************************************************ // State // ************************************************ void DocxXmlDocumentReader::saveState() { DocumentReaderState state(m_usedListStyles, m_continueListNum, m_numIdXmlId); m_statesBkp.push(state); m_usedListStyles.clear(); m_continueListNum.clear(); m_numIdXmlId.clear(); } void DocxXmlDocumentReader::restoreState() { if (m_statesBkp.isEmpty()) { warnDocx << "Error: DocumentReaderState stack is corrupt!"; return; } DocumentReaderState s = m_statesBkp.pop(); m_usedListStyles = s.usedListStyles; m_continueListNum = s.continueListNum; m_numIdXmlId = s.numIdXmlId; } #define DRAWINGML_NS "a" #define DRAWINGML_PIC_NS "pic" // DrawingML/Picture #include // this adds pic:pic, etc. #include // this adds w:pict, etc. diff --git a/filters/words/docx/import/DocxXmlDocumentReader.h b/filters/words/docx/import/DocxXmlDocumentReader.h index 38fa71f5c51..0a34b86b1f0 100644 --- a/filters/words/docx/import/DocxXmlDocumentReader.h +++ b/filters/words/docx/import/DocxXmlDocumentReader.h @@ -1,452 +1,451 @@ /* * This file is part of Office 2007 Filters for Calligra * * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). * * Contact: Suresh Chande suresh.chande@nokia.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * */ #ifndef DOCXXMLDOCUMENTREADER_H #define DOCXXMLDOCUMENTREADER_H #include #include #include #include #include #include #include #include #include #include +#include //#define NO_DRAWINGML_PICTURE // disables pic:pic, etc. in MsooXmlCommonReader class DocxImport; class DocxXmlDocumentReaderContext; namespace MSOOXML { class MsooXmlRelationships; struct TableStyleProperties; class LocalTableStyles; } -class KoTable; - //! A class reading MSOOXML DOCX markup - document.xml part. class DocxXmlDocumentReader : public MSOOXML::MsooXmlCommonReader { public: explicit DocxXmlDocumentReader(KoOdfWriters *writers); virtual ~DocxXmlDocumentReader(); //! Reads/parses the file of format document.xml. //! The output goes mainly to KoXmlWriter* KoOdfWriters::body virtual KoFilter::ConversionStatus read(MSOOXML::MsooXmlReaderContext* context = 0); #include // separated as it is not a part of OOXML protected: KoFilter::ConversionStatus read_body(); KoFilter::ConversionStatus read_p(); KoFilter::ConversionStatus read_r(); KoFilter::ConversionStatus read_smartTag(); KoFilter::ConversionStatus read_rPr(); KoFilter::ConversionStatus read_pPr(); KoFilter::ConversionStatus read_vanish(); KoFilter::ConversionStatus read_numPr(); KoFilter::ConversionStatus read_numId(); KoFilter::ConversionStatus read_ilvl(); KoFilter::ConversionStatus read_sectPr(); bool m_footerActive; bool m_headerActive; KoFilter::ConversionStatus read_footerReference(); KoFilter::ConversionStatus read_headerReference(); KoFilter::ConversionStatus read_cols(); KoFilter::ConversionStatus read_pgSz(); KoFilter::ConversionStatus read_textDirection(); KoFilter::ConversionStatus read_pgMar(); KoFilter::ConversionStatus read_pgBorders(); KoFilter::ConversionStatus read_object(); KoFilter::ConversionStatus read_ind(); KoFilter::ConversionStatus read_outline(); KoFilter::ConversionStatus read_outlineLvl(); KoFilter::ConversionStatus read_framePr(); KoFilter::ConversionStatus read_OLEObject(); KoFilter::ConversionStatus read_control(); KoFilter::ConversionStatus read_webHidden(); KoFilter::ConversionStatus read_bookmarkStart(); KoFilter::ConversionStatus read_bookmarkEnd(); //KoFilter::ConversionStatus read_commentRangeEnd(); KoFilter::ConversionStatus read_commentRangeStart(); KoFilter::ConversionStatus read_endnoteReference(); KoFilter::ConversionStatus read_footnoteReference(); KoFilter::ConversionStatus read_footnotePr(); KoFilter::ConversionStatus read_endnotePr(); KoFilter::ConversionStatus read_lnNumType(); KoFilter::ConversionStatus read_numFmt(); KoFilter::ConversionStatus read_numRestart(); KoFilter::ConversionStatus read_numStart(); KoFilter::ConversionStatus read_pos(); KoFilter::ConversionStatus read_suppressLineNumbers(); KoFilter::ConversionStatus read_hyperlink(); KoFilter::ConversionStatus read_del(); KoFilter::ConversionStatus read_ins(); KoFilter::ConversionStatus read_delText(); KoFilter::ConversionStatus read_drawing(); KoFilter::ConversionStatus read_ptab(); KoFilter::ConversionStatus read_tabs(); KoFilter::ConversionStatus read_tab(); KoFilter::ConversionStatus read_i(); KoFilter::ConversionStatus read_b(); KoFilter::ConversionStatus read_u(); KoFilter::ConversionStatus read_sz(); enum jcCaller { jc_tblPr, jc_pPr }; KoFilter::ConversionStatus read_jc(jcCaller caller); KoFilter::ConversionStatus read_spacing(); KoFilter::ConversionStatus read_trPr(); KoFilter::ConversionStatus read_cnfStyle(); KoFilter::ConversionStatus read_trHeight(); enum shdCaller { shd_rPr, shd_pPr, shd_tcPr }; KoFilter::ConversionStatus read_shd(shdCaller caller); KoFilter::ConversionStatus read_rFonts(); KoFilter::ConversionStatus read_pStyle(); KoFilter::ConversionStatus read_rStyle(); KoFilter::ConversionStatus read_tblpPr(); KoFilter::ConversionStatus read_tblStyle(); KoFilter::ConversionStatus read_tblBorders(); KoFilter::ConversionStatus read_tblCellMar(); KoFilter::ConversionStatus read_fldSimple(); KoFilter::ConversionStatus read_br(); KoFilter::ConversionStatus read_lastRenderedPageBreak(); KoFilter::ConversionStatus read_instrText(); KoFilter::ConversionStatus read_fldChar(); KoFilter::ConversionStatus read_strike(); KoFilter::ConversionStatus read_dstrike(); KoFilter::ConversionStatus read_caps(); KoFilter::ConversionStatus read_smallCaps(); KoFilter::ConversionStatus read_w(); KoFilter::ConversionStatus read_txbxContent(); KoFilter::ConversionStatus read_color(); KoFilter::ConversionStatus read_highlight(); KoFilter::ConversionStatus read_vertAlign(); KoFilter::ConversionStatus read_lang(); KoFilter::ConversionStatus read_background(); KoFilter::ConversionStatus read_pBdr(); KoFilter::ConversionStatus read_bdr(); KoFilter::ConversionStatus read_tbl(); KoFilter::ConversionStatus read_tblPr(); KoFilter::ConversionStatus read_tblPrEx(); KoFilter::ConversionStatus read_tblGrid(); KoFilter::ConversionStatus read_gridCol(); KoFilter::ConversionStatus read_tr(); KoFilter::ConversionStatus read_tc(); KoFilter::ConversionStatus read_tcPr(); KoFilter::ConversionStatus read_vAlign(); KoFilter::ConversionStatus read_textDirectionTc(); KoFilter::ConversionStatus read_vMerge(); KoFilter::ConversionStatus read_tcBorders(); KoFilter::ConversionStatus read_tl2br(); KoFilter::ConversionStatus read_tr2bl(); KoFilter::ConversionStatus read_tcMar(); KoFilter::ConversionStatus read_gridSpan(); int m_gridSpan; KoFilter::ConversionStatus read_oMath(); KoFilter::ConversionStatus read_oMathPara(); KoFilter::ConversionStatus read_oMathParaPr(); KoFilter::ConversionStatus read_jc_m(); KoFilter::ConversionStatus read_r_m(); KoFilter::ConversionStatus read_t_m(); enum posOffsetCaller { posOffset_positionH, posOffset_positionV }; enum alignCaller { align_positionH, align_positionV }; KoFilter::ConversionStatus read_align(alignCaller caller); KoFilter::ConversionStatus read_pict(); KoFilter::ConversionStatus read_sdt(); KoFilter::ConversionStatus read_sdtContent(); KoFilter::ConversionStatus read_inline(); KoFilter::ConversionStatus read_extent(); KoFilter::ConversionStatus read_docPr(); KoFilter::ConversionStatus read_anchor(); KoFilter::ConversionStatus read_positionH(); KoFilter::ConversionStatus read_positionV(); KoFilter::ConversionStatus read_posOffset(posOffsetCaller caller); KoFilter::ConversionStatus read_wrapPolygon(); KoFilter::ConversionStatus read_wrapSquare(); KoFilter::ConversionStatus read_wrapTight(); KoFilter::ConversionStatus read_wrapThrough(); //! Read wrapping related attributes. void readWrapAttrs(); bool m_createSectionStyle; QString m_currentSectionStyleName; QByteArray m_currentSectionStyleFamily; bool m_createSectionToNext; KoGenStyle m_currentPageStyle; KoGenStyle m_masterPageStyle; DocxXmlDocumentReaderContext* m_context; KoOdfWriters *m_writers; // Needed to create new relationship for header/footer enum PageMargin { MarginTop, MarginBottom, MarginLeft, MarginRight }; //! Used for setting up properties for page margins. QMap m_pageMargins; QString m_pageBorderOffsetFrom; enum BorderSide { TopBorder, BottomBorder, LeftBorder, RightBorder, InsideH, InsideV }; //! Whether the picture when run-through wrap is active should be in fore or background bool m_behindDoc; //! Used for setting up properties for pages QMap m_pageBorderStyles; //! Used for setting up properties for paragraphs. QMap m_borderStyles; //! Used for setting up properties r element QMap m_textBorderStyles; //! Used for setting up properties for pages QMap m_pageBorderPaddings; //! Used for setting up properties for paragraphs QMap m_borderPaddings; // ! Used for setting up properties for border padding QMap m_textBorderPaddings; - KoTable* m_table; + KoTable::Ptr m_table; QString m_currentTableStyleName; KoTblStyle::Ptr m_tableMainStyle; MSOOXML::LocalTableStyles* m_currentLocalTableStyles; MSOOXML::TableStyleProperties* m_currentTableStyleProperties; MSOOXML::TableStyleProperties* m_currentDefaultCellStyle; //! Name of the KoGenStyle style of type GraphicAutoStyle prepared for the //! parent element containing the element //! of a floating table. QString m_currentDrawStyleName; //! The complete XML snippet representing a floating table, which MUST be //! inserted into the following paragraph. QString m_floatingTable; //! The complete XML snippet representing a bookmark-start or //! bookmark-end, which MUST be inserted into the following paragraph. QString m_bookmarkSnippet; QList m_currentBulletList; private: void init(); //! Returns true if the field returned something that requires a closing element bool handleSpecialField(); QString m_specialCharacters; QColor m_backgroundColor; //Documet background color //! Reads CT_Border complex type (p.392), used by children of pgBorders and children of pBdr KoFilter::ConversionStatus readBorderElement(BorderSide borderSide, const char *borderSideName, QMap &sourceBorder, QMap &sourcePadding); ///reads the border in a table style KoBorder::BorderData getBorderData(); //! Creates border style for readBorderElement(). //! Result is added to m_borderStyles and m_borderPaddings void createBorderStyle(const QString& size, const QString& color, const QString& lineStyle, BorderSide borderSide, QMap &sourceBorder); //! Used by read_strike() and read_dstrike() void readStrikeElement(KoCharacterStyle::LineType type); //! Applies border styles and paddings obtained in readBorderElement() //! to style @a style (paragraph or page...) void applyBorders(KoGenStyle *style, QMap sourceBorder, QMap sourcePadding); //! Applies border styles and paddings for page void applyPageBorders(KoGenStyle &style, QMap &pageMargins, QMap &pageBorder, QMap &pagePadding, QString & offsetFrom); void defineTableStyles(); enum ComplexFieldCharType { NoComplexFieldCharType, HyperlinkComplexFieldCharType, ReferenceComplexFieldCharType, ReferenceNextComplexFieldCharType, InternalHyperlinkComplexFieldCharType, MacroButtonFieldCharType }; //! Type of complex field characters we have ComplexFieldCharType m_complexCharType; //! Value of the complex field char if applicable QString m_complexCharValue; enum ComplexCharStatus { NoneAllowed, InstrAllowed, InstrExecute, ExecuteInstrNow }; //! State of fldChar ComplexCharStatus m_complexCharStatus; int m_z_index; enum DropCapStatus { NoDropCap, DropCapRead, DropCapDone }; //! State of dropCap DropCapStatus m_dropCapStatus; //! Buffer where first letters of drop cap are read QBuffer* m_dropCapBuffer; KoXmlWriter* m_dropCapWriter; QString m_dropCapLines; qreal m_dropCapDistance; QMap m_bookmarks; //!< Bookmarks //!< Width of the object QString m_currentObjectWidthCm; QString m_currentObjectHeightCm; uint m_currentTableNumber; //!< table counter, from 0 uint m_currentTableRowNumber; //!< row counter, from 0, initialized in read_tbl() uint m_currentTableColumnNumber; //!< column counter, from 0, initialized in read_tr() KoGenStyle m_currentTableRowStyle; QString m_currentTableName; qreal m_currentTableWidth; //!< in cm MSOOXML::DrawingTableStyleConverterProperties::Roles m_activeRoles; bool m_wasCaption; // bookkeeping to ensure next para is suppressed if a caption is encountered bool m_closeHyperlink; // should read_r close hyperlink bool m_listFound; // was there numPr element in ppr bool m_insideParagraph; QString m_currentNumId; //! Map of list styles encountered so far, reuse already created list style. QMap m_usedListStyles; //TODO: Merge with m_continueListNumbering defined in MsooXmlCommenReaderDrawingMLMethods.h QMap > m_continueListNum; //! Map of numId.level keys and list-item num./last xml:id pairs. QMap > m_numIdXmlId; QMap m_headers; QMap m_footers; //processing the ins/del element (Inserted/Deleted Run Content) enum ChangeTrackingState { InsertedRunContent, DeletedRunContent }; QStack m_changeTrackingState; // ************************************************ // State // ************************************************ struct DocumentReaderState { explicit DocumentReaderState(const QMap &usedListStyles, const QMap > &continueListNum, const QMap > &numIdXmlId) : usedListStyles(usedListStyles), continueListNum(continueListNum), numIdXmlId(numIdXmlId) {} DocumentReaderState() {} QMap usedListStyles; QMap > continueListNum; QMap > numIdXmlId; }; void saveState(); void restoreState(); QStack m_statesBkp; #include #include class Private; Private* const d; }; //! Context for DocxXmlDocumentReader class DocxXmlDocumentReaderContext : public MSOOXML::MsooXmlReaderContext { public: //! Creates the context object. DocxXmlDocumentReaderContext( DocxImport& _import, const QString& _path, const QString& _file, MSOOXML::MsooXmlRelationships& _relationships, MSOOXML::DrawingMLTheme* _themes ); DocxImport* import; const QString path; const QString file; MSOOXML::DrawingMLTheme* themes; // Contains footnotes when read QMap m_footnotes; QMap m_endnotes; QMap m_comments; QMap m_tableStyles; QMap > m_bulletStyles; // The map contains names of default styles applied to objects that do not // explicitly declare a style. The object type (family) is the key. QMap m_namedDefaultStyles; // The map contains abstractNumId of the abstract numbering definition that // is inherited by a numbering definition instance identified by numId (key). QMap m_abstractNumIDs; QString m_defaultFontSizePt; private: }; #endif //DOCXXMLDOCUMENTREADER_H