working on styles, don't use yet

This commit is contained in:
Thomas Fussell 2016-11-02 18:16:34 -04:00
parent eeba8ffa86
commit 4e51e9e0e5
17 changed files with 1070 additions and 513 deletions

View File

@ -36,7 +36,6 @@ namespace xlnt {
enum class calendar;
class alignment;
class base_format;
class border;
class cell_reference;
class comment;
@ -177,41 +176,32 @@ public:
// computed format
/// <summary>
/// For each of alignment, border, fill, font, number format, and protection,
/// returns a format using the value from the cell format if that value is
/// applied, or else the value from the named style if that value is applied,
/// or else the default value. This is used to retreive the formatting of the cell
/// as it will be displayed in an editing application.
/// </summary>
base_format get_computed_format() const;
/// <summary>
/// Returns the result of get_computed_format().get_alignment().
///
/// </summary>
alignment get_computed_alignment() const;
/// <summary>
/// Returns the result of get_computed_format().get_border().
///
/// </summary>
border get_computed_border() const;
/// <summary>
/// Returns the result of get_computed_format().get_fill().
///
/// </summary>
fill get_computed_fill() const;
/// <summary>
/// Returns the result of get_computed_format().get_font().
///
/// </summary>
font get_computed_font() const;
/// <summary>
/// Returns the result of get_computed_format().get_number_format().
///
/// </summary>
number_format get_computed_number_format() const;
/// <summary>
/// Returns the result of get_computed_format().get_protection().
///
/// </summary>
protection get_computed_protection() const;
@ -492,27 +482,21 @@ private:
// make these friends so they can use the private constructor
friend class style;
friend class worksheet;
friend class detail::xlsx_consumer;
friend class detail::xlsx_producer;
friend class detail::xlsx_consumer;
friend class detail::xlsx_producer;
friend struct detail::cell_impl;
/// <summary>
/// Helper function to guess the type of a string, convert it,
/// and then use the correct cell::get_value according to the type.
/// </summary>
void guess_type_and_set_value(const std::string &value);
/// <summary>
/// Returns a non-const reference to the format of this cell.
/// This is for internal use only.
/// </summary>
format &get_format_internal();
/// <summary>
/// Helper function to guess the type of a string, convert it,
/// and then use the correct cell::get_value according to the type.
/// </summary>
void guess_type_and_set_value(const std::string &value);
/// <summary>
/// Use workbook::create_format() to create a new format then copy
/// this cell's formatting to that new format and return it.
/// Returns a non-const reference to the format of this cell.
/// This is for internal use only.
/// </summary>
format &duplicate_format();
format &get_format_internal();
/// <summary>
/// Private constructor to create a cell from its implementation.

View File

@ -1,94 +0,0 @@
// Copyright (c) 2014-2016 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// 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 <xlnt/xlnt_config.hpp>
#include <xlnt/styles/alignment.hpp>
#include <xlnt/styles/border.hpp>
#include <xlnt/styles/fill.hpp>
#include <xlnt/styles/font.hpp>
#include <xlnt/styles/number_format.hpp>
#include <xlnt/styles/protection.hpp>
namespace xlnt {
/// <summary>
/// Describes the formatting of a particular cell.
/// </summary>
class XLNT_API base_format
{
public:
// Alignment
class alignment &alignment();
const class alignment &alignment() const;
void alignment(const xlnt::alignment &new_alignment, bool applied);
bool alignment_applied() const;
// Border
virtual class border &border();
virtual const class border &border() const;
virtual void border(const xlnt::border &new_border, bool applied);
bool border_applied() const;
// Fill
virtual class fill &fill();
virtual const class fill &fill() const;
virtual void fill(const xlnt::fill &new_fill, bool applied);
bool fill_applied() const;
// Font
virtual class font &font();
virtual const class font &font() const;
virtual void font(const xlnt::font &new_font, bool applied);
bool font_applied() const;
// Number Format
virtual class number_format &number_format();
virtual const class number_format &number_format() const;
virtual void number_format(const xlnt::number_format &new_number_format, bool applied);
bool number_format_applied() const;
// Protection
class protection &protection();
const class protection &protection() const;
void protection(const xlnt::protection &new_protection, bool applied);
bool protection_applied() const;
protected:
class alignment alignment_;
class border border_;
class fill fill_;
class font font_;
class number_format number_format_;
class protection protection_;
bool apply_alignment_ = false;
bool apply_border_ = false;
bool apply_fill_ = false;
bool apply_font_ = false;
bool apply_number_format_ = false;
bool apply_protection_ = false;
};
} // namespace xlnt

View File

@ -36,53 +36,200 @@ class fill;
class font;
class number_format;
class protection;
class workbook;
namespace detail {
struct format_impl;
struct stylesheet;
class xlsx_consumer;
class xlsx_producer;
} // namespace detail
/// <summary>
/// Describes the formatting of a particular cell.
/// </summary>
class XLNT_API format : public base_format
class XLNT_API format
{
public:
std::size_t id() const;
bool has_style() const;
void clear_style();
void style(const std::string &name);
void style(const xlnt::style &new_style);
const class style &style() const;
class border &border() override;
const class border &border() const override;
void border(const xlnt::border &new_border, bool applied) override;
class fill &fill() override;
const class fill &fill() const override;
void fill(const xlnt::fill &new_fill, bool applied) override;
/// <summary>
/// Returns the index of this format.
/// </summary>
std::size_t id() const;
class font &font() override;
const class font &font() const override;
void font(const xlnt::font &new_font, bool applied) override;
// Alignment
class number_format &number_format() override;
const class number_format &number_format() const override;
void number_format(const xlnt::number_format &new_number_format, bool applied) override;
/// <summary>
/// Returns the alignment to be applied to contents of cells using this format.
/// </summary>
class alignment &alignment();
format &alignment_id(std::size_t id);
format &border_id(std::size_t id);
format &fill_id(std::size_t id);
format &font_id(std::size_t id);
format &number_format_id(std::size_t id);
format &protection_id(std::size_t id);
/// <summary>
/// Returns the alignment to be applied to contents of cells using this format.
/// </summary>
const class alignment &alignment() const;
/// <summary>
/// Sets the alignment of this format to new_alignment. If applied is true,
/// the alignment will be used when displaying the cell. Updates all cells
/// currently using this format if update is true, otherwise creates new
/// format with the new protection.
/// </summary>
void alignment(const xlnt::alignment &new_alignment,
bool applied = true, bool update = true);
/// <summary>
/// Returns true if the alignment is being applied.
/// </summary>
bool alignment_applied() const;
// Border
/// <summary>
/// Returns the border properties to be applied to the outline of cells using this format.
/// </summary>
class border &border();
/// <summary>
/// Returns the border properties to be applied to the outline of cells using this format.
/// </summary>
const class border &border() const;
/// <summary>
/// Sets the border of this format to new_border. If applied is true,
/// the border will be used when displaying the cell. Updates all cells
/// currently using this format if update is true, otherwise creates
/// new format with the new protection.
/// </summary>
void border(const xlnt::border &new_border,
bool applied = true, bool update = true);
/// <summary>
/// Returns true if the border is being applied.
/// </summary>
bool border_applied() const;
// Fill
/// <summary>
/// Returns the fill to be applied to the background of cells using this format.
/// </summary>
class fill &fill();
/// <summary>
/// Returns the fill to be applied to the background of cells using this format.
/// </summary>
const class fill &fill() const;
/// <summary>
/// Sets the fill of this format to new_fill and applies it if applied is true.
/// Updates all cells currently using this format if update is true,
/// otherwise creates new format with the new protection.
/// </summary>
void fill(const xlnt::fill &new_fill,
bool applied = true, bool update = true);
/// <summary>
/// Returns true if the fill is being applied.
/// </summary>
bool fill_applied() const;
// Font
/// <summary>
/// Returns the font to be applied to contents of cells using this format.
/// </summary>
class font &font();
/// <summary>
/// Returns the font to be applied to contents of cells using this format.
/// </summary>
const class font &font() const;
/// <summary>
/// Sets the font of this format to new_font and applies it if applied is true.
/// Updates all cells currently using this format if update is true,
/// otherwise creates new format with the new protection.
/// </summary>
void font(const xlnt::font &new_font,
bool applied = true, bool update = true);
/// <summary>
/// Returns true if the font is being applied.
/// </summary>
bool font_applied() const;
// Number Format
/// <summary>
/// Returns the number format to be applied to text/numbers in cells using this format.
/// </summary>
class number_format &number_format();
/// <summary>
/// Returns the number format to be applied to text/numbers in cells using this format.
/// </summary>
const class number_format &number_format() const;
/// <summary>
/// Sets the number format applied to text/numbers in cells using this format
/// and applies it if applied is true. Updates all cells currently using this
/// format if update is true, otherwise creates new format with the new number
/// format.
/// </summary>
void number_format(const xlnt::number_format &new_number_format,
bool applied = true, bool update = true);
/// <summary>
/// Returns true if the number format is being applied.
/// </summary>
bool number_format_applied() const;
// Protection
/// <summary>
/// Returns the protection to be applied to the contents of cells using this format.
/// </summary>
class protection &protection();
/// <summary>
/// Returns the protection to be applied to the contents of cells using this format.
/// </summary>
const class protection &protection() const;
/// <summary>
/// Sets the protection of the contents of the cell using this format. Applies it if
/// applied is true. Updates all cells currently using this format if update is true,
/// otherwise creates new format with the new protection.
/// </summary>
void protection(const xlnt::protection &new_protection,
bool applied = true, bool update = true);
/// <summary>
/// Returns true if the protection is being applied.
/// </summary>
bool protection_applied() const;
/// <summary>
/// Returns true if the formats are identical.
/// </summary>
XLNT_API friend bool operator==(const format &left, const format &right);
private:
friend struct detail::stylesheet;
format(detail::format_impl *d);
detail::format_impl *d_;
friend struct detail::stylesheet;
friend class detail::xlsx_consumer;
friend class detail::xlsx_producer;
friend class cell;
friend class workbook;
/// <summary>
/// Private constructor used by stylesheet.
/// </summary>
format(detail::format_impl *d);
/// <summary>
/// Pointer to implementation. This memory is held in a vector in stylesheet.
/// </summary>
detail::format_impl *d_;
};
} // namespace xlnt

