improve fill and style serialization test coverage

This commit is contained in:
Thomas Fussell 2016-07-14 22:09:57 -04:00
parent 64c95aa7c5
commit 25b995bc78
7 changed files with 625 additions and 325 deletions

View File

@ -23,69 +23,47 @@
// @author: see AUTHORS file
#pragma once
#include <unordered_map>
#include <xlnt/xlnt_config.hpp>
#include <xlnt/styles/color.hpp>
#include <xlnt/utils/optional.hpp>
namespace xlnt {
/// <summary>
/// Describes the fill style of a particular cell.
/// </summary>
class XLNT_CLASS fill : public hashable
class pattern_fill : public hashable
{
public:
enum class type
{
none,
solid,
gradient,
pattern
};
enum class gradient_type
{
none,
linear,
path
};
enum class pattern_type
{
none,
solid,
darkdown,
darkgray,
darkgrid,
darkhorizontal,
darktrellis,
darkup,
darkvertical,
gray0625,
gray125,
lightdown,
lightgray,
lightgrid,
lighthorizontal,
lighttrellis,
lightup,
lightvertical,
mediumgray,
darkgray,
lightgray,
darkhorizontal,
darkvertical,
darkdown,
darkup,
darkgrid,
darktrellis,
lighthorizontal,
lightvertical,
lightdown,
lightup,
lightgrid,
lighttrellis,
gray125,
gray0625
};
fill();
pattern_fill();
pattern_fill(type pattern_type);
type get_type() const;
void set_type(type t);
pattern_type get_pattern_type() const;
void set_pattern_type(pattern_type t);
gradient_type get_gradient_type() const;
void set_gradient_type(gradient_type t);
void set_type(type pattern_type);
void set_foreground_color(const color &c);
@ -99,49 +77,110 @@ public:
const std::experimental::optional<color> &get_background_color() const;
void set_start_color(const color &c);
protected:
std::string to_hash_string() const override;
std::experimental::optional<color> &get_start_color();
private:
type type_ = type::none;
const std::experimental::optional<color> &get_start_color() const;
std::experimental::optional<color> foreground_color_;
std::experimental::optional<color> background_color_;
};
void set_end_color(const color &c);
class gradient_fill : public hashable
{
public:
enum class type
{
linear,
path
};
std::experimental::optional<color> &get_end_color();
gradient_fill();
const std::experimental::optional<color> &get_end_color() const;
gradient_fill(type gradient_type);
void set_rotation(double rotation);
type get_type() const;
double get_rotation() const;
void set_type(type gradient_type);
void set_degree(double degree);
double get_degree() const;
double get_gradient_left() const;
void set_gradient_left(double value);
double get_gradient_right() const;
void set_gradient_right(double value);
double get_gradient_top() const;
void set_gradient_top(double value);
double get_gradient_bottom() const;
void set_gradient_bottom(double value);
void add_stop(double position, color stop_color);
void delete_stop(double position);
void clear_stops();
const std::unordered_map<double, color> &get_stops() const;
protected:
std::string to_hash_string() const override;
private:
type type_;
pattern_type pattern_type_;
gradient_type gradient_type_;
double rotation_;
std::experimental::optional<color> foreground_color_;
std::experimental::optional<color> background_color_;
std::experimental::optional<color> start_color_;
std::experimental::optional<color> end_color_;
double gradient_path_left_;
double gradient_path_right_;
double gradient_path_top_;
double gradient_path_bottom_;
type type_ = type::linear;
std::unordered_map<double, color> stops_;
double degree_ = 0;
double left_ = 0;
double right_ = 0;
double top_ = 0;
double bottom_ = 0;
};
/// <summary>
/// Describes the fill style of a particular cell.
/// </summary>
class XLNT_CLASS fill : public hashable
{
public:
enum class type
{
pattern,
gradient
};
static fill gradient(gradient_fill::type gradient_type);
static fill pattern(pattern_fill::type pattern_type);
type get_type() const;
gradient_fill &get_gradient_fill();
const gradient_fill &get_gradient_fill() const;
pattern_fill &get_pattern_fill();
const pattern_fill &get_pattern_fill() const;
protected:
std::string to_hash_string() const override;
private:
type type_ = type::pattern;
gradient_fill gradient_;
pattern_fill pattern_;
};
} // namespace xlnt

View File

@ -360,9 +360,8 @@ public:
auto ws = wb.create_sheet();
auto cell = ws.get_cell("A1");
xlnt::fill f;
f.set_pattern_type(xlnt::fill::pattern_type::solid);
f.set_foreground_color(xlnt::color(xlnt::color::type::rgb, "FF0000"));
xlnt::fill f = xlnt::fill::pattern(xlnt::pattern_fill::type::solid);
f.get_pattern_fill().set_foreground_color(xlnt::color::red());
cell.set_fill(f);

View File

