diff --git a/src/liborcus/odf_helper.cpp b/src/liborcus/odf_helper.cpp index f83f8b00f3ccf2779aaf50241d9d47e1003b66f4..30ee52a45e2d2cee82a7f36e2ff87de324affaae 100644 --- a/src/liborcus/odf_helper.cpp +++ b/src/liborcus/odf_helper.cpp @@ -69,6 +69,26 @@ odf_underline_style_map::entry odf_underline_style_entries[] = { MDDS_ASCII("wave"), spreadsheet::underline_t::wave} }; +typedef mdds::sorted_string_map odf_horizontal_alignment_map; + +odf_horizontal_alignment_map::entry odf_horizontal_alignment_entries[] = +{ + { MDDS_ASCII("center"), spreadsheet::hor_alignment_t::center}, + { MDDS_ASCII("end"), spreadsheet::hor_alignment_t::right}, + { MDDS_ASCII("justified"), spreadsheet::hor_alignment_t::justified}, + { MDDS_ASCII("start"), spreadsheet::hor_alignment_t::left} +}; + +typedef mdds::sorted_string_map odf_vertical_alignment_map; + +odf_vertical_alignment_map::entry odf_vertical_alignment_entries[] = +{ + { MDDS_ASCII("bottom"), spreadsheet::ver_alignment_t::bottom}, + { MDDS_ASCII("justified"), spreadsheet::ver_alignment_t::justified}, + { MDDS_ASCII("middle"), spreadsheet::ver_alignment_t::middle}, + { MDDS_ASCII("top"), spreadsheet::ver_alignment_t::top} +}; + bool is_valid_hex_digit(const char& character, orcus::spreadsheet::color_elem_t& val) { if ('0' <= character && character <= '9') @@ -167,6 +187,33 @@ orcus::spreadsheet::underline_t odf_helper::extract_underline_style(const orcus: return underline_style; } +bool odf_helper::extract_hor_alignment_style(const orcus::pstring& value, spreadsheet::hor_alignment_t& alignment) +{ + odf_horizontal_alignment_map horizontal_alignment_map(odf_horizontal_alignment_entries, + ORCUS_N_ELEMENTS(odf_horizontal_alignment_entries), + spreadsheet::hor_alignment_t::unknown); + + alignment = horizontal_alignment_map.find(value.get(), value.size()); + + if (alignment == spreadsheet::hor_alignment_t::unknown) + return false; + + return true; +} + +bool odf_helper::extract_ver_alignment_style(const orcus::pstring& value, spreadsheet::ver_alignment_t& alignment) +{ + odf_vertical_alignment_map vertical_alignment_map(odf_vertical_alignment_entries, + ORCUS_N_ELEMENTS(odf_vertical_alignment_entries), + spreadsheet::ver_alignment_t::unknown); + alignment = vertical_alignment_map.find(value.get(), value.size()); + + if (alignment == spreadsheet::ver_alignment_t::unknown) + return false; + + return true; +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_helper.hpp b/src/liborcus/odf_helper.hpp index e022412e0b0b994092ebf62705f49f146aeabc97..b0ba5108a9ad82ef5d49527586c3379a6d646e37 100644 --- a/src/liborcus/odf_helper.hpp +++ b/src/liborcus/odf_helper.hpp @@ -40,6 +40,13 @@ public: static orcus::spreadsheet::underline_width_t extract_underline_width(const orcus::pstring& value); static orcus::spreadsheet::underline_t extract_underline_style(const orcus::pstring& value); + + static bool extract_hor_alignment_style(const orcus::pstring& value, + spreadsheet::hor_alignment_t& alignment); + + static bool extract_ver_alignment_style(const orcus::pstring& value, + spreadsheet::ver_alignment_t& alignment); + }; } diff --git a/src/liborcus/odf_number_formatting_context.cpp b/src/liborcus/odf_number_formatting_context.cpp index 58ba9c58ea2caf1ee28205e39a110f2edde93110..142bfc0bd478f136ed74d787d00330e53dae24e9 100644 --- a/src/liborcus/odf_number_formatting_context.cpp +++ b/src/liborcus/odf_number_formatting_context.cpp @@ -84,6 +84,8 @@ class number_attr_parser : std::unary_function public: number_attr_parser() : + m_decimal_places(0), + m_min_int_digits(0), m_grouping(false), m_has_decimal_places(false) {} @@ -129,7 +131,10 @@ class scientific_number_attr_parser : std::unary_function public: month_attr_parser(): + m_style_name(false), m_textual(false) {} @@ -233,6 +239,7 @@ class seconds_attr_parser : std::unary_function public: seconds_attr_parser(): + m_decimal_places(0), m_style_name(false), m_has_decimal_places(false) {} @@ -268,6 +275,9 @@ class fraction_attr_parser : std::unary_function public: fraction_attr_parser(): + m_min_int_digits(0), + m_min_deno_digits(0), + m_min_num_digits(0), m_predefined_deno(false) {} diff --git a/src/liborcus/odf_styles.cpp b/src/liborcus/odf_styles.cpp index cbbf3f8bec4b0cbf9fc3c5e41e342eb39d080967..b07a467c47ebff95c4806b3d210a1a0d0546d4c1 100644 --- a/src/liborcus/odf_styles.cpp +++ b/src/liborcus/odf_styles.cpp @@ -79,6 +79,7 @@ number_formatting_style::number_formatting_style(const pstring& style_name, cons { name = style_name; is_volatile = volatile_style; + number_formatting = 0; } diff --git a/src/liborcus/odf_styles.hpp b/src/liborcus/odf_styles.hpp index c89f464aab93c536c6b6829621a95c087d35f80a..28bb0521cbc7d3f7ec217cfa418094b520b9483d 100644 --- a/src/liborcus/odf_styles.hpp +++ b/src/liborcus/odf_styles.hpp @@ -107,6 +107,7 @@ struct number_formatting_style pstring character_stream; number_formatting_style(): + number_formatting(0), is_volatile(false) {} diff --git a/src/liborcus/odf_styles_context.cpp b/src/liborcus/odf_styles_context.cpp index 752f7faa435e794a2bec81ee9a9ce594d4c1d6b0..6c4d1d5e8730a9739406cc0f0fd109c565643e89 100644 --- a/src/liborcus/odf_styles_context.cpp +++ b/src/liborcus/odf_styles_context.cpp @@ -119,6 +119,7 @@ class text_prop_attr_parser : std::unary_function spreadsheet::underline_t m_underline_style; spreadsheet::underline_type_t m_underline_type; + public: text_prop_attr_parser() : m_bold(false), m_italic(false), m_color(false), m_underline_is_text_color(false), m_underline(false), @@ -241,7 +242,9 @@ public: m_hidden(false), m_formula_hidden(false), m_print_content(false), - m_cell_protection(false) + m_cell_protection(false), + m_ver_alignment(spreadsheet::ver_alignment_t::unknown), + m_has_ver_alignment(false) {} private: @@ -259,6 +262,9 @@ private: border_map_type m_border_style_dir_pair; + spreadsheet::ver_alignment_t m_ver_alignment; + bool m_has_ver_alignment; + public: void operator() (const xml_token_attr_t& attr) @@ -355,6 +361,9 @@ public: m_locked = true; } } + case XML_vertical_align: + m_has_ver_alignment = odf_helper::extract_ver_alignment_style(attr.value, m_ver_alignment); + break; default: ; } @@ -383,7 +392,38 @@ public: { return m_border_style_dir_pair; } + bool has_ver_alignment() const { return m_has_ver_alignment;} + const spreadsheet::ver_alignment_t& get_ver_alignment() const { return m_ver_alignment;} + +}; + +class paragraph_prop_attr_parser : std::unary_function +{ + spreadsheet::hor_alignment_t m_hor_alignment; + bool m_has_hor_alignment; +public: + paragraph_prop_attr_parser(): + m_hor_alignment(spreadsheet::hor_alignment_t::unknown), + m_has_hor_alignment(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_fo) + { + switch (attr.name) + { + case XML_text_align: + m_has_hor_alignment = odf_helper::extract_hor_alignment_style(attr.value, m_hor_alignment); + break; + default: + ; + } + } + } + bool has_hor_alignment() const { return m_has_hor_alignment;} + const spreadsheet::hor_alignment_t& get_hor_alignment() const { return m_hor_alignment;} }; } @@ -510,7 +550,14 @@ void styles_context::start_element(xmlns_id_t ns, xml_token_t name, const std::v xml_element_expected(parent, NS_odf_style, XML_style); break; case XML_paragraph_properties: + { xml_element_expected(parent, NS_odf_style, XML_style); + paragraph_prop_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + if (func.has_hor_alignment()) + mp_styles->set_xf_horizontal_alignment(func.get_hor_alignment()); + + } break; case XML_text_properties: { @@ -629,6 +676,10 @@ void styles_context::start_element(xmlns_id_t ns, xml_token_t name, const std::v mp_styles->set_cell_print_content(func.is_print_content()); mp_styles->set_cell_formula_hidden(func.is_formula_hidden()); } + + if (func.has_ver_alignment()) + mp_styles->set_xf_vertical_alignment(func.get_ver_alignment()); + size_t cell_protection_id = mp_styles->commit_cell_protection(); switch (m_current_style->family) { diff --git a/src/liborcus/odf_styles_context_test.cpp b/src/liborcus/odf_styles_context_test.cpp index 95d57971a84453b54006c5b7fee033fc2f328f84..b90fc994c311ecee3011bf374ff503d4667cab1e 100644 --- a/src/liborcus/odf_styles_context_test.cpp +++ b/src/liborcus/odf_styles_context_test.cpp @@ -49,7 +49,7 @@ void test_odf_fill(orcus::spreadsheet::import_styles &styles) void test_odf_border(orcus::spreadsheet::import_styles &styles) { - assert(styles.get_border_count() == 8); + assert(styles.get_border_count() == 9); /* Test that border style applies to all the sides when not specified */ const orcus::spreadsheet::cell_style_t* style = find_cell_style_by_name("Name1", &styles); @@ -269,6 +269,18 @@ void test_odf_number_formatting(orcus::spreadsheet::import_styles& styles) cell_number_format = styles.get_number_format(number_format); assert(cell_number_format->format_string.str() == "[>=0]0.00;[RED]-0.00"); +} + +void test_odf_text_alignment(orcus::spreadsheet::import_styles& styles) +{ + const orcus::spreadsheet::cell_style_t* style = find_cell_style_by_name("Name22", &styles); + size_t xf = style->xf; + const orcus::spreadsheet::cell_format_t* cell_format = styles.get_cell_style_format(xf); + assert(cell_format); + + assert(cell_format->hor_align == orcus::spreadsheet::hor_alignment_t::right); + assert(cell_format->ver_align == orcus::spreadsheet::ver_alignment_t::middle); + } int main() { @@ -282,6 +294,7 @@ int main() test_odf_border(styles); test_odf_cell_protection(styles); test_odf_font(styles); + test_odf_text_alignment(styles); orcus::string_pool string_pool2; path = SRCDIR"/test/ods/styles/number-format.xml"; diff --git a/test/ods/styles/cell-styles.xml b/test/ods/styles/cell-styles.xml index 070f7ee6725d5cf677430af84eaf4cfb5f549a92..5bdd45e72137c451a4198bf760fda2a2a334936c 100644 --- a/test/ods/styles/cell-styles.xml +++ b/test/ods/styles/cell-styles.xml @@ -27,4 +27,9 @@ + + + + +