Add serialisation of worksheet phonetic properties

This commit is contained in:
Crzyrndm 2018-06-23 12:15:15 +12:00
parent 5a14d7b9d1
commit 5817ef5cf0
7 changed files with 375 additions and 8 deletions

View File

@ -0,0 +1,143 @@
// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE
//
// @license: http://www.opensource.org/licenses/mit-license.php
// @author: see AUTHORS file
#include "phonetic_pr.hpp"
#include <array>
namespace {
// Order of elements defined by phonetic_pr::Type enum
const std::array<std::string, 4> Types{
"fullwidthKatakana",
"halfwidthKatakana",
"Hiragana",
"noConversion"};
// Order of elements defined by phonetic_pr::Alignment enum
const std::array<std::string, 4> Alignments{
"Center",
"Distributed",
"Left",
"NoControl"};
} // namespace
namespace xlnt {
/// <summary>
/// out of line initialiser for static const member
/// </summary>
const std::string phonetic_pr::Serialised_ID = "phoneticPr";
phonetic_pr::phonetic_pr(Font_ID font)
: font_id_(font)
{
}
void phonetic_pr::serialise(std::ostream &output_stream) const
{
output_stream << '<' << Serialised_ID << R"( fontID=")" << std::to_string(font_id_) << '"';
if (has_type())
{
output_stream << R"( type=")" << type_as_string(type_.get()) << '"';
}
if (has_alignment())
{
output_stream << R"( alignment=")" << alignment_as_string(alignment_.get()) << '"';
}
output_stream << "/>";
}
phonetic_pr::Font_ID phonetic_pr::font_id() const
{
return font_id_;
}
void phonetic_pr::font_id(Font_ID font)
{
font_id_ = font;
}
bool phonetic_pr::has_type() const
{
return type_.is_set();
}
phonetic_pr::Type phonetic_pr::type() const
{
return type_.get();
}
void phonetic_pr::type(Type type)
{
type_.set(type);
}
bool phonetic_pr::has_alignment() const
{
return alignment_.is_set();
}
phonetic_pr::Alignment phonetic_pr::alignment() const
{
return alignment_.get();
}
void phonetic_pr::alignment(Alignment align)
{
alignment_.set(align);
}
// serialisation
const std::string &phonetic_pr::type_as_string(phonetic_pr::Type type)
{
return Types[static_cast<int>(type)];
}
phonetic_pr::Type phonetic_pr::type_from_string(const std::string &str)
{
for (int i = 0; i < Types.size(); ++i)
{
if (str == Types[i])
{
return static_cast<Type>(i);
}
}
return Type::No_Conversion;
}
const std::string &phonetic_pr::alignment_as_string(Alignment type)
{
return Alignments[static_cast<int>(type)];
}
phonetic_pr::Alignment phonetic_pr::alignment_from_string(const std::string &str)
{
for (int i = 0; i < Alignments.size(); ++i)
{
if (str == Alignments[i])
{
return static_cast<Alignment>(i);
}
}
return Alignment::No_Control;
}
} // namespace xlnt

View File