View File

@ -27,7 +27,6 @@
#include <string>
#include <xlnt/xlnt_config.hpp>
#include <xlnt/styles/base_format.hpp>
namespace xlnt {
@ -40,7 +39,7 @@ struct stylesheet;
/// Describes a style which has a name and can be applied to multiple individual
/// formats. In Excel this is a "Cell Style".
/// </summary>
class XLNT_API style : public base_format
class XLNT_API style
{
public:
std::string name() const;
@ -55,18 +54,152 @@ public:
optional<std::size_t> builtin_id() const;
style &builtin_id(std::size_t builtin_id);
style &alignment_id(std::size_t id);
style &border_id(std::size_t id);
style &fill_id(std::size_t id);
style &font_id(std::size_t id);
style &number_format_id(std::size_t id);
style &protection_id(std::size_t id);
// Alignment
bool operator==(const style &other);
/// <summary>
/// Returns the alignment to be applied to contents of cells using this format.
/// </summary>
class alignment &alignment();
/// <summary>
/// Returns the alignment to be applied to contents of cells using this format.
/// </summary>
const class alignment &alignment() const;
/// <summary>
/// Sets the alignment of this format to new_alignment. If applied is true,
/// the alignment will be used when displaying the cell.
/// </summary>
void alignment(const xlnt::alignment &new_alignment, bool applied = true, bool update = true);
/// <summary>
/// Returns true if the alignment is being applied.
/// </summary>
bool alignment_applied() const;
// Border
/// <summary>
/// Returns the border properties to be applied to the outline of cells using this format.
/// </summary>
class border &border();
/// <summary>
/// Returns the border properties to be applied to the outline of cells using this format.
/// </summary>
const class border &border() const;
/// <summary>
/// Sets the border of this format to new_border. If applied is true,
/// the border will be used when displaying the cell.
/// </summary>
void border(const xlnt::border &new_border, bool applied = true, bool update = true);
/// <summary>
/// Returns true if the border is being applied.
/// </summary>
bool border_applied() const;
// Fill
/// <summary>
/// Returns the fill to be applied to the background of cells using this format.
/// </summary>
class fill &fill();
/// <summary>
/// Returns the fill to be applied to the background of cells using this format.
/// </summary>
const class fill &fill() const;
/// <summary>
/// Sets the fill of this format to new_fill and applies it if applied is true.
/// </summary>
void fill(const xlnt::fill &new_fill, bool applied = true, bool update = true);
/// <summary>
/// Returns true if the fill is being applied.
/// </summary>
bool fill_applied() const;
// Font
/// <summary>
/// Returns the font to be applied to contents of cells using this format.
/// </summary>
class font &font();
/// <summary>
/// Returns the font to be applied to contents of cells using this format.
/// </summary>
const class font &font() const;
/// <summary>
/// Sets the font of this format to new_font and applies it if applied is true.
/// </summary>
void font(const xlnt::font &new_font, bool applied = true, bool update = true);
/// <summary>
/// Returns true if the font is being applied.
/// </summary>
bool font_applied() const;
// Number Format
/// <summary>
/// Returns the number format to be applied to text/numbers in cells using this format.
/// </summary>
class number_format &number_format();
/// <summary>
/// Returns the number format to be applied to text/numbers in cells using this format.
/// </summary>
const class number_format &number_format() const;
/// <summary>
/// Sets the number format applied to text/numbers in cells using this format
/// and applies it if applied is true.
/// </summary>
void number_format(const xlnt::number_format &new_number_format, bool applied = true, bool update = true);
/// <summary>
/// Returns true if the number format is being applied.
/// </summary>
bool number_format_applied() const;
// Protection
/// <summary>
/// Returns the protection to be applied to the contents of cells using this format.
/// </summary>
class protection &protection();
/// <summary>
/// Returns the protection to be applied to the contents of cells using this format.
/// </summary>
const class protection &protection() const;
/// <summary>
/// Sets the protection of the contents of the cell using this format. Applies it if
/// applied is true.
/// </summary>
void protection(const xlnt::protection &new_protection, bool applied = true, bool update = true);
/// <summary>
/// Returns true if the protection is being applied.
/// </summary>
bool protection_applied() const;
/// <summary>
/// Returns true if the formats are identical.
/// </summary>
XLNT_API friend bool operator==(const style &left, const style &right);
private:
friend struct detail::stylesheet;
style(detail::style_impl *d);
detail::style_impl *d_;
};

View File

@ -36,6 +36,7 @@
namespace xlnt {
class alignment;
class base_format;
class border;
class cell;
class cell_style;
@ -419,7 +420,9 @@ public:
format &get_format(std::size_t format_index);
const format &get_format(std::size_t format_index) const;
format &create_format();
format &create_format();
format &create_format(format pattern);
format &create_format(base_format pattern);
void clear_formats();
// styles

View File

@ -30,8 +30,14 @@
#include <xlnt/cell/comment.hpp>
#include <xlnt/cell/formatted_text.hpp>
#include <xlnt/packaging/relationship.hpp>
#include <xlnt/styles/alignment.hpp>
#include <xlnt/styles/border.hpp>
#include <xlnt/styles/color.hpp>
#include <xlnt/styles/fill.hpp>
#include <xlnt/styles/font.hpp>
#include <xlnt/styles/format.hpp>
#include <xlnt/styles/number_format.hpp>
#include <xlnt/styles/protection.hpp>
#include <xlnt/styles/style.hpp>
#include <xlnt/utils/date.hpp>
#include <xlnt/utils/datetime.hpp>
@ -44,6 +50,7 @@
#include <xlnt/worksheet/worksheet.hpp>
#include <detail/cell_impl.hpp>
#include <detail/format_impl.hpp>
namespace {
@ -610,32 +617,104 @@ void cell::set_data_type(type t)
number_format cell::get_computed_number_format() const
{
return get_computed_format().number_format();
number_format computed;
if (has_format() && get_format().number_format_applied())
{
computed = get_format().number_format();
}
/*
if (has_style() && get_style().number_format_applied())
{
computed = get_style().number_format();
}
*/
return computed;
}
font cell::get_computed_font() const
{
return get_computed_format().font();
font computed;
if (has_format() && get_format().number_format_applied())
{
computed = get_format().font();
}
/*
if (has_style() && get_style().number_format_applied())
{
computed = get_style().number_format();
}
*/
return computed;
}
fill cell::get_computed_fill() const
{
return get_computed_format().fill();
fill computed;
if (has_format() && get_format().number_format_applied())
{
computed = get_format().fill();
}
/*
if (has_style() && get_style().number_format_applied())
{
computed = get_style().number_format();
}
*/
return computed;
}
border cell::get_computed_border() const
{
return get_computed_format().border();
border computed;
if (has_format() && get_format().number_format_applied())
{
computed = get_format().border();
}
/*
if (has_style() && get_style().number_format_applied())
{
computed = get_style().number_format();
}
*/
return computed;
}
alignment cell::get_computed_alignment() const
{
return get_computed_format().alignment();
alignment computed;
if (has_format() && get_format().number_format_applied())
{
computed = get_format().alignment();
}
/*
if (has_style() && get_style().number_format_applied())
{
computed = get_style().number_format();
}
*/
return computed;
}
protection cell::get_computed_protection() const
{
return get_computed_format().protection();
protection computed;
if (has_format() && get_format().number_format_applied())
{
computed = get_format().protection();
}
/*
if (has_style() && get_style().number_format_applied())
{
computed = get_style().number_format();
}
*/
return computed;
}
void cell::clear_value()
@ -758,44 +837,80 @@ XLNT_API timedelta cell::get_value() const
void cell::set_alignment(const xlnt::alignment &alignment_)
{
auto &format = duplicate_format();
format.alignment(alignment_, true);
d_->format_id_ = format.id();
if (!has_format())
{
set_format(get_workbook().create_format());
get_format().alignment(alignment_, true, true);
}
else
{
get_format().alignment(alignment_, true, false);
}
}
void cell::set_border(const xlnt::border &border_)
{
auto &format = duplicate_format();
format.border(border_, true);
d_->format_id_ = format.id();
if (!has_format())
{
set_format(get_workbook().create_format());
get_format().border(border_, true, true);
}
else
{
get_format().border(border_, true, false);
}
}
void cell::set_fill(const xlnt::fill &fill_)
{
auto &format = duplicate_format();
format.fill(fill_, true);
d_->format_id_ = format.id();
if (!has_format())
{
set_format(get_workbook().create_format());
get_format().fill(fill_, true, true);
}
else
{
get_format().fill(fill_, true, false);
}
}
void cell::set_font(const font &font_)
{
auto &format = duplicate_format();
format.font(font_, true);
d_->format_id_ = format.id();
if (!has_format())
{
set_format(get_workbook().create_format());
get_format().font(font_, true, true);
}
else
{
get_format().font(font_, true, false);
}
}
void cell::set_number_format(const number_format &number_format_)
{
auto &format = duplicate_format();
format.number_format(number_format_, true);
d_->format_id_ = format.id();
if (!has_format())
{
set_format(get_workbook().create_format());
get_format().number_format(number_format_, true, true);
}
else
{
get_format().number_format(number_format_, true, false);
}
}
void cell::set_protection(const xlnt::protection &protection_)
{
auto &format = duplicate_format();
format.protection(protection_, true);
d_->format_id_ = format.id();
if (!has_format())
{
set_format(get_workbook().create_format());
get_format().protection(protection_, true, true);
}
else
{
get_format().protection(protection_, true, false);
}
}
template <>
@ -898,81 +1013,39 @@ void cell::clear_style()
{
if (has_format())
{
get_format_internal().clear_style();
get_format().d_->style.clear();
}
}
void cell::set_style(const style &new_style)
{
auto &new_format = duplicate_format();
new_format.style(new_style);
d_->format_id_ = new_format.id();
if (!has_format())
{
set_format(get_workbook().create_format());
}
auto current_format = get_format();
current_format.d_->style = new_style.name();
}
void cell::set_style(const std::string &style_name)
{
auto &new_format = duplicate_format();
new_format.style(get_workbook().get_style(style_name).name());
d_->format_id_ = new_format.id();
set_style(get_workbook().get_style(style_name));
}
style cell::get_style() const
{
if (!has_format() || !get_format().has_style())
if (!has_format() || !get_format().d_->style.is_set())
{
throw invalid_attribute();
}
return get_format().style();
return get_workbook().get_style(get_format().d_->style.get());
}
bool cell::has_style() const
{
return has_format() && get_format().has_style();
}
base_format cell::get_computed_format() const
{
base_format result;
// Check style first
if (has_style())
{
style cell_style = get_style();
if (cell_style.alignment_applied()) result.alignment(cell_style.alignment(), true);
if (cell_style.border_applied()) result.border(cell_style.border(), true);
if (cell_style.fill_applied()) result.fill(cell_style.fill(), true);
if (cell_style.font_applied()) result.font(cell_style.font(), true);
if (cell_style.number_format_applied()) result.number_format(cell_style.number_format(), true);
if (cell_style.protection_applied()) result.protection(cell_style.protection(), true);
}
// Cell format overrides style
if (has_format())
{
format cell_format = get_format();
if (cell_format.alignment_applied()) result.alignment(cell_format.alignment(), true);
if (cell_format.border_applied()) result.border(cell_format.border(), true);
if (cell_format.fill_applied()) result.fill(cell_format.fill(), true);
if (cell_format.font_applied()) result.font(cell_format.font(), true);
if (cell_format.number_format_applied()) result.number_format(cell_format.number_format(), true);
if (cell_format.protection_applied()) result.protection(cell_format.protection(), true);
}
// Use defaults for any remaining non-applied components
if (!result.alignment_applied()) result.alignment(alignment(), true);
if (!result.border_applied()) result.border(border(), true);
if (!result.fill_applied()) result.fill(fill(), true);
if (!result.font_applied()) result.font(font(), true);
if (!result.number_format_applied()) result.number_format(number_format(), true);
if (!result.protection_applied()) result.protection(protection(), true);
return result;
return has_format() && get_format().d_->style.is_set();
}
format &cell::get_format_internal()
@ -985,25 +1058,6 @@ format &cell::get_format_internal()
return get_workbook().get_format(*d_->format_id_);
}
format &cell::duplicate_format()
{
auto &new_format = get_workbook().create_format();
if (has_format())
{
auto &current_format = get_format_internal();
new_format.alignment(current_format.alignment(), current_format.alignment_applied());
new_format.border(current_format.border(), current_format.border_applied());
new_format.fill(current_format.fill(), current_format.fill_applied());
new_format.font(current_format.font(), current_format.font_applied());
new_format.number_format(current_format.number_format(), current_format.number_format_applied());
new_format.protection(current_format.protection(), current_format.protection_applied());
}
return new_format;
}
format cell::get_format() const
{
if (!d_->format_id_)

View File

@ -18,6 +18,19 @@ public:
wb_guess_types.set_guess_types(true);
}
void test_temp()
{
xlnt::workbook wb;
auto cell = wb[0].get_cell("A1");
cell.set_value("right");
cell.set_alignment(xlnt::alignment().horizontal(xlnt::horizontal_alignment::right));
cell.set_font(xlnt::font().size(20).color(xlnt::color::white()));
cell.set_fill(xlnt::fill::solid(xlnt::color::black()));
wb.create_style("yellow-fill").fill(xlnt::fill::solid(xlnt::color::yellow()), true);
cell.set_style("yellow-fill");
wb.save("temp.xlsx");
}
void test_infer_numeric()
{
auto ws = wb_guess_types.create_sheet();

View File

@ -29,14 +29,42 @@ struct format_impl
std::size_t id;
bool alignment_applied = false;
optional<std::size_t> alignment_id;
bool border_applied = false;
optional<std::size_t> border_id;
bool fill_applied = false;
optional<std::size_t> fill_id;
bool font_applied = false;
optional<std::size_t> font_id;
bool number_format_applied = false;
optional<std::size_t> number_format_id;
bool protection_applied = false;
optional<std::size_t> protection_id;
optional<std::string> style;
bool operator==(const format_impl &other) const
{
return alignment_applied == other.alignment_applied
&& alignment_id.is_set() == other.alignment_id.is_set()
&& (!alignment_id.is_set() || alignment_id.get() == other.alignment_id.get())
&& border_applied == other.border_applied
&& border_id.is_set() == other.border_id.is_set()
&& (!border_id.is_set() || border_id.get() == other.border_id.get())
&& fill_applied == other.fill_applied
&& fill_id.is_set() == other.fill_id.is_set()
&& (!fill_id.is_set() || fill_id.get() == other.fill_id.get())
&& font_applied == other.font_applied
&& font_id.is_set() == other.font_id.is_set()
&& (!font_id.is_set() || font_id.get() == other.font_id.get())
&& number_format_applied == other.number_format_applied
&& number_format_id.is_set() == other.number_format_id.is_set()
&& (!number_format_id.is_set() || number_format_id.get() == other.number_format_id.get())
&& protection_applied == other.protection_applied
&& protection_id.is_set() == other.protection_id.is_set()
&& (!protection_id.is_set() || protection_id.get() == other.protection_id.get());
}
};
} // namespace detail

View File

@ -31,12 +31,18 @@ struct style_impl
optional<std::size_t> builtin_id;
optional<std::size_t> outline_style;
optional<class alignment> alignment;
optional<class border> border;
optional<class fill> fill;
optional<class font> font;
optional<class number_format> number_format;
optional<class protection> protection;
bool alignment_applied = false;
optional<std::size_t> alignment_id;
bool border_applied = false;
optional<std::size_t> border_id;
bool fill_applied = false;
optional<std::size_t> fill_id;
bool font_applied = false;
optional<std::size_t> font_id;
bool number_format_applied = false;
optional<std::size_t> number_format_id;
bool protection_applied = false;
optional<std::size_t> protection_id;
};
} // namespace detail

