diff --git a/src/odr/document_element.cpp b/src/odr/document_element.cpp index c9809b3f..aea6f549 100644 --- a/src/odr/document_element.cpp +++ b/src/odr/document_element.cpp @@ -182,12 +182,22 @@ TableDimensions Sheet::content(std::optional range) const { return exists_() ? m_element->content(m_document, range) : TableDimensions(); } -ElementRange Sheet::cell_elements(std::uint32_t column, - std::uint32_t row) const { - return exists_() ? ElementRange(ElementIterator(m_document, - m_element->first_cell_element( - m_document, column, row))) - : ElementRange(); +SheetColumn Sheet::column(std::uint32_t column) const { + return exists_() ? SheetColumn(m_document, m_element, column, + m_element->column(m_document, column)) + : SheetColumn(); +} + +SheetRow Sheet::row(std::uint32_t row) const { + return exists_() ? SheetRow(m_document, m_element, row, + m_element->row(m_document, row)) + : SheetRow(); +} + +SheetCell Sheet::cell(std::uint32_t column, std::uint32_t row) const { + return exists_() ? SheetCell(m_document, m_element, column, row, + m_element->cell(m_document, column, row)) + : SheetCell(); } ElementRange Sheet::shapes() const { @@ -196,39 +206,50 @@ ElementRange Sheet::shapes() const { : ElementRange(); } -TableStyle Sheet::style() const { - return exists_() ? m_element->style(m_document) : TableStyle(); -} +SheetColumn::SheetColumn(const internal::abstract::Document *document, + internal::abstract::Sheet *sheet, std::uint32_t column, + internal::abstract::SheetColumn *element) + : TypedElement(document, element), m_sheet{sheet}, m_column{column} {} -TableColumnStyle Sheet::column_style(std::uint32_t column) const { - return exists_() ? m_element->column_style(m_document, column) - : TableColumnStyle(); +TableColumnStyle SheetColumn::style() const { + return m_element->style(m_document, m_sheet, m_column); } -TableRowStyle Sheet::row_style(std::uint32_t row) const { - return exists_() ? m_element->row_style(m_document, row) : TableRowStyle(); -} +SheetRow::SheetRow(const internal::abstract::Document *document, + internal::abstract::Sheet *sheet, std::uint32_t row, + internal::abstract::SheetRow *element) + : TypedElement(document, element), m_sheet{sheet}, m_row{row} {} -TableCellStyle Sheet::cell_style(std::uint32_t column, - std::uint32_t row) const { - return exists_() ? m_element->cell_style(m_document, column, row) - : TableCellStyle(); +TableRowStyle SheetRow::style() const { + return m_element->style(m_document, m_sheet, m_row); } -bool Sheet::is_covered(std::uint32_t column, std::uint32_t row) const { - return exists_() ? m_element->is_covered(m_document, column, row) : false; +SheetCell::SheetCell(const internal::abstract::Document *document, + internal::abstract::Sheet *sheet, std::uint32_t column, + std::uint32_t row, internal::abstract::SheetCell *element) + : TypedElement(document, element), m_sheet{sheet}, m_column{column}, + m_row{row} {} + +bool SheetCell::is_covered() const { + return exists_() ? m_element->is_covered(m_document, m_sheet, m_column, m_row) + : false; } -TableDimensions Sheet::span(std::uint32_t column, std::uint32_t row) const { - return exists_() ? m_element->span(m_document, column, row) +TableDimensions SheetCell::span() const { + return exists_() ? m_element->span(m_document, m_sheet, m_column, m_row) : TableDimensions(); } -ValueType Sheet::value_type(std::uint32_t column, std::uint32_t row) const { - return exists_() ? m_element->value_type(m_document, column, row) +ValueType SheetCell::value_type() const { + return exists_() ? m_element->value_type(m_document, m_sheet, m_column, m_row) : ValueType::unknown; } +TableCellStyle SheetCell::style() const { + return exists_() ? m_element->style(m_document, m_sheet, m_column, m_row) + : TableCellStyle(); +} + std::string Page::name() const { return exists_() ? m_element->name(m_document) : ""; } diff --git a/src/odr/document_element.hpp b/src/odr/document_element.hpp index 0f2073fe..a65a6709 100644 --- a/src/odr/document_element.hpp +++ b/src/odr/document_element.hpp @@ -13,6 +13,9 @@ class Element; class TextRoot; class Slide; class Sheet; +class SheetColumn; +class SheetRow; +class SheetCell; class Page; class MasterPage; class LineBreak; @@ -53,6 +56,9 @@ class ElementRange; class TextRoot; class Slide; class Sheet; +class SheetColumn; +class SheetRow; +class SheetCell; class Page; class MasterPage; class LineBreak; @@ -216,6 +222,8 @@ class ElementRange { template class TypedElement : public Element { public: TypedElement() = default; + TypedElement(const internal::abstract::Document *document, T *element) + : Element(document, element), m_element{element} {} TypedElement(const internal::abstract::Document *document, internal::abstract::Element *element) : Element(document, element), m_element{dynamic_cast(element)} {} @@ -261,21 +269,58 @@ class Sheet final : public TypedElement { [[nodiscard]] TableDimensions content(std::optional range) const; - [[nodiscard]] ElementRange cell_elements(std::uint32_t column, - std::uint32_t row) const; + [[nodiscard]] SheetColumn column(std::uint32_t column) const; + [[nodiscard]] SheetRow row(std::uint32_t row) const; + [[nodiscard]] SheetCell cell(std::uint32_t column, std::uint32_t row) const; + [[nodiscard]] ElementRange shapes() const; +}; - [[nodiscard]] TableStyle style() const; - [[nodiscard]] TableColumnStyle column_style(std::uint32_t column) const; - [[nodiscard]] TableRowStyle row_style(std::uint32_t row) const; - [[nodiscard]] TableCellStyle cell_style(std::uint32_t column, - std::uint32_t row) const; +class SheetColumn final : public TypedElement { +public: + SheetColumn() = default; + SheetColumn(const internal::abstract::Document *document, + internal::abstract::Sheet *sheet, std::uint32_t column, + internal::abstract::SheetColumn *element); + + [[nodiscard]] TableColumnStyle style() const; + +private: + internal::abstract::Sheet *m_sheet{}; + std::uint32_t m_column{}; +}; + +class SheetRow final : public TypedElement { +public: + SheetRow() = default; + SheetRow(const internal::abstract::Document *document, + internal::abstract::Sheet *sheet, std::uint32_t row, + internal::abstract::SheetRow *element); + + [[nodiscard]] TableRowStyle style() const; - [[nodiscard]] bool is_covered(std::uint32_t column, std::uint32_t row) const; - [[nodiscard]] TableDimensions span(std::uint32_t column, - std::uint32_t row) const; - [[nodiscard]] ValueType value_type(std::uint32_t column, - std::uint32_t row) const; +private: + internal::abstract::Sheet *m_sheet{}; + std::uint32_t m_row{}; +}; + +class SheetCell final : public TypedElement { +public: + SheetCell() = default; + SheetCell(const internal::abstract::Document *document, + internal::abstract::Sheet *sheet, std::uint32_t column, + std::uint32_t row, internal::abstract::SheetCell *element); + + [[nodiscard]] bool is_covered() const; + [[nodiscard]] TableDimensions span() const; + [[nodiscard]] ValueType value_type() const; + + [[nodiscard]] TableCellStyle style() const; + +private: + internal::abstract::Sheet *m_sheet{}; + std::uint32_t m_column{}; + std::uint32_t m_row{}; }; class Page final : public TypedElement { @@ -379,9 +424,6 @@ class TableCell final : public TypedElement { public: using TypedElement::TypedElement; - [[nodiscard]] TableColumn column() const; - [[nodiscard]] TableRow row() const; - [[nodiscard]] bool is_covered() const; [[nodiscard]] TableDimensions span() const; [[nodiscard]] ValueType value_type() const; diff --git a/src/odr/internal/html/document_element.cpp b/src/odr/internal/html/document_element.cpp index 801d6954..791b2a2f 100644 --- a/src/odr/internal/html/document_element.cpp +++ b/src/odr/internal/html/document_element.cpp @@ -104,7 +104,8 @@ void html::translate_sheet(Element element, std::ostream &out, for (std::uint32_t column_index = 0; column_index < end_column; ++column_index) { - auto table_column_style = sheet.column_style(column_index); + auto table_column = sheet.column(column_index); + auto table_column_style = table_column.style(); out << " 1) { diff --git a/src/odr/internal/odf/odf_spreadsheet.hpp b/src/odr/internal/odf/odf_spreadsheet.hpp index b05362bf..c905f068 100644 --- a/src/odr/internal/odf/odf_spreadsheet.hpp +++ b/src/odr/internal/odf/odf_spreadsheet.hpp @@ -2,7 +2,7 @@ #define ODR_INTERNAL_ODF_SPREADSHEET_H #include -#include +#include #include #include #include @@ -24,7 +24,7 @@ class SpreadsheetRoot final : public Root { using Root::Root; }; -class Sheet final : public Element, public common::Sheet { +class Sheet final : public Element, public abstract::Sheet { public: using Element::Element; @@ -38,30 +38,8 @@ class Sheet final : public Element, public common::Sheet { const std::optional range) const final; [[nodiscard]] abstract::Element * - first_cell_element(const abstract::Document *, std::uint32_t column, - std::uint32_t row) const final; - [[nodiscard]] abstract::Element * first_shape(const abstract::Document *) const final; - [[nodiscard]] TableStyle style(const abstract::Document *) const final; - [[nodiscard]] TableColumnStyle column_style(const abstract::Document *, - std::uint32_t column) const final; - [[nodiscard]] TableRowStyle row_style(const abstract::Document *, - std::uint32_t row) const final; - [[nodiscard]] TableCellStyle cell_style(const abstract::Document *, - std::uint32_t column, - std::uint32_t row) const final; - - [[nodiscard]] bool is_covered(const abstract::Document *, - std::uint32_t column, - std::uint32_t row) const final; - [[nodiscard]] TableDimensions span(const abstract::Document *, - std::uint32_t column, - std::uint32_t row) const final; - [[nodiscard]] ValueType value_type(const abstract::Document *, - std::uint32_t column, - std::uint32_t row) const final; - void init_column_(std::uint32_t column, std::uint32_t repeated, Element *element); void init_row_(std::uint32_t row, std::uint32_t repeated, Element *element); diff --git a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.cpp b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.cpp index 873c5a25..e072d500 100644 --- a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.cpp +++ b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.cpp @@ -86,51 +86,24 @@ TableDimensions Sheet::content(const abstract::Document *document, return dimensions(document); // TODO } -abstract::Element *Sheet::first_cell_element(const abstract::Document *, - std::uint32_t /*column*/, - std::uint32_t /*row*/) const { - return nullptr; // TODO -} - -abstract::Element *Sheet::first_shape(const abstract::Document *) const { - return nullptr; // TODO -} - -TableStyle Sheet::style(const abstract::Document *document) const { - return partial_style(document).table_style; -} - -TableColumnStyle Sheet::column_style(const abstract::Document *, +abstract::SheetColumn *Sheet::column(const abstract::Document *, std::uint32_t /*column*/) const { - return {}; // TODO + return nullptr; // TODO } -TableRowStyle Sheet::row_style(const abstract::Document *, +abstract::SheetRow *Sheet::row(const abstract::Document *, std::uint32_t /*row*/) const { - return {}; // TODO + return nullptr; // TODO } -TableCellStyle Sheet::cell_style(const abstract::Document *, +abstract::SheetCell *Sheet::cell(const abstract::Document *, std::uint32_t /*column*/, std::uint32_t /*row*/) const { - return {}; // TODO -} - -bool Sheet::is_covered(const abstract::Document *, std::uint32_t /*column*/, - std::uint32_t /*row*/) const { - return false; // TODO -} - -TableDimensions Sheet::span(const abstract::Document *, - std::uint32_t /*column*/, - std::uint32_t /*row*/) const { - return TableDimensions(); // TODO + return nullptr; // TODO } -ValueType Sheet::value_type(const abstract::Document *, - std::uint32_t /*column*/, - std::uint32_t /*row*/) const { - return ValueType::unknown; // TODO +abstract::Element *Sheet::first_shape(const abstract::Document *) const { + return nullptr; // TODO } pugi::xml_node Sheet::sheet_node_(const abstract::Document *document) const { @@ -141,7 +114,9 @@ pugi::xml_node Sheet::drawing_node_(const abstract::Document *document) const { return drawing_(document, m_node.attribute("r:id").value()); } -TableColumnStyle TableColumn::style(const abstract::Document *) const { +TableColumnStyle SheetColumn::style(const abstract::Document *, + const abstract::Sheet *, + std::uint32_t /*column*/) const { TableColumnStyle result; if (auto width = m_node.attribute("width")) { result.width = Measure(width.as_float(), DynamicUnit("ch")); @@ -150,16 +125,18 @@ TableColumnStyle TableColumn::style(const abstract::Document *) const { } [[nodiscard]] std::uint32_t -TableColumn::min_(const abstract::Document *) const { +SheetColumn::min_(const abstract::Document *) const { return m_node.attribute("min").as_uint() - 1; } [[nodiscard]] std::uint32_t -TableColumn::max_(const abstract::Document *) const { +SheetColumn::max_(const abstract::Document *) const { return m_node.attribute("max").as_uint() - 1; } -TableRowStyle TableRow::style(const abstract::Document *) const { +TableRowStyle SheetRow::style(const abstract::Document *, + const abstract::Sheet *, + std::uint32_t /*row*/) const { TableRowStyle result; if (auto height = m_node.attribute("ht")) { result.height = Measure(height.as_float(), DynamicUnit("pt")); @@ -167,27 +144,38 @@ TableRowStyle TableRow::style(const abstract::Document *) const { return result; } -bool TableCell::is_covered(const abstract::Document *) const { +bool SheetCell::is_covered(const abstract::Document *, const abstract::Sheet *, + std::uint32_t /*column*/, + std::uint32_t /*row*/) const { return false; // TODO } -ValueType TableCell::value_type(const abstract::Document *) const { +ValueType SheetCell::value_type(const abstract::Document *, + const abstract::Sheet *, + std::uint32_t /*column*/, + std::uint32_t /*row*/) const { return ValueType::string; } common::ResolvedStyle -TableCell::partial_style(const abstract::Document *document) const { +SheetCell::partial_style(const abstract::Document *document) const { if (auto style_id = m_node.attribute("s")) { return style_registry_(document)->cell_style(style_id.as_uint()); } return {}; } -TableDimensions TableCell::span(const abstract::Document *) const { +TableDimensions SheetCell::span(const abstract::Document *document, + const abstract::Sheet *, + std::uint32_t /*column*/, + std::uint32_t /*row*/) const { return {1, 1}; } -TableCellStyle TableCell::style(const abstract::Document *document) const { +TableCellStyle SheetCell::style(const abstract::Document *document, + const abstract::Sheet *, + std::uint32_t /*column*/, + std::uint32_t /*row*/) const { return partial_style(document).table_cell_style; } diff --git a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.hpp b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.hpp index e0a6f5c2..ae78034f 100644 --- a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.hpp +++ b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.hpp @@ -2,6 +2,8 @@ #define ODR_INTERNAL_OOXML_SPREADSHEET_ELEMENT_H #include +#include +#include #include #include @@ -18,10 +20,12 @@ class Element : public common::Element { public: explicit Element(pugi::xml_node node); - virtual common::ResolvedStyle partial_style(const abstract::Document *) const; - common::ResolvedStyle intermediate_style(const abstract::Document *) const; + [[nodiscard]] virtual common::ResolvedStyle + partial_style(const abstract::Document *) const; + [[nodiscard]] common::ResolvedStyle + intermediate_style(const abstract::Document *) const; - bool is_editable(const abstract::Document *) const override; + [[nodiscard]] bool is_editable(const abstract::Document *) const override; protected: pugi::xml_node m_node; @@ -62,67 +66,67 @@ class Sheet final : public Element, public abstract::Sheet { content(const abstract::Document *, std::optional) const final; - [[nodiscard]] abstract::Element * - first_cell_element(const abstract::Document *, std::uint32_t column, - std::uint32_t row) const final; - [[nodiscard]] abstract::Element * - first_shape(const abstract::Document *) const final; - - [[nodiscard]] TableStyle style(const abstract::Document *) const final; - [[nodiscard]] TableColumnStyle column_style(const abstract::Document *, + [[nodiscard]] abstract::SheetColumn *column(const abstract::Document *, std::uint32_t column) const final; - [[nodiscard]] TableRowStyle row_style(const abstract::Document *, + [[nodiscard]] abstract::SheetRow *row(const abstract::Document *, std::uint32_t row) const final; - [[nodiscard]] TableCellStyle cell_style(const abstract::Document *, + [[nodiscard]] abstract::SheetCell *cell(const abstract::Document *, std::uint32_t column, std::uint32_t row) const final; - [[nodiscard]] bool is_covered(const abstract::Document *, - std::uint32_t column, - std::uint32_t row) const final; - [[nodiscard]] TableDimensions span(const abstract::Document *, - std::uint32_t column, - std::uint32_t row) const final; - [[nodiscard]] ValueType value_type(const abstract::Document *, - std::uint32_t column, - std::uint32_t row) const final; + [[nodiscard]] abstract::Element * + first_shape(const abstract::Document *) const final; private: pugi::xml_node sheet_node_(const abstract::Document *) const; pugi::xml_node drawing_node_(const abstract::Document *) const; }; -class TableColumn final : public Element, public abstract::TableColumn { +class SheetColumn final : public Element, public abstract::SheetColumn { public: using Element::Element; - [[nodiscard]] TableColumnStyle style(const abstract::Document *) const final; + [[nodiscard]] TableColumnStyle style(const abstract::Document *, + const abstract::Sheet *, + std::uint32_t column) const final; private: [[nodiscard]] std::uint32_t min_(const abstract::Document *) const; [[nodiscard]] std::uint32_t max_(const abstract::Document *) const; }; -class TableRow final : public Element, public abstract::TableRow { +class SheetRow final : public Element, public abstract::SheetRow { public: using Element::Element; - [[nodiscard]] TableRowStyle style(const abstract::Document *) const final; + [[nodiscard]] TableRowStyle style(const abstract::Document *, + const abstract::Sheet *, + std::uint32_t row) const final; }; -class TableCell final : public Element, public abstract::TableCell { +class SheetCell final : public Element, public abstract::SheetCell { public: using Element::Element; - [[nodiscard]] bool is_covered(const abstract::Document *) const final; - - [[nodiscard]] TableDimensions span(const abstract::Document *) const final; - - [[nodiscard]] ValueType value_type(const abstract::Document *) const final; + [[nodiscard]] bool is_covered(const abstract::Document *, + const abstract::Sheet *, std::uint32_t column, + std::uint32_t row) const final; + [[nodiscard]] TableDimensions span(const abstract::Document *, + const abstract::Sheet *, + std::uint32_t column, + std::uint32_t row) const final; + [[nodiscard]] ValueType value_type(const abstract::Document *, + const abstract::Sheet *, + std::uint32_t column, + std::uint32_t row) const final; - common::ResolvedStyle partial_style(const abstract::Document *) const final; + [[nodiscard]] TableCellStyle style(const abstract::Document *, + const abstract::Sheet *, + std::uint32_t column, + std::uint32_t row) const final; - [[nodiscard]] TableCellStyle style(const abstract::Document *) const final; + [[nodiscard]] common::ResolvedStyle + partial_style(const abstract::Document *) const final; }; class Span final : public Element, public abstract::Span { diff --git a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_parser.cpp b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_parser.cpp index 6e6c76b6..d7d3916f 100644 --- a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_parser.cpp +++ b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_parser.cpp @@ -88,8 +88,8 @@ parse_any_element_tree(Document &document, pugi::xml_node node) { static std::unordered_map parser_table{ {"workbook", parse_element_tree}, {"worksheet", parse_element_tree}, - {"col", parse_element_tree}, - {"row", parse_element_tree}, + {"col", parse_element_tree}, + {"row", parse_element_tree}, {"r", parse_element_tree}, {"t", parse_element_tree}, {"v", parse_element_tree},