@ -0,0 +1,165 @@
// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE
//
// @license: http://www.opensource.org/licenses/mit-license.php
// @author: see AUTHORS file
#pragma once
#include <cstdint>
#include <ostream>
#include <xlnt/xlnt_config.hpp>
#include <xlnt/utils/optional.hpp>
namespace xlnt {
/// <summary>
/// Phonetic properties
/// Element provides a collection of properties that affect display of East Asian Languages
/// [Serialised phoneticPr]
/// </summary>
class XLNT_API phonetic_pr
{
public:
static const std::string Serialised_ID;
/// <summary>
/// possible values for alignment property
/// </summary>
enum class Alignment
{
Center,
Distributed,
Left,
No_Control
};
/// <summary>
/// possible values for type property
/// </summary>
enum class Type
{
Full_Width_Katakana,
Half_Width_Katakana,
Hiragana,
No_Conversion
};
/// <summary>
/// FontID represented by an unsigned 32-bit integer
/// </summary>
using Font_ID = std::uint32_t;
/// <summary>
/// Default ctor for phonetic properties
/// </summary>
phonetic_pr() = default;
/// <summary>
/// FontID ctor for phonetic properties
/// </summary>
explicit phonetic_pr(Font_ID font);
/// <summary>
/// adds the xml serialised representation of this element to the stream
/// </summary>
void serialise(std::ostream& output_stream) const;
/// <summary>
/// get the font index
/// </summary>
Font_ID font_id() const;
/// <summary>
/// set the font index
/// </summary>
void font_id(Font_ID font);
/// <summary>
/// is the phonetic type set
/// </summary>
bool has_type() const;
/// <summary>
/// returns the phonetic type
/// </summary>
Type type() const;
/// <summary>
/// sets the phonetic type
/// </summary>
void type(Type type);
/// <summary>
/// is the alignment set
/// </summary>
bool has_alignment() const;
/// <summary>
/// get the alignment
/// </summary>
Alignment alignment() const;
/// <summary>
/// set the alignment
/// </summary>
void alignment(Alignment align);
// serialisation
/// <summary>
/// string form of the type enum
/// </summary>
static const std::string &type_as_string(Type type);
/// <summary>
/// type enum from string
/// </summary>
static Type type_from_string(const std::string &str);
/// <summary>
/// string form of alignment enum
/// </summary>
static const std::string &alignment_as_string(xlnt::phonetic_pr::Alignment type);
/// <summary>
/// alignment enum from string
/// </summary>
static Alignment alignment_from_string(const std::string &str);
private:
/// <summary>
/// zero based index into style sheet font record.
/// Default: 0
/// </summary>
Font_ID font_id_ = 0;
/// <summary>
/// Type of characters to use.
/// Default: full width katakana
/// </summary>
xlnt::optional<Type> type_;
/// <summary>
/// Alignment across the cell(s).
/// Default: Left
/// </summary>
xlnt::optional<Alignment> alignment_;
};
}

View File

@ -56,6 +56,7 @@ class relationship;
class row_properties;
class sheet_format_properties;
class workbook;
class phonetic_pr;
struct date;
@ -556,6 +557,21 @@ public:
/// </summary>
void reserve(std::size_t n);
/// <summary>
/// Returns true if this sheet has phonetic properties
/// </summary>
bool has_phonetic_properties() const;
/// <summary>
/// Returns the phonetic properties of this sheet.
/// </summary>
const phonetic_pr &phonetic_properties() const;
/// <summary>
/// Sets the phonetic properties of this sheet to phonetic_props
/// </summary>
void phonetic_properties(const phonetic_pr& phonetic_props);
/// <summary>
/// Returns true if this sheet has a header/footer.
/// </summary>

View File