View File

@ -25,6 +25,7 @@
#include <list>
#include <string>
#include <unordered_map>
#include <vector>
#include <detail/format_impl.hpp>
@ -38,23 +39,23 @@ namespace detail {
struct stylesheet
{
~stylesheet()
{
}
format &create_format()
{
format_impls.push_back(format_impl());
auto &impl = format_impls.back();
impl.parent = this;
impl.id = format_impls.size() - 1;
formats.push_back(format(&impl));
format_impls.push_back(format_impl());
auto &impl = format_impls.back();
impl.parent = this;
impl.id = format_impls.size() - 1;
formats.push_back(format(&impl));
auto &format = formats.back();
if (!alignments.empty())
{
format.alignment(alignments.front(), false);
}
else
{
format.alignment(alignment(), false);
}
if (!borders.empty())
{
@ -73,7 +74,7 @@ struct stylesheet
if (!number_formats.empty())
{
format.number_format(number_formats.front(), false);
format.number_format(number_formats.begin()->second, false);
}
if (!protections.empty())
@ -84,10 +85,27 @@ struct stylesheet
return format;
}
format &get_format(std::size_t index)
{
return formats.at(index);
}
format &get_format(std::size_t index)
{
return formats.at(index);
}
std::pair<bool, std::size_t> find_format(format pattern)
{
std::size_t index = 0;
for (const format &f : formats)
{
if (f == pattern)
{
return {true, index};
}
++index;
}
return {false, 0};
}
style &create_style()
{
@ -130,14 +148,26 @@ struct stylesheet
for (const auto &nf : number_formats)
{
if (nf.get_id() >= id)
if (nf.second.get_id() >= id)
{
id = nf.get_id() + 1;
id = nf.second.get_id() + 1;
}
}
return id;
}
std::size_t add_alignment(const alignment &new_alignment)
{
auto match = std::find(alignments.begin(), alignments.end(), new_alignment);
if (match == alignments.end())
{
match = alignments.insert(alignments.end(), new_alignment);
}
return std::distance(alignments.begin(), match);
}
std::size_t add_border(const border &new_border)
{
@ -196,6 +226,26 @@ struct stylesheet
return index;
}
std::size_t add_protection(const protection &new_protection)
{
std::size_t index = 0;
for (const auto &p : protections)
{
if (p == new_protection)
{
return index;
}
++index;
}
protections.push_back(new_protection);
return index;
}
void clear()
{
format_impls.clear();
@ -224,7 +274,7 @@ struct stylesheet
std::vector<border> borders;
std::vector<fill> fills;
std::vector<font> fonts;
std::vector<number_format> number_formats;
std::unordered_map<std::size_t, number_format> number_formats;
std::vector<protection> protections;
std::vector<color> colors;

View File

@ -1265,7 +1265,7 @@ void xlsx_consumer::read_stylesheet()
nf.set_format_string(format_string);
nf.set_id(string_to_size_t(parser().attribute("numFmtId")));
stylesheet.number_formats.push_back(nf);
stylesheet.number_formats[nf.get_id()] = nf;
parser().next_expect(xml::parser::event_type::end_element); // numFmt
}
@ -1510,9 +1510,9 @@ void xlsx_consumer::read_stylesheet()
for (const auto &nf : stylesheet.number_formats)
{
if (nf.get_id() == number_format_id)
if (nf.first == number_format_id)
{
result = nf;
result = nf.second;
is_custom_number_format = true;
break;
}
@ -1552,7 +1552,7 @@ void xlsx_consumer::read_stylesheet()
{
auto &new_format = stylesheet.create_format();
new_format.style(stylesheet.styles.at(record.style_id.first).name());
new_format.d_->style = stylesheet.styles.at(record.style_id.first).name();
new_format.alignment(record.alignment.first, record.alignment.second);
new_format.border(stylesheet.borders.at(record.border_id.first), record.border_id.second);

View File

@ -776,8 +776,8 @@ void xlsx_producer::write_styles(const relationship &rel)
for (const auto &num_fmt : number_formats)
{
serializer().start_element(xmlns, "numFmt");
serializer().attribute("numFmtId", num_fmt.get_id());
serializer().attribute("formatCode", num_fmt.get_format_string());
serializer().attribute("numFmtId", num_fmt.first);
serializer().attribute("formatCode", num_fmt.second.get_format_string());
serializer().end_element(xmlns, "numFmt");
}
@ -1117,11 +1117,11 @@ void xlsx_producer::write_styles(const relationship &rel)
if (current_format.alignment_applied()) serializer().attribute("applyAlignment", write_bool(true));
if (current_format.protection_applied()) serializer().attribute("applyProtection", write_bool(true));
if (current_format.has_style())
if (current_format.d_->style.is_set())
{
serializer().attribute("xfId", std::distance(stylesheet.styles.begin(),
std::find_if(stylesheet.styles.begin(), stylesheet.styles.end(),
[&](const xlnt::style &s) { return s.name() == current_format.style().name(); })));
[&](const xlnt::style &s) { return s.name() == current_format.d_->style.get(); })));
}
if (current_format.alignment_applied())

View File

@ -1,154 +0,0 @@
// Copyright (c) 2014-2016 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// 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/styles/base_format.hpp>
namespace xlnt {
alignment &base_format::alignment()
{
return alignment_;
}
const alignment &base_format::alignment() const
{
return alignment_;
}
void base_format::alignment(const xlnt::alignment &new_alignment, bool apply)
{
alignment_ = new_alignment;
apply_alignment_ = apply;
}
number_format &base_format::number_format()
{
return number_format_;
}
const number_format &base_format::number_format() const
{
return number_format_;
}
void base_format::number_format(const xlnt::number_format &new_number_format, bool apply)
{
number_format_ = new_number_format;
apply_number_format_ = apply;
}
border &base_format::border()
{
return border_;
}
const border &base_format::border() const
{
return border_;
}
void base_format::border(const xlnt::border &new_border, bool apply)
{
border_ = new_border;
apply_border_ = apply;
}
fill &base_format::fill()
{
return fill_;
}
const fill &base_format::fill() const
{
return fill_;
}
void base_format::fill(const xlnt::fill &new_fill, bool apply)
{
fill_ = new_fill;
apply_fill_ = apply;
}
font &base_format::font()
{
return font_;
}
const font &base_format::font() const
{
return font_;
}
void base_format::font(const xlnt::font &new_font, bool apply)
{
font_ = new_font;
apply_font_ = apply;
}
protection &base_format::protection()
{
return protection_;
}
const protection &base_format::protection() const
{
return protection_;
}
void base_format::protection(const xlnt::protection &new_protection, bool apply)
{
protection_ = new_protection;
apply_protection_ = apply;
}
bool base_format::alignment_applied() const
{
return apply_alignment_;
}
bool base_format::border_applied() const
{
return apply_border_;
}
bool base_format::fill_applied() const
{
return apply_fill_;
}
bool base_format::font_applied() const
{
return apply_font_;
}
bool base_format::number_format_applied() const
{
return apply_number_format_;
}
bool base_format::protection_applied() const
{
return apply_protection_;
}
} // namespace xlnt

View File

@ -38,132 +38,334 @@ std::size_t format::id() const
return d_->id;
}
void format::clear_style()
alignment &format::alignment()
{
d_->style.clear();
return d_->parent->alignments.at(d_->alignment_id);
}
void format::style(const xlnt::style &new_style)
const alignment &format::alignment() const
{
d_->style = new_style.name();
return d_->parent->alignments.at(d_->alignment_id);
}
void format::style(const std::string &new_style)
void format::alignment(const xlnt::alignment &new_alignment, bool applied, bool update)
{
for (auto &style : d_->parent->styles)
{
if (style.name() == new_style)
{
d_->style = new_style;
return;
}
}
auto alignment_id = d_->parent->add_alignment(new_alignment);
throw key_not_found();
}
if (update)
{
d_->alignment_id = alignment_id;
d_->alignment_applied = applied;
}
else
{
auto impl_copy = *d_;
bool format::has_style() const
{
return d_->style;
}
impl_copy.alignment_id = alignment_id;
impl_copy.alignment_applied = applied;
const style &format::style() const
{
if (!has_style())
{
throw invalid_attribute();
}
auto match = std::find(d_->parent->format_impls.begin(), d_->parent->format_impls.end(), impl_copy);
return d_->parent->get_style(*d_->style);
if (match != d_->parent->format_impls.end())
{
d_ = &*match;
}
else
{
d_->parent->format_impls.push_back(impl_copy);
d_ = &d_->parent->format_impls.back();
}
}
}
xlnt::border &format::border()
{
return base_format::border();
const auto &self = *this;
return const_cast<class border &>(self.border());
}
const xlnt::border &format::border() const
{
return base_format::border();
if (!d_->border_id)
{
throw xlnt::exception("no border");
}
return d_->parent->borders.at(d_->border_id.get());
}
void format::border(const xlnt::border &new_border, bool applied)
void format::border(const xlnt::border &new_border, bool applied, bool update)
{
border_id(d_->parent->add_border(new_border));
base_format::border(new_border, applied);
auto border_id = d_->parent->add_border(new_border);
if (update)
{
d_->border_id = border_id;
d_->border_applied = applied;
}
else
{
auto impl_copy = *d_;
impl_copy.border_id = border_id;
impl_copy.border_applied = applied;
auto match = std::find(d_->parent->format_impls.begin(), d_->parent->format_impls.end(), impl_copy);
if (match != d_->parent->format_impls.end())
{
d_ = &*match;
}
else
{
d_->parent->format_impls.push_back(impl_copy);
d_ = &d_->parent->format_impls.back();
}
}
}
xlnt::fill &format::fill()
{
return base_format::fill();
const auto &self = *this;
return const_cast<class fill &>(self.fill());
}
const xlnt::fill &format::fill() const
{
return base_format::fill();
if (!d_->fill_id)
{
throw xlnt::exception("no border");
}
return d_->parent->fills.at(d_->fill_id.get());
}
void format::fill(const xlnt::fill &new_fill, bool applied)
void format::fill(const xlnt::fill &new_fill, bool applied, bool update)
{
fill_id(d_->parent->add_fill(new_fill));
base_format::fill(new_fill, applied);
auto fill_id = d_->parent->add_fill(new_fill);
if (update)
{
d_->fill_id = fill_id;
d_->fill_applied = applied;
}
else
{
auto impl_copy = *d_;
impl_copy.fill_id = fill_id;
impl_copy.fill_applied = applied;
auto match = std::find(d_->parent->format_impls.begin(), d_->parent->format_impls.end(), impl_copy);
if (match != d_->parent->format_impls.end())
{
d_ = &*match;
}
else
{
d_->parent->format_impls.push_back(impl_copy);
d_ = &d_->parent->format_impls.back();
}
}
}
xlnt::font &format::font()
{
return base_format::font();
const auto &self = *this;
return const_cast<class font &>(self.font());
}
const xlnt::font &format::font() const
{
return base_format::font();
if (!d_->font_id)
{
throw xlnt::exception("no border");
}
return d_->parent->fonts.at(d_->font_id.get());
}
void format::font(const xlnt::font &new_font, bool applied)
void format::font(const xlnt::font &new_font, bool applied, bool update)
{
font_id(d_->parent->add_font(new_font));
base_format::font(new_font, applied);
auto font_id = d_->parent->add_font(new_font);
if (update)
{
d_->font_id = font_id;
d_->font_applied = applied;
}
else
{
auto impl_copy = *d_;
impl_copy.font_id = font_id;
impl_copy.font_applied = applied;
auto match = std::find(d_->parent->format_impls.begin(), d_->parent->format_impls.end(), impl_copy);
if (match != d_->parent->format_impls.end())
{
d_ = &*match;
}
else
{
d_->parent->format_impls.push_back(impl_copy);
d_ = &d_->parent->format_impls.back();
}
}
}
xlnt::number_format &format::number_format()
{
return base_format::number_format();
const auto &self = *this;
return const_cast<class number_format &>(self.number_format());
}
const xlnt::number_format &format::number_format() const
{
return base_format::number_format();
if (!d_->number_format_id)
{
throw xlnt::exception("no number format");
}
return d_->parent->number_formats.at(d_->number_format_id.get());
}
void format::number_format(const xlnt::number_format &new_number_format, bool applied)
void format::number_format(const xlnt::number_format &new_number_format, bool applied, bool update)
{
auto copy = new_number_format;
if (!copy.has_id())
{
copy.set_id(d_->parent->next_custom_number_format_id());
d_->parent->number_formats.push_back(copy);
d_->parent->number_formats[copy.get_id()] = copy;
}
base_format::number_format(copy, applied);
auto number_format_id = copy.get_id();
if (update)
{
d_->number_format_id = number_format_id;
d_->number_format_applied = applied;
}
else
{
auto impl_copy = *d_;
impl_copy.number_format_id = number_format_id;
impl_copy.number_format_applied = applied;
auto match = std::find(d_->parent->format_impls.begin(), d_->parent->format_impls.end(), impl_copy);
if (match != d_->parent->format_impls.end())
{
d_ = &*match;
}
else
{
d_->parent->format_impls.push_back(impl_copy);
d_ = &d_->parent->format_impls.back();
}
}
}
format &format::border_id(std::size_t id)
protection &format::protection()
{
d_->border_id = id;
return *this;
return d_->parent->protections.at(d_->protection_id);
}
format &format::fill_id(std::size_t id)
const protection &format::protection() const
{
d_->fill_id = id;
return *this;
return d_->parent->protections.at(d_->protection_id);
}
format &format::font_id(std::size_t id)
void format::protection(const xlnt::protection &new_protection, bool applied, bool update)
{
d_->font_id = id;
return *this;
auto protection_id = d_->parent->add_protection(new_protection);
if (update)
{
d_->protection_id = protection_id;
d_->protection_applied = applied;
}
else
{
auto impl_copy = *d_;
impl_copy.protection_id = protection_id;
impl_copy.protection_applied = applied;
auto match = std::find(d_->parent->format_impls.begin(), d_->parent->format_impls.end(), impl_copy);
if (match != d_->parent->format_impls.end())
{
d_ = &*match;
}
else
{
d_->parent->format_impls.push_back(impl_copy);
d_ = &d_->parent->format_impls.back();
}
}
}
bool format::alignment_applied() const
{
return d_->alignment_applied;
}
bool format::border_applied() const
{
return d_->border_applied;
}
bool format::fill_applied() const
{
return d_->fill_applied;
}
bool format::font_applied() const
{
return d_->font_applied;
}
bool format::number_format_applied() const
{
return d_->number_format_applied;
}
bool format::protection_applied() const
{
return d_->protection_applied;
}
XLNT_API bool operator==(const format &left, const format &right)
{
if (left.alignment_applied() != right.alignment_applied()) return false;
if (left.alignment_applied() && left.alignment() != right.alignment()) return false;
if (left.border_applied() != right.border_applied()) return false;
if (left.border_applied() && left.border() != right.border()) return false;
if (left.fill_applied() != right.fill_applied()) return false;
if (left.fill_applied() && left.fill() != right.fill()) return false;
if (left.font_applied() != right.font_applied()) return false;
if (left.font_applied() && left.font() != right.font()) return false;
if (left.number_format_applied() != right.number_format_applied()) return false;
if (left.number_format_applied() && left.number_format() != right.number_format()) return false;
if (left.protection_applied() != right.protection_applied()) return false;
if (left.protection_applied() && left.protection() != right.protection()) return false;
if (left.d_->style.is_set() != right.d_->style.is_set()) return false;
if (left.d_->style.is_set() && left.d_->style.get() != right.d_->style.get()) return false;
return true;
}
} // namespace xlnt

