From c9ce984c890595fcbf74d9679e92ee9c4849448e Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Wed, 15 Jun 2016 17:14:17 +0530 Subject: [PATCH 01/13] Switch orcus_import_ods from xml simple stream handler to xml stream handler --- src/liborcus/orcus_import_ods.cpp | 3 +-- src/liborcus/xml_stream_handler.hpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/liborcus/orcus_import_ods.cpp b/src/liborcus/orcus_import_ods.cpp index 2d76dbb78..f929fe095 100644 --- a/src/liborcus/orcus_import_ods.cpp +++ b/src/liborcus/orcus_import_ods.cpp @@ -18,7 +18,6 @@ #include "session_context.hpp" #include "xml_stream_parser.hpp" -#include "xml_simple_stream_handler.hpp" namespace orcus { @@ -34,7 +33,7 @@ void import_ods::read_styles(const char* p, size_t n, spreadsheet::iface::import odf_styles_map_type styles_map; auto context = orcus::make_unique(cxt, odf_tokens, styles_map, styles); - xml_simple_stream_handler stream_handler(context.release()); + xml_stream_handler stream_handler(context.release()); xmlns_repository ns_repo; ns_repo.add_predefined_values(NS_odf_all); diff --git a/src/liborcus/xml_stream_handler.hpp b/src/liborcus/xml_stream_handler.hpp index 25c7de341..cf0dc38f2 100644 --- a/src/liborcus/xml_stream_handler.hpp +++ b/src/liborcus/xml_stream_handler.hpp @@ -31,7 +31,7 @@ class xml_stream_handler xml_stream_handler(); // disabled public: xml_stream_handler(xml_context_base* root_context); - virtual ~xml_stream_handler() = 0; + virtual ~xml_stream_handler() ; virtual void start_document(); virtual void end_document(); -- GitLab From dd0885d23e66d205666c64433c488c29c9e1e718 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Wed, 15 Jun 2016 17:09:36 +0530 Subject: [PATCH 02/13] Add ODF Number formatting as a child context to styles context and parser classes for it --- src/liborcus/Makefile.am | 2 + .../odf_number_formatting_context.cpp | 696 ++++++++++++++++++ .../odf_number_formatting_context.hpp | 49 ++ src/liborcus/odf_styles.cpp | 7 + src/liborcus/odf_styles.hpp | 16 + src/liborcus/odf_styles_context.cpp | 16 +- src/liborcus/odf_styles_context.hpp | 1 + 7 files changed, 785 insertions(+), 2 deletions(-) create mode 100644 src/liborcus/odf_number_formatting_context.cpp create mode 100644 src/liborcus/odf_number_formatting_context.hpp diff --git a/src/liborcus/Makefile.am b/src/liborcus/Makefile.am index e24a6dccf..746f3b98f 100644 --- a/src/liborcus/Makefile.am +++ b/src/liborcus/Makefile.am @@ -195,6 +195,8 @@ liborcus_@ORCUS_API_VERSION@_la_SOURCES += \ odf_styles.cpp \ odf_styles_context.hpp \ odf_styles_context.cpp \ + odf_number_formatting_context.hpp \ + odf_number_formatting_context.cpp \ odf_token_constants.hpp \ odf_token_constants.inl \ odf_tokens.hpp \ diff --git a/src/liborcus/odf_number_formatting_context.cpp b/src/liborcus/odf_number_formatting_context.cpp new file mode 100644 index 000000000..3c2c99181 --- /dev/null +++ b/src/liborcus/odf_number_formatting_context.cpp @@ -0,0 +1,696 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "odf_number_formatting_context.hpp" +#include "odf_namespace_types.hpp" +#include "odf_token_constants.hpp" +#include "odf_helper.hpp" +#include "orcus/measurement.hpp" +#include "orcus/spreadsheet/import_interface.hpp" +#include + +#include +#include +#include + +using namespace std; + +namespace orcus { + +namespace { + +class number_style_attr_parser : std::unary_function +{ + pstring m_country_code; + pstring m_style_name; + pstring m_language; + bool m_volatile; + +public: + + number_style_attr_parser(): + m_volatile(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_number) + { + switch(attr.name) + { + case XML_country: + m_country_code = attr.value; + break; + case XML_language: + m_language = attr.value; + break; + default: + ; + } + } + else if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_name: + m_style_name = attr.value; + break; + case XML_volatile: + m_volatile = attr.value == "true"; + break; + default: + ; + } + } + } + + pstring get_style_name() const { return m_style_name;} + pstring get_country_code() const { return m_country_code;} + bool is_volatile() const { return m_volatile;} + pstring get_language() const { return m_language;} +}; + +class number_attr_parser : std::unary_function +{ + size_t m_decimal_places; + size_t m_min_int_digits; + bool m_grouping; + bool m_has_decimal_places; + +public: + + number_attr_parser() : + m_grouping(false), + m_has_decimal_places(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_number) + { + switch (attr.name) + { + case XML_decimal_places: + { + m_decimal_places = to_long(attr.value); + if (m_decimal_places > 0) + m_has_decimal_places = true; + } + break; + case XML_grouping: + m_grouping = attr.value == "true"; + break; + case XML_min_integer_digits: + m_min_int_digits = to_long(attr.value); + break; + default: + ; + } + } + } + + size_t get_decimal_places() const { return m_decimal_places;} + bool is_grouped() const { return m_grouping;} + size_t get_min_int_digits() const { return m_min_int_digits;} + bool has_decimal_places() const { return m_has_decimal_places;} +}; + +class scientific_number_attr_parser : std::unary_function +{ + size_t m_decimal_places; + bool m_grouping; + size_t m_min_exp_digits; + size_t m_min_int_digits; + +public: + + scientific_number_attr_parser() : + m_grouping(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_number) + { + switch(attr.name) + { + case XML_decimal_places: + m_decimal_places = to_long(attr.value); + break; + case XML_grouping: + m_grouping = attr.value == "true"; + break; + case XML_min_exponent_digits: + m_min_exp_digits = to_long(attr.value); + break; + case XML_min_integer_digits: + m_min_int_digits = to_long(attr.value); + break; + default: + ; + } + } + } + + size_t get_decimal_places() const { return m_decimal_places;} + bool is_grouped() const { return m_grouping;} + size_t get_min_exp_digits() const { return m_min_exp_digits;} + size_t get_min_int_digits() const { return m_min_int_digits;} +}; + +class percentage_style_attr_parser : std::unary_function +{ + pstring m_style_name; + bool m_volatile; + +public: + percentage_style_attr_parser() : + m_volatile(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_name: + m_style_name = attr.value; + break; + case XML_volatile: + m_volatile = attr.value == "true"; + break; + default: + ; + } + } + } + + pstring get_style_name() const { return m_style_name;} + bool is_volatile() const { return m_volatile;} +}; + +class currency_style_attr_parser : std::unary_function +{ + pstring m_style_name; + bool m_volatile; + +public: + currency_style_attr_parser() : + m_volatile(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_name: + m_style_name = attr.value; + break; + case XML_volatile: + m_volatile = attr.value == "true"; + break; + default: + ; + } + } + } + + pstring get_style_name() const { return m_style_name;} + bool is_volatile() const { return m_volatile;} +}; + + +class date_style_attr_parser : std::unary_function +{ + pstring m_style_name; + bool m_volatile; + +public: + date_style_attr_parser(): + m_volatile(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_name: + m_style_name = attr.value; + break; + case XML_volatile: + m_volatile = attr.value == "true"; + break; + default: + ; + } + } + } + pstring get_style_name() const { return m_style_name;} + bool is_volatile() const { return m_volatile;} +}; + +class day_attr_parser : std::unary_function +{ + bool m_style_name; + +public: + day_attr_parser(): + m_style_name(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_number) + if (attr.name == XML_style) + m_style_name = attr.value == "true"; + } + + bool has_long() const { return m_style_name;} + +}; + +class year_attr_parser : std::unary_function +{ + bool m_style_name; + +public: + year_attr_parser(): + m_style_name(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_number) + if (attr.name == XML_style) + m_style_name = attr.value =="true"; + } + + bool has_long() const { return m_style_name;} + +}; + +class month_attr_parser : std::unary_function +{ + bool m_style_name; + bool m_textual; + +public: + month_attr_parser(): + m_textual(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_number) + { + if (attr.name == XML_style) + m_style_name = attr.value == "true"; + if (attr.name == XML_textual) + m_textual = attr.value == "true"; + } + } + + bool has_long() const { return m_style_name;} + bool is_textual() const { return m_textual;} +}; + + +class time_style_attr_parser : std::unary_function +{ + pstring m_style_name; + bool m_volatile; + +public: + time_style_attr_parser(): + m_volatile(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_name: + m_style_name = attr.value; + break; + case XML_volatile: + m_volatile = attr.value == "true"; + break; + default: + ; + } + } + } + + pstring get_style_name() const { return m_style_name;} + bool is_volatile() const { return m_volatile;} +}; + +class hours_attr_parser : std::unary_function +{ + bool m_style_name; + +public: + hours_attr_parser(): + m_style_name() + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_number) + if (attr.name == XML_style) + m_style_name = attr.value == "true"; + } + + bool has_long() const { return m_style_name;} +}; + +class minutes_attr_parser : std::unary_function +{ + bool m_style_name; + +public: + minutes_attr_parser(): + m_style_name(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_number) + if (attr.name == XML_style) + m_style_name = attr.value == "true"; + } + + bool has_long() const { return m_style_name;} +}; + +class seconds_attr_parser : std::unary_function +{ + bool m_style_name; + +public: + seconds_attr_parser(): + m_style_name(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_number) + if (attr.name == XML_style) + m_style_name = attr.value == "true"; + } + + bool has_long() const { return m_style_name;} +}; + + +class fraction_attr_parser : std::unary_function +{ + size_t m_min_int_digits; + size_t m_min_deno_digits; + size_t m_min_num_digits; + +public: + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_number) + { + switch(attr.name) + { + case XML_min_integer_digits: + m_min_int_digits = to_long(attr.value); + break; + case XML_min_numerator_digits: + m_min_num_digits = to_long(attr.value); + break; + case XML_min_denominator_digits: + m_min_deno_digits = to_long(attr.value); + break; + default: + ; + } + } + } + + size_t get_min_int_digits() const { return m_min_int_digits;} + size_t get_min_num_digits() const { return m_min_num_digits;} + size_t get_min_deno_digits() const { return m_min_deno_digits;} +}; + +class boolean_style_attr_parser : std::unary_function +{ + pstring m_style_name; + bool m_volatile; + +public: + boolean_style_attr_parser(): + m_volatile(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_name: + m_style_name = attr.value; + break; + case XML_volatile: + m_volatile = attr.value == "true"; + break; + default: + ; + } + } + } + + pstring get_style_name() const { return m_style_name;} + bool is_volatile() const { return m_volatile;} +}; + +class text_style_attr_parser : std::unary_function +{ + pstring m_style_name; + bool m_volatile; + +public: + text_style_attr_parser(): + m_volatile(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_name: + m_style_name = attr.value; + break; + case XML_volatile: + m_volatile = attr.value == "true"; + break; + default: + ; + } + } + } + + pstring get_style_name() const { return m_style_name;} + bool is_volatile() const { return m_volatile;} +}; + +class text_properties_attr_parser : std::unary_function +{ + pstring m_color; + bool color_absent; + +public: + text_properties_attr_parser(): + color_absent(true) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_fo) + { + switch (attr.name) + { + case XML_color: + { + if (attr.value == "#000000") + m_color = "BLACK"; + if (attr.value == "#ff0000") + m_color = "RED"; + if (attr.value == "#00ff00") + m_color = "GREEN"; + if (attr.value == "#0000ff") + m_color = "BLUE"; + if (attr.value == "#ffff00") + m_color = "YELLOW"; + if (attr.value == "#00ffff") + m_color = "CYAN"; + if (attr.value == "#ff00ff") + m_color = "MAGENTA"; + if (attr.value == "#ffffff") + m_color = "WHITE"; + else + color_absent = false; + } + } + } + } + + pstring get_color() const { return m_color;} + bool has_color() const { return !color_absent;} +}; + +} + +number_formatting_context::number_formatting_context( + session_context& session_cxt, const tokens& tk, odf_styles_map_type& styles, + spreadsheet::iface::import_styles* iface_styles, number_formatting_style* number_format_style) : + xml_context_base(session_cxt, tk), + mp_styles(iface_styles), + m_styles(styles), + m_current_style(number_format_style) +{} + +bool number_formatting_context::can_handle_element(xmlns_id_t ns, xml_token_t name) const +{ + return true; +} + +xml_context_base* number_formatting_context::create_child_context(xmlns_id_t ns, xml_token_t name) +{ + return NULL; +} + +void number_formatting_context::end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) +{ +} + +void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, const std::vector& attrs) +{ + if (ns == NS_odf_number) + { + switch(name) + { + case XML_number_style: + { + number_style_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + m_current_style->name = func.get_style_name(); + m_current_style->is_volatile = func.is_volatile(); + } + break; + case XML_number: + { + number_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + if (func.is_grouped()) + { + if (func.get_min_int_digits() < 4) + { + m_current_style->number_formatting_code += "#,"; + for (size_t i = 0; i < 3 - func.get_min_int_digits(); i++) + { + m_current_style->number_formatting_code += "#"; + } + for (size_t i = 0; i < func.get_min_int_digits(); i++) + { + m_current_style->number_formatting_code += "0"; + } + } + else + { + std:: string temporary_code; + for(size_t i = 0; i < func.get_min_int_digits(); i++) + { + if (i % 3 == 0 && i != 0) + temporary_code += ","; + temporary_code += "0"; + } + std::reverse(temporary_code.begin(), temporary_code.end()); + m_current_style->number_formatting_code += temporary_code; + } + } + else + { + if (func.get_min_int_digits() == 0) + m_current_style->number_formatting_code += "#"; + + for (size_t i = 0; i < func.get_min_int_digits(); i++) + { + m_current_style->number_formatting_code += "0"; + } + } + if (func.has_decimal_places()) + { + m_current_style->number_formatting_code += "."; + for(size_t i = 0; i < func.get_decimal_places() ; i++) + m_current_style->number_formatting_code += "0"; + } + } + break; + default: + ; + } + } +} + +bool number_formatting_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_odf_number) + { + if (name == XML_number_style) + { + if (m_current_style->is_volatile) + { + m_current_style->number_formatting_code += ";"; + } + else + { + mp_styles->set_number_format_code(m_current_style->number_formatting_code.c_str(), + m_current_style->number_formatting_code.size()); + mp_styles->set_xf_number_format(mp_styles->commit_number_format()); + + mp_styles->set_cell_style_name( m_current_style->name.get(), m_current_style->name.size()); + mp_styles->set_cell_style_xf(mp_styles->commit_cell_style_xf()); + mp_styles->commit_cell_style(); + return true; + } + } + else if (name == XML_currency_symbol) + m_current_style->number_formatting_code = m_current_style->number_formatting_code + "[$" + + m_current_style->character_stream + "]"; + + else if (name == XML_text) + m_current_style->number_formatting_code += m_current_style->character_stream; + } + return false; +} + + +void number_formatting_context::characters(const pstring& str, bool transient) +{ + if (str != "\n") + m_current_style->character_stream = str; +} + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_number_formatting_context.hpp b/src/liborcus/odf_number_formatting_context.hpp new file mode 100644 index 000000000..7b191407e --- /dev/null +++ b/src/liborcus/odf_number_formatting_context.hpp @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ODF_NUMBER_FORMATTING_CONTEXT_HPP +#define ODF_NUMBER_FORMATTING_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "odf_styles.hpp" +#include "odf_styles_context.hpp" +#include "orcus/global.hpp" + +namespace orcus { + +namespace spreadsheet { namespace iface { + class import_styles; +}} + + +/** + * Context that handles scope. + */ +class number_formatting_context : public xml_context_base +{ +public: + number_formatting_context( + session_context& session_cxt, const tokens& tk, odf_styles_map_type& styles, spreadsheet::iface::import_styles* iface_styles, number_formatting_style*); + + virtual bool can_handle_element(xmlns_id_t ns, xml_token_t name) const; + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child); + virtual void start_element(xmlns_id_t ns, xml_token_t name, const std::vector& attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + virtual void characters(const pstring& str, bool transient); + +private: + + spreadsheet::iface::import_styles* mp_styles; + odf_styles_map_type& m_styles; + number_formatting_style* m_current_style; +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_styles.cpp b/src/liborcus/odf_styles.cpp index 15b2448f3..cbbf3f8be 100644 --- a/src/liborcus/odf_styles.cpp +++ b/src/liborcus/odf_styles.cpp @@ -75,5 +75,12 @@ odf_style::~odf_style() } } +number_formatting_style::number_formatting_style(const pstring& style_name, const bool volatile_style) +{ + name = style_name; + is_volatile = volatile_style; +} + + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_styles.hpp b/src/liborcus/odf_styles.hpp index 62a392b69..c89f464aa 100644 --- a/src/liborcus/odf_styles.hpp +++ b/src/liborcus/odf_styles.hpp @@ -97,6 +97,22 @@ struct odf_style ~odf_style(); }; +struct number_formatting_style +{ + size_t number_formatting; + + pstring name; + std::string number_formatting_code; + bool is_volatile; + pstring character_stream; + + number_formatting_style(): + is_volatile(false) + {} + + number_formatting_style(const pstring& style_name, const bool volatile_style); +}; + typedef std::map> odf_styles_map_type; } diff --git a/src/liborcus/odf_styles_context.cpp b/src/liborcus/odf_styles_context.cpp index c0847fbd8..752f7faa4 100644 --- a/src/liborcus/odf_styles_context.cpp +++ b/src/liborcus/odf_styles_context.cpp @@ -11,7 +11,7 @@ #include "odf_helper.hpp" #include "orcus/measurement.hpp" #include "orcus/spreadsheet/import_interface.hpp" - +#include "odf_number_formatting_context.hpp" #include using namespace std; @@ -431,16 +431,28 @@ styles_context::styles_context( bool styles_context::can_handle_element(xmlns_id_t ns, xml_token_t name) const { + if (ns == NS_odf_number) + return false; + return true; } xml_context_base* styles_context::create_child_context(xmlns_id_t ns, xml_token_t name) { - return NULL; + number_formatting_style* number_formatting = new number_formatting_style; + if (ns == NS_odf_number ) + { + mp_child.reset(new number_formatting_context(get_session_context(), get_tokens(), m_styles, mp_styles, number_formatting)); + mp_child->transfer_common(*this); + return mp_child.get(); + } + + return nullptr; } void styles_context::end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) { + return; } void styles_context::start_element(xmlns_id_t ns, xml_token_t name, const std::vector& attrs) diff --git a/src/liborcus/odf_styles_context.hpp b/src/liborcus/odf_styles_context.hpp index fe9923ecf..a1eb45e09 100644 --- a/src/liborcus/odf_styles_context.hpp +++ b/src/liborcus/odf_styles_context.hpp @@ -54,6 +54,7 @@ private: private: spreadsheet::iface::import_styles* mp_styles; odf_styles_map_type& m_styles; + std::unique_ptr mp_child; style_value_converter m_converter; -- GitLab From f0d03ced8a9a01a277e93cca01a5180f61fd9a04 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Thu, 16 Jun 2016 15:40:04 +0530 Subject: [PATCH 03/13] Add code for importing currency styles and its sub-elements --- .../odf_number_formatting_context.cpp | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/liborcus/odf_number_formatting_context.cpp b/src/liborcus/odf_number_formatting_context.cpp index 3c2c99181..ccfe35b54 100644 --- a/src/liborcus/odf_number_formatting_context.cpp +++ b/src/liborcus/odf_number_formatting_context.cpp @@ -645,6 +645,30 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c } } break; + case XML_currency_style: + { + currency_style_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + m_current_style->name = func.get_style_name(); + m_current_style->is_volatile = func.is_volatile(); + } + break; + default: + ; + } + } + if (ns == NS_odf_style) + { + switch (name) + { + case XML_text_properties: + { + text_properties_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + if (func.has_color()) + m_current_style->number_formatting_code = m_current_style->number_formatting_code + "[" + func.get_color() + "]"; + } + break; default: ; } @@ -655,7 +679,7 @@ bool number_formatting_context::end_element(xmlns_id_t ns, xml_token_t name) { if (ns == NS_odf_number) { - if (name == XML_number_style) + if (name == XML_number_style || name == XML_currency_style) { if (m_current_style->is_volatile) { -- GitLab From ac3765829daa6e306c8e25ef669cb4f1fe736722 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Thu, 16 Jun 2016 16:22:58 +0530 Subject: [PATCH 04/13] Add code for percentage number format import --- src/liborcus/odf_number_formatting_context.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/liborcus/odf_number_formatting_context.cpp b/src/liborcus/odf_number_formatting_context.cpp index ccfe35b54..178897e98 100644 --- a/src/liborcus/odf_number_formatting_context.cpp +++ b/src/liborcus/odf_number_formatting_context.cpp @@ -653,6 +653,14 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c m_current_style->is_volatile = func.is_volatile(); } break; + case XML_percentage_style: + { + percentage_style_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + m_current_style->name = func.get_style_name(); + m_current_style->is_volatile = func.is_volatile(); + } + break; default: ; } @@ -679,7 +687,7 @@ bool number_formatting_context::end_element(xmlns_id_t ns, xml_token_t name) { if (ns == NS_odf_number) { - if (name == XML_number_style || name == XML_currency_style) + if (name == XML_number_style || name == XML_currency_style || name == XML_percentage_style) { if (m_current_style->is_volatile) { -- GitLab From 2f451de29b9818a03d532f6eb86d8709863a4794 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Thu, 16 Jun 2016 17:19:12 +0530 Subject: [PATCH 05/13] Add code for scientific number formatting import --- .../odf_number_formatting_context.cpp | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/liborcus/odf_number_formatting_context.cpp b/src/liborcus/odf_number_formatting_context.cpp index 178897e98..5d5927ff6 100644 --- a/src/liborcus/odf_number_formatting_context.cpp +++ b/src/liborcus/odf_number_formatting_context.cpp @@ -661,6 +661,58 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c m_current_style->is_volatile = func.is_volatile(); } break; + case XML_scientific_number: + { + scientific_number_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + + if (func.is_grouped()) + { + if (func.get_min_int_digits() < 4) + { + m_current_style->number_formatting_code += "#,"; + for (size_t i = 0; i < 3 - func.get_min_int_digits(); i++) + { + m_current_style->number_formatting_code += "#"; + } + for (size_t i = 0; i < func.get_min_int_digits(); i++) + { + m_current_style->number_formatting_code += "0"; + } + } + else + { + std:: string temporary_code; + for(size_t i = 0; i < func.get_min_int_digits(); i++) + { + if (i % 3 == 0 && i != 0) + temporary_code += ","; + temporary_code += "0"; + } + std::reverse(temporary_code.begin(), temporary_code.end()); + m_current_style->number_formatting_code += temporary_code; + } + } + else + { + if (func.get_min_int_digits() == 0) + m_current_style->number_formatting_code += "#"; + + for (size_t i = 0; i < func.get_min_int_digits(); i++) + { + m_current_style->number_formatting_code += "0"; + } + } + + m_current_style->number_formatting_code += "."; + for(size_t i = 0; i < func.get_decimal_places() ; i++) + m_current_style->number_formatting_code += "0"; + + m_current_style->number_formatting_code += "E+"; + for(size_t i = 0; i < func.get_min_exp_digits() ; i++) + m_current_style->number_formatting_code += "0"; + } + break; default: ; } -- GitLab From 4f4c9f80114d251d5aa229f51edeb4395fd3df2c Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Thu, 16 Jun 2016 17:45:07 +0530 Subject: [PATCH 06/13] Add code for text style import --- src/liborcus/odf_number_formatting_context.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/liborcus/odf_number_formatting_context.cpp b/src/liborcus/odf_number_formatting_context.cpp index 5d5927ff6..8e36603b6 100644 --- a/src/liborcus/odf_number_formatting_context.cpp +++ b/src/liborcus/odf_number_formatting_context.cpp @@ -713,6 +713,19 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c m_current_style->number_formatting_code += "0"; } break; + case XML_text_style: + { + text_style_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + m_current_style->name = func.get_style_name(); + m_current_style->is_volatile = func.is_volatile(); + } + break; + case XML_text_content: + { + m_current_style->number_formatting_code += "@"; + } + break; default: ; } @@ -739,7 +752,8 @@ bool number_formatting_context::end_element(xmlns_id_t ns, xml_token_t name) { if (ns == NS_odf_number) { - if (name == XML_number_style || name == XML_currency_style || name == XML_percentage_style) + if (name == XML_number_style || name == XML_currency_style || name == XML_percentage_style + || name == XML_text_style) { if (m_current_style->is_volatile) { -- GitLab From 1212a48f1ab1a81b91c604a92f693f4ecd5dd15a Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Thu, 16 Jun 2016 18:32:47 +0530 Subject: [PATCH 07/13] Add code to import boolean number format and fix for fraction parser class` --- .../odf_number_formatting_context.cpp | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/liborcus/odf_number_formatting_context.cpp b/src/liborcus/odf_number_formatting_context.cpp index 8e36603b6..182025cb0 100644 --- a/src/liborcus/odf_number_formatting_context.cpp +++ b/src/liborcus/odf_number_formatting_context.cpp @@ -419,8 +419,14 @@ class fraction_attr_parser : std::unary_function size_t m_min_int_digits; size_t m_min_deno_digits; size_t m_min_num_digits; + pstring m_deno_value; + + bool m_predefined_deno; public: + fraction_attr_parser(): + m_predefined_deno(false) + {} void operator() (const xml_token_attr_t& attr) { @@ -437,6 +443,12 @@ public: case XML_min_denominator_digits: m_min_deno_digits = to_long(attr.value); break; + case XML_denominator_value: + { + m_deno_value = attr.value; + m_predefined_deno = true; + } + break; default: ; } @@ -446,6 +458,8 @@ public: size_t get_min_int_digits() const { return m_min_int_digits;} size_t get_min_num_digits() const { return m_min_num_digits;} size_t get_min_deno_digits() const { return m_min_deno_digits;} + pstring get_deno_value() const { return m_deno_value;} + bool has_predefined_deno() const { return m_predefined_deno;} }; class boolean_style_attr_parser : std::unary_function @@ -713,6 +727,41 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c m_current_style->number_formatting_code += "0"; } break; + case XML_boolean_style: + { + boolean_style_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + m_current_style->name = func.get_style_name(); + m_current_style->is_volatile = func.is_volatile(); + } + break; + case XML_boolean: + { + m_current_style->number_formatting_code += "BOOLEAN"; + } + break; + case XML_fraction: + { + fraction_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + + for (size_t i = 0; i < func.get_min_int_digits(); i++) + m_current_style->number_formatting_code += "#"; + + if (func.get_min_int_digits() != 0) + m_current_style->number_formatting_code += " "; + + for (size_t i = 0; i < func.get_min_num_digits(); i++) + m_current_style->number_formatting_code += "?"; + + m_current_style->number_formatting_code += "/"; + if (func.has_predefined_deno()) + m_current_style->number_formatting_code += func.get_deno_value(); + else + for(size_t i = 0; i < func.get_min_deno_digits(); i++) + m_current_style->number_formatting_code += "?"; + } + break; case XML_text_style: { text_style_attr_parser func; @@ -753,7 +802,7 @@ bool number_formatting_context::end_element(xmlns_id_t ns, xml_token_t name) if (ns == NS_odf_number) { if (name == XML_number_style || name == XML_currency_style || name == XML_percentage_style - || name == XML_text_style) + || name == XML_text_style || name == XML_boolean_style) { if (m_current_style->is_volatile) { -- GitLab From 8113b3e9511649d6cc030a1f98ea1a08f74f18eb Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Thu, 16 Jun 2016 21:24:19 +0530 Subject: [PATCH 08/13] Add code for date number format import --- .../odf_number_formatting_context.cpp | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/liborcus/odf_number_formatting_context.cpp b/src/liborcus/odf_number_formatting_context.cpp index 182025cb0..deb2d3150 100644 --- a/src/liborcus/odf_number_formatting_context.cpp +++ b/src/liborcus/odf_number_formatting_context.cpp @@ -762,6 +762,45 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c m_current_style->number_formatting_code += "?"; } break; + case XML_date_style: + { + date_style_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + m_current_style->name = func.get_style_name(); + m_current_style->is_volatile = func.is_volatile(); + } + break; + case XML_day: + { + day_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + m_current_style->number_formatting_code += "D"; + if (func.has_long()) + m_current_style->number_formatting_code += "D"; + } + break; + case XML_month: + { + month_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + m_current_style->number_formatting_code += "M"; + if (func.has_long()) + m_current_style->number_formatting_code += "M"; + if (func.is_textual()) + m_current_style->number_formatting_code += "M"; + if (func.has_long() && func.is_textual()) + m_current_style->number_formatting_code += "M"; + } + break; + case XML_year: + { + year_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + m_current_style->number_formatting_code += "YY"; + if (func.has_long()) + m_current_style->number_formatting_code += "YY"; + } + break; case XML_text_style: { text_style_attr_parser func; @@ -802,7 +841,7 @@ bool number_formatting_context::end_element(xmlns_id_t ns, xml_token_t name) if (ns == NS_odf_number) { if (name == XML_number_style || name == XML_currency_style || name == XML_percentage_style - || name == XML_text_style || name == XML_boolean_style) + || name == XML_text_style || name == XML_boolean_style || name == XML_date_style) { if (m_current_style->is_volatile) { -- GitLab From edbd1097cb522d471047e1e599076622c64aea7c Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Thu, 16 Jun 2016 22:14:12 +0530 Subject: [PATCH 09/13] Add code for time number formatting import and a few quick fixes --- .../odf_number_formatting_context.cpp | 75 ++++++++++++++++--- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/src/liborcus/odf_number_formatting_context.cpp b/src/liborcus/odf_number_formatting_context.cpp index deb2d3150..e0b5f4971 100644 --- a/src/liborcus/odf_number_formatting_context.cpp +++ b/src/liborcus/odf_number_formatting_context.cpp @@ -271,7 +271,7 @@ public: { if (attr.ns == NS_odf_number) if (attr.name == XML_style) - m_style_name = attr.value == "true"; + m_style_name = attr.value == "long"; } bool has_long() const { return m_style_name;} @@ -291,7 +291,7 @@ public: { if (attr.ns == NS_odf_number) if (attr.name == XML_style) - m_style_name = attr.value =="true"; + m_style_name = attr.value =="long"; } bool has_long() const { return m_style_name;} @@ -313,7 +313,7 @@ public: if (attr.ns == NS_odf_number) { if (attr.name == XML_style) - m_style_name = attr.value == "true"; + m_style_name = attr.value == "long"; if (attr.name == XML_textual) m_textual = attr.value == "true"; } @@ -362,14 +362,14 @@ class hours_attr_parser : std::unary_function public: hours_attr_parser(): - m_style_name() + m_style_name(false) {} void operator() (const xml_token_attr_t& attr) { if (attr.ns == NS_odf_number) if (attr.name == XML_style) - m_style_name = attr.value == "true"; + m_style_name = attr.value == "long"; } bool has_long() const { return m_style_name;} @@ -388,7 +388,7 @@ public: { if (attr.ns == NS_odf_number) if (attr.name == XML_style) - m_style_name = attr.value == "true"; + m_style_name = attr.value == "long"; } bool has_long() const { return m_style_name;} @@ -396,21 +396,33 @@ public: class seconds_attr_parser : std::unary_function { + size_t m_decimal_places; bool m_style_name; + bool m_has_decimal_places; public: seconds_attr_parser(): - m_style_name(false) + m_style_name(false), + m_has_decimal_places(false) {} void operator() (const xml_token_attr_t& attr) { if (attr.ns == NS_odf_number) + { if (attr.name == XML_style) - m_style_name = attr.value == "true"; + m_style_name = attr.value == "long"; + if (attr.name == XML_decimal_places) + { + m_decimal_places = to_long(attr.value); + m_has_decimal_places = true; + } + } } bool has_long() const { return m_style_name;} + size_t get_decimal_places() const { return m_decimal_places;} + bool has_decimal_places() const { return m_has_decimal_places;} }; @@ -801,6 +813,49 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c m_current_style->number_formatting_code += "YY"; } break; + case XML_time_style: + { + time_style_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + m_current_style->name = func.get_style_name(); + m_current_style->is_volatile = func.is_volatile(); + } + break; + case XML_hours: + { + hours_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + m_current_style->number_formatting_code += "H"; + if (func.has_long()) + m_current_style->number_formatting_code += "H"; + } + break; + case XML_minutes: + { + minutes_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + m_current_style->number_formatting_code += "M"; + if (func.has_long()) + m_current_style->number_formatting_code += "M"; + } + break; + case XML_seconds: + { + seconds_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + m_current_style->number_formatting_code += "S"; + if (func.has_long()) + m_current_style->number_formatting_code += "S"; + if (func.has_decimal_places()) + for (size_t i = 0; i < func.get_decimal_places(); i++) + m_current_style->number_formatting_code += "S"; + } + break; + case XML_am_pm: + { + m_current_style->number_formatting_code += " AM/PM"; + } + break; case XML_text_style: { text_style_attr_parser func; @@ -841,7 +896,8 @@ bool number_formatting_context::end_element(xmlns_id_t ns, xml_token_t name) if (ns == NS_odf_number) { if (name == XML_number_style || name == XML_currency_style || name == XML_percentage_style - || name == XML_text_style || name == XML_boolean_style || name == XML_date_style) + || name == XML_text_style || name == XML_boolean_style || name == XML_date_style + || name == XML_time_style) { if (m_current_style->is_volatile) { @@ -866,6 +922,7 @@ bool number_formatting_context::end_element(xmlns_id_t ns, xml_token_t name) else if (name == XML_text) m_current_style->number_formatting_code += m_current_style->character_stream; } + m_current_style->character_stream.clear(); return false; } -- GitLab From 21a00bb8296b5aa455805854cd2c0b12361fe779 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Fri, 17 Jun 2016 00:49:22 +0530 Subject: [PATCH 10/13] Add code for mapping number format styles --- .../odf_number_formatting_context.cpp | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/liborcus/odf_number_formatting_context.cpp b/src/liborcus/odf_number_formatting_context.cpp index e0b5f4971..27d4037fd 100644 --- a/src/liborcus/odf_number_formatting_context.cpp +++ b/src/liborcus/odf_number_formatting_context.cpp @@ -583,6 +583,39 @@ public: bool has_color() const { return !color_absent;} }; +class map_attr_parser : std::unary_function +{ + string m_value; + string m_sign; + bool m_has_map; + +public: + map_attr_parser(): + m_has_map(false) + {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_odf_style) + { + if (attr.name == XML_condition) + { + for (size_t i = 0; i < attr.value.size(); i++) + { + if (attr.value[i] == '<' || attr.value[i] == '>' || attr.value[i] == '=') + m_sign = m_sign + attr.value[i]; + if (isdigit(attr.value[i])) + m_value = m_value + attr.value[i]; + } + m_has_map = true; + } + } + } + string get_value() const { return m_value;} + string get_sign() const { return m_sign;} + bool has_map() const { return m_has_map;} +}; + } number_formatting_context::number_formatting_context( @@ -885,6 +918,17 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c m_current_style->number_formatting_code = m_current_style->number_formatting_code + "[" + func.get_color() + "]"; } break; + case XML_map: + { + map_attr_parser func; + func = std::for_each(attrs.begin(), attrs.end(), func); + if (func.has_map()) + { + m_current_style->number_formatting_code = "[" + func.get_sign() + func.get_value() + "]" + + m_current_style->number_formatting_code; + } + } + break; default: ; } -- GitLab From 1eb52f862fb79ebc60225a9c845537ffddd27d36 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Fri, 17 Jun 2016 11:08:52 +0530 Subject: [PATCH 11/13] Add test document for number-format --- test/ods/styles/number-format.xml | 58 +++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 test/ods/styles/number-format.xml diff --git a/test/ods/styles/number-format.xml b/test/ods/styles/number-format.xml new file mode 100644 index 000000000..ecc1fbc9a --- /dev/null +++ b/test/ods/styles/number-format.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + - + + + + + + % + + + + + + + December + + + + + + + + + + / + + / + + + + + : + + : + + + + + + + + + + - + + + + -- GitLab From 741be3cba0b9070f1b3edeff794db3e9ff260256 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Fri, 17 Jun 2016 11:40:35 +0530 Subject: [PATCH 12/13] Restructure ods styles test and test cases for number formatting --- src/liborcus/odf_styles_context_test.cpp | 154 ++++++++++++++++++----- 1 file changed, 126 insertions(+), 28 deletions(-) diff --git a/src/liborcus/odf_styles_context_test.cpp b/src/liborcus/odf_styles_context_test.cpp index a283b23c0..95d57971a 100644 --- a/src/liborcus/odf_styles_context_test.cpp +++ b/src/liborcus/odf_styles_context_test.cpp @@ -28,17 +28,8 @@ const orcus::spreadsheet::cell_style_t* find_cell_style_by_name(const orcus::pst } -int main() +void test_odf_fill(orcus::spreadsheet::import_styles &styles) { - orcus::string_pool string_pool; - const char* path = SRCDIR"/test/ods/styles/cell-styles.xml"; - std::string content = orcus::load_file_content(path); - orcus::spreadsheet::import_styles styles(string_pool); - orcus::import_ods::read_styles(content.c_str(), content.size(), &styles); - -/* Test for Cell Fill - ===================================================== -*/ const orcus::spreadsheet::cell_style_t* style = find_cell_style_by_name("Name1", &styles); assert(style->parent_name == "Text"); size_t xf = style->xf; @@ -54,16 +45,16 @@ int main() assert(cell_fill->bg_color.red == 0xfe); assert(cell_fill->bg_color.green == 0xff); assert(cell_fill->bg_color.blue == 0xcc); +} -/* Test for Border Styles - ===================================================== -*/ +void test_odf_border(orcus::spreadsheet::import_styles &styles) +{ assert(styles.get_border_count() == 8); /* Test that border style applies to all the sides when not specified */ - style = find_cell_style_by_name("Name1", &styles); - xf = style->xf; - cell_format = styles.get_cell_style_format(xf); + const orcus::spreadsheet::cell_style_t* style = find_cell_style_by_name("Name1", &styles); + size_t xf = style->xf; + const orcus::spreadsheet::cell_format_t* cell_format = styles.get_cell_style_format(xf); size_t border = cell_format->border; assert(cell_format); @@ -109,14 +100,14 @@ int main() assert(cell_border->diagonal_bl_tr.border_color.red == 0xff); assert(cell_border->diagonal_tl_br.border_color.green == 0x00); assert(cell_border->diagonal_tl_br.border_width.value == 0.74); +} -/* Test for Cell Protection - ======================================================== -*/ +void test_odf_cell_protection(orcus::spreadsheet::import_styles& styles) +{ /* Test that Cell is only protected and not hidden , Print Content is true */ - style = find_cell_style_by_name("Name5", &styles); - xf = style->xf; - cell_format = styles.get_cell_style_format(xf); + const orcus::spreadsheet::cell_style_t* style = find_cell_style_by_name("Name5", &styles); + size_t xf = style->xf; + const orcus::spreadsheet::cell_format_t* cell_format = styles.get_cell_style_format(xf); size_t protection = cell_format->protection; assert(cell_format); @@ -151,13 +142,13 @@ int main() assert(cell_protection->hidden == false); assert(cell_protection->print_content == true); assert(cell_protection->formula_hidden == false); +} -/* Test for Font and underline - ================================================== -*/ - style = find_cell_style_by_name("Name8", &styles); - xf = style->xf; - cell_format = styles.get_cell_style_format(xf); +void test_odf_font(orcus::spreadsheet::import_styles& styles) +{ + const orcus::spreadsheet::cell_style_t* style = find_cell_style_by_name("Name8", &styles); + size_t xf = style->xf; + const orcus::spreadsheet::cell_format_t* cell_format = styles.get_cell_style_format(xf); size_t font = cell_format->font; assert(cell_format); @@ -192,6 +183,113 @@ int main() assert(cell_font->underline_color.red == (int)0x18); assert(cell_font->underline_color.green == (int)0x56); assert(cell_font->underline_color.blue == (int)0xff); +} + +void test_odf_number_formatting(orcus::spreadsheet::import_styles& styles) +{ + const orcus::spreadsheet::cell_style_t* style = find_cell_style_by_name("Name10", &styles); + size_t xf = style->xf; + const orcus::spreadsheet::cell_format_t* cell_format = styles.get_cell_style_format(xf); + assert(cell_format); + + size_t number_format = cell_format->number_format; + const orcus::spreadsheet::number_format_t* cell_number_format = styles.get_number_format(number_format); + assert(cell_number_format->format_string.str() == "#.000000"); + + style = find_cell_style_by_name("Name11", &styles); + xf = style->xf; + cell_format = styles.get_cell_style_format(xf); + assert(cell_format); + + number_format = cell_format->number_format; + cell_number_format = styles.get_number_format(number_format); + assert(cell_number_format->format_string.str() == "[$₹]#,##0.00;[RED]-[$₹]#,##0.00"); + + style = find_cell_style_by_name("Name12", &styles); + xf = style->xf; + cell_format = styles.get_cell_style_format(xf); + assert(cell_format); + + number_format = cell_format->number_format; + cell_number_format = styles.get_number_format(number_format); + assert(cell_number_format->format_string.str() == "0.00%"); + + style = find_cell_style_by_name("Name13", &styles); + xf = style->xf; + cell_format = styles.get_cell_style_format(xf); + assert(cell_format); + + number_format = cell_format->number_format; + cell_number_format = styles.get_number_format(number_format); + assert(cell_number_format->format_string.str() == "#.00E+00"); + + style = find_cell_style_by_name("Name15", &styles); + xf = style->xf; + cell_format = styles.get_cell_style_format(xf); + assert(cell_format); + + number_format = cell_format->number_format; + cell_number_format = styles.get_number_format(number_format); + assert(cell_number_format->format_string.str() == "BOOLEAN"); + + style = find_cell_style_by_name("Name16", &styles); + xf = style->xf; + cell_format = styles.get_cell_style_format(xf); + assert(cell_format); + + number_format = cell_format->number_format; + cell_number_format = styles.get_number_format(number_format); + assert(cell_number_format->format_string.str() == "#### ?/11"); + + style = find_cell_style_by_name("Name17", &styles); + xf = style->xf; + cell_format = styles.get_cell_style_format(xf); + assert(cell_format); + + number_format = cell_format->number_format; + cell_number_format = styles.get_number_format(number_format); + assert(cell_number_format->format_string.str() == "MM/DD/YY"); + + style = find_cell_style_by_name("Name18", &styles); + xf = style->xf; + cell_format = styles.get_cell_style_format(xf); + assert(cell_format); + + number_format = cell_format->number_format; + cell_number_format = styles.get_number_format(number_format); + std::cerr<format_string.str(); + assert(cell_number_format->format_string.str() == "HH:MM:SS AM/PM"); + + style = find_cell_style_by_name("Name19", &styles); + xf = style->xf; + cell_format = styles.get_cell_style_format(xf); + assert(cell_format); + + number_format = cell_format->number_format; + cell_number_format = styles.get_number_format(number_format); + assert(cell_number_format->format_string.str() == "[>=0]0.00;[RED]-0.00"); + +} +int main() +{ + orcus::string_pool string_pool; + const char* path = SRCDIR"/test/ods/styles/cell-styles.xml"; + std::string content = orcus::load_file_content(path); + orcus::spreadsheet::import_styles styles(string_pool); + orcus::import_ods::read_styles(content.c_str(), content.size(), &styles); + + test_odf_fill(styles); + test_odf_border(styles); + test_odf_cell_protection(styles); + test_odf_font(styles); + + orcus::string_pool string_pool2; + path = SRCDIR"/test/ods/styles/number-format.xml"; + std::string content2 = orcus::load_file_content(path); + orcus::spreadsheet::import_styles styles2(string_pool2); + orcus::import_ods::read_styles(content2.c_str(), content2.size(), &styles2); + + test_odf_number_formatting(styles2); return 0; } -- GitLab From 83c3e6255a4a228270d0f5a18ef393272825b1d6 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Tue, 28 Jun 2016 18:40:42 +0530 Subject: [PATCH 13/13] Make generic classes --- .../odf_number_formatting_context.cpp | 271 ++---------------- 1 file changed, 19 insertions(+), 252 deletions(-) diff --git a/src/liborcus/odf_number_formatting_context.cpp b/src/liborcus/odf_number_formatting_context.cpp index 27d4037fd..58ba9c58e 100644 --- a/src/liborcus/odf_number_formatting_context.cpp +++ b/src/liborcus/odf_number_formatting_context.cpp @@ -162,46 +162,16 @@ public: size_t get_min_int_digits() const { return m_min_int_digits;} }; -class percentage_style_attr_parser : std::unary_function +class generic_style_attr_parser : std::unary_function { pstring m_style_name; bool m_volatile; + bool m_long; public: - percentage_style_attr_parser() : - m_volatile(false) - {} - - void operator() (const xml_token_attr_t& attr) - { - if (attr.ns == NS_odf_style) - { - switch (attr.name) - { - case XML_name: - m_style_name = attr.value; - break; - case XML_volatile: - m_volatile = attr.value == "true"; - break; - default: - ; - } - } - } - - pstring get_style_name() const { return m_style_name;} - bool is_volatile() const { return m_volatile;} -}; - -class currency_style_attr_parser : std::unary_function -{ - pstring m_style_name; - bool m_volatile; - -public: - currency_style_attr_parser() : - m_volatile(false) + generic_style_attr_parser() : + m_volatile(false), + m_long(false) {} void operator() (const xml_token_attr_t& attr) @@ -220,82 +190,14 @@ public: ; } } + else if (attr.ns == NS_odf_number) + if (attr.name == XML_style) + m_long = attr.value == "long"; } pstring get_style_name() const { return m_style_name;} bool is_volatile() const { return m_volatile;} -}; - - -class date_style_attr_parser : std::unary_function -{ - pstring m_style_name; - bool m_volatile; - -public: - date_style_attr_parser(): - m_volatile(false) - {} - - void operator() (const xml_token_attr_t& attr) - { - if (attr.ns == NS_odf_style) - { - switch (attr.name) - { - case XML_name: - m_style_name = attr.value; - break; - case XML_volatile: - m_volatile = attr.value == "true"; - break; - default: - ; - } - } - } - pstring get_style_name() const { return m_style_name;} - bool is_volatile() const { return m_volatile;} -}; - -class day_attr_parser : std::unary_function -{ - bool m_style_name; - -public: - day_attr_parser(): - m_style_name(false) - {} - - void operator() (const xml_token_attr_t& attr) - { - if (attr.ns == NS_odf_number) - if (attr.name == XML_style) - m_style_name = attr.value == "long"; - } - - bool has_long() const { return m_style_name;} - -}; - -class year_attr_parser : std::unary_function -{ - bool m_style_name; - -public: - year_attr_parser(): - m_style_name(false) - {} - - void operator() (const xml_token_attr_t& attr) - { - if (attr.ns == NS_odf_number) - if (attr.name == XML_style) - m_style_name = attr.value =="long"; - } - - bool has_long() const { return m_style_name;} - + bool has_long() const { return m_long;} }; class month_attr_parser : std::unary_function @@ -323,77 +225,6 @@ public: bool is_textual() const { return m_textual;} }; - -class time_style_attr_parser : std::unary_function -{ - pstring m_style_name; - bool m_volatile; - -public: - time_style_attr_parser(): - m_volatile(false) - {} - - void operator() (const xml_token_attr_t& attr) - { - if (attr.ns == NS_odf_style) - { - switch (attr.name) - { - case XML_name: - m_style_name = attr.value; - break; - case XML_volatile: - m_volatile = attr.value == "true"; - break; - default: - ; - } - } - } - - pstring get_style_name() const { return m_style_name;} - bool is_volatile() const { return m_volatile;} -}; - -class hours_attr_parser : std::unary_function -{ - bool m_style_name; - -public: - hours_attr_parser(): - m_style_name(false) - {} - - void operator() (const xml_token_attr_t& attr) - { - if (attr.ns == NS_odf_number) - if (attr.name == XML_style) - m_style_name = attr.value == "long"; - } - - bool has_long() const { return m_style_name;} -}; - -class minutes_attr_parser : std::unary_function -{ - bool m_style_name; - -public: - minutes_attr_parser(): - m_style_name(false) - {} - - void operator() (const xml_token_attr_t& attr) - { - if (attr.ns == NS_odf_number) - if (attr.name == XML_style) - m_style_name = attr.value == "long"; - } - - bool has_long() const { return m_style_name;} -}; - class seconds_attr_parser : std::unary_function { size_t m_decimal_places; @@ -474,70 +305,6 @@ public: bool has_predefined_deno() const { return m_predefined_deno;} }; -class boolean_style_attr_parser : std::unary_function -{ - pstring m_style_name; - bool m_volatile; - -public: - boolean_style_attr_parser(): - m_volatile(false) - {} - - void operator() (const xml_token_attr_t& attr) - { - if (attr.ns == NS_odf_style) - { - switch (attr.name) - { - case XML_name: - m_style_name = attr.value; - break; - case XML_volatile: - m_volatile = attr.value == "true"; - break; - default: - ; - } - } - } - - pstring get_style_name() const { return m_style_name;} - bool is_volatile() const { return m_volatile;} -}; - -class text_style_attr_parser : std::unary_function -{ - pstring m_style_name; - bool m_volatile; - -public: - text_style_attr_parser(): - m_volatile(false) - {} - - void operator() (const xml_token_attr_t& attr) - { - if (attr.ns == NS_odf_style) - { - switch (attr.name) - { - case XML_name: - m_style_name = attr.value; - break; - case XML_volatile: - m_volatile = attr.value == "true"; - break; - default: - ; - } - } - } - - pstring get_style_name() const { return m_style_name;} - bool is_volatile() const { return m_volatile;} -}; - class text_properties_attr_parser : std::unary_function { pstring m_color; @@ -706,7 +473,7 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c break; case XML_currency_style: { - currency_style_attr_parser func; + generic_style_attr_parser func; func = std::for_each(attrs.begin(), attrs.end(), func); m_current_style->name = func.get_style_name(); m_current_style->is_volatile = func.is_volatile(); @@ -714,7 +481,7 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c break; case XML_percentage_style: { - percentage_style_attr_parser func; + generic_style_attr_parser func; func = std::for_each(attrs.begin(), attrs.end(), func); m_current_style->name = func.get_style_name(); m_current_style->is_volatile = func.is_volatile(); @@ -774,7 +541,7 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c break; case XML_boolean_style: { - boolean_style_attr_parser func; + generic_style_attr_parser func; func = std::for_each(attrs.begin(), attrs.end(), func); m_current_style->name = func.get_style_name(); m_current_style->is_volatile = func.is_volatile(); @@ -809,7 +576,7 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c break; case XML_date_style: { - date_style_attr_parser func; + generic_style_attr_parser func; func = std::for_each(attrs.begin(), attrs.end(), func); m_current_style->name = func.get_style_name(); m_current_style->is_volatile = func.is_volatile(); @@ -817,7 +584,7 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c break; case XML_day: { - day_attr_parser func; + generic_style_attr_parser func; func = std::for_each(attrs.begin(), attrs.end(), func); m_current_style->number_formatting_code += "D"; if (func.has_long()) @@ -839,7 +606,7 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c break; case XML_year: { - year_attr_parser func; + generic_style_attr_parser func; func = std::for_each(attrs.begin(), attrs.end(), func); m_current_style->number_formatting_code += "YY"; if (func.has_long()) @@ -848,7 +615,7 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c break; case XML_time_style: { - time_style_attr_parser func; + generic_style_attr_parser func; func = std::for_each(attrs.begin(), attrs.end(), func); m_current_style->name = func.get_style_name(); m_current_style->is_volatile = func.is_volatile(); @@ -856,7 +623,7 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c break; case XML_hours: { - hours_attr_parser func; + generic_style_attr_parser func; func = std::for_each(attrs.begin(), attrs.end(), func); m_current_style->number_formatting_code += "H"; if (func.has_long()) @@ -865,7 +632,7 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c break; case XML_minutes: { - minutes_attr_parser func; + generic_style_attr_parser func; func = std::for_each(attrs.begin(), attrs.end(), func); m_current_style->number_formatting_code += "M"; if (func.has_long()) @@ -891,7 +658,7 @@ void number_formatting_context::start_element(xmlns_id_t ns, xml_token_t name, c break; case XML_text_style: { - text_style_attr_parser func; + generic_style_attr_parser func; func = std::for_each(attrs.begin(), attrs.end(), func); m_current_style->name = func.get_style_name(); m_current_style->is_volatile = func.is_volatile(); -- GitLab