@ -27,15 +27,16 @@
#include <unordered_map>
#include <vector>
#include <detail/implementations/cell_impl.hpp>
#include <xlnt/workbook/named_range.hpp>
#include <xlnt/worksheet/column_properties.hpp>
#include <xlnt/worksheet/header_footer.hpp>
#include <xlnt/worksheet/phonetic_pr.hpp>
#include <xlnt/worksheet/range.hpp>
#include <xlnt/worksheet/range_reference.hpp>
#include <xlnt/worksheet/row_properties.hpp>
#include <xlnt/worksheet/sheet_format_properties.hpp>
#include <xlnt/worksheet/sheet_view.hpp>
#include <detail/implementations/cell_impl.hpp>
namespace xlnt {
@ -72,6 +73,7 @@ struct worksheet_impl
page_margins_ = other.page_margins_;
merged_cells_ = other.merged_cells_;
named_ranges_ = other.named_ranges_;
phonetic_properties_ = other.phonetic_properties_;
header_footer_ = other.header_footer_;
print_title_cols_ = other.print_title_cols_;
print_title_rows_ = other.print_title_rows_;
@ -107,6 +109,7 @@ struct worksheet_impl
std::vector<range_reference> merged_cells_;
std::unordered_map<std::string, named_range> named_ranges_;
optional<phonetic_pr> phonetic_properties_;
optional<header_footer> header_footer_;
std::string print_title_cols_;

View File

@ -835,7 +835,16 @@ worksheet xlsx_consumer::read_worksheet_end(const std::string &rel_id)
}
else if (current_worksheet_element == qn("spreadsheetml", "phoneticPr")) // CT_PhoneticPr 0-1
{
skip_remaining_content(current_worksheet_element);
phonetic_pr phonetic_properties(parser().attribute<std::uint32_t>("fontId"));
if (parser().attribute_present("type"))
{
phonetic_properties.type(phonetic_pr::type_from_string(parser().attribute("type")));
}
if (parser().attribute_present("alignment"))
{
phonetic_properties.alignment(phonetic_pr::alignment_from_string(parser().attribute("alignment")));
}
current_worksheet_->phonetic_properties_.set(phonetic_properties);
}
else if (current_worksheet_element == qn("spreadsheetml", "conditionalFormatting")) // CT_ConditionalFormatting 0+
{
@ -847,7 +856,7 @@ worksheet xlsx_consumer::read_worksheet_end(const std::string &rel_id)
}
else if (current_worksheet_element == qn("spreadsheetml", "hyperlinks")) // CT_Hyperlinks 0-1
{
while (in_element(qn("spreadsheetml", "hyperlinks")))
while (in_element(current_worksheet_element))
{
// CT_Hyperlink
expect_start_element(qn("spreadsheetml", "hyperlink"), xml::content::simple);

View File

@ -2705,6 +2705,22 @@ void xlsx_producer::write_worksheet(const relationship &rel)
write_end_element(xmlns, "printOptions");
}
if (ws.has_phonetic_properties())
{
write_start_element(xmlns, phonetic_pr::Serialised_ID);
const auto &ph_props = ws.phonetic_properties();
write_attribute("fontId", ph_props.font_id());
if (ph_props.has_type())
{
write_attribute("type", phonetic_pr::type_as_string(ph_props.type()));
}
if (ph_props.has_alignment())
{
write_attribute("alignment", phonetic_pr::alignment_as_string(ph_props.alignment()));
}
write_end_element(xmlns, phonetic_pr::Serialised_ID);
}
if (ws.has_page_margins())
{
write_start_element(xmlns, "pageMargins");

View File

@ -26,10 +26,6 @@
#include <cmath>
#include <limits>
#include <detail/constants.hpp>
#include <detail/implementations/cell_impl.hpp>
#include <detail/implementations/workbook_impl.hpp>
#include <detail/implementations/worksheet_impl.hpp>
#include <xlnt/cell/cell.hpp>
#include <xlnt/cell/cell_reference.hpp>
#include <xlnt/cell/index_types.hpp>
@ -46,6 +42,10 @@
#include <xlnt/worksheet/range_iterator.hpp>
#include <xlnt/worksheet/range_reference.hpp>
#include <xlnt/worksheet/worksheet.hpp>
#include <detail/constants.hpp>
#include <detail/implementations/cell_impl.hpp>
#include <detail/implementations/workbook_impl.hpp>
#include <detail/implementations/worksheet_impl.hpp>
namespace {
@ -1027,6 +1027,21 @@ void worksheet::register_calc_chain_in_manifest()
workbook().register_workbook_part(relationship_type::calculation_chain);
}
bool worksheet::has_phonetic_properties() const
{
return d_->phonetic_properties_.is_set();
}
const phonetic_pr& worksheet::phonetic_properties() const
{
return d_->phonetic_properties_.get();
}
void worksheet::phonetic_properties(const phonetic_pr& phonetic_props)
{
d_->phonetic_properties_.set(phonetic_props);
}
bool worksheet::has_header_footer() const
{
return d_->header_footer_.is_set();
@ -1103,7 +1118,7 @@ void worksheet::parent(xlnt::workbook &wb)
conditional_format worksheet::conditional_format(const range_reference &ref, const condition &when)
{
return workbook().d_->stylesheet_.get().add_conditional_format_rule(d_, ref, when);
return workbook().d_->stylesheet_.get().add_conditional_format_rule(d_, ref, when);
}
path worksheet::path() const