View File

@ -22,13 +22,14 @@
// @license: http://www.opensource.org/licenses/mit-license.php
// @author: see AUTHORS file
#include <detail/style_impl.hpp> // include order is important here
#include <detail/stylesheet.hpp>
#include <xlnt/styles/alignment.hpp>
#include <xlnt/styles/border.hpp>
#include <xlnt/styles/fill.hpp>
#include <xlnt/styles/font.hpp>
#include <xlnt/styles/number_format.hpp>
#include <xlnt/styles/protection.hpp>
#include <detail/style_impl.hpp> // include order is important here
#include <xlnt/styles/style.hpp>
namespace xlnt {
@ -81,9 +82,171 @@ style &style::custom(bool value)
return *this;
}
bool style::operator==(const style &other)
alignment &style::alignment()
{
return d_ == other.d_;
return d_->parent->alignments.at(d_->alignment_id);
}
const alignment &style::alignment() const
{
return d_->parent->alignments.at(d_->alignment_id);
}
void style::alignment(const xlnt::alignment &new_alignment, bool applied, bool update)
{
if (update)
{
d_->alignment_id = 0;
}
}
xlnt::border &style::border()
{
const auto &self = *this;
return const_cast<class border &>(self.border());
}
const xlnt::border &style::border() const
{
if (!d_->border_id)
{
throw xlnt::exception("no border");
}
return d_->parent->borders.at(d_->border_id.get());
}
void style::border(const xlnt::border &new_border, bool applied, bool update)
{
d_->border_id = d_->parent->add_border(new_border);
}
xlnt::fill &style::fill()
{
const auto &self = *this;
return const_cast<class fill &>(self.fill());
}
const xlnt::fill &style::fill() const
{
if (!d_->fill_id)
{
throw xlnt::exception("no border");
}
return d_->parent->fills.at(d_->fill_id.get());
}
void style::fill(const xlnt::fill &new_fill, bool applied, bool update)
{
d_->fill_id = d_->parent->add_fill(new_fill);
d_->fill_applied = applied;
}
xlnt::font &style::font()
{
const auto &self = *this;
return const_cast<class font &>(self.font());
}
const xlnt::font &style::font() const
{
if (!d_->font_id)
{
throw xlnt::exception("no border");
}
return d_->parent->fonts.at(d_->font_id.get());
}
void style::font(const xlnt::font &new_font, bool applied, bool update)
{
d_->font_id = d_->parent->add_font(new_font);
d_->font_applied = applied;
}
xlnt::number_format &style::number_format()
{
const auto &self = *this;
return const_cast<class number_format &>(self.number_format());
}
const xlnt::number_format &style::number_format() const
{
if (!d_->number_format_id)
{
throw xlnt::exception("no number format");
}
return d_->parent->number_formats.at(d_->number_format_id.get());
}
void style::number_format(const xlnt::number_format &new_number_format, bool applied, bool update)
{
auto copy = new_number_format;
if (!copy.has_id())
{
copy.set_id(d_->parent->next_custom_number_format_id());
d_->parent->number_formats[copy.get_id()] = copy;
}
d_->number_format_id = copy.get_id();
d_->number_format_applied = applied;
}
protection &style::protection()
{
return d_->parent->protections.at(d_->protection_id);
}
const protection &style::protection() const
{
return d_->parent->protections.at(d_->protection_id);
}
void style::protection(const xlnt::protection &new_protection, bool applied, bool update)
{
if (update)
{
d_->protection_id = 0;
}
}
bool style::alignment_applied() const
{
return d_->alignment_applied;
}
bool style::border_applied() const
{
return d_->border_applied;
}
bool style::fill_applied() const
{
return d_->fill_applied;
}
bool style::font_applied() const
{
return d_->font_applied;
}
bool style::number_format_applied() const
{
return d_->number_format_applied;
}
bool style::protection_applied() const
{
return d_->protection_applied;
}
XLNT_API bool operator==(const style &left, const style &right)
{
return left.d_ == right.d_;
}
} // namespace xlnt