@ -144,46 +144,46 @@ std::string underline_style_to_string(xlnt::font::underline_style underline_styl
// fill::pattern_type serialization
const std::unordered_map<std::string, xlnt::fill::pattern_type> &get_string_pattern_fill_type_map()
const std::unordered_map<std::string, xlnt::pattern_fill::type> &get_string_pattern_fill_type_map()
{
static std::unordered_map<std::string, xlnt::fill::pattern_type> *map = nullptr;
static std::unordered_map<std::string, xlnt::pattern_fill::type> *map = nullptr;
if (map == nullptr)
{
map = new std::unordered_map<std::string, xlnt::fill::pattern_type>
map = new std::unordered_map<std::string, xlnt::pattern_fill::type>
{
{ "darkdown", xlnt::fill::pattern_type::darkdown },
{ "darkgray", xlnt::fill::pattern_type::darkgray },
{ "darkgrid", xlnt::fill::pattern_type::darkgrid },
{ "darkhorizontal", xlnt::fill::pattern_type::darkhorizontal },
{ "darktrellis", xlnt::fill::pattern_type::darktrellis },
{ "darkup", xlnt::fill::pattern_type::darkup },
{ "darkvertical", xlnt::fill::pattern_type::darkvertical },
{ "gray0625", xlnt::fill::pattern_type::gray0625 },
{ "gray125", xlnt::fill::pattern_type::gray125 },
{ "lightdown", xlnt::fill::pattern_type::lightdown },
{ "lightgray", xlnt::fill::pattern_type::lightgray },
{ "lightgrid", xlnt::fill::pattern_type::lightgrid },
{ "lighthorizontal", xlnt::fill::pattern_type::lighthorizontal },
{ "lighttrellis", xlnt::fill::pattern_type::lighttrellis },
{ "lightup", xlnt::fill::pattern_type::lightup },
{ "lightvertical", xlnt::fill::pattern_type::lightvertical },
{ "mediumgray", xlnt::fill::pattern_type::mediumgray },
{ "none", xlnt::fill::pattern_type::none },
{ "solid", xlnt::fill::pattern_type::solid }
{ "darkdown", xlnt::pattern_fill::type::darkdown },
{ "darkgray", xlnt::pattern_fill::type::darkgray },
{ "darkgrid", xlnt::pattern_fill::type::darkgrid },
{ "darkhorizontal", xlnt::pattern_fill::type::darkhorizontal },
{ "darktrellis", xlnt::pattern_fill::type::darktrellis },
{ "darkup", xlnt::pattern_fill::type::darkup },
{ "darkvertical", xlnt::pattern_fill::type::darkvertical },
{ "gray0625", xlnt::pattern_fill::type::gray0625 },
{ "gray125", xlnt::pattern_fill::type::gray125 },
{ "lightdown", xlnt::pattern_fill::type::lightdown },
{ "lightgray", xlnt::pattern_fill::type::lightgray },
{ "lightgrid", xlnt::pattern_fill::type::lightgrid },
{ "lighthorizontal", xlnt::pattern_fill::type::lighthorizontal },
{ "lighttrellis", xlnt::pattern_fill::type::lighttrellis },
{ "lightup", xlnt::pattern_fill::type::lightup },
{ "lightvertical", xlnt::pattern_fill::type::lightvertical },
{ "mediumgray", xlnt::pattern_fill::type::mediumgray },
{ "none", xlnt::pattern_fill::type::none },
{ "solid", xlnt::pattern_fill::type::solid }
};
}
return *map;
}
const std::unordered_map<xlnt::fill::pattern_type, std::string, EnumClassHash> &get_pattern_fill_type_string_map()
const std::unordered_map<xlnt::pattern_fill::type, std::string, EnumClassHash> &get_pattern_fill_type_string_map()
{
static std::unordered_map<xlnt::fill::pattern_type, std::string, EnumClassHash> *map = nullptr;
static std::unordered_map<xlnt::pattern_fill::type, std::string, EnumClassHash> *map = nullptr;
if (map == nullptr)
{
map = new std::unordered_map<xlnt::fill::pattern_type, std::string, EnumClassHash>;
map = new std::unordered_map<xlnt::pattern_fill::type, std::string, EnumClassHash>;
for (auto pair : get_string_pattern_fill_type_map())
{
@ -194,16 +194,61 @@ const std::unordered_map<xlnt::fill::pattern_type, std::string, EnumClassHash> &
return *map;
}
xlnt::fill::pattern_type pattern_fill_type_from_string(const std::string &fill_type)
xlnt::pattern_fill::type pattern_fill_type_from_string(const std::string &fill_type)
{
return get_string_pattern_fill_type_map().at(string_lower(fill_type));
};
std::string pattern_fill_type_to_string(xlnt::fill::pattern_type fill_type)
std::string pattern_fill_type_to_string(xlnt::pattern_fill::type fill_type)
{
return get_pattern_fill_type_string_map().at(fill_type);
}
// fill::gradient_type serialization
const std::unordered_map<std::string, xlnt::gradient_fill::type> &get_string_gradient_fill_type_map()
{
static std::unordered_map<std::string, xlnt::gradient_fill::type> *map = nullptr;
if (map == nullptr)
{
map = new std::unordered_map<std::string, xlnt::gradient_fill::type>
{
{ "linear", xlnt::gradient_fill::type::linear },
{ "path", xlnt::gradient_fill::type::path }
};
}
return *map;
}
const std::unordered_map<xlnt::gradient_fill::type, std::string, EnumClassHash> &get_gradient_fill_type_string_map()
{
static std::unordered_map<xlnt::gradient_fill::type, std::string, EnumClassHash> *map = nullptr;
if (map == nullptr)
{
map = new std::unordered_map<xlnt::gradient_fill::type, std::string, EnumClassHash>;
for (auto pair : get_string_gradient_fill_type_map())
{
map->emplace(pair.second, pair.first);
}
}
return *map;
}
xlnt::gradient_fill::type gradient_fill_type_from_string(const std::string &fill_type)
{
return get_string_gradient_fill_type_map().at(string_lower(fill_type));
};
std::string gradient_fill_type_to_string(xlnt::gradient_fill::type fill_type)
{
return get_gradient_fill_type_string_map().at(fill_type);
}
// border_style serialization
@ -563,25 +608,41 @@ xlnt::fill read_fill(const pugi::xml_node &fill_node)
if (fill_node.child("patternFill"))
{
new_fill.set_type(xlnt::fill::type::pattern);
auto pattern_fill_node = fill_node.child("patternFill");
std::string pattern_fill_type_string = pattern_fill_node.attribute("patternType").value();
if (!pattern_fill_type_string.empty())
{
new_fill.set_pattern_type(pattern_fill_type_from_string(pattern_fill_type_string));
new_fill = xlnt::fill::pattern(pattern_fill_type_from_string(pattern_fill_type_string));
if (pattern_fill_node.child("bgColor"))
{
new_fill.get_background_color() = read_color(pattern_fill_node.child("bgColor"));
new_fill.get_pattern_fill().get_background_color() = read_color(pattern_fill_node.child("bgColor"));
}
if (pattern_fill_node.child("fgColor"))
{
new_fill.get_foreground_color() = read_color(pattern_fill_node.child("fgColor"));
new_fill.get_pattern_fill().get_foreground_color() = read_color(pattern_fill_node.child("fgColor"));
}
}
else
{
new_fill = xlnt::fill::pattern(xlnt::pattern_fill::type::none);
}
}
else if (fill_node.child("gradientFill"))
{
auto gradient_fill_node = fill_node.child("gradientFill");
std::string gradient_fill_type_string = gradient_fill_node.attribute("gradientType").value();
if (!gradient_fill_type_string.empty())
{
new_fill = xlnt::fill::gradient(gradient_fill_type_from_string(gradient_fill_type_string));
}
else
{
new_fill = xlnt::fill::gradient(xlnt::gradient_fill::type::linear);
}
}
return new_fill;
@ -895,46 +956,59 @@ bool write_fills(const std::vector<xlnt::fill> &fills, pugi::xml_node &fills_nod
if (fill_.get_type() == xlnt::fill::type::pattern)
{
const auto &pattern = fill_.get_pattern_fill();
auto pattern_fill_node = fill_node.append_child("patternFill");
pattern_fill_node.append_attribute("patternType").set_value(pattern_fill_type_to_string(fill_.get_pattern_type()).c_str());
if (fill_.get_pattern_type() != xlnt::fill::pattern_type::solid) continue;
pattern_fill_node.append_attribute("patternType").set_value(pattern_fill_type_to_string(pattern.get_type()).c_str());
if (fill_.get_foreground_color())
if (pattern.get_foreground_color())
{
write_color(*fill_.get_foreground_color(), pattern_fill_node.append_child("fgColor"));
write_color(*pattern.get_foreground_color(), pattern_fill_node.append_child("fgColor"));
}
if (fill_.get_background_color())
if (pattern.get_background_color())
{
write_color(*fill_.get_background_color(), pattern_fill_node.append_child("bgColor"));
write_color(*pattern.get_background_color(), pattern_fill_node.append_child("bgColor"));
}
}
else if (fill_.get_type() == xlnt::fill::type::solid)
{
auto solid_fill_node = fill_node.append_child("solidFill");
solid_fill_node.append_child("color");
}
else if (fill_.get_type() == xlnt::fill::type::gradient)
{
const auto &gradient = fill_.get_gradient_fill();
auto gradient_fill_node = fill_node.append_child("gradientFill");
auto gradient_fill_type_string = gradient_fill_type_to_string(gradient.get_type());
gradient_fill_node.append_attribute("gradientType").set_value(gradient_fill_type_string.c_str());
if (fill_.get_gradient_type() == xlnt::fill::gradient_type::linear)
if (gradient.get_degree() != 0)
{
gradient_fill_node.append_attribute("degree").set_value(std::to_string(fill_.get_rotation()).c_str());
gradient_fill_node.append_attribute("degree").set_value(gradient.get_degree());
}
else if (fill_.get_gradient_type() == xlnt::fill::gradient_type::path)
if (gradient.get_gradient_left() != 0)
{
gradient_fill_node.append_attribute("left").set_value(std::to_string(fill_.get_gradient_left()).c_str());
gradient_fill_node.append_attribute("right").set_value(std::to_string(fill_.get_gradient_right()).c_str());
gradient_fill_node.append_attribute("top").set_value(std::to_string(fill_.get_gradient_top()).c_str());
gradient_fill_node.append_attribute("bottom").set_value(std::to_string(fill_.get_gradient_bottom()).c_str());
gradient_fill_node.append_attribute("left").set_value(gradient.get_gradient_left());
}
auto start_node = gradient_fill_node.append_child("stop");
start_node.append_attribute("position").set_value("0");
if (gradient.get_gradient_right() != 0)
{
gradient_fill_node.append_attribute("right").set_value(gradient.get_gradient_right());
}
auto end_node = gradient_fill_node.append_child("stop");
end_node.append_attribute("position").set_value("1");
if (gradient.get_gradient_top() != 0)
{
gradient_fill_node.append_attribute("top").set_value(gradient.get_gradient_top());
}
if (gradient.get_gradient_bottom() != 0)
{
gradient_fill_node.append_attribute("bottom").set_value(gradient.get_gradient_bottom());
}
for (const auto &stop : gradient.get_stops())
{
auto stop_node = gradient_fill_node.append_child("stop");
stop_node.append_attribute("position").set_value(stop.first);
write_color(stop.second, stop_node.append_child("color"));
}
}
}
@ -989,6 +1063,41 @@ bool write_borders(const std::vector<xlnt::border> &borders, pugi::xml_node &bor
return true;
}
bool write_alignment(const xlnt::alignment &a, pugi::xml_node alignment_node)
{
if (a.has_vertical())
{
auto vertical = vertical_alignment_to_string(a.get_vertical());
alignment_node.append_attribute("vertical").set_value(vertical.c_str());
}
if (a.has_horizontal())
{
auto horizontal = horizontal_alignment_to_string(a.get_horizontal());
alignment_node.append_attribute("horizontal").set_value(horizontal.c_str());
}
if (a.get_wrap_text())
{
alignment_node.append_attribute("wrapText").set_value("1");
}
if (a.get_shrink_to_fit())
{
alignment_node.append_attribute("shrinkToFit").set_value("1");
}
return true;
}
bool write_protection(const xlnt::protection &p, pugi::xml_node protection_node)
{
protection_node.append_attribute("locked").set_value(p.get_locked() ? "1" : "0");
protection_node.append_attribute("hidden").set_value(p.get_hidden() ? "1" : "0");
return true;
}
bool write_base_format(const xlnt::base_format &xf, const xlnt::detail::stylesheet &stylesheet, pugi::xml_node xf_node)
{
xf_node.append_attribute("numFmtId").set_value(std::to_string(xf.get_number_format().get_id()).c_str());
@ -1006,41 +1115,17 @@ bool write_base_format(const xlnt::base_format &xf, const xlnt::detail::styleshe
if(xf.fill_applied()) xf_node.append_attribute("applyFill").set_value("1");
if(xf.font_applied()) xf_node.append_attribute("applyFont").set_value("1");
if(xf.border_applied()) xf_node.append_attribute("applyBorder").set_value("1");
if(xf.alignment_applied()) xf_node.append_attribute("applyAlignment").set_value("1");
if(xf.protection_applied()) xf_node.append_attribute("applyProtection").set_value("1");
if (xf.alignment_applied())
if(xf.alignment_applied())
{
auto alignment_node = xf_node.append_child("alignment");
if (xf.get_alignment().has_vertical())
{
auto vertical = vertical_alignment_to_string(xf.get_alignment().get_vertical());
alignment_node.append_attribute("vertical").set_value(vertical.c_str());
}
if (xf.get_alignment().has_horizontal())
{
auto horizontal = horizontal_alignment_to_string(xf.get_alignment().get_horizontal());
alignment_node.append_attribute("horizontal").set_value(horizontal.c_str());
}
if (xf.get_alignment().get_wrap_text())
{
alignment_node.append_attribute("wrapText").set_value("1");
}
if (xf.get_alignment().get_shrink_to_fit())
{
alignment_node.append_attribute("shrinkToFit").set_value("1");
}
xf_node.append_attribute("applyAlignment").set_value("1");
write_alignment(xf.get_alignment(), xf_node.append_child("alignment"));
}
if (xf.protection_applied())
{
auto protection_node = xf_node.append_child("protection");
protection_node.append_attribute("locked").set_value(xf.get_protection().get_locked() ? "1" : "0");
protection_node.append_attribute("hidden").set_value(xf.get_protection().get_hidden() ? "1" : "0");
xf_node.append_attribute("applyProtection").set_value("1");
write_protection(xf.get_protection(), xf_node.append_child("protection"));
}
return true;

View File

@ -26,103 +26,105 @@
namespace xlnt {
fill::fill()
: type_(type::pattern),
pattern_type_(pattern_type::none),
gradient_type_(gradient_type::none),
rotation_(0),
gradient_path_left_(0),
gradient_path_right_(0),
gradient_path_top_(0),
gradient_path_bottom_(0)
{
}
fill::type fill::get_type() const
{
return type_;
}
void fill::set_type(type t)
pattern_fill::type pattern_fill::get_type() const
{
return type_;
}
void pattern_fill::set_type(pattern_fill::type t)
{
type_ = t;
}
fill::pattern_type fill::get_pattern_type() const
gradient_fill::type gradient_fill::get_type() const
{
return pattern_type_;
return type_;
}
void fill::set_pattern_type(pattern_type t)
void gradient_fill::set_type(gradient_fill::type t)
{
type_ = type::pattern;
pattern_type_ = t;
type_ = t;
}
fill::gradient_type fill::get_gradient_type() const
{
return gradient_type_;
}
void fill::set_gradient_type(gradient_type t)
{
type_ = type::gradient;
gradient_type_ = t;
}
void fill::set_foreground_color(const color &c)
void pattern_fill::set_foreground_color(const color &c)
{
foreground_color_ = c;
}
std::experimental::optional<color> &fill::get_foreground_color()
std::experimental::optional<color> &pattern_fill::get_foreground_color()
{
return foreground_color_;
}
const std::experimental::optional<color> &fill::get_foreground_color() const
const std::experimental::optional<color> &pattern_fill::get_foreground_color() const
{
return foreground_color_;
}
std::experimental::optional<color> &fill::get_background_color()
void pattern_fill::set_background_color(const color &c)
{
background_color_ = c;
}
std::experimental::optional<color> &pattern_fill::get_background_color()
{
return background_color_;
}
const std::experimental::optional<color> &fill::get_background_color() const
const std::experimental::optional<color> &pattern_fill::get_background_color() const
{
return background_color_;
}
std::experimental::optional<color> &fill::get_start_color()
void gradient_fill::set_degree(double degree)
{
return start_color_;
degree_ = degree;
}
const std::experimental::optional<color> &fill::get_start_color() const
double gradient_fill::get_degree() const
{
return start_color_;
return degree_;
}
std::experimental::optional<color> &fill::get_end_color()
std::string pattern_fill::to_hash_string() const
{
return end_color_;
std::string hash_string = "pattern_fill";
hash_string.append(background_color_ ? "1" : "0");
if (background_color_)
{
hash_string.append(std::to_string(background_color_->hash()));
}
hash_string.append(background_color_ ? "1" : "0");
if (background_color_)
{
hash_string.append(std::to_string(background_color_->hash()));
}
return hash_string;
}
const std::experimental::optional<color> &fill::get_end_color() const
std::string gradient_fill::to_hash_string() const
{
return end_color_;
}
std::string hash_string = "gradient_fill";
void fill::set_rotation(double rotation)
{
rotation_ = rotation;
}
double fill::get_rotation() const
{
return rotation_;
hash_string.append(std::to_string(static_cast<std::size_t>(type_)));
hash_string.append(std::to_string(stops_.size()));
hash_string.append(std::to_string(degree_));
hash_string.append(std::to_string(left_));
hash_string.append(std::to_string(right_));
hash_string.append(std::to_string(top_));
hash_string.append(std::to_string(bottom_));
return hash_string;
}
std::string fill::to_hash_string() const
@ -134,99 +136,154 @@ std::string fill::to_hash_string() const
switch (type_)
{
case type::pattern:
{
hash_string.append(std::to_string(static_cast<std::size_t>(pattern_type_)));
hash_string.append(background_color_ ? "1" : "0");
if (background_color_)
{
hash_string.append(std::to_string(background_color_->hash()));
}
hash_string.append(background_color_ ? "1" : "0");
if (background_color_)
{
hash_string.append(std::to_string(background_color_->hash()));
}
hash_string.append(std::to_string(pattern_.hash()));
break;
}
case type::gradient:
{
hash_string.append(std::to_string(static_cast<std::size_t>(gradient_type_)));
if (gradient_type_ == gradient_type::path)
{
hash_string.append(std::to_string(gradient_path_left_));
hash_string.append(std::to_string(gradient_path_right_));
hash_string.append(std::to_string(gradient_path_top_));
hash_string.append(std::to_string(gradient_path_bottom_));
}
else if (gradient_type_ == gradient_type::linear)
{
hash_string.append(std::to_string(rotation_));
}
hash_string.append(start_color_ ? "1" : "0");
if (start_color_)
{
hash_string.append(std::to_string(start_color_->hash()));
}
hash_string.append(end_color_ ? "1" : "0");
if (end_color_)
{
hash_string.append(std::to_string(end_color_->hash()));
}
hash_string.append(std::to_string(gradient_.hash()));
break;
}
default:
{
break;
}
} // switch (type_)
return hash_string;
}
double fill::get_gradient_left() const
double gradient_fill::get_gradient_left() const
{
return gradient_path_left_;
return left_;
}
double fill::get_gradient_right() const
void gradient_fill::set_gradient_left(double value)
{
return gradient_path_right_;
left_ = value;
}
double fill::get_gradient_top() const
double gradient_fill::get_gradient_right() const
{
return gradient_path_top_;
return right_;
}
double fill::get_gradient_bottom() const
void gradient_fill::set_gradient_right(double value)
{
return gradient_path_bottom_;
right_ = value;
}
void fill::set_background_color(const color &c)
double gradient_fill::get_gradient_top() const
{
background_color_ = c;
return top_;
}
void fill::set_start_color(const color &c)
void gradient_fill::set_gradient_top(double value)
{
start_color_ = c;
top_ = value;
}
void fill::set_end_color(const color &c)
double gradient_fill::get_gradient_bottom() const
{
end_color_ = c;
return bottom_;
}
void gradient_fill::set_gradient_bottom(double value)
{
bottom_ = value;
}
fill fill::pattern(pattern_fill::type pattern_type)
{
fill f;
f.type_ = type::pattern;
f.pattern_ = pattern_fill(pattern_type);
return f;
}
fill fill::gradient(gradient_fill::type gradient_type)
{
fill f;
f.type_ = type::gradient;
f.gradient_ = gradient_fill(gradient_type);
return f;
}
pattern_fill::pattern_fill(type pattern_type) : type_(pattern_type)
{
}
pattern_fill::pattern_fill() : pattern_fill(type::none)
{
}
gradient_fill::gradient_fill(type gradient_type) : type_(gradient_type)
{
}
gradient_fill::gradient_fill() : gradient_fill(type::linear)
{
}
gradient_fill &fill::get_gradient_fill()
{
if (type_ != fill::type::gradient)
{
throw std::runtime_error("not gradient");
}
return gradient_;
}
const gradient_fill &fill::get_gradient_fill() const
{
if (type_ != fill::type::gradient)
{
throw std::runtime_error("not gradient");
}
return gradient_;
}
pattern_fill &fill::get_pattern_fill()
{
if (type_ != fill::type::pattern)
{
throw std::runtime_error("not pattern");
}
return pattern_;
}
const pattern_fill &fill::get_pattern_fill() const
{
if (type_ != fill::type::pattern)
{
throw std::runtime_error("not pattern");
}
return pattern_;
}
void gradient_fill::add_stop(double position, color stop_color)
{
stops_[position] = stop_color;
}
void gradient_fill::delete_stop(double position)
{
stops_.erase(stops_.find(position));
}
void gradient_fill::clear_stops()
{
stops_.clear();
}
const std::unordered_map<double, color> &gradient_fill::get_stops() const
{
return stops_;
}
} // namespace xlnt

View File

@ -12,66 +12,45 @@ public:
{
xlnt::fill fill;
TS_ASSERT_EQUALS(fill.get_gradient_type(), xlnt::fill::gradient_type::none);
fill.set_gradient_type(xlnt::fill::gradient_type::linear);
TS_ASSERT_EQUALS(fill.get_gradient_type(), xlnt::fill::gradient_type::linear);
TS_ASSERT_EQUALS(fill.get_type(), xlnt::fill::type::pattern);
fill = xlnt::fill::gradient(xlnt::gradient_fill::type::linear);
TS_ASSERT_EQUALS(fill.get_type(), xlnt::fill::type::gradient);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_type(), xlnt::gradient_fill::type::linear);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_gradient_left(), 0);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_gradient_right(), 0);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_gradient_top(), 0);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_gradient_bottom(), 0);
TS_ASSERT_THROWS(fill.get_pattern_fill(), std::runtime_error);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_degree(), 0);
fill.get_gradient_fill().set_degree(1);
TS_ASSERT_EQUALS(fill.get_gradient_fill().get_degree(), 1);
fill = xlnt::fill::pattern(xlnt::pattern_fill::type::solid);
fill.get_pattern_fill().set_foreground_color(xlnt::color::black());
TS_ASSERT(fill.get_pattern_fill().get_foreground_color());
TS_ASSERT_EQUALS(*fill.get_pattern_fill().get_foreground_color(), xlnt::color::black());
TS_ASSERT(!fill.get_foreground_color());
fill.set_foreground_color(xlnt::color::black());
TS_ASSERT(fill.get_foreground_color());
TS_ASSERT(!fill.get_background_color());
fill.set_background_color(xlnt::color::black());
TS_ASSERT(fill.get_background_color());
TS_ASSERT(!fill.get_start_color());
fill.set_start_color(xlnt::color::black());
TS_ASSERT(fill.get_start_color());
TS_ASSERT(!fill.get_end_color());
fill.set_end_color(xlnt::color::black());
TS_ASSERT(fill.get_end_color());
TS_ASSERT_EQUALS(fill.get_rotation(), 0);
fill.set_rotation(1);
TS_ASSERT_EQUALS(fill.get_rotation(), 1);
TS_ASSERT_EQUALS(fill.get_gradient_bottom(), 0);
TS_ASSERT_EQUALS(fill.get_gradient_left(), 0);
TS_ASSERT_EQUALS(fill.get_gradient_top(), 0);
TS_ASSERT_EQUALS(fill.get_gradient_right(), 0);
fill.get_pattern_fill().set_background_color(xlnt::color::green());
TS_ASSERT(fill.get_pattern_fill().get_background_color());
TS_ASSERT_EQUALS(*fill.get_pattern_fill().get_background_color(), xlnt::color::green());
const auto &const_fill = fill;
TS_ASSERT(const_fill.get_foreground_color());
TS_ASSERT(const_fill.get_background_color());
TS_ASSERT(const_fill.get_start_color());
TS_ASSERT(const_fill.get_end_color());
TS_ASSERT(const_fill.get_pattern_fill().get_foreground_color());
TS_ASSERT(const_fill.get_pattern_fill().get_background_color());
}
void test_hash()
{
xlnt::fill none_fill;
xlnt::fill pattern_fill = xlnt::fill::pattern(xlnt::pattern_fill::type::solid);
xlnt::fill gradient_fill_linear = xlnt::fill::gradient(xlnt::gradient_fill::type::linear);
xlnt::fill gradient_fill_path = xlnt::fill::gradient(xlnt::gradient_fill::type::path);
xlnt::fill solid_fill;
solid_fill.set_type(xlnt::fill::type::solid);
xlnt::fill pattern_fill;
pattern_fill.set_type(xlnt::fill::type::pattern);
xlnt::fill gradient_fill_linear;
gradient_fill_linear.set_type(xlnt::fill::type::gradient);
gradient_fill_linear.set_gradient_type(xlnt::fill::gradient_type::linear);
xlnt::fill gradient_fill_path;
gradient_fill_path.set_type(xlnt::fill::type::gradient);
gradient_fill_path.set_gradient_type(xlnt::fill::gradient_type::path);
gradient_fill_path.set_start_color(xlnt::color::red());
gradient_fill_path.set_end_color(xlnt::color::green());
TS_ASSERT_DIFFERS(none_fill.hash(), solid_fill.hash());
TS_ASSERT_DIFFERS(solid_fill.hash(), pattern_fill.hash());
TS_ASSERT_DIFFERS(pattern_fill.hash(), gradient_fill_linear.hash());
TS_ASSERT_DIFFERS(gradient_fill_linear.hash(), gradient_fill_path.hash());
TS_ASSERT_DIFFERS(gradient_fill_path.hash(), none_fill.hash());
TS_ASSERT_DIFFERS(gradient_fill_path.hash(), pattern_fill.hash());
}
};

