mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
Merge branch 'dev' into issue378-unicode_title
This commit is contained in:
commit
123ecc95fe
|
@ -54,6 +54,7 @@ class workbook;
|
||||||
class worksheet;
|
class worksheet;
|
||||||
class xlsx_consumer;
|
class xlsx_consumer;
|
||||||
class xlsx_producer;
|
class xlsx_producer;
|
||||||
|
class phonetic_pr;
|
||||||
|
|
||||||
struct date;
|
struct date;
|
||||||
struct datetime;
|
struct datetime;
|
||||||
|
@ -501,6 +502,18 @@ public:
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void merged(bool merged);
|
void merged(bool merged);
|
||||||
|
|
||||||
|
// phonetics
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if this cell is set to show phonetic information.
|
||||||
|
/// </summary>
|
||||||
|
bool phonetics_visible() const;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables the display of phonetic information on this cell.
|
||||||
|
/// </summary>
|
||||||
|
void show_phonetics(bool phonetics);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the error string that is stored in this cell.
|
/// Returns the error string that is stored in this cell.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
46
include/xlnt/cell/phonetic_run.hpp
Normal file
46
include/xlnt/cell/phonetic_run.hpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright (c) 2016-2018
|
||||||
|
//
|
||||||
|
// 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 <string>
|
||||||
|
|
||||||
|
#include <xlnt/xlnt_config.hpp>
|
||||||
|
|
||||||
|
namespace xlnt {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Encapsulates a run of text that
|
||||||
|
/// </summary>
|
||||||
|
struct XLNT_API phonetic_run
|
||||||
|
{
|
||||||
|
std::string text;
|
||||||
|
uint32_t start;
|
||||||
|
uint32_t end;
|
||||||
|
bool preserve_space;
|
||||||
|
|
||||||
|
bool operator==(const phonetic_run &other) const;
|
||||||
|
bool operator!=(const phonetic_run &other) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xlnt
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
#include <xlnt/xlnt_config.hpp>
|
#include <xlnt/xlnt_config.hpp>
|
||||||
#include <xlnt/cell/rich_text_run.hpp>
|
#include <xlnt/cell/rich_text_run.hpp>
|
||||||
|
#include <xlnt/cell/phonetic_run.hpp>
|
||||||
|
#include <xlnt/worksheet/phonetic_pr.hpp>
|
||||||
|
|
||||||
namespace xlnt {
|
namespace xlnt {
|
||||||
|
|
||||||
|
@ -94,6 +96,36 @@ public:
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void add_run(const rich_text_run &t);
|
void add_run(const rich_text_run &t);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a copy of the individual runs that comprise this text.
|
||||||
|
/// </summary>
|
||||||
|
std::vector<phonetic_run> phonetic_runs() const;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the runs of this text all at once.
|
||||||
|
/// </summary>
|
||||||
|
void phonetic_runs(const std::vector<phonetic_run> &new_phonetic_runs);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a new run to the end of the set of runs.
|
||||||
|
/// </summary>
|
||||||
|
void add_phonetic_run(const phonetic_run &t);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if this text has phonetic properties
|
||||||
|
/// </summary>
|
||||||
|
bool has_phonetic_properties() const;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the phonetic properties of this text.
|
||||||
|
/// </summary>
|
||||||
|
const phonetic_pr &phonetic_properties() const;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the phonetic properties of this text to phonetic_props
|
||||||
|
/// </summary>
|
||||||
|
void phonetic_properties(const phonetic_pr& phonetic_props);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Copies rich text object from other
|
/// Copies rich text object from other
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -124,6 +156,8 @@ private:
|
||||||
/// The runs that make up this rich text.
|
/// The runs that make up this rich text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
std::vector<rich_text_run> runs_;
|
std::vector<rich_text_run> runs_;
|
||||||
|
std::vector<phonetic_run> phonetic_runs_;
|
||||||
|
optional<phonetic_pr> phonetic_properties_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class XLNT_API rich_text_hash
|
class XLNT_API rich_text_hash
|
||||||
|
|
|
@ -63,6 +63,13 @@ public:
|
||||||
/// The index to the style used by all cells in this row
|
/// The index to the style used by all cells in this row
|
||||||
/// </summary>
|
/// </summary>
|
||||||
optional<std::size_t> style;
|
optional<std::size_t> style;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The row column span, used as part of the row block optimisation.
|
||||||
|
/// This used for loading this attribute from existing excel files mainly for inspecting
|
||||||
|
/// and not used when saving, it is calculated in the xlsx_producer.
|
||||||
|
/// </summary>
|
||||||
|
optional<std::string> spans;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(const row_properties &lhs, const row_properties &rhs)
|
inline bool operator==(const row_properties &lhs, const row_properties &rhs)
|
||||||
|
@ -72,7 +79,8 @@ inline bool operator==(const row_properties &lhs, const row_properties &rhs)
|
||||||
&& lhs.custom_height == rhs.custom_height
|
&& lhs.custom_height == rhs.custom_height
|
||||||
&& lhs.hidden == rhs.hidden
|
&& lhs.hidden == rhs.hidden
|
||||||
&& lhs.custom_format == rhs.custom_format
|
&& lhs.custom_format == rhs.custom_format
|
||||||
&& lhs.style == rhs.style;
|
&& lhs.style == rhs.style
|
||||||
|
&& lhs.spans == rhs.spans;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace xlnt
|
} // namespace xlnt
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#include <xlnt/worksheet/column_properties.hpp>
|
#include <xlnt/worksheet/column_properties.hpp>
|
||||||
#include <xlnt/worksheet/row_properties.hpp>
|
#include <xlnt/worksheet/row_properties.hpp>
|
||||||
#include <xlnt/worksheet/worksheet.hpp>
|
#include <xlnt/worksheet/worksheet.hpp>
|
||||||
|
#include <xlnt/worksheet/phonetic_pr.hpp>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -198,7 +199,7 @@ cell::cell(detail::cell_impl *d)
|
||||||
|
|
||||||
bool cell::garbage_collectible() const
|
bool cell::garbage_collectible() const
|
||||||
{
|
{
|
||||||
return !(has_value() || is_merged() || has_formula() || has_format() || has_hyperlink());
|
return !(has_value() || is_merged() || phonetics_visible() || has_formula() || has_format() || has_hyperlink());
|
||||||
}
|
}
|
||||||
|
|
||||||
void cell::value(std::nullptr_t)
|
void cell::value(std::nullptr_t)
|
||||||
|
@ -329,6 +330,16 @@ bool cell::is_merged() const
|
||||||
return d_->is_merged_;
|
return d_->is_merged_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cell::phonetics_visible() const
|
||||||
|
{
|
||||||
|
return d_->phonetics_visible_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cell::show_phonetics(bool phonetics)
|
||||||
|
{
|
||||||
|
d_->phonetics_visible_ = phonetics;
|
||||||
|
}
|
||||||
|
|
||||||
bool cell::is_date() const
|
bool cell::is_date() const
|
||||||
{
|
{
|
||||||
return data_type() == type::number
|
return data_type() == type::number
|
||||||
|
|
40
source/cell/phonetic_run.cpp
Normal file
40
source/cell/phonetic_run.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// Copyright (c) 2014-2018
|
||||||
|
//
|
||||||
|
// 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 <xlnt/cell/phonetic_run.hpp>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace xlnt {
|
||||||
|
|
||||||
|
bool phonetic_run::operator==(const phonetic_run &other) const
|
||||||
|
{
|
||||||
|
return std::tie(text, start, end, preserve_space) ==
|
||||||
|
std::tie(other.text, other.start, other.end, other.preserve_space);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool phonetic_run::operator!=(const phonetic_run &other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace xlnt
|
|
@ -52,8 +52,10 @@ rich_text::rich_text(const rich_text &other)
|
||||||
|
|
||||||
rich_text &rich_text::operator=(const rich_text &rhs)
|
rich_text &rich_text::operator=(const rich_text &rhs)
|
||||||
{
|
{
|
||||||
runs_.clear();
|
clear();
|
||||||
runs_ = rhs.runs_;
|
runs_ = rhs.runs_;
|
||||||
|
phonetic_runs_ = rhs.phonetic_runs_;
|
||||||
|
phonetic_properties_ = rhs.phonetic_properties_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +67,8 @@ rich_text::rich_text(const rich_text_run &single_run)
|
||||||
void rich_text::clear()
|
void rich_text::clear()
|
||||||
{
|
{
|
||||||
runs_.clear();
|
runs_.clear();
|
||||||
|
phonetic_runs_.clear();
|
||||||
|
phonetic_properties_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rich_text::plain_text(const std::string &s, bool preserve_space = false)
|
void rich_text::plain_text(const std::string &s, bool preserve_space = false)
|
||||||
|
@ -99,6 +103,36 @@ void rich_text::add_run(const rich_text_run &t)
|
||||||
runs_.push_back(t);
|
runs_.push_back(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<phonetic_run> rich_text::phonetic_runs() const
|
||||||
|
{
|
||||||
|
return phonetic_runs_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rich_text::phonetic_runs(const std::vector<phonetic_run> &new_phonetic_runs)
|
||||||
|
{
|
||||||
|
phonetic_runs_ = new_phonetic_runs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rich_text::add_phonetic_run(const phonetic_run &r)
|
||||||
|
{
|
||||||
|
phonetic_runs_.push_back(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rich_text::has_phonetic_properties() const
|
||||||
|
{
|
||||||
|
return phonetic_properties_.is_set();
|
||||||
|
}
|
||||||
|
|
||||||
|
const phonetic_pr& rich_text::phonetic_properties() const
|
||||||
|
{
|
||||||
|
return phonetic_properties_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rich_text::phonetic_properties(const phonetic_pr& phonetic_props)
|
||||||
|
{
|
||||||
|
phonetic_properties_.set(phonetic_props);
|
||||||
|
}
|
||||||
|
|
||||||
bool rich_text::operator==(const rich_text &rhs) const
|
bool rich_text::operator==(const rich_text &rhs) const
|
||||||
{
|
{
|
||||||
if (runs_.size() != rhs.runs_.size()) return false;
|
if (runs_.size() != rhs.runs_.size()) return false;
|
||||||
|
@ -108,6 +142,15 @@ bool rich_text::operator==(const rich_text &rhs) const
|
||||||
if (runs_[i] != rhs.runs_[i]) return false;
|
if (runs_[i] != rhs.runs_[i]) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (phonetic_runs_.size() != rhs.phonetic_runs_.size()) return false;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < phonetic_runs_.size(); i++)
|
||||||
|
{
|
||||||
|
if (phonetic_runs_[i] != rhs.phonetic_runs_[i]) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phonetic_properties_ != rhs.phonetic_properties_) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ cell_impl::cell_impl()
|
||||||
column_(1),
|
column_(1),
|
||||||
row_(1),
|
row_(1),
|
||||||
is_merged_(false),
|
is_merged_(false),
|
||||||
|
phonetics_visible_(false),
|
||||||
value_numeric_(0)
|
value_numeric_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ struct cell_impl
|
||||||
row_t row_;
|
row_t row_;
|
||||||
|
|
||||||
bool is_merged_;
|
bool is_merged_;
|
||||||
|
bool phonetics_visible_;
|
||||||
|
|
||||||
rich_text value_text_;
|
rich_text value_text_;
|
||||||
double value_numeric_;
|
double value_numeric_;
|
||||||
|
@ -72,6 +73,7 @@ inline bool operator==(const cell_impl &lhs, const cell_impl &rhs)
|
||||||
&& lhs.column_ == rhs.column_
|
&& lhs.column_ == rhs.column_
|
||||||
&& lhs.row_ == rhs.row_
|
&& lhs.row_ == rhs.row_
|
||||||
&& lhs.is_merged_ == rhs.is_merged_
|
&& lhs.is_merged_ == rhs.is_merged_
|
||||||
|
&& lhs.phonetics_visible_ == rhs.phonetics_visible_
|
||||||
&& lhs.value_text_ == rhs.value_text_
|
&& lhs.value_text_ == rhs.value_text_
|
||||||
&& lhs.value_numeric_ == rhs.value_numeric_
|
&& lhs.value_numeric_ == rhs.value_numeric_
|
||||||
&& lhs.formula_ == rhs.formula_
|
&& lhs.formula_ == rhs.formula_
|
||||||
|
|
|
@ -221,9 +221,13 @@ cell xlsx_consumer::read_cell()
|
||||||
row_properties.dy_descent = parser().attribute<double>(qn("x14ac", "dyDescent"));
|
row_properties.dy_descent = parser().attribute<double>(qn("x14ac", "dyDescent"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parser().attribute_present("spans")) {
|
||||||
|
row_properties.spans = parser().attribute("spans");
|
||||||
|
}
|
||||||
|
|
||||||
skip_attributes({"customFormat", "s", "customFont",
|
skip_attributes({"customFormat", "s", "customFont",
|
||||||
"outlineLevel", "collapsed", "thickTop", "thickBot",
|
"outlineLevel", "collapsed", "thickTop", "thickBot",
|
||||||
"ph", "spans"});
|
"ph"});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_element(qn("spreadsheetml", "row")))
|
if (!in_element(qn("spreadsheetml", "row")))
|
||||||
|
@ -241,6 +245,11 @@ cell xlsx_consumer::read_cell()
|
||||||
cell.d_->column_ = reference.column_index();
|
cell.d_->column_ = reference.column_index();
|
||||||
cell.d_->row_ = reference.row();
|
cell.d_->row_ = reference.row();
|
||||||
|
|
||||||
|
if (parser().attribute_present("ph"))
|
||||||
|
{
|
||||||
|
cell.d_->phonetics_visible_ = parser().attribute<bool>("ph");
|
||||||
|
}
|
||||||
|
|
||||||
auto has_type = parser().attribute_present("t");
|
auto has_type = parser().attribute_present("t");
|
||||||
auto type = has_type ? parser().attribute("t") : "n";
|
auto type = has_type ? parser().attribute("t") : "n";
|
||||||
|
|
||||||
|
@ -713,9 +722,13 @@ void xlsx_consumer::read_worksheet_sheetdata()
|
||||||
row_properties.custom_format.set(parser().attribute<bool>("customFormat"));
|
row_properties.custom_format.set(parser().attribute<bool>("customFormat"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parser().attribute_present("spans")) {
|
||||||
|
row_properties.spans = parser().attribute("spans");
|
||||||
|
}
|
||||||
|
|
||||||
skip_attributes({"customFont",
|
skip_attributes({"customFont",
|
||||||
"outlineLevel", "collapsed", "thickTop", "thickBot",
|
"outlineLevel", "collapsed", "thickTop", "thickBot",
|
||||||
"ph", "spans"});
|
"ph"});
|
||||||
|
|
||||||
while (in_element(qn("spreadsheetml", "row")))
|
while (in_element(qn("spreadsheetml", "row")))
|
||||||
{
|
{
|
||||||
|
@ -730,6 +743,11 @@ void xlsx_consumer::read_worksheet_sheetdata()
|
||||||
cell.format(target_.format(static_cast<std::size_t>(std::stoull(parser().attribute("s")))));
|
cell.format(target_.format(static_cast<std::size_t>(std::stoull(parser().attribute("s")))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parser().attribute_present("ph"))
|
||||||
|
{
|
||||||
|
cell.d_->phonetics_visible_ = parser().attribute<bool>("ph");
|
||||||
|
}
|
||||||
|
|
||||||
auto has_value = false;
|
auto has_value = false;
|
||||||
auto value_string = std::string();
|
auto value_string = std::string();
|
||||||
|
|
||||||
|
@ -2989,11 +3007,34 @@ rich_text xlsx_consumer::read_rich_text(const xml::qname &parent)
|
||||||
}
|
}
|
||||||
else if (text_element == xml::qname(xmlns, "rPh"))
|
else if (text_element == xml::qname(xmlns, "rPh"))
|
||||||
{
|
{
|
||||||
skip_remaining_content(text_element);
|
phonetic_run pr;
|
||||||
|
pr.start = parser().attribute<std::uint32_t>("sb");
|
||||||
|
pr.end = parser().attribute<std::uint32_t>("eb");
|
||||||
|
|
||||||
|
expect_start_element(xml::qname(xmlns, "t"), xml::content::simple);
|
||||||
|
pr.text = read_text();
|
||||||
|
|
||||||
|
if (parser().attribute_present(xml_space))
|
||||||
|
{
|
||||||
|
pr.preserve_space = parser().attribute(xml_space) == "preserve";
|
||||||
|
}
|
||||||
|
|
||||||
|
expect_end_element(xml::qname(xmlns, "t"));
|
||||||
|
|
||||||
|
t.add_phonetic_run(pr);
|
||||||
}
|
}
|
||||||
else if (text_element == xml::qname(xmlns, "phoneticPr"))
|
else if (text_element == xml::qname(xmlns, "phoneticPr"))
|
||||||
{
|
{
|
||||||
skip_remaining_content(text_element);
|
phonetic_pr ph(parser().attribute<std::uint32_t>("fontId"));
|
||||||
|
if (parser().attribute_present("type"))
|
||||||
|
{
|
||||||
|
ph.type(phonetic_pr::type_from_string(parser().attribute("type")));
|
||||||
|
}
|
||||||
|
if (parser().attribute_present("alignment"))
|
||||||
|
{
|
||||||
|
ph.alignment(phonetic_pr::alignment_from_string(parser().attribute("alignment")));
|
||||||
|
}
|
||||||
|
t.phonetic_properties(ph);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -862,6 +862,36 @@ void xlsx_producer::write_shared_string_table(const relationship & /*rel*/)
|
||||||
write_characters(string.second.plain_text(), string.second.runs().front().preserve_space);
|
write_characters(string.second.plain_text(), string.second.runs().front().preserve_space);
|
||||||
|
|
||||||
write_end_element(xmlns, "t");
|
write_end_element(xmlns, "t");
|
||||||
|
|
||||||
|
for (const auto &run : string.second.phonetic_runs())
|
||||||
|
{
|
||||||
|
write_start_element(xmlns, "rPh");
|
||||||
|
write_attribute("eb", run.end);
|
||||||
|
write_attribute("sb", run.start);
|
||||||
|
|
||||||
|
write_start_element(xmlns, "t");
|
||||||
|
write_characters(run.text, run.preserve_space);
|
||||||
|
write_end_element(xmlns, "t");
|
||||||
|
|
||||||
|
write_end_element(xmlns, "rPh");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.second.has_phonetic_properties())
|
||||||
|
{
|
||||||
|
write_start_element(xmlns, phonetic_pr::Serialised_ID());
|
||||||
|
const auto &ph_props = string.second.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());
|
||||||
|
}
|
||||||
|
|
||||||
write_end_element(xmlns, "si");
|
write_end_element(xmlns, "si");
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -927,6 +957,35 @@ void xlsx_producer::write_shared_string_table(const relationship & /*rel*/)
|
||||||
write_end_element(xmlns, "r");
|
write_end_element(xmlns, "r");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const auto &run : string.second.phonetic_runs())
|
||||||
|
{
|
||||||
|
write_start_element(xmlns, "rPh");
|
||||||
|
write_attribute("sb", run.start);
|
||||||
|
write_attribute("eb", run.end);
|
||||||
|
|
||||||
|
write_start_element(xmlns, "t");
|
||||||
|
write_characters(run.text, run.preserve_space);
|
||||||
|
write_end_element(xmlns, "t");
|
||||||
|
|
||||||
|
write_end_element(xmlns, "rPh");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.second.has_phonetic_properties())
|
||||||
|
{
|
||||||
|
write_start_element(xmlns, phonetic_pr::Serialised_ID());
|
||||||
|
const auto &ph_props = string.second.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());
|
||||||
|
}
|
||||||
|
|
||||||
write_end_element(xmlns, "si");
|
write_end_element(xmlns, "si");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2439,6 +2498,10 @@ void xlsx_producer::write_worksheet(const relationship &rel)
|
||||||
// See note for CT_Row, span attribute about block optimization
|
// See note for CT_Row, span attribute about block optimization
|
||||||
if (first_row_in_block)
|
if (first_row_in_block)
|
||||||
{
|
{
|
||||||
|
// reset block column range
|
||||||
|
first_block_column = constants::max_column();
|
||||||
|
last_block_column = constants::min_column();
|
||||||
|
|
||||||
first_check_row = row;
|
first_check_row = row;
|
||||||
// round up to the next multiple of 16
|
// round up to the next multiple of 16
|
||||||
last_check_row = ((row / 16) + 1) * 16;
|
last_check_row = ((row / 16) + 1) * 16;
|
||||||
|
@ -2448,8 +2511,8 @@ void xlsx_producer::write_worksheet(const relationship &rel)
|
||||||
{
|
{
|
||||||
for (auto column = dimension.top_left().column(); column <= dimension.bottom_right().column(); ++column)
|
for (auto column = dimension.top_left().column(); column <= dimension.bottom_right().column(); ++column)
|
||||||
{
|
{
|
||||||
if (!ws.has_cell(cell_reference(column, row))) continue;
|
if (!ws.has_cell(cell_reference(column, check_row))) continue;
|
||||||
auto cell = ws.cell(cell_reference(column, row));
|
auto cell = ws.cell(cell_reference(column, check_row));
|
||||||
if (cell.garbage_collectible()) continue;
|
if (cell.garbage_collectible()) continue;
|
||||||
|
|
||||||
first_block_column = std::min(first_block_column, cell.column());
|
first_block_column = std::min(first_block_column, cell.column());
|
||||||
|
@ -2534,6 +2597,11 @@ void xlsx_producer::write_worksheet(const relationship &rel)
|
||||||
|
|
||||||
write_attribute("r", cell.reference().to_string());
|
write_attribute("r", cell.reference().to_string());
|
||||||
|
|
||||||
|
if (cell.phonetics_visible())
|
||||||
|
{
|
||||||
|
write_attribute("ph", write_bool(true));
|
||||||
|
}
|
||||||
|
|
||||||
if (cell.has_format())
|
if (cell.has_format())
|
||||||
{
|
{
|
||||||
write_attribute("s", cell.format().d_->id);
|
write_attribute("s", cell.format().d_->id);
|
||||||
|
|
|
@ -578,7 +578,7 @@ column_t worksheet::highest_column_or_props() const
|
||||||
|
|
||||||
range_reference worksheet::calculate_dimension() const
|
range_reference worksheet::calculate_dimension() const
|
||||||
{
|
{
|
||||||
return range_reference(lowest_column(), lowest_row(),
|
return range_reference(lowest_column(), lowest_row_or_props(),
|
||||||
highest_column(), highest_row_or_props());
|
highest_column(), highest_row_or_props());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ public:
|
||||||
register_test(test_hyperlink);
|
register_test(test_hyperlink);
|
||||||
register_test(test_comment);
|
register_test(test_comment);
|
||||||
register_test(test_copy_and_compare);
|
register_test(test_copy_and_compare);
|
||||||
|
register_test(test_cell_phonetic_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -811,6 +812,19 @@ private:
|
||||||
cell3 = cell2;
|
cell3 = cell2;
|
||||||
xlnt_assert_equals(cell2, cell3);
|
xlnt_assert_equals(cell2, cell3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_cell_phonetic_properties()
|
||||||
|
{
|
||||||
|
xlnt::workbook wb;
|
||||||
|
auto ws = wb.active_sheet();
|
||||||
|
auto cell1 = ws.cell("A1");
|
||||||
|
|
||||||
|
xlnt_assert_equals(cell1.phonetics_visible(), false);
|
||||||
|
cell1.show_phonetics(true);
|
||||||
|
xlnt_assert_equals(cell1.phonetics_visible(), true);
|
||||||
|
cell1.show_phonetics(false);
|
||||||
|
xlnt_assert_equals(cell1.phonetics_visible(), false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static cell_test_suite x{};
|
static cell_test_suite x{};
|
|
@ -36,6 +36,8 @@ public:
|
||||||
{
|
{
|
||||||
register_test(test_operators);
|
register_test(test_operators);
|
||||||
register_test(test_runs);
|
register_test(test_runs);
|
||||||
|
register_test(test_phonetic_runs);
|
||||||
|
register_test(test_phonetic_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_operators()
|
void test_operators()
|
||||||
|
@ -115,5 +117,30 @@ public:
|
||||||
rt.runs(test_runs);
|
rt.runs(test_runs);
|
||||||
xlnt_assert_equals(test_runs, rt.runs());
|
xlnt_assert_equals(test_runs, rt.runs());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_phonetic_runs()
|
||||||
|
{
|
||||||
|
xlnt::rich_text rt;
|
||||||
|
rt.plain_text("取引", true);
|
||||||
|
rt.add_phonetic_run({"トリヒキ", 0, 2});
|
||||||
|
|
||||||
|
xlnt_assert_equals(rt.phonetic_runs().size(), 1);
|
||||||
|
xlnt_assert_equals(rt.phonetic_runs()[0].text, "トリヒキ");
|
||||||
|
xlnt_assert_equals(rt.phonetic_runs()[0].start, 0);
|
||||||
|
xlnt_assert_equals(rt.phonetic_runs()[0].end, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_phonetic_properties()
|
||||||
|
{
|
||||||
|
xlnt::rich_text rt;
|
||||||
|
xlnt::phonetic_pr ph(1);
|
||||||
|
ph.type(xlnt::phonetic_pr::type_from_string("fullwidthKatakana"));
|
||||||
|
ph.alignment(xlnt::phonetic_pr::alignment_from_string("Center"));
|
||||||
|
rt.phonetic_properties(ph);
|
||||||
|
|
||||||
|
xlnt_assert_equals(rt.has_phonetic_properties(), true);
|
||||||
|
xlnt_assert_equals(rt.phonetic_properties().has_type(), true);
|
||||||
|
xlnt_assert_equals(rt.phonetic_properties().has_alignment(), true);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
static rich_text_test_suite x{};
|
static rich_text_test_suite x{};
|
BIN
tests/data/15_phonetics.xlsx
Normal file
BIN
tests/data/15_phonetics.xlsx
Normal file
Binary file not shown.
BIN
tests/data/Issue353_first_row_empty_w_properties.xlsx
Normal file
BIN
tests/data/Issue353_first_row_empty_w_properties.xlsx
Normal file
Binary file not shown.
|
@ -67,6 +67,7 @@ public:
|
||||||
register_test(test_id_gen);
|
register_test(test_id_gen);
|
||||||
register_test(test_load_file);
|
register_test(test_load_file);
|
||||||
register_test(test_Issue279);
|
register_test(test_Issue279);
|
||||||
|
register_test(test_Issue353);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_active_sheet()
|
void test_active_sheet()
|
||||||
|
@ -495,5 +496,18 @@ public:
|
||||||
//save a copy file
|
//save a copy file
|
||||||
wb.save("temp.xlsx");
|
wb.save("temp.xlsx");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_Issue353()
|
||||||
|
{
|
||||||
|
xlnt::workbook wb1;
|
||||||
|
wb1.load(path_helper::test_file("Issue353_first_row_empty_w_properties.xlsx"));
|
||||||
|
wb1.save("temp_issue353.xlsx");
|
||||||
|
|
||||||
|
xlnt::workbook wb2;
|
||||||
|
wb2.load("temp_issue353.xlsx");
|
||||||
|
auto ws = wb2.active_sheet();
|
||||||
|
xlnt_assert_equals(ws.row_properties(1).spans.get(), "1:8");
|
||||||
|
xlnt_assert_equals(ws.row_properties(17).spans.get(), "2:7");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
static workbook_test_suite x;
|
static workbook_test_suite x;
|
|
@ -105,6 +105,7 @@ public:
|
||||||
register_test(test_clear_row);
|
register_test(test_clear_row);
|
||||||
register_test(test_set_title);
|
register_test(test_set_title);
|
||||||
register_test(test_set_title_unicode);
|
register_test(test_set_title_unicode);
|
||||||
|
register_test(test_phonetics);
|
||||||
register_test(test_insert_rows);
|
register_test(test_insert_rows);
|
||||||
register_test(test_insert_columns);
|
register_test(test_insert_columns);
|
||||||
register_test(test_delete_rows);
|
register_test(test_delete_rows);
|
||||||
|
@ -1279,6 +1280,29 @@ public:
|
||||||
xlnt::exception);
|
xlnt::exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_phonetics()
|
||||||
|
{
|
||||||
|
xlnt::workbook wb;
|
||||||
|
wb.load(path_helper::test_file("15_phonetics.xlsx"));
|
||||||
|
auto ws = wb.active_sheet();
|
||||||
|
|
||||||
|
xlnt_assert_equals(ws.cell("A1").phonetics_visible(), true);
|
||||||
|
xlnt_assert_equals(ws.cell("A1").value<xlnt::rich_text>().phonetic_runs()[0].text, "シュウ ");
|
||||||
|
xlnt_assert_equals(ws.cell("B1").phonetics_visible(), true);
|
||||||
|
xlnt_assert_equals(ws.cell("C1").phonetics_visible(), false);
|
||||||
|
|
||||||
|
wb.save("temp.xlsx");
|
||||||
|
|
||||||
|
xlnt::workbook wb2;
|
||||||
|
wb2.load("temp.xlsx");
|
||||||
|
auto ws2 = wb2.active_sheet();
|
||||||
|
|
||||||
|
xlnt_assert_equals(ws2.cell("A1").phonetics_visible(), true);
|
||||||
|
xlnt_assert_equals(ws2.cell("A1").value<xlnt::rich_text>().phonetic_runs()[0].text, "シュウ ");
|
||||||
|
xlnt_assert_equals(ws2.cell("B1").phonetics_visible(), true);
|
||||||
|
xlnt_assert_equals(ws2.cell("C1").phonetics_visible(), false);
|
||||||
|
}
|
||||||
|
|
||||||
void test_insert_rows()
|
void test_insert_rows()
|
||||||
{
|
{
|
||||||
xlnt::workbook wb;
|
xlnt::workbook wb;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user