View File

@ -165,7 +165,7 @@ workbook workbook::empty_excel()
auto &default_format = wb.create_format();
default_format.font(default_font, false);
default_format.border(default_border, false);
default_format.style("Normal");
default_format.d_->style.set("Normal");
wb.set_theme(theme());
@ -255,7 +255,7 @@ workbook workbook::empty_libre_office()
auto default_number_format = xlnt::number_format();
default_number_format.set_format_string("General");
default_number_format.set_id(164);
wb.d_->stylesheet_.number_formats.push_back(default_number_format);
wb.d_->stylesheet_.number_formats[default_number_format.get_id()] = default_number_format;
auto default_protection = xlnt::protection()
.locked(true)
@ -314,7 +314,7 @@ workbook workbook::empty_libre_office()
format.number_format(default_number_format, true);
format.alignment(default_alignment, true);
format.protection(default_protection, true);
format.style("Normal");
format.d_->style.set("Normal");
wb.d_->has_file_version_ = true;
wb.d_->file_version_.app_name = "Calc";
@ -993,10 +993,32 @@ std::vector<named_range> workbook::get_named_ranges() const
format &workbook::create_format()
{
register_stylesheet_in_manifest();
register_stylesheet_in_manifest();
return d_->stylesheet_.create_format();
}
format &workbook::create_format(format pattern)
{
register_stylesheet_in_manifest();
auto existing = d_->stylesheet_.find_format(pattern);
if (existing.first)
{
return d_->stylesheet_.get_format(existing.second);
}
auto &new_format = create_format();
new_format.alignment(pattern.alignment(), pattern.alignment_applied());
new_format.border(pattern.border(), pattern.border_applied());
new_format.fill(pattern.fill(), pattern.fill_applied());
new_format.font(pattern.font(), pattern.font_applied());
new_format.number_format(pattern.number_format(), pattern.number_format_applied());
new_format.protection(pattern.protection(), pattern.protection_applied());;
new_format.d_->style.set(pattern.d_->style.get());
return new_format;
}
bool workbook::has_style(const std::string &name) const
{
return d_->stylesheet_.has_style(name);

2
third-party/botan vendored

@ -1 +1 @@
Subproject commit dad94a550613733d8c75b2fbd8db47048dfdaf13
Subproject commit 73c2605f50e6192bf6cb560c51d32bc53b4c5597