View File

@ -214,4 +214,147 @@ public:
TS_ASSERT(style_xml_matches(expected, wb));
}
void test_alignment()
{
xlnt::workbook wb;
xlnt::alignment a;
a.set_horizontal(xlnt::horizontal_alignment::center_continuous);
a.set_vertical(xlnt::vertical_alignment::justify);
a.set_wrap_text(true);
a.set_shrink_to_fit(true);
wb.get_active_sheet().get_cell("A1").set_alignment(a);
std::string expected =
"<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\" mc:Ignorable=\"x14ac\">"
" <fonts count=\"1\">"
" <font>"
" <sz val=\"12\"/>"
" <color theme=\"1\"/>"
" <name val=\"Calibri\"/>"
" <family val=\"2\"/>"
" <scheme val=\"minor\"/>"
" </font>"
" </fonts>"
" <fills count=\"2\">"
" <fill>"
" <patternFill patternType=\"none\"/>"
" </fill>"
" <fill>"
" <patternFill patternType=\"gray125\"/>"
" </fill>"
" </fills>"
" <borders count=\"1\">"
" <border>"
" <left/>"
" <right/>"
" <top/>"
" <bottom/>"
" <diagonal/>"
" </border>"
" </borders>"
" <cellStyleXfs count=\"1\">"
" <xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/>"
" </cellStyleXfs>"
" <cellXfs count=\"2\">"
" <xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>"
" <xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\">"
" <alignment vertical=\"justify\" horizontal=\"center-continuous\" wrapText=\"1\" shrinkToFit=\"1\"/>"
" </xf>"
" </cellXfs>"
" <cellStyles count=\"1\">"
" <cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\"/>"
" </cellStyles>"
" <dxfs count=\"0\"/>"
" <tableStyles count=\"0\" defaultTableStyle=\"TableStyleMedium9\" defaultPivotStyle=\"PivotStyleMedium7\"/>"
"</styleSheet>";
TS_ASSERT(style_xml_matches(expected, wb));
}
void test_fill()
{
xlnt::workbook wb;
xlnt::fill pattern_fill = xlnt::fill::pattern(xlnt::pattern_fill::type::solid);
pattern_fill.get_pattern_fill().set_foreground_color(xlnt::color::red());
pattern_fill.get_pattern_fill().set_background_color(xlnt::color::blue());
wb.get_active_sheet().get_cell("A1").set_fill(pattern_fill);
xlnt::fill gradient_fill_linear = xlnt::fill::gradient(xlnt::gradient_fill::type::linear);
gradient_fill_linear.get_gradient_fill().set_degree(90);
wb.get_active_sheet().get_cell("A1").set_fill(gradient_fill_linear);
xlnt::fill gradient_fill_path = xlnt::fill::gradient(xlnt::gradient_fill::type::path);
gradient_fill_path.get_gradient_fill().set_gradient_left(1);
gradient_fill_path.get_gradient_fill().set_gradient_right(2);
gradient_fill_path.get_gradient_fill().set_gradient_top(3);
gradient_fill_path.get_gradient_fill().set_gradient_bottom(4);
gradient_fill_path.get_gradient_fill().add_stop(0, xlnt::color::red());
gradient_fill_path.get_gradient_fill().add_stop(1, xlnt::color::blue());
wb.get_active_sheet().get_cell("A1").set_fill(gradient_fill_path);
std::string expected =
"<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\" mc:Ignorable=\"x14ac\">"
" <fonts count=\"1\">"
" <font>"
" <sz val=\"12\"/>"
" <color theme=\"1\"/>"
" <name val=\"Calibri\"/>"
" <family val=\"2\"/>"
" <scheme val=\"minor\"/>"
" </font>"
" </fonts>"
" <fills count=\"5\">"
" <fill>"
" <patternFill patternType=\"none\"/>"
" </fill>"
" <fill>"
" <patternFill patternType=\"gray125\"/>"
" </fill>"
" <fill>"
" <patternFill patternType=\"solid\">"
" <fgColor rgb=\"ffff0000\"/>"
" <bgColor rgb=\"ff0000ff\"/>"
" </patternFill>"
" </fill>"
" <fill>"
" <gradientFill gradientType=\"linear\" degree=\"90\"/>"
" </fill>"
" <fill>"
" <gradientFill gradientType=\"path\" left=\"1\" right=\"2\" top=\"3\" bottom=\"4\">"
" <stop position=\"0\">"
" <color rgb=\"ff00ff00\"/>"
" </stop>"
" <stop position=\"1\">"
" <color rgb=\"ffffff00\"/>"
" </stop>"
" </gradientFill>"
" </fill>"
" </fills>"
" <borders count=\"1\">"
" <border>"
" <left/>"
" <right/>"
" <top/>"
" <bottom/>"
" <diagonal/>"
" </border>"
" </borders>"
" <cellStyleXfs count=\"1\">"
" <xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/>"
" </cellStyleXfs>"
" <cellXfs count=\"2\">"
" <xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>"
" <xf numFmtId=\"0\" fontId=\"0\" fillId=\"2\" borderId=\"0\" xfId=\"0\"/>"
" <xf numFmtId=\"0\" fontId=\"0\" fillId=\"3\" borderId=\"0\" xfId=\"0\"/>"
" <xf numFmtId=\"0\" fontId=\"0\" fillId=\"4\" borderId=\"0\" xfId=\"0\"/>"
" </cellXfs>"
" <cellStyles count=\"1\">"
" <cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\"/>"
" </cellStyles>"
" <dxfs count=\"0\"/>"
" <tableStyles count=\"0\" defaultTableStyle=\"TableStyleMedium9\" defaultPivotStyle=\"PivotStyleMedium7\"/>"
"</styleSheet>";
TS_ASSERT(style_xml_matches(expected, wb));
}
};

View File

@ -92,9 +92,7 @@ workbook::workbook() : d_(new detail::workbook_impl())
create_style("Normal");
d_->stylesheet_.format_styles.front() = "Normal";
xlnt::fill gray125;
gray125.set_type(xlnt::fill::type::pattern);
gray125.set_pattern_type(xlnt::fill::pattern_type::gray125);
xlnt::fill gray125 = xlnt::fill::pattern(xlnt::pattern_fill::type::gray125);
d_->stylesheet_.fills.push_back(gray125);
}