diff --git a/xlnt/include/xlnt/cell/cell.hpp b/xlnt/include/xlnt/cell/cell.hpp
index e65eab0..9ff5fb9 100644
--- a/xlnt/include/xlnt/cell/cell.hpp
+++ b/xlnt/include/xlnt/cell/cell.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -47,6 +47,8 @@ class font;
class format;
class number_format;
class protection;
+class range;
+class relationship;
class style;
class workbook;
class worksheet;
@@ -238,6 +240,11 @@ class XLNT_API cell
///
column_t column() const;
+ ///
+ /// Returns the numeric index (A == 1) of the column of this cell.
+ ///
+ column_t::index_t column_index() const;
+
///
/// Returns the row of this cell.
///
@@ -251,25 +258,25 @@ class XLNT_API cell
// hyperlink
///
- /// Returns the URL of this cell's hyperlink.
+ /// Returns the relationship of this cell's hyperlink.
///
- std::string hyperlink() const;
-
- ///
- /// Adds a hyperlink to this cell pointing to the URL of the given value.
- ///
- void hyperlink(const std::string &url);
+ class hyperlink hyperlink() const;
///
/// Adds a hyperlink to this cell pointing to the URI of the given value and sets
/// the text value of the cell to the given parameter.
///
- void hyperlink(const std::string &url, const std::string &display);
+ void hyperlink(const std::string &url, const std::string &display = "");
///
/// Adds an internal hyperlink to this cell pointing to the given cell.
///
- void hyperlink(xlnt::cell target);
+ void hyperlink(xlnt::cell target, const std::string& display = "");
+
+ ///
+ /// Adds an internal hyperlink to this cell pointing to the given range.
+ ///
+ void hyperlink(xlnt::range target, const std::string& display = "");
///
/// Returns true if this cell has a hyperlink set.
@@ -601,9 +608,9 @@ class XLNT_API cell
bool operator==(const cell &comparand) const;
///
- /// Returns true if this cell is uninitialized.
+ /// Returns false if this cell the same cell as comparand (compared by reference).
///
- bool operator==(std::nullptr_t) const;
+ bool operator!=(const cell &comparand) const;
private:
friend class style;
@@ -639,6 +646,11 @@ class XLNT_API cell
///
XLNT_API bool operator==(std::nullptr_t, const cell &cell);
+///
+/// Returns true if this cell is uninitialized.
+///
+XLNT_API bool operator==(const cell &cell, std::nullptr_t);
+
///
/// Convenience function for writing cell to an ostream.
/// Uses cell::to_string() internally.
diff --git a/xlnt/include/xlnt/cell/cell_reference.hpp b/xlnt/include/xlnt/cell/cell_reference.hpp
index b9472f7..57fd54b 100644
--- a/xlnt/include/xlnt/cell/cell_reference.hpp
+++ b/xlnt/include/xlnt/cell/cell_reference.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/include/xlnt/cell/cell_type.hpp b/xlnt/include/xlnt/cell/cell_type.hpp
index cee0e48..dac6ad2 100644
--- a/xlnt/include/xlnt/cell/cell_type.hpp
+++ b/xlnt/include/xlnt/cell/cell_type.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/xlnt/include/xlnt/cell/comment.hpp b/xlnt/include/xlnt/cell/comment.hpp
index 9b3a7c8..124d22d 100644
--- a/xlnt/include/xlnt/cell/comment.hpp
+++ b/xlnt/include/xlnt/cell/comment.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/include/xlnt/cell/index_types.hpp b/xlnt/include/xlnt/cell/index_types.hpp
index 63dbd8a..129a5ee 100644
--- a/xlnt/include/xlnt/cell/index_types.hpp
+++ b/xlnt/include/xlnt/cell/index_types.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/include/xlnt/cell/rich_text.hpp b/xlnt/include/xlnt/cell/rich_text.hpp
index 3784958..31cb279 100644
--- a/xlnt/include/xlnt/cell/rich_text.hpp
+++ b/xlnt/include/xlnt/cell/rich_text.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2017 Thomas Fussell
+// Copyright (c) 2016-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -48,6 +48,11 @@ class XLNT_API rich_text
///
rich_text(const std::string &plain_text);
+ ///
+ /// Constructs a rich text object from other
+ ///
+ rich_text(const rich_text &other);
+
///
/// Constructs a rich text object with the given text and font.
///
@@ -67,7 +72,7 @@ class XLNT_API rich_text
/// Clears any runs in this text and adds a single run with default formatting and
/// the given string as its textual content.
///
- void plain_text(const std::string &s);
+ void plain_text(const std::string &s, bool preserve_space);
///
/// Combines the textual content of each text run in order and returns the result.
@@ -89,6 +94,11 @@ class XLNT_API rich_text
///
void add_run(const rich_text_run &t);
+ ///
+ /// Copies rich text object from other
+ ///
+ rich_text& operator=(const rich_text &rhs);
+
///
/// Returns true if the runs that make up this text are identical to those in rhs.
///
@@ -97,7 +107,7 @@ class XLNT_API rich_text
///
/// Returns true if the runs that make up this text are identical to those in rhs.
///
- bool operator!=(const rich_text &rhs) const;
+ bool operator!=(const rich_text &rhs) const;
///
/// Returns true if this text has a single unformatted run with text equal to rhs.
@@ -116,4 +126,20 @@ class XLNT_API rich_text
std::vector runs_;
};
+class XLNT_API rich_text_hash
+{
+public:
+ std::size_t operator()(const rich_text& k) const
+ {
+ std::size_t res = 0;
+
+ for (auto r : k.runs())
+ {
+ res ^= std::hash()(r.first);
+ }
+
+ return res;
+ }
+};
+
} // namespace xlnt
diff --git a/xlnt/include/xlnt/cell/rich_text_run.hpp b/xlnt/include/xlnt/cell/rich_text_run.hpp
index 432097e..dc31fe5 100644
--- a/xlnt/include/xlnt/cell/rich_text_run.hpp
+++ b/xlnt/include/xlnt/cell/rich_text_run.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2017 Thomas Fussell
+// Copyright (c) 2016-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -34,10 +34,11 @@ namespace xlnt {
///
/// Typedef a rich_text_run as a pair of string and optional font.
///
-struct rich_text_run
+struct XLNT_API rich_text_run
{
std::string first;
optional second;
+ bool preserve_space;
bool operator==(const rich_text_run &other) const;
diff --git a/xlnt/include/xlnt/packaging/manifest.hpp b/xlnt/include/xlnt/packaging/manifest.hpp
index 5aa2eae..03d19de 100644
--- a/xlnt/include/xlnt/packaging/manifest.hpp
+++ b/xlnt/include/xlnt/packaging/manifest.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -172,6 +172,8 @@ class XLNT_API manifest
///
void unregister_override_type(const path &part);
+ bool operator==(const manifest &other) const;
+
private:
///
/// Returns the lowest rId for the given part that hasn't already been registered.
diff --git a/xlnt/include/xlnt/packaging/relationship.hpp b/xlnt/include/xlnt/packaging/relationship.hpp
index 3b6c192..2dcbb4a 100644
--- a/xlnt/include/xlnt/packaging/relationship.hpp
+++ b/xlnt/include/xlnt/packaging/relationship.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -115,7 +115,7 @@ class XLNT_API relationship
///
/// Returns a string of the form rId# that identifies the relationship.
///
- std::string id() const;
+ const std::string& id() const;
///
/// Returns the type of this relationship.
@@ -130,12 +130,12 @@ class XLNT_API relationship
///
/// Returns the URI of the package part this relationship points to.
///
- uri source() const;
+ const uri &source() const;
///
/// Returns the URI of the package part this relationship points to.
///
- uri target() const;
+ const uri &target() const;
///
/// Returns true if and only if rhs is equal to this relationship.
diff --git a/xlnt/include/xlnt/packaging/uri.hpp b/xlnt/include/xlnt/packaging/uri.hpp
index d1e5ee9..66d6358 100644
--- a/xlnt/include/xlnt/packaging/uri.hpp
+++ b/xlnt/include/xlnt/packaging/uri.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -123,7 +123,7 @@ class XLNT_API uri
/// Returns the path of this URI.
/// E.g. the path of http://example.com/document is "/document"
///
- class path path() const;
+ const class path& path() const;
///
/// Returns true if this URI has a non-null query string section.
diff --git a/xlnt/include/xlnt/styles/alignment.hpp b/xlnt/include/xlnt/styles/alignment.hpp
index d2972bc..f8a777a 100644
--- a/xlnt/include/xlnt/styles/alignment.hpp
+++ b/xlnt/include/xlnt/styles/alignment.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/xlnt/include/xlnt/styles/border.hpp b/xlnt/include/xlnt/styles/border.hpp
index 1f54849..0c953aa 100644
--- a/xlnt/include/xlnt/styles/border.hpp
+++ b/xlnt/include/xlnt/styles/border.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/xlnt/include/xlnt/styles/color.hpp b/xlnt/include/xlnt/styles/color.hpp
index 2905b2e..2402145 100644
--- a/xlnt/include/xlnt/styles/color.hpp
+++ b/xlnt/include/xlnt/styles/color.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -101,7 +101,7 @@ class XLNT_API rgb_color
///
/// Constructs an RGB color from red, green, and blue values in the range 0 to 255
- /// plus an optional alpha which defaults to fully opaque.
+ /// plus an optional alpha which defaults to fully opaque.
///
rgb_color(std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a = 255);
@@ -116,17 +116,17 @@ class XLNT_API rgb_color
std::uint8_t red() const;
///
- /// Returns a byte representing the red component of this color
+ /// Returns a byte representing the red component of this color
///
std::uint8_t green() const;
///
- /// Returns a byte representing the blue component of this color
+ /// Returns a byte representing the blue component of this color
///
std::uint8_t blue() const;
///
- /// Returns a byte representing the alpha component of this color
+ /// Returns a byte representing the alpha component of this color
///
std::uint8_t alpha() const;
@@ -136,7 +136,7 @@ class XLNT_API rgb_color
std::array rgb() const;
///
- /// Returns the red, green, blue, and alpha components of this color separately in an array in that order.
+ /// Returns the red, green, blue, and alpha components of this color separately in an array in that order.
///
std::array rgba() const;
@@ -174,42 +174,42 @@ class XLNT_API color
static const color white();
///
- /// Returns the color \#ff0000
+ /// Returns the color \#ff0000
///
static const color red();
///
- /// Returns the color \#8b0000
+ /// Returns the color \#8b0000
///
static const color darkred();
///
- /// Returns the color \#00ff00
+ /// Returns the color \#00ff00
///
static const color blue();
///
- /// Returns the color \#008b00
+ /// Returns the color \#008b00
///
static const color darkblue();
///
- /// Returns the color \#0000ff
+ /// Returns the color \#0000ff
///
static const color green();
///
- /// Returns the color \#00008b
+ /// Returns the color \#00008b
///
static const color darkgreen();
///
- /// Returns the color \#ffff00
+ /// Returns the color \#ffff00
///
static const color yellow();
///
- /// Returns the color \#cccc00
+ /// Returns the color \#cccc00
///
static const color darkyellow();
@@ -249,22 +249,40 @@ class XLNT_API color
void auto_(bool value);
///
- /// Returns the internal indexed color representing this color. If this is not an RGB color,
- /// an invalid_attribute exception will be thrown.
+ /// Returns the internal indexed color representing this color. If this is not an RGB color,
+ /// an invalid_attribute exception will be thrown.
+ ///
+ const rgb_color& rgb() const;
+
+ ///
+ /// Returns the internal indexed color representing this color. If this is not an RGB color,
+ /// an invalid_attribute exception will be thrown.
///
- rgb_color rgb() const;
+ rgb_color &rgb();
///
/// Returns the internal indexed color representing this color. If this is not an indexed color,
- /// an invalid_attribute exception will be thrown.
+ /// an invalid_attribute exception will be thrown.
///
- indexed_color indexed() const;
+ const indexed_color& indexed() const;
///
- /// Returns the internal indexed color representing this color. If this is not a theme color,
- /// an invalid_attribute exception will be thrown.
+ /// Returns the internal indexed color representing this color. If this is not an indexed color,
+ /// an invalid_attribute exception will be thrown.
///
- theme_color theme() const;
+ indexed_color &indexed();
+
+ ///
+ /// Returns the internal indexed color representing this color. If this is not a theme color,
+ /// an invalid_attribute exception will be thrown.
+ ///
+ const theme_color& theme() const;
+
+ ///
+ /// Returns the internal indexed color representing this color. If this is not a theme color,
+ /// an invalid_attribute exception will be thrown.
+ ///
+ theme_color& theme();
///
/// Returns the tint of this color.
@@ -276,15 +294,15 @@ class XLNT_API color
///
void tint(double tint);
- ///
- /// Returns true if this color is equivalent to other
- ///
- bool operator==(const color &other) const;
+ ///
+ /// Returns true if this color is equivalent to other
+ ///
+ bool operator==(const color &other) const;
///
/// Returns true if this color is not equivalent to other
///
- bool operator!=(const color &other) const;
+ bool operator!=(const color &other) const;
private:
///
@@ -303,12 +321,12 @@ class XLNT_API color
rgb_color rgb_;
///
- /// The internal RGB color. Only valid when this color has a type of indexed
+ /// The internal RGB color. Only valid when this color has a type of indexed
///
indexed_color indexed_;
///
- /// The internal RGB color. Only valid when this color has a type of theme
+ /// The internal RGB color. Only valid when this color has a type of theme
///
theme_color theme_;
diff --git a/xlnt/include/xlnt/styles/conditional_format.hpp b/xlnt/include/xlnt/styles/conditional_format.hpp
index a43a6d4..0260b6b 100644
--- a/xlnt/include/xlnt/styles/conditional_format.hpp
+++ b/xlnt/include/xlnt/styles/conditional_format.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -53,6 +53,11 @@ class XLNT_API condition
static condition text_contains(const std::string &start);
static condition text_does_not_contain(const std::string &start);
+ bool operator==(const condition& rhs) const
+ {
+ return text_comparand_ == rhs.text_comparand_;
+ }
+
private:
friend class detail::xlsx_producer;
diff --git a/xlnt/include/xlnt/styles/fill.hpp b/xlnt/include/xlnt/styles/fill.hpp
index 0479ad4..d456fcf 100644
--- a/xlnt/include/xlnt/styles/fill.hpp
+++ b/xlnt/include/xlnt/styles/fill.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/xlnt/include/xlnt/styles/font.hpp b/xlnt/include/xlnt/styles/font.hpp
index 2cb9f42..195271e 100644
--- a/xlnt/include/xlnt/styles/font.hpp
+++ b/xlnt/include/xlnt/styles/font.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -68,12 +68,22 @@ class XLNT_API font
bool bold() const;
///
- /// Sets the bold state of the font to bold and returns a reference to the font.
+ /// Sets the vertical alignment of the font to subscript and returns a reference to the font.
+ ///
+ font &subscript(bool value);
+
+ ///
+ /// Returns true if this font has a vertical alignment of subscript.
///
- font &superscript(bool superscript);
+ bool subscript() const;
///
- /// Returns true if this font has a superscript applied.
+ /// Sets the vertical alignment of the font to superscript and returns a reference to the font.
+ ///
+ font &superscript(bool value);
+
+ ///
+ /// Returns true if this font has a vertical alignment of superscript.
///
bool superscript() const;
@@ -160,7 +170,7 @@ class XLNT_API font
///
/// Returns the name of the font face.
///
- std::string name() const;
+ const std::string& name() const;
///
/// Returns true if this font has a color applied.
@@ -222,7 +232,7 @@ class XLNT_API font
///
/// Returns the scheme of this font.
///
- std::string scheme() const;
+ const std::string& scheme() const;
///
/// Returns true if left is exactly equal to right.
@@ -232,7 +242,10 @@ class XLNT_API font
///
/// Returns true if left is not exactly equal to right.
///
- bool operator!=(const font &other) const;
+ bool operator!=(const font &other) const
+ {
+ return !operator==(other);
+ }
private:
friend class style;
diff --git a/xlnt/include/xlnt/styles/format.hpp b/xlnt/include/xlnt/styles/format.hpp
index 0a549cf..252f7cb 100644
--- a/xlnt/include/xlnt/styles/format.hpp
+++ b/xlnt/include/xlnt/styles/format.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -63,7 +63,7 @@ class XLNT_API format
/// to true, determines whether the alignment should be enabled for cells using
/// this format.
///
- format alignment(const xlnt::alignment &new_alignment, bool applied = true);
+ format alignment(const xlnt::alignment &new_alignment, optional applied = {});
///
/// Returns true if the alignment of this format should be applied to cells
@@ -81,7 +81,7 @@ class XLNT_API format
/// to true, determines whether the border should be enabled for cells using
/// this format.
///
- format border(const xlnt::border &new_border, bool applied = true);
+ format border(const xlnt::border &new_border, optional applied = {});
///
/// Returns true if the border set for this format should be applied to cells using the format.
@@ -98,7 +98,7 @@ class XLNT_API format
/// to true, determines whether the border should be enabled for cells using
/// this format.
///
- format fill(const xlnt::fill &new_fill, bool applied = true);
+ format fill(const xlnt::fill &new_fill, optional applied = {});
///
/// Returns true if the fill set for this format should be applied to cells using the format.
@@ -115,7 +115,7 @@ class XLNT_API format
/// to true, determines whether the font should be enabled for cells using
/// this format.
///
- format font(const xlnt::font &new_font, bool applied = true);
+ format font(const xlnt::font &new_font, optional applied = {});
///
/// Returns true if the font set for this format should be applied to cells using the format.
@@ -132,7 +132,7 @@ class XLNT_API format
/// to true, determines whether the number format should be enabled for cells using
/// this format.
///
- format number_format(const xlnt::number_format &new_number_format, bool applied = true);
+ format number_format(const xlnt::number_format &new_number_format, optional applied = {});
///
/// Returns true if the number_format set for this format should be applied to cells using the format.
@@ -154,7 +154,7 @@ class XLNT_API format
/// to true, determines whether the protection should be enabled for cells using
/// this format.
///
- format protection(const xlnt::protection &new_protection, bool applied = true);
+ format protection(const xlnt::protection &new_protection, optional applied = {});
///
/// Returns true if the pivot table interface is enabled for this format.
diff --git a/xlnt/include/xlnt/styles/number_format.hpp b/xlnt/include/xlnt/styles/number_format.hpp
index 8d0574a..b967665 100644
--- a/xlnt/include/xlnt/styles/number_format.hpp
+++ b/xlnt/include/xlnt/styles/number_format.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/xlnt/include/xlnt/styles/protection.hpp b/xlnt/include/xlnt/styles/protection.hpp
index 9b9d8f1..42a07a3 100644
--- a/xlnt/include/xlnt/styles/protection.hpp
+++ b/xlnt/include/xlnt/styles/protection.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/xlnt/include/xlnt/styles/style.hpp b/xlnt/include/xlnt/styles/style.hpp
index d75fcb7..4ba5725 100644
--- a/xlnt/include/xlnt/styles/style.hpp
+++ b/xlnt/include/xlnt/styles/style.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -123,7 +123,7 @@ class XLNT_API style
/// to true, determines whether the alignment should be enabled for cells using
/// this style.
///
- style alignment(const xlnt::alignment &new_alignment, bool applied = true);
+ style alignment(const xlnt::alignment &new_alignment, optional applied = {});
///
/// Returns the border of this style.
@@ -140,7 +140,7 @@ class XLNT_API style
/// to true, determines whether the border should be enabled for cells using
/// this style.
///
- style border(const xlnt::border &new_border, bool applied = true);
+ style border(const xlnt::border &new_border, optional applied = {});
///
/// Returns the fill of this style.
@@ -157,7 +157,7 @@ class XLNT_API style
/// to true, determines whether the border should be enabled for cells using
/// this style.
///
- style fill(const xlnt::fill &new_fill, bool applied = true);
+ style fill(const xlnt::fill &new_fill, optional applied = {});
///
/// Returns the font of this style.
@@ -174,7 +174,7 @@ class XLNT_API style
/// to true, determines whether the font should be enabled for cells using
/// this style.
///
- style font(const xlnt::font &new_font, bool applied = true);
+ style font(const xlnt::font &new_font, optional applied = {});
///
/// Returns the number_format of this style.
@@ -191,7 +191,7 @@ class XLNT_API style
/// to true, determines whether the number format should be enabled for cells using
/// this style.
///
- style number_format(const xlnt::number_format &new_number_format, bool applied = true);
+ style number_format(const xlnt::number_format &new_number_format, optional applied = {});
///
/// Returns the protection of this style.
@@ -208,7 +208,7 @@ class XLNT_API style
/// to true, determines whether the protection should be enabled for cells using
/// this style.
///
- style protection(const xlnt::protection &new_protection, bool applied = true);
+ style protection(const xlnt::protection &new_protection, optional applied = {});
///
/// Returns true if the pivot table interface is enabled for this style.
diff --git a/xlnt/include/xlnt/utils/calendar.hpp b/xlnt/include/xlnt/utils/calendar.hpp
index 88de229..ade6fab 100644
--- a/xlnt/include/xlnt/utils/calendar.hpp
+++ b/xlnt/include/xlnt/utils/calendar.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/include/xlnt/utils/date.hpp b/xlnt/include/xlnt/utils/date.hpp
index 73be2f6..8eb9d1a 100644
--- a/xlnt/include/xlnt/utils/date.hpp
+++ b/xlnt/include/xlnt/utils/date.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/include/xlnt/utils/datetime.hpp b/xlnt/include/xlnt/utils/datetime.hpp
index 24ca765..646b2bd 100644
--- a/xlnt/include/xlnt/utils/datetime.hpp
+++ b/xlnt/include/xlnt/utils/datetime.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/include/xlnt/utils/exceptions.hpp b/xlnt/include/xlnt/utils/exceptions.hpp
index 3b108e7..0618a0f 100644
--- a/xlnt/include/xlnt/utils/exceptions.hpp
+++ b/xlnt/include/xlnt/utils/exceptions.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -120,7 +120,7 @@ class XLNT_API missing_number_format : public exception
///
/// Default constructor.
///
- missing_number_format();
+ missing_number_format() = default;
///
/// Default copy constructor.
diff --git a/xlnt/include/xlnt/utils/optional.hpp b/xlnt/include/xlnt/utils/optional.hpp
index 655923d..8677f24 100644
--- a/xlnt/include/xlnt/utils/optional.hpp
+++ b/xlnt/include/xlnt/utils/optional.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2017 Thomas Fussell
+// Copyright (c) 2016-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -25,6 +25,7 @@
#include
#include
+#include
namespace xlnt {
@@ -34,39 +35,207 @@ namespace xlnt {
/// within the optional class.
///
template
-class XLNT_API optional
+class optional
{
+#if defined(_MSC_VER) && _MSC_VER <= 1900 // v14, visual studio 2015
+#define XLNT_NOEXCEPT_VALUE_COMPAT(...) (false)
+#else
+#define XLNT_NOEXCEPT_VALUE_COMPAT(...) (__VA_ARGS__)
+ using ctor_copy_T_noexcept = typename std::conditional{}, std::true_type, std::false_type>::type;
+ using ctor_move_T_noexcept = typename std::conditional{}, std::true_type, std::false_type>::type;
+ using copy_ctor_noexcept = ctor_copy_T_noexcept;
+ using move_ctor_noexcept = ctor_move_T_noexcept;
+ using set_copy_noexcept_t = typename std::conditional{} && std::is_nothrow_assignable{}, std::true_type, std::false_type>::type;
+ using set_move_noexcept_t = typename std::conditional{} && std::is_nothrow_move_assignable{}, std::true_type, std::false_type>::type;
+ using clear_noexcept_t = typename std::conditional{}, std::true_type, std::false_type>::type;
+#endif
+
public:
///
/// Default contructor. is_set() will be false initially.
///
- optional() : has_value_(false), value_(T())
+ optional() noexcept
+ : has_value_(false)
+ {
+ }
+
+ ///
+ /// Constructs this optional with a value.
+ /// noexcept if T copy ctor is noexcept
+ ///
+ optional(const T &value) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(ctor_copy_T_noexcept{}))
+ : has_value_(true)
{
+ new (&storage_) T(value);
}
///
/// Constructs this optional with a value.
+ /// noexcept if T move ctor is noexcept
+ ///
+ optional(T &&value) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(ctor_move_T_noexcept{}))
+ : has_value_(true)
+ {
+ new (&storage_) T(std::move(value));
+ }
+
+ ///
+ /// Copy constructs this optional from other
+ /// noexcept if T copy ctor is noexcept
+ ///
+ optional(const optional &other) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(copy_ctor_noexcept{}))
+ : has_value_(other.has_value_)
+ {
+ if (has_value_)
+ {
+ new (&storage_) T(other.value_ref());
+ }
+ }
+
+ ///
+ /// Move constructs this optional from other. Clears the value from other if set
+ /// noexcept if T move ctor is noexcept
///
- explicit optional(const T &value) : has_value_(true), value_(value)
+ optional(optional &&other) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(move_ctor_noexcept{}))
+ : has_value_(other.has_value_)
{
+ if (has_value_)
+ {
+ new (&storage_) T(std::move(other.value_ref()));
+ other.clear();
+ }
+ }
+
+ ///
+ /// Copy assignment of this optional from other
+ /// noexcept if set and clear are noexcept for T&
+ ///
+ optional &operator=(const optional &other) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(set_copy_noexcept_t{} && clear_noexcept_t{}))
+ {
+ if (other.has_value_)
+ {
+ set(other.value_ref());
+ }
+ else
+ {
+ clear();
+ }
+ return *this;
+ }
+
+ ///
+ /// Move assignment of this optional from other
+ /// noexcept if set and clear are noexcept for T&&
+ ///
+ optional &operator=(optional &&other) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(set_move_noexcept_t{} && clear_noexcept_t{}))
+ {
+ if (other.has_value_)
+ {
+ set(std::move(other.value_ref()));
+ other.clear();
+ }
+ else
+ {
+ clear();
+ }
+ return *this;
+ }
+
+ ///
+ /// Destructor cleans up the T instance if set
+ ///
+ ~optional() noexcept // note:: unconditional because msvc freaks out otherwise
+ {
+ clear();
}
///
/// Returns true if this object currently has a value set. This should
/// be called before accessing the value with optional::get().
///
- bool is_set() const
+ bool is_set() const noexcept
{
return has_value_;
}
///
- /// Sets the value to value.
+ /// Copies the value into the stored value
///
- void set(const T &value)
+ void set(const T &value) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(set_copy_noexcept_t{}))
{
- has_value_ = true;
- value_ = value;
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (has_value_)
+ {
+ value_ref() = value;
+ }
+ else
+ {
+ new (&storage_) T(value);
+ has_value_ = true;
+ }
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+ }
+
+ ///
+ /// Moves the value into the stored value
+ ///
+ void set(T &&value) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(set_move_noexcept_t{}))
+ {
+ // note seperate overload for two reasons (as opposed to perfect forwarding)
+ // 1. have to deal with implicit conversions internally with perfect forwarding
+ // 2. have to deal with the noexcept specfiers for all the different variations
+ // overload is just far and away the simpler solution
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (has_value_)
+ {
+ value_ref() = std::move(value);
+ }
+ else
+ {
+ new (&storage_) T(std::move(value));
+ has_value_ = true;
+ }
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+ }
+
+ ///
+ /// Assignment operator overload. Equivalent to setting the value using optional::set.
+ ///
+ optional &operator=(const T &rhs) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(set_copy_noexcept_t{}))
+ {
+ set(rhs);
+ return *this;
+ }
+
+ ///
+ /// Assignment operator overload. Equivalent to setting the value using optional::set.
+ ///
+ optional &operator=(T &&rhs) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(set_move_noexcept_t{}))
+ {
+ set(std::move(rhs));
+ return *this;
+ }
+
+ ///
+ /// After this is called, is_set() will return false until a new value is provided.
+ ///
+ void clear() noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(clear_noexcept_t{}))
+ {
+ if (has_value_)
+ {
+ reinterpret_cast(&storage_)->~T();
+ }
+ has_value_ = false;
}
///
@@ -80,7 +249,7 @@ class XLNT_API optional
throw invalid_attribute();
}
- return value_;
+ return value_ref();
}
///
@@ -94,44 +263,55 @@ class XLNT_API optional
throw invalid_attribute();
}
- return value_;
+ return value_ref();
}
///
- /// Resets the internal value using its default constructor. After this is
- /// called, is_set() will return false until a new value is provided.
+ /// Returns true if neither this nor other have a value
+ /// or both have a value and those values are equal according to
+ /// their equality operator.
///
- void clear()
+ bool operator==(const optional &other) const noexcept
{
- has_value_ = false;
- value_ = T();
+ if (has_value_ != other.has_value_)
+ {
+ return false;
+ }
+ if (!has_value_)
+ {
+ return true;
+ }
+ return value_ref() == other.value_ref();
}
///
- /// Assignment operator. Equivalent to setting the value using optional::set.
+ /// Returns false if neither this nor other have a value
+ /// or both have a value and those values are equal according to
+ /// their equality operator.
///
- optional &operator=(const T &rhs)
+ bool operator!=(const optional &other) const noexcept
{
- has_value_ = true;
- value_ = rhs;
+ return !operator==(other);
+ }
- return *this;
+private:
+ // helpers for getting a T out of storage
+ T &value_ref() noexcept
+ {
+ return *reinterpret_cast(&storage_);
}
- ///
- /// Returns true if neither this nor other have a value
- /// or both have a value and those values are equal according to
- /// their equality operator.
- ///
- bool operator==(const optional &other) const
+ const T &value_ref() const noexcept
{
- return has_value_ == other.has_value_
- && (!has_value_ || (has_value_ && value_ == other.value_));
+ return *reinterpret_cast(&storage_);
}
-private:
bool has_value_;
- T value_;
+ typename std::aligned_storage::type storage_;
};
+#ifdef XLNT_NOEXCEPT_VALUE_COMPAT
+#undef XLNT_NOEXCEPT_VALUE_COMPAT
+#endif
+
} // namespace xlnt
diff --git a/xlnt/include/xlnt/utils/path.hpp b/xlnt/include/xlnt/utils/path.hpp
index 4a392c1..ba16526 100644
--- a/xlnt/include/xlnt/utils/path.hpp
+++ b/xlnt/include/xlnt/utils/path.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -107,7 +107,7 @@ class XLNT_API path
/// Create a string representing this path separated by the provided
/// separator or the system-default separator if not provided.
///
- std::string string() const;
+ const std::string& string() const;
#ifdef _MSC_VER
///
@@ -176,6 +176,11 @@ class XLNT_API path
///
bool operator==(const path &other) const;
+ ///
+ /// Returns true if left path is equal to right path.
+ ///
+ bool operator!=(const path &other) const;
+
private:
///
/// Returns the character that separates directories in the path.
diff --git a/xlnt/include/xlnt/utils/scoped_enum_hash.hpp b/xlnt/include/xlnt/utils/scoped_enum_hash.hpp
index 6bac514..bf18432 100644
--- a/xlnt/include/xlnt/utils/scoped_enum_hash.hpp
+++ b/xlnt/include/xlnt/utils/scoped_enum_hash.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2017 Thomas Fussell
+// Copyright (c) 2016-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/include/xlnt/utils/time.hpp b/xlnt/include/xlnt/utils/time.hpp
index 36d6f42..247c28b 100644
--- a/xlnt/include/xlnt/utils/time.hpp
+++ b/xlnt/include/xlnt/utils/time.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/include/xlnt/utils/timedelta.hpp b/xlnt/include/xlnt/utils/timedelta.hpp
index 797e6d9..80aa7df 100644
--- a/xlnt/include/xlnt/utils/timedelta.hpp
+++ b/xlnt/include/xlnt/utils/timedelta.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/include/xlnt/utils/variant.hpp b/xlnt/include/xlnt/utils/variant.hpp
index 4fe6417..a7c4c30 100644
--- a/xlnt/include/xlnt/utils/variant.hpp
+++ b/xlnt/include/xlnt/utils/variant.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -162,6 +162,8 @@ class XLNT_API variant
///
type value_type() const;
+ bool operator==(const variant &rhs) const;
+
private:
type type_;
std::vector vector_value_;
diff --git a/xlnt/include/xlnt/workbook/calculation_properties.hpp b/xlnt/include/xlnt/workbook/calculation_properties.hpp
index b1f85c6..2202664 100644
--- a/xlnt/include/xlnt/workbook/calculation_properties.hpp
+++ b/xlnt/include/xlnt/workbook/calculation_properties.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2017 Thomas Fussell
+// Copyright (c) 2016-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -46,4 +46,10 @@ class XLNT_API calculation_properties
bool concurrent_calc;
};
+inline bool operator==(const calculation_properties &lhs, const calculation_properties &rhs)
+{
+ return lhs.calc_id == rhs.calc_id
+ && lhs.concurrent_calc == rhs.concurrent_calc;
+}
+
} // namespace xlnt
diff --git a/xlnt/include/xlnt/workbook/document_security.hpp b/xlnt/include/xlnt/workbook/document_security.hpp
index ac368a4..b6d5624 100644
--- a/xlnt/include/xlnt/workbook/document_security.hpp
+++ b/xlnt/include/xlnt/workbook/document_security.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -67,7 +67,7 @@ class XLNT_API document_security
///
/// Constructs a new document security object with default values.
///
- document_security();
+ document_security() = default;
///
/// If true, the workbook is locked for revisions.
diff --git a/xlnt/include/xlnt/workbook/external_book.hpp b/xlnt/include/xlnt/workbook/external_book.hpp
index e410954..061c421 100644
--- a/xlnt/include/xlnt/workbook/external_book.hpp
+++ b/xlnt/include/xlnt/workbook/external_book.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/xlnt/include/xlnt/workbook/metadata_property.hpp b/xlnt/include/xlnt/workbook/metadata_property.hpp
index 4a3dc22..c380079 100644
--- a/xlnt/include/xlnt/workbook/metadata_property.hpp
+++ b/xlnt/include/xlnt/workbook/metadata_property.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/include/xlnt/workbook/named_range.hpp b/xlnt/include/xlnt/workbook/named_range.hpp
index 8015668..bc90b20 100644
--- a/xlnt/include/xlnt/workbook/named_range.hpp
+++ b/xlnt/include/xlnt/workbook/named_range.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -76,6 +76,8 @@ class XLNT_API named_range
///
named_range &operator=(const named_range &other);
+ bool operator==(const named_range &rhs) const;
+
private:
///
/// The name of this named range.
diff --git a/xlnt/include/xlnt/workbook/streaming_workbook_reader.hpp b/xlnt/include/xlnt/workbook/streaming_workbook_reader.hpp
index 012746c..f5538fd 100644
--- a/xlnt/include/xlnt/workbook/streaming_workbook_reader.hpp
+++ b/xlnt/include/xlnt/workbook/streaming_workbook_reader.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/xlnt/include/xlnt/workbook/streaming_workbook_writer.hpp b/xlnt/include/xlnt/workbook/streaming_workbook_writer.hpp
index 7ed8f7f..8c7b1b1 100644
--- a/xlnt/include/xlnt/workbook/streaming_workbook_writer.hpp
+++ b/xlnt/include/xlnt/workbook/streaming_workbook_writer.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/xlnt/include/xlnt/workbook/theme.hpp b/xlnt/include/xlnt/workbook/theme.hpp
index 9d05873..96b0434 100644
--- a/xlnt/include/xlnt/workbook/theme.hpp
+++ b/xlnt/include/xlnt/workbook/theme.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -33,6 +33,11 @@ namespace xlnt {
///
class XLNT_API theme
{
+public:
+ bool operator==(const theme&) const
+ {
+ return true;
+ }
};
} // namespace xlnt
diff --git a/xlnt/include/xlnt/workbook/workbook.hpp b/xlnt/include/xlnt/workbook/workbook.hpp
index fd2dcc5..3ba2685 100644
--- a/xlnt/include/xlnt/workbook/workbook.hpp
+++ b/xlnt/include/xlnt/workbook/workbook.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -26,6 +26,7 @@
#include
#include
+#include
workbook();
+ ///
+ /// load the xlsx file at path
+ ///
+ workbook(const xlnt::path &file);
+
+ ///
+ /// load the encrpyted xlsx file at path
+ ///
+ workbook(const xlnt::path &file, const std::string& password);
+
+ ///
+ /// construct the workbook from any data stream where the data is the binary form of a workbook
+ ///
+ workbook(std::istream & data);
+
+ ///
+ /// construct the workbook from any data stream where the data is the binary form of an encrypted workbook
+ ///
+ workbook(std::istream &data, const std::string& password);
+
///
/// Move constructor. Constructs a workbook from existing workbook, other.
///
@@ -390,6 +412,16 @@ class XLNT_API workbook
///
void title(const std::string &title);
+ ///
+ /// Sets the absolute path of this workbook to path.
+ ///
+ void abs_path(const std::string &path);
+
+ ///
+ /// Sets the ArchID flags of this workbook to flags.
+ ///
+ void arch_id_flags(const std::size_t flags);
+
// Named Ranges
///
@@ -670,10 +702,10 @@ class XLNT_API workbook
///
class style create_style(const std::string &name);
- ///
- /// Creates a new style and returns it.
- ///
- class style create_builtin_style(std::size_t builtin_id);
+ ///
+ /// Creates a new style and returns it.
+ ///
+ class style create_builtin_style(std::size_t builtin_id);
///
/// Clear all named styles from cells and remove the styles from
@@ -682,6 +714,31 @@ class XLNT_API workbook
///
void clear_styles();
+ ///
+ /// Sets the default slicer style to the given value.
+ ///
+ void default_slicer_style(const std::string &value);
+
+ ///
+ /// Returns the default slicer style.
+ ///
+ std::string default_slicer_style() const;
+
+ ///
+ /// Enables knownFonts in stylesheet.
+ ///
+ void enable_known_fonts();
+
+ ///
+ /// Disables knownFonts in stylesheet.
+ ///
+ void disable_known_fonts();
+
+ ///
+ /// Returns true if knownFonts are enabled in the stylesheet.
+ ///
+ bool known_fonts_enabled() const;
+
// Manifest
///
@@ -704,17 +761,27 @@ class XLNT_API workbook
///
std::size_t add_shared_string(const rich_text &shared, bool allow_duplicates = false);
+ ///
+ /// Returns a reference to the shared string ordered by id
+ ///
+ const std::map &shared_strings_by_id() const;
+
+ ///
+ /// Returns a reference to the shared string related to the specified index
+ ///
+ const rich_text &shared_strings(std::size_t index) const;
+
///
/// Returns a reference to the shared strings being used by cells
/// in this workbook.
///
- std::vector &shared_strings();
+ std::unordered_map &shared_strings();
///
/// Returns a reference to the shared strings being used by cells
/// in this workbook.
///
- const std::vector &shared_strings() const;
+ const std::unordered_map &shared_strings() const;
// Thumbnail
@@ -839,6 +906,11 @@ class XLNT_API workbook
///
void swap(workbook &other);
+ ///
+ /// Sheet 1 should be rId1, sheet 2 should be rId2, etc.
+ ///
+ void reorder_relationships();
+
///
/// An opaque pointer to a structure that holds all of the data relating to this workbook.
///
diff --git a/xlnt/include/xlnt/workbook/workbook_view.hpp b/xlnt/include/xlnt/workbook/workbook_view.hpp
index d74c9a8..6d1efc6 100644
--- a/xlnt/include/xlnt/workbook/workbook_view.hpp
+++ b/xlnt/include/xlnt/workbook/workbook_view.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -102,4 +102,17 @@ class XLNT_API workbook_view
optional y_window;
};
+inline bool operator==(const workbook_view &lhs, const workbook_view &rhs)
+{
+ return lhs.active_tab == rhs.active_tab
+ && lhs.auto_filter_date_grouping == rhs.auto_filter_date_grouping
+ && lhs.first_sheet == rhs.first_sheet
+ && lhs.minimized == rhs.minimized
+ && lhs.show_horizontal_scroll == rhs.show_horizontal_scroll
+ && lhs.show_sheet_tabs == rhs.show_sheet_tabs
+ && lhs.show_vertical_scroll == rhs.show_vertical_scroll
+ && lhs.tab_ratio == rhs.tab_ratio
+ && lhs.visible == rhs.visible;
+}
+
} // namespace xlnt
diff --git a/xlnt/include/xlnt/workbook/worksheet_iterator.hpp b/xlnt/include/xlnt/workbook/worksheet_iterator.hpp
index f73348e..3e0165f 100644
--- a/xlnt/include/xlnt/workbook/worksheet_iterator.hpp
+++ b/xlnt/include/xlnt/workbook/worksheet_iterator.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -37,18 +37,22 @@ class worksheet;
// because one needs to point at a const workbook and the other needs
// to point at a non-const workbook stored as a member variable, respectively.
-///
-/// Alias the parent class of this iterator to increase clarity.
-///
-using ws_iter_type = std::iterator;
///
/// An iterator which is used to iterate over the worksheets in a workbook.
///
-class XLNT_API worksheet_iterator : public ws_iter_type
+class XLNT_API worksheet_iterator
{
public:
+ ///
+ /// iterator tags required for use with standard algorithms and adapters
+ ///
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = worksheet;
+ using difference_type = std::ptrdiff_t;
+ using pointer = worksheet *;
+ using reference = worksheet; // intentionally value
+
///
/// Constructs a worksheet iterator from a workbook and sheet index.
///
@@ -57,19 +61,41 @@ class XLNT_API worksheet_iterator : public ws_iter_type
///
/// Copy constructs a worksheet iterator from another iterator.
///
- worksheet_iterator(const worksheet_iterator &);
+ worksheet_iterator(const worksheet_iterator &) = default;
+
+ ///
+ /// Copy assigns the iterator so that it points to the same worksheet in the same workbook.
+ ///
+ worksheet_iterator &operator=(const worksheet_iterator &) = default;
+
+ ///
+ /// Move constructs a worksheet iterator from a temporary iterator.
+ ///
+ worksheet_iterator(worksheet_iterator &&) = default;
+
+ ///
+ /// Move assign the iterator from a temporary iterator
+ ///
+ worksheet_iterator &operator=(worksheet_iterator &&) = default;
+
+ ///
+ /// Default destructor
+ ///
+ ~worksheet_iterator() = default;
///
- /// Assigns the iterator so that it points to the same worksheet in the same workbook.
+ /// Dereferences the iterator to return the worksheet it is pointing to.
+ /// If the iterator points to one-past-the-end of the workbook, an invalid_parameter
+ /// exception will be thrown.
///
- worksheet_iterator &operator=(const worksheet_iterator &);
+ reference operator*();
///
/// Dereferences the iterator to return the worksheet it is pointing to.
/// If the iterator points to one-past-the-end of the workbook, an invalid_parameter
/// exception will be thrown.
///
- worksheet operator*();
+ const reference operator*() const;
///
/// Returns true if this iterator points to the same worksheet as comparand.
@@ -93,11 +119,23 @@ class XLNT_API worksheet_iterator : public ws_iter_type
///
worksheet_iterator &operator++();
+ ///
+ /// Post-decrement the iterator's internal workseet index. Returns a copy of the
+ /// iterator as it was before being incremented.
+ ///
+ worksheet_iterator operator--(int);
+
+ ///
+ /// Pre-decrement the iterator's internal workseet index. Returns a refernce
+ /// to the same iterator.
+ ///
+ worksheet_iterator &operator--();
+
private:
///
/// The target workbook of this iterator.
///
- workbook &wb_;
+ workbook *wb_;
///
/// The index of the worksheet in wb_ this iterator is currently pointing to.
@@ -106,18 +144,21 @@ class XLNT_API worksheet_iterator : public ws_iter_type
};
-///
-/// Alias the parent class of this iterator to increase clarity.
-///
-using c_ws_iter_type = std::iterator;
-
///
/// An iterator which is used to iterate over the worksheets in a const workbook.
///
-class XLNT_API const_worksheet_iterator : public c_ws_iter_type
+class XLNT_API const_worksheet_iterator
{
public:
+ ///
+ /// iterator tags required for use with standard algorithms and adapters
+ ///
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = const worksheet;
+ using difference_type = std::ptrdiff_t;
+ using pointer = const worksheet *;
+ using reference = const worksheet; // intentionally value
+
///
/// Constructs a worksheet iterator from a workbook and sheet index.
///
@@ -126,19 +167,34 @@ class XLNT_API const_worksheet_iterator : public c_ws_iter_type
///
/// Copy constructs a worksheet iterator from another iterator.
///
- const_worksheet_iterator(const const_worksheet_iterator &);
+ const_worksheet_iterator(const const_worksheet_iterator &) = default;
+
+ ///
+ /// Copy assigns the iterator so that it points to the same worksheet in the same workbook.
+ ///
+ const_worksheet_iterator &operator=(const const_worksheet_iterator &) = default;
///
- /// Assigns the iterator so that it points to the same worksheet in the same workbook.
+ /// Move constructs a worksheet iterator from a temporary iterator.
///
- const_worksheet_iterator &operator=(const const_worksheet_iterator &);
+ const_worksheet_iterator(const_worksheet_iterator &&) = default;
+
+ ///
+ /// Move assigns the iterator from a temporary iterator
+ ///
+ const_worksheet_iterator &operator=(const_worksheet_iterator &&) = default;
+
+ ///
+ /// Default destructor
+ ///
+ ~const_worksheet_iterator() = default;
///
/// Dereferences the iterator to return the worksheet it is pointing to.
/// If the iterator points to one-past-the-end of the workbook, an invalid_parameter
/// exception will be thrown.
///
- const worksheet operator*();
+ const reference operator*() const;
///
/// Returns true if this iterator points to the same worksheet as comparand.
@@ -162,11 +218,23 @@ class XLNT_API const_worksheet_iterator : public c_ws_iter_type
///
const_worksheet_iterator &operator++();
+ ///
+ /// Post-decrement the iterator's internal workseet index. Returns a copy of the
+ /// iterator as it was before being incremented.
+ ///
+ const_worksheet_iterator operator--(int);
+
+ ///
+ /// Pre-decrement the iterator's internal workseet index. Returns a refernce
+ /// to the same iterator.
+ ///
+ const_worksheet_iterator &operator--();
+
private:
///
/// The target workbook of this iterator.
///
- const workbook &wb_;
+ const workbook *wb_;
///
/// The index of the worksheet in wb_ this iterator is currently pointing to.
diff --git a/xlnt/include/xlnt/worksheet/cell_iterator.hpp b/xlnt/include/xlnt/worksheet/cell_iterator.hpp
index 71d6f94..415dee6 100644
--- a/xlnt/include/xlnt/worksheet/cell_iterator.hpp
+++ b/xlnt/include/xlnt/worksheet/cell_iterator.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -40,18 +40,21 @@ class cell;
class cell_reference;
class range_reference;
-///
-/// Alias the parent class of this iterator to increase clarity.
-///
-using c_iter_type = std::iterator;
-
///
/// A cell iterator iterates over a 1D range by row or by column.
///
-class XLNT_API cell_iterator : public c_iter_type
+class XLNT_API cell_iterator
{
public:
+ ///
+ /// iterator tags required for use with standard algorithms and adapters
+ ///
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = cell;
+ using difference_type = std::ptrdiff_t;
+ using pointer = cell *;
+ using reference = cell; // intentionally value
+
///
/// Constructs a cell_iterator from a worksheet, range, and iteration settings.
///
@@ -61,17 +64,38 @@ class XLNT_API cell_iterator : public c_iter_type
///
/// Constructs a cell_iterator as a copy of an existing cell_iterator.
///
- cell_iterator(const cell_iterator &other);
+ cell_iterator(const cell_iterator &) = default;
///
/// Assigns this iterator to match the data in rhs.
///
- cell_iterator &operator=(const cell_iterator &rhs) = default;
+ cell_iterator &operator=(const cell_iterator &) = default;
+
+ ///
+ /// Constructs a cell_iterator by moving from a cell_iterator temporary
+ ///
+ cell_iterator(cell_iterator &&) = default;
+
+ ///
+ /// Assigns this iterator to from a cell_iterator temporary
+ ///
+ cell_iterator &operator=(cell_iterator &&) = default;
+
+ ///
+ /// destructor for const_cell_iterator
+ ///
+ ~cell_iterator() = default;
///
/// Dereferences this iterator to return the cell it points to.
///
- cell operator*();
+ reference operator*();
+
+ ///
+ /// Dereferences this iterator to return the cell it points to.
+ ///
+ const reference operator*() const;
+
///
/// Returns true if this iterator is equivalent to other.
@@ -135,7 +159,7 @@ class XLNT_API cell_iterator : public c_iter_type
/// If true, cells that don't exist in the worksheet will be skipped during iteration.
///
bool skip_null_;
-
+
///
/// If true, when on the last column, the cursor will continue to the next row
/// (and vice versa when iterating in column-major order) until reaching the
@@ -144,18 +168,21 @@ class XLNT_API cell_iterator : public c_iter_type
bool wrap_;
};
-///
-/// Alias the parent class of this iterator to increase clarity.
-///
-using cc_iter_type = std::iterator;
-
///
/// A cell iterator iterates over a 1D range by row or by column.
///
-class XLNT_API const_cell_iterator : public cc_iter_type
+class XLNT_API const_cell_iterator
{
public:
+ ///
+ /// iterator tags required for use with standard algorithms and adapters
+ ///
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = const cell;
+ using difference_type = std::ptrdiff_t;
+ using pointer = const cell *;
+ using reference = const cell; // intentionally value
+
///
/// Constructs a cell_iterator from a worksheet, range, and iteration settings.
///
@@ -163,19 +190,34 @@ class XLNT_API const_cell_iterator : public cc_iter_type
const range_reference &limits, major_order order, bool skip_null, bool wrap);
///
- /// Constructs a cell_iterator as a copy of an existing cell_iterator.
+ /// Constructs a const_cell_iterator as a copy of an existing cell_iterator.
///
- const_cell_iterator(const const_cell_iterator &other);
+ const_cell_iterator(const const_cell_iterator &) = default;
///
/// Assigns this iterator to match the data in rhs.
///
const_cell_iterator &operator=(const const_cell_iterator &) = default;
+ ///
+ /// Constructs a const_cell_iterator by moving from a const_cell_iterator temporary
+ ///
+ const_cell_iterator(const_cell_iterator &&) = default;
+
+ ///
+ /// Assigns this iterator to from a const_cell_iterator temporary
+ ///
+ const_cell_iterator &operator=(const_cell_iterator &&) = default;
+
+ ///
+ /// destructor for const_cell_iterator
+ ///
+ ~const_cell_iterator() = default;
+
///
/// Dereferences this iterator to return the cell it points to.
///
- const cell operator*() const;
+ const reference operator*() const;
///
/// Returns true if this iterator is equivalent to other.
diff --git a/xlnt/include/xlnt/worksheet/cell_vector.hpp b/xlnt/include/xlnt/worksheet/cell_vector.hpp
index 33c741c..cb83924 100644
--- a/xlnt/include/xlnt/worksheet/cell_vector.hpp
+++ b/xlnt/include/xlnt/worksheet/cell_vector.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/include/xlnt/worksheet/column_properties.hpp b/xlnt/include/xlnt/worksheet/column_properties.hpp
index 5619c02..3254993 100644
--- a/xlnt/include/xlnt/worksheet/column_properties.hpp
+++ b/xlnt/include/xlnt/worksheet/column_properties.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -51,10 +51,25 @@ class XLNT_API column_properties
///
optional style;
+ ///
+ /// Is this column sized to fit its content as best it can
+ /// serialise if true
+ ///
+ bool best_fit = false;
+
///
/// If true, this column will be hidden
///
bool hidden = false;
};
+inline bool operator==(const column_properties &lhs, const column_properties &rhs)
+{
+ return lhs.width == rhs.width
+ && lhs.custom_width == rhs.custom_width
+ && lhs.style == rhs.style
+ && lhs.best_fit == rhs.best_fit
+ && lhs.hidden == rhs.hidden;
+}
+
} // namespace xlnt
diff --git a/xlnt/include/xlnt/worksheet/header_footer.hpp b/xlnt/include/xlnt/worksheet/header_footer.hpp
index bb139af..3b70b1f 100644
--- a/xlnt/include/xlnt/worksheet/header_footer.hpp
+++ b/xlnt/include/xlnt/worksheet/header_footer.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -312,6 +312,8 @@ class XLNT_API header_footer
///
rich_text even_footer(location where) const;
+ bool operator==(const header_footer &rhs) const;
+
private:
bool align_with_margins_ = false;
bool different_odd_even_ = false;
diff --git a/xlnt/include/xlnt/worksheet/major_order.hpp b/xlnt/include/xlnt/worksheet/major_order.hpp
index 30b62cd..46f0a20 100644
--- a/xlnt/include/xlnt/worksheet/major_order.hpp
+++ b/xlnt/include/xlnt/worksheet/major_order.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/include/xlnt/worksheet/page_margins.hpp b/xlnt/include/xlnt/worksheet/page_margins.hpp
index 23b426f..7f38f8b 100644
--- a/xlnt/include/xlnt/worksheet/page_margins.hpp
+++ b/xlnt/include/xlnt/worksheet/page_margins.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -99,6 +99,8 @@ class XLNT_API page_margins
///
void footer(double footer);
+ bool operator==(const page_margins &rhs) const;
+
private:
///
/// The top margin
diff --git a/xlnt/include/xlnt/worksheet/page_setup.hpp b/xlnt/include/xlnt/worksheet/page_setup.hpp
index ae398bf..03d6a01 100644
--- a/xlnt/include/xlnt/worksheet/page_setup.hpp
+++ b/xlnt/include/xlnt/worksheet/page_setup.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -25,6 +25,7 @@
#pragma once
#include
+#include
namespace xlnt {
@@ -33,6 +34,7 @@ namespace xlnt {
///
enum class XLNT_API orientation
{
+ default_orientation,
portrait,
landscape
};
@@ -117,16 +119,6 @@ struct XLNT_API page_setup
///
void paper_size(xlnt::paper_size paper_size);
- ///
- /// Returns the orientation of the worksheet using this page setup.
- ///
- xlnt::orientation orientation() const;
-
- ///
- /// Sets the orientation of the page.
- ///
- void orientation(xlnt::orientation orientation);
-
///
/// Returns true if this worksheet should be scaled to fit on a single page during printing.
///
@@ -158,36 +150,29 @@ struct XLNT_API page_setup
void fit_to_width(bool fit_to_width);
///
- /// Sets whether the worksheet should be centered horizontall on the page if it takes
- /// up less than a full page.
+ /// Sets the factor by which the page should be scaled during printing.
///
- void horizontal_centered(bool horizontal_centered);
+ void scale(double scale);
///
- /// Returns whether horizontal centering has been enabled.
+ /// Returns the factor by which the page should be scaled during printing.
///
- bool horizontal_centered() const;
+ double scale() const;
///
- /// Sets whether the worksheet should be vertically centered on the page if it takes
- /// up less than a full page.
+ /// The orientation
///
- void vertical_centered(bool vertical_centered);
-
+ xlnt::optional orientation_;
///
- /// Returns whether vertical centering has been enabled.
+ /// The horizontal dpi
///
- bool vertical_centered() const;
-
+ xlnt::optional horizontal_dpi_;
///
- /// Sets the factor by which the page should be scaled during printing.
+ /// The vertical dpi
///
- void scale(double scale);
+ xlnt::optional vertical_dpi_;
- ///
- /// Returns the factor by which the page should be scaled during printing.
- ///
- double scale() const;
+ bool operator==(const page_setup &rhs) const;
private:
///
@@ -205,11 +190,6 @@ struct XLNT_API page_setup
///
xlnt::paper_size paper_size_;
- ///
- /// The orientation
- ///
- xlnt::orientation orientation_;
-
///
/// Whether or not to fit to page
///
@@ -225,20 +205,10 @@ struct XLNT_API page_setup
///
bool fit_to_width_;
- ///
- /// Whether or not to center the content horizontally
- ///
- bool horizontal_centered_;
-
- ///
- /// Whether or not to center the conent vertically
- ///
- bool vertical_centered_;
-
///
/// The amount to scale the worksheet
///
double scale_;
};
-} // namespace xlnt
+} // namespace xlnt
\ No newline at end of file
diff --git a/xlnt/include/xlnt/worksheet/pane.hpp b/xlnt/include/xlnt/worksheet/pane.hpp
index 7ed8d17..e8bb3c7 100644
--- a/xlnt/include/xlnt/worksheet/pane.hpp
+++ b/xlnt/include/xlnt/worksheet/pane.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/xlnt/include/xlnt/worksheet/range.hpp b/xlnt/include/xlnt/worksheet/range.hpp
index 6c5272c..02b88a1 100644
--- a/xlnt/include/xlnt/worksheet/range.hpp
+++ b/xlnt/include/xlnt/worksheet/range.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -117,6 +117,11 @@ class XLNT_API range
///
const class cell cell(const cell_reference &ref) const;
+ ///
+ /// The worksheet this range targets
+ ///
+ const worksheet & target_worksheet() const;
+
///
/// Returns the reference defining the bounds of this range.
///
@@ -285,11 +290,11 @@ class XLNT_API range
///
bool operator!=(const range &comparand) const;
-private:
+ private:
///
/// The worksheet this range is within
///
- worksheet ws_;
+ class worksheet ws_;
///
/// The reference of this range
diff --git a/xlnt/include/xlnt/worksheet/range_iterator.hpp b/xlnt/include/xlnt/worksheet/range_iterator.hpp
index 1b47a51..c6f4397 100644
--- a/xlnt/include/xlnt/worksheet/range_iterator.hpp
+++ b/xlnt/include/xlnt/worksheet/range_iterator.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -35,19 +35,22 @@ namespace xlnt {
class cell_vector;
-///
-/// Alias the parent class of this iterator to increase clarity.
-///
-using r_iter_type = std::iterator;
-
///
/// An iterator used by worksheet and range for traversing
/// a 2D grid of cells by row/column then across that row/column.
///
-class XLNT_API range_iterator : public r_iter_type
+class XLNT_API range_iterator
{
public:
+ ///
+ /// iterator tags required for use with standard algorithms and adapters
+ ///
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = cell_vector;
+ using difference_type = std::ptrdiff_t;
+ using pointer = cell_vector *;
+ using reference = cell_vector; // intentionally value
+
///
/// Constructs a range iterator on a worksheet, cell pointing to the current
/// row or column, range bounds, an order, and whether or not to skip null column/rows.
@@ -56,19 +59,39 @@ class XLNT_API range_iterator : public r_iter_type
const range_reference &bounds, major_order order, bool skip_null);
///
- /// Copy constructor.
+ /// Default copy constructor.
+ ///
+ range_iterator(const range_iterator &) = default;
+
+ ///
+ /// Default assignment operator.
+ ///
+ range_iterator &operator=(const range_iterator &) = default;
+
+ ///
+ /// Default move constructor.
+ ///
+ range_iterator(range_iterator &&) = default;
+
+ ///
+ /// Default move assignment operator.
///
- range_iterator(const range_iterator &other);
+ range_iterator &operator=(range_iterator &&) = default;
+
+ ///
+ /// Default destructor
+ ///
+ ~range_iterator() = default;
///
/// Dereference the iterator to return a column or row.
///
- cell_vector operator*() const;
+ reference operator*();
///
- /// Default assignment operator.
+ /// Dereference the iterator to return a column or row.
///
- range_iterator &operator=(const range_iterator &) = default;
+ const reference operator*() const;
///
/// Returns true if this iterator is equivalent to other.
@@ -127,19 +150,22 @@ class XLNT_API range_iterator : public r_iter_type
bool skip_null_;
};
-///
-/// Alias the parent class of this iterator to increase clarity.
-///
-using cr_iter_type = std::iterator;
-
///
/// A const version of range_iterator which does not allow modification
/// to the dereferenced cell_vector.
///
-class XLNT_API const_range_iterator : public cr_iter_type
+class XLNT_API const_range_iterator
{
public:
+ ///
+ /// this iterator meets the interface requirements of bidirection_iterator
+ ///
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = const cell_vector;
+ using difference_type = std::ptrdiff_t;
+ using pointer = const cell_vector *;
+ using reference = const cell_vector; // intentionally value
+
///
/// Constructs a range iterator on a worksheet, cell pointing to the current
/// row or column, range bounds, an order, and whether or not to skip null column/rows.
@@ -148,19 +174,34 @@ class XLNT_API const_range_iterator : public cr_iter_type
const range_reference &bounds, major_order order, bool skip_null);
///
- /// Copy constructor.
+ /// Default copy constructor.
///
- const_range_iterator(const const_range_iterator &other);
+ const_range_iterator(const const_range_iterator &) = default;
///
- /// Dereferennce the iterator to return the current column/row.
+ /// Default assignment operator.
///
- const cell_vector operator*() const;
+ const_range_iterator &operator=(const const_range_iterator &) = default;
///
- /// Default assignment operator.
+ /// Default move constructor.
///
- const_range_iterator &operator=(const const_range_iterator &) = default;
+ const_range_iterator(const_range_iterator &&) = default;
+
+ ///
+ /// Default move assignment operator.
+ ///
+ const_range_iterator &operator=(const_range_iterator &&) = default;
+
+ ///
+ /// Default destructor
+ ///
+ ~const_range_iterator() = default;
+
+ ///
+ /// Dereferennce the iterator to return the current column/row.
+ ///
+ const reference operator*() const;
///
/// Returns true if this iterator is equivalent to other.
diff --git a/xlnt/include/xlnt/worksheet/range_reference.hpp b/xlnt/include/xlnt/worksheet/range_reference.hpp
index 44f6b76..93643f6 100644
--- a/xlnt/include/xlnt/worksheet/range_reference.hpp
+++ b/xlnt/include/xlnt/worksheet/range_reference.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -56,12 +56,7 @@ class XLNT_API range_reference
/// top_left:bottom_right.
///
explicit range_reference(const char *range_string);
-
- ///
- /// Constructs a range reference from a pair of cell references.
- ///
- explicit range_reference(const std::pair &reference_pair);
-
+
///
/// Constructs a range reference from cell references indicating top
/// left and bottom right coordinates of the range.
@@ -74,6 +69,8 @@ class XLNT_API range_reference
range_reference(column_t column_index_start, row_t row_index_start,
column_t column_index_end, row_t row_index_end);
+ range_reference(const range_reference &ref);
+
///
/// Returns true if the range has a width and height of 1 cell.
///
@@ -154,6 +151,11 @@ class XLNT_API range_reference
///
bool operator!=(const char *reference_string) const;
+ ///
+ /// Assigns the extents of the provided range to this range.
+ ///
+ range_reference &operator=(const range_reference &ref);
+
private:
///
/// The top left cell in the range
diff --git a/xlnt/include/xlnt/worksheet/row_properties.hpp b/xlnt/include/xlnt/worksheet/row_properties.hpp
index 911492e..d78c431 100644
--- a/xlnt/include/xlnt/worksheet/row_properties.hpp
+++ b/xlnt/include/xlnt/worksheet/row_properties.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -35,10 +35,15 @@ class XLNT_API row_properties
{
public:
///
- /// Optional height
+ /// Row height
///
optional height;
+ ///
+ /// Distance in pixels from the bottom of the cell to the baseline of the cell content
+ ///
+ optional dy_descent;
+
///
/// Whether or not the height is different from the default
///
@@ -49,10 +54,25 @@ class XLNT_API row_properties
///
bool hidden = false;
+ ///
+ /// True if row style should be applied
+ ///
+ optional custom_format;
+
///
/// The index to the style used by all cells in this row
///
optional style;
};
+inline bool operator==(const row_properties &lhs, const row_properties &rhs)
+{
+ return lhs.height == rhs.height
+ && lhs.dy_descent == rhs.dy_descent
+ && lhs.custom_height == rhs.custom_height
+ && lhs.hidden == rhs.hidden
+ && lhs.custom_format == rhs.custom_format
+ && lhs.style == rhs.style;
+}
+
} // namespace xlnt
diff --git a/xlnt/include/xlnt/worksheet/selection.hpp b/xlnt/include/xlnt/worksheet/selection.hpp
index e467c99..f88519d 100644
--- a/xlnt/include/xlnt/worksheet/selection.hpp
+++ b/xlnt/include/xlnt/worksheet/selection.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -36,6 +36,27 @@ namespace xlnt {
class XLNT_API selection
{
public:
+ ///
+ /// default ctor
+ ///
+ explicit selection() = default;
+
+ ///
+ /// ctor when no range selected
+ /// sqref == active_cell
+ ///
+ explicit selection(pane_corner quadrant, cell_reference active_cell)
+ : active_cell_(active_cell), sqref_(range_reference(active_cell, active_cell)), pane_(quadrant)
+ {}
+
+ ///
+ /// ctor with selected range
+ /// sqref must contain active_cell
+ ///
+ explicit selection(pane_corner quadrant, cell_reference active_cell, range_reference selected)
+ : active_cell_(active_cell), sqref_(selected), pane_(quadrant)
+ {}
+
///
/// Returns true if this selection has a defined active cell.
///
@@ -60,12 +81,36 @@ class XLNT_API selection
active_cell_ = ref;
}
+ ///
+ /// Returns true if this selection has a defined sqref.
+ ///
+ bool has_sqref() const
+ {
+ return sqref_.is_set();
+ }
+
///
/// Returns the range encompassed by this selection.
///
range_reference sqref() const
{
- return sqref_;
+ return sqref_.get();
+ }
+
+ ///
+ /// Sets the range encompassed by this selection.
+ ///
+ void sqref(const range_reference &ref)
+ {
+ sqref_ = ref;
+ }
+
+ ///
+ /// Sets the range encompassed by this selection.
+ ///
+ void sqref(const std::string &ref)
+ {
+ sqref(range_reference(ref));
}
///
@@ -97,17 +142,18 @@ class XLNT_API selection
private:
///
- /// The active cell
+ /// The last selected cell in the selection
///
optional active_cell_;
///
- /// The range
+ /// The last selected block in the selection
+ /// contains active_cell_, normally == to active_cell_
///
- range_reference sqref_;
+ optional sqref_;
///
- /// The quadrant
+ /// The corner of the worksheet that this selection extends to
///
pane_corner pane_;
};
diff --git a/xlnt/include/xlnt/worksheet/sheet_protection.hpp b/xlnt/include/xlnt/worksheet/sheet_protection.hpp
index 67d8e50..e3e783e 100644
--- a/xlnt/include/xlnt/worksheet/sheet_protection.hpp
+++ b/xlnt/include/xlnt/worksheet/sheet_protection.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/xlnt/include/xlnt/worksheet/sheet_view.hpp b/xlnt/include/xlnt/worksheet/sheet_view.hpp
index 0c91268..2c04bd9 100644
--- a/xlnt/include/xlnt/worksheet/sheet_view.hpp
+++ b/xlnt/include/xlnt/worksheet/sheet_view.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -192,6 +192,30 @@ class XLNT_API sheet_view
return type_;
}
+ ///
+ /// has a top left cell?
+ ///
+ bool has_top_left_cell() const
+ {
+ return top_left_cell_.is_set();
+ }
+
+ ///
+ /// Sets the top left cell of this view.
+ ///
+ void top_left_cell(const cell_reference& ref)
+ {
+ top_left_cell_.set(ref);
+ }
+
+ ///
+ /// Returns the top left cell of this view.
+ ///
+ cell_reference top_left_cell() const
+ {
+ return top_left_cell_.get();
+ }
+
///
/// Returns true if this view is equal to rhs based on its id, grid lines setting,
/// default grid color, pane, and selections.
@@ -202,7 +226,8 @@ class XLNT_API sheet_view
&& show_grid_lines_ == rhs.show_grid_lines_
&& default_grid_color_ == rhs.default_grid_color_
&& pane_ == rhs.pane_
- && selections_ == rhs.selections_;
+ && selections_ == rhs.selections_
+ && top_left_cell_ == rhs.top_left_cell_;
}
private:
@@ -231,6 +256,11 @@ class XLNT_API sheet_view
///
optional pane_;
+ ///
+ /// The top left cell
+ ///
+ optional top_left_cell_;
+
///
/// The collection of selections
///
diff --git a/xlnt/include/xlnt/worksheet/worksheet.hpp b/xlnt/include/xlnt/worksheet/worksheet.hpp
index 018d8fc..ed46099 100644
--- a/xlnt/include/xlnt/worksheet/worksheet.hpp
+++ b/xlnt/include/xlnt/worksheet/worksheet.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -54,7 +54,9 @@ class range_iterator;
class range_reference;
class relationship;
class row_properties;
+class sheet_format_properties;
class workbook;
+class phonetic_pr;
struct date;
@@ -555,6 +557,21 @@ class XLNT_API worksheet
///
void reserve(std::size_t n);
+ ///
+ /// Returns true if this sheet has phonetic properties
+ ///
+ bool has_phonetic_properties() const;
+
+ ///
+ /// Returns the phonetic properties of this sheet.
+ ///
+ const phonetic_pr &phonetic_properties() const;
+
+ ///
+ /// Sets the phonetic properties of this sheet to phonetic_props
+ ///
+ void phonetic_properties(const phonetic_pr& phonetic_props);
+
///
/// Returns true if this sheet has a header/footer.
///
@@ -653,7 +670,7 @@ class XLNT_API worksheet
///
/// Returns the view at the given index.
///
- sheet_view view(std::size_t index = 0) const;
+ sheet_view &view(std::size_t index = 0) const;
///
/// Adds new_view to the set of available views for this sheet.
@@ -708,6 +725,26 @@ class XLNT_API worksheet
///
xlnt::conditional_format conditional_format(const range_reference &ref, const condition &when);
+ ///
+ /// Returns the path of this worksheet in the containing package.
+ ///
+ xlnt::path path() const;
+
+ ///
+ /// Returns the relationship from the parent workbook to this worksheet.
+ ///
+ relationship referring_relationship() const;
+
+ ///
+ /// Returns the current formatting properties.
+ ///
+ sheet_format_properties format_properties() const;
+
+ ///
+ /// Sets the format properties to the given properties.
+ ///
+ void format_properties(const sheet_format_properties &properties);
+
private:
friend class cell;
friend class const_range_iterator;
diff --git a/xlnt/include/xlnt/xlnt.hpp b/xlnt/include/xlnt/xlnt.hpp
index 7a4daf3..01fe498 100644
--- a/xlnt/include/xlnt/xlnt.hpp
+++ b/xlnt/include/xlnt/xlnt.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -30,6 +30,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/xlnt/include/xlnt/xlnt_config.hpp b/xlnt/include/xlnt/xlnt_config.hpp
index 399657f..5c8ca97 100644
--- a/xlnt/include/xlnt/xlnt_config.hpp
+++ b/xlnt/include/xlnt/xlnt_config.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/CMakeLists.txt b/xlnt/source/CMakeLists.txt
index ded96a8..5c924e8 100644
--- a/xlnt/source/CMakeLists.txt
+++ b/xlnt/source/CMakeLists.txt
@@ -1,11 +1,9 @@
cmake_minimum_required(VERSION 3.1)
project(xlnt VERSION 1.2)
-# Require C99 and C++11 compilers
-set(CMAKE_C_STANDARD 99)
-set(CMAKE_C_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD ${XLNT_CXX_LANG})
set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CXX_EXTENSIONS OFF)
# Project metadata
set(PROJECT_VENDOR "Thomas Fussell")
@@ -37,12 +35,18 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas") # ignore MSVC and Clang pragmas
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weverything") # all warnings
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") # warnings are errors
+ # blacklist warnings that are not relevant
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++98-compat") # ignore warnings about C++98 compatibility
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++98-compat-pedantic") # ignore pedantic warnings about C++98 compatibility
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-padded") # ignore padding warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-documentation-unknown-command") # ignore unknown commands in Javadoc-style comments
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas") # ignore Windows and GCC pragmas
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option") # ignore Windows and GCC pragmas
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-float-equal") # don't warn on uses of == for fp types
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-newline-eof") # no longer an issue with post-c++11 standards which mandate include add a newline if neccesary
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-covered-switch-default") # default is often added to switches for completeness or to cover future alternatives
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-exit-time-destructors") # this is just a warning to notify that the destructor will run during exit
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-braces") # Wmissing-field-initializers has less false positives
endif()
if(STATIC_CRT)
@@ -151,6 +155,9 @@ else()
target_compile_definitions(xlnt PUBLIC XLNT_STATIC=1)
endif()
+# requires cmake 3.8+
+#target_compile_features(xlnt PUBLIC cxx_std_${XLNT_CXX_LANG})
+
# Includes
target_include_directories(xlnt PUBLIC ${XLNT_INCLUDE_DIR})
target_include_directories(xlnt PRIVATE ${XLNT_SOURCE_DIR})
@@ -173,23 +180,23 @@ if(MSVC)
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/cryptography/aes.cpp
PROPERTIES
COMPILE_FLAGS "/wd\"4996\"")
-endif()
-
-# Platform- and file-specific settings, Clang
-if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/miniz.cpp
- PROPERTIES
- COMPILE_FLAGS "-Wno-undef")
- set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/zstream.cpp
- PROPERTIES
- COMPILE_FLAGS "-Wno-undef -Wno-shorten-64-to-32")
-endif()
-
-# Platform- and file-specific settings, GCC
-if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
- set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/miniz.cpp
- PROPERTIES
- COMPILE_FLAGS "-Wno-strict-aliasing")
+else()
+ # Platform- and file-specific settings, Clang
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/miniz.cpp
+ PROPERTIES
+ COMPILE_FLAGS "-Wno-undef")
+ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/zstream.cpp
+ PROPERTIES
+ COMPILE_FLAGS "-Wno-undef -Wno-shorten-64-to-32")
+ endif()
+
+ # Platform- and file-specific settings, GCC
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/detail/serialization/miniz.cpp
+ PROPERTIES
+ COMPILE_FLAGS "-Wno-strict-aliasing")
+ endif()
endif()
# Group files into pseudo-folders in IDEs
diff --git a/xlnt/source/cell/cell.cpp b/xlnt/source/cell/cell.cpp
index 6a0545a..667212d 100644
--- a/xlnt/source/cell/cell.cpp
+++ b/xlnt/source/cell/cell.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -28,12 +28,15 @@
#include
#include
+#include
#include
#include
#include
#include
#include
+#include
#include
+#include
#include
#include
#include
@@ -195,7 +198,7 @@ cell::cell(detail::cell_impl *d)
bool cell::garbage_collectible() const
{
- return !(has_value() || is_merged() || has_formula() || has_format());
+ return !(has_value() || is_merged() || has_formula() || has_format() || has_hyperlink());
}
void cell::value(std::nullptr_t)
@@ -311,6 +314,11 @@ column_t cell::column() const
return d_->column_;
}
+column_t::index_t cell::column_index() const
+{
+ return d_->column_.index;
+}
+
void cell::merged(bool merged)
{
d_->is_merged_ = merged;
@@ -333,57 +341,104 @@ cell_reference cell::reference() const
return {d_->column_, d_->row_};
}
-bool cell::operator==(std::nullptr_t) const
-{
- return d_ == nullptr;
-}
-
bool cell::operator==(const cell &comparand) const
{
return d_ == comparand.d_;
}
-cell &cell::operator=(const cell &rhs)
+bool cell::operator!=(const cell &comparand) const
{
- d_->column_ = rhs.d_->column_;
- d_->format_ = rhs.d_->format_;
- d_->formula_ = rhs.d_->formula_;
- d_->hyperlink_ = rhs.d_->hyperlink_;
- d_->is_merged_ = rhs.d_->is_merged_;
- d_->parent_ = rhs.d_->parent_;
- d_->row_ = rhs.d_->row_;
- d_->type_ = rhs.d_->type_;
- d_->value_numeric_ = rhs.d_->value_numeric_;
- d_->value_text_ = rhs.d_->value_text_;
-
- return *this;
+ return d_ != comparand.d_;
}
-std::string cell::hyperlink() const
+cell &cell::operator=(const cell &rhs) = default;
+
+hyperlink cell::hyperlink() const
{
- return d_->hyperlink_.get();
+ return xlnt::hyperlink(&d_->hyperlink_.get());
}
-void cell::hyperlink(const std::string &hyperlink)
+void cell::hyperlink(const std::string &url, const std::string &display)
{
- if (hyperlink.length() == 0
- || std::find(hyperlink.begin(), hyperlink.end(), ':') == hyperlink.end())
+ if (url.empty() || std::find(url.begin(), url.end(), ':') == url.end())
{
throw invalid_parameter();
}
- d_->hyperlink_ = hyperlink;
+ auto ws = worksheet();
+ auto &manifest = ws.workbook().manifest();
+
+ d_->hyperlink_ = detail::hyperlink_impl();
+
+ // check for existing relationships
+ auto relationships = manifest.relationships(ws.path(), relationship_type::hyperlink);
+ auto relation = std::find_if(relationships.cbegin(), relationships.cend(),
+ [&url](xlnt::relationship rel) { return rel.target().path().string() == url; });
+ if (relation != relationships.end())
+ {
+ d_->hyperlink_.get().relationship = *relation;
+ }
+ else
+ { // register a new relationship
+ auto rel_id = manifest.register_relationship(
+ uri(ws.path().string()),
+ relationship_type::hyperlink,
+ uri(url),
+ target_mode::external);
+ // TODO: make manifest::register_relationship return the created relationship instead of rel id
+ d_->hyperlink_.get().relationship = manifest.relationship(ws.path(), rel_id);
+ }
+ // if a value is already present, the display string is ignored
+ if (has_value())
+ {
+ d_->hyperlink_.get().display.set(to_string());
+ }
+ else
+ {
+ d_->hyperlink_.get().display.set(display.empty() ? url : display);
+ value(hyperlink().display());
+ }
}
-void cell::hyperlink(const std::string &url, const std::string &display)
+void cell::hyperlink(xlnt::cell target, const std::string& display)
{
- hyperlink(url);
- value(display);
+ // TODO: should this computed value be a method on a cell?
+ const auto cell_address = target.worksheet().title() + "!" + target.reference().to_string();
+
+ d_->hyperlink_ = detail::hyperlink_impl();
+ d_->hyperlink_.get().relationship = xlnt::relationship("", relationship_type::hyperlink,
+ uri(""), uri(cell_address), target_mode::internal);
+ // if a value is already present, the display string is ignored
+ if (has_value())
+ {
+ d_->hyperlink_.get().display.set(to_string());
+ }
+ else
+ {
+ d_->hyperlink_.get().display.set(display.empty() ? cell_address : display);
+ value(hyperlink().display());
+ }
}
-void cell::hyperlink(xlnt::cell /*target*/)
+void cell::hyperlink(xlnt::range target, const std::string &display)
{
- //todo: implement
+ // TODO: should this computed value be a method on a cell?
+ const auto range_address = target.target_worksheet().title() + "!" + target.reference().to_string();
+
+ d_->hyperlink_ = detail::hyperlink_impl();
+ d_->hyperlink_.get().relationship = xlnt::relationship("", relationship_type::hyperlink,
+ uri(""), uri(range_address), target_mode::internal);
+
+ // if a value is already present, the display string is ignored
+ if (has_value())
+ {
+ d_->hyperlink_.get().display.set(to_string());
+ }
+ else
+ {
+ d_->hyperlink_.get().display.set(display.empty() ? range_address : display);
+ value(hyperlink().display());
+ }
}
void cell::formula(const std::string &formula)
@@ -402,8 +457,6 @@ void cell::formula(const std::string &formula)
d_->formula_ = formula;
}
- data_type(type::number);
-
worksheet().register_calc_chain_in_manifest();
}
@@ -426,6 +479,15 @@ void cell::clear_formula()
}
}
+std::string cell::error() const
+{
+ if (d_->type_ != type::error)
+ {
+ throw xlnt::exception("called error() when cell type is not error");
+ }
+ return value();
+}
+
void cell::error(const std::string &error)
{
if (error.length() == 0 || error[0] != '#')
@@ -433,7 +495,7 @@ void cell::error(const std::string &error)
throw invalid_data_type();
}
- d_->value_text_.plain_text(error);
+ d_->value_text_.plain_text(error, false);
d_->type_ = type::error;
}
@@ -598,37 +660,37 @@ XLNT_API timedelta cell::value() const
void cell::alignment(const class alignment &alignment_)
{
auto new_format = has_format() ? modifiable_format() : workbook().create_format();
- format(new_format.alignment(alignment_, true));
+ format(new_format.alignment(alignment_, optional(true)));
}
void cell::border(const class border &border_)
{
auto new_format = has_format() ? modifiable_format() : workbook().create_format();
- format(new_format.border(border_, true));
+ format(new_format.border(border_, optional(true)));
}
void cell::fill(const class fill &fill_)
{
auto new_format = has_format() ? modifiable_format() : workbook().create_format();
- format(new_format.fill(fill_, true));
+ format(new_format.fill(fill_, optional(true)));
}
void cell::font(const class font &font_)
{
auto new_format = has_format() ? modifiable_format() : workbook().create_format();
- format(new_format.font(font_, true));
+ format(new_format.font(font_, optional(true)));
}
void cell::number_format(const class number_format &number_format_)
{
auto new_format = has_format() ? modifiable_format() : workbook().create_format();
- format(new_format.number_format(number_format_, true));
+ format(new_format.number_format(number_format_, optional(true)));
}
void cell::protection(const class protection &protection_)
{
auto new_format = has_format() ? modifiable_format() : workbook().create_format();
- format(new_format.protection(protection_, true));
+ format(new_format.protection(protection_, optional(true)));
}
template <>
@@ -642,7 +704,7 @@ XLNT_API rich_text cell::value() const
{
if (data_type() == cell::type::shared_string)
{
- return workbook().shared_strings().at(static_cast(d_->value_numeric_));
+ return workbook().shared_strings(static_cast(d_->value_numeric_));
}
return d_->value_text_;
@@ -697,6 +759,16 @@ calendar cell::base_date() const
return workbook().base_date();
}
+bool operator==(std::nullptr_t, const cell &cell)
+{
+ return cell.data_type() == cell::type::empty;
+}
+
+bool operator==(const cell &cell, std::nullptr_t)
+{
+ return nullptr == cell;
+}
+
XLNT_API std::ostream &operator<<(std::ostream &stream, const xlnt::cell &cell)
{
return stream << cell.to_string();
@@ -756,8 +828,11 @@ void cell::value(const std::string &value_string, bool infer_type)
void cell::clear_format()
{
- format().d_->references -= format().d_->references > 0 ? 1 : 0;
- d_->format_.clear();
+ if (d_->format_.is_set())
+ {
+ format().d_->references -= format().d_->references > 0 ? 1 : 0;
+ d_->format_.clear();
+ }
}
void cell::clear_style()
@@ -786,19 +861,19 @@ style cell::style()
throw invalid_attribute();
}
- auto f = format();
+ auto f = format();
return f.style();
}
const style cell::style() const
{
- if (!has_format() || !format().has_style())
- {
- throw invalid_attribute();
- }
+ if (!has_format() || !format().has_style())
+ {
+ throw invalid_attribute();
+ }
- return format().style();
+ return format().style();
}
bool cell::has_style() const
diff --git a/xlnt/source/cell/cell_reference.cpp b/xlnt/source/cell/cell_reference.cpp
index 42bea3f..ea4ad83 100644
--- a/xlnt/source/cell/cell_reference.cpp
+++ b/xlnt/source/cell/cell_reference.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/xlnt/source/cell/comment.cpp b/xlnt/source/cell/comment.cpp
index 0eb7aa2..16722d2 100644
--- a/xlnt/source/cell/comment.cpp
+++ b/xlnt/source/cell/comment.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -38,7 +38,7 @@ comment::comment(const rich_text &text, const std::string &author)
comment::comment(const std::string &text, const std::string &author)
: text_(), author_(author)
{
- text_.plain_text(text);
+ text_.plain_text(text, false);
}
rich_text comment::text() const
diff --git a/xlnt/source/cell/index_types.cpp b/xlnt/source/cell/index_types.cpp
index c330421..1d04031 100644
--- a/xlnt/source/cell/index_types.cpp
+++ b/xlnt/source/cell/index_types.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/xlnt/source/cell/rich_text.cpp b/xlnt/source/cell/rich_text.cpp
index 44bb558..3cf1329 100644
--- a/xlnt/source/cell/rich_text.cpp
+++ b/xlnt/source/cell/rich_text.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -26,16 +26,35 @@
#include
#include
+namespace {
+bool has_trailing_whitespace(const std::string &s)
+{
+ return !s.empty() && (s.front() == ' ' || s.back() == ' ');
+};
+}
+
namespace xlnt {
rich_text::rich_text(const std::string &plain_text)
- : rich_text({plain_text, optional()})
+ : rich_text(rich_text_run{plain_text, optional(), has_trailing_whitespace(plain_text)})
{
}
rich_text::rich_text(const std::string &plain_text, const class font &text_font)
- : rich_text({plain_text, optional(text_font)})
+ : rich_text(rich_text_run{plain_text, optional(text_font), has_trailing_whitespace(plain_text)})
+{
+}
+
+rich_text::rich_text(const rich_text &other)
+{
+ *this = other;
+}
+
+rich_text &rich_text::operator=(const rich_text &rhs)
{
+ runs_.clear();
+ runs_ = rhs.runs_;
+ return *this;
}
rich_text::rich_text(const rich_text_run &single_run)
@@ -48,14 +67,19 @@ void rich_text::clear()
runs_.clear();
}
-void rich_text::plain_text(const std::string &s)
+void rich_text::plain_text(const std::string &s, bool preserve_space = false)
{
clear();
- add_run(rich_text_run{s, {}});
+ add_run(rich_text_run{s, {}, preserve_space});
}
std::string rich_text::plain_text() const
{
+ if (runs_.size() == 1)
+ {
+ return runs_.begin()->first;
+ }
+
return std::accumulate(runs_.begin(), runs_.end(), std::string(),
[](const std::string &a, const rich_text_run &run) { return a + run.first; });
}
@@ -65,6 +89,11 @@ std::vector rich_text::runs() const
return runs_;
}
+void rich_text::runs(const std::vector &new_runs)
+{
+ runs_ = new_runs;
+}
+
void rich_text::add_run(const rich_text_run &t)
{
runs_.push_back(t);
diff --git a/xlnt/source/cell/rich_text_run.cpp b/xlnt/source/cell/rich_text_run.cpp
index 79b2456..2d717d0 100644
--- a/xlnt/source/cell/rich_text_run.cpp
+++ b/xlnt/source/cell/rich_text_run.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/binary.hpp b/xlnt/source/detail/binary.hpp
index e908870..cda8e56 100644
--- a/xlnt/source/detail/binary.hpp
+++ b/xlnt/source/detail/binary.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/constants.cpp b/xlnt/source/detail/constants.cpp
index 759511e..9ccb4cd 100644
--- a/xlnt/source/detail/constants.cpp
+++ b/xlnt/source/detail/constants.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/constants.hpp b/xlnt/source/detail/constants.hpp
index b88c5c6..719fcd1 100644
--- a/xlnt/source/detail/constants.hpp
+++ b/xlnt/source/detail/constants.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/aes.cpp b/xlnt/source/detail/cryptography/aes.cpp
index d88c66b..87a2cf7 100644
--- a/xlnt/source/detail/cryptography/aes.cpp
+++ b/xlnt/source/detail/cryptography/aes.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/aes.hpp b/xlnt/source/detail/cryptography/aes.hpp
index e1657bd..6c0af31 100644
--- a/xlnt/source/detail/cryptography/aes.hpp
+++ b/xlnt/source/detail/cryptography/aes.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/base64.cpp b/xlnt/source/detail/cryptography/base64.cpp
index 90c7a83..ddc9322 100644
--- a/xlnt/source/detail/cryptography/base64.cpp
+++ b/xlnt/source/detail/cryptography/base64.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Thomas Fussell
+// Copyright (C) 2017-2018 Thomas Fussell
// Copyright (C) 2013 Tomas Kislan
// Copyright (C) 2013 Adam Rudd
//
diff --git a/xlnt/source/detail/cryptography/base64.hpp b/xlnt/source/detail/cryptography/base64.hpp
index cbe5ac8..7a33922 100644
--- a/xlnt/source/detail/cryptography/base64.hpp
+++ b/xlnt/source/detail/cryptography/base64.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/cipher.hpp b/xlnt/source/detail/cryptography/cipher.hpp
index 408af36..4410e81 100644
--- a/xlnt/source/detail/cryptography/cipher.hpp
+++ b/xlnt/source/detail/cryptography/cipher.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/compound_document.cpp b/xlnt/source/detail/cryptography/compound_document.cpp
index 3815f17..5026ea7 100644
--- a/xlnt/source/detail/cryptography/compound_document.cpp
+++ b/xlnt/source/detail/cryptography/compound_document.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2016-2017 Thomas Fussell
+// Copyright (C) 2016-2018 Thomas Fussell
// Copyright (C) 2002-2007 Ariya Hidayat (ariya@kde.org).
//
// Redistribution and use in source and binary forms, with or without
diff --git a/xlnt/source/detail/cryptography/encryption_info.cpp b/xlnt/source/detail/cryptography/encryption_info.cpp
index 61b1514..968852d 100644
--- a/xlnt/source/detail/cryptography/encryption_info.cpp
+++ b/xlnt/source/detail/cryptography/encryption_info.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/encryption_info.hpp b/xlnt/source/detail/cryptography/encryption_info.hpp
index 4f1dff5..98431a4 100644
--- a/xlnt/source/detail/cryptography/encryption_info.hpp
+++ b/xlnt/source/detail/cryptography/encryption_info.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/hash.cpp b/xlnt/source/detail/cryptography/hash.cpp
index 0e9ef08..440362d 100644
--- a/xlnt/source/detail/cryptography/hash.cpp
+++ b/xlnt/source/detail/cryptography/hash.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/hash.hpp b/xlnt/source/detail/cryptography/hash.hpp
index eeb4a3c..c1ebd36 100644
--- a/xlnt/source/detail/cryptography/hash.hpp
+++ b/xlnt/source/detail/cryptography/hash.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/sha.cpp b/xlnt/source/detail/cryptography/sha.cpp
index 67eefbd..02cfd8b 100644
--- a/xlnt/source/detail/cryptography/sha.cpp
+++ b/xlnt/source/detail/cryptography/sha.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/sha.hpp b/xlnt/source/detail/cryptography/sha.hpp
index fd3108b..6ac84a7 100644
--- a/xlnt/source/detail/cryptography/sha.hpp
+++ b/xlnt/source/detail/cryptography/sha.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/value_traits.hpp b/xlnt/source/detail/cryptography/value_traits.hpp
index 00ab7ba..3f49364 100644
--- a/xlnt/source/detail/cryptography/value_traits.hpp
+++ b/xlnt/source/detail/cryptography/value_traits.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp b/xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp
index a614523..6370ba0 100644
--- a/xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp
+++ b/xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/xlsx_crypto_consumer.hpp b/xlnt/source/detail/cryptography/xlsx_crypto_consumer.hpp
index f8d5809..78b3e74 100644
--- a/xlnt/source/detail/cryptography/xlsx_crypto_consumer.hpp
+++ b/xlnt/source/detail/cryptography/xlsx_crypto_consumer.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/xlsx_crypto_producer.cpp b/xlnt/source/detail/cryptography/xlsx_crypto_producer.cpp
index 2916b15..d9af4cf 100644
--- a/xlnt/source/detail/cryptography/xlsx_crypto_producer.cpp
+++ b/xlnt/source/detail/cryptography/xlsx_crypto_producer.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/cryptography/xlsx_crypto_producer.hpp b/xlnt/source/detail/cryptography/xlsx_crypto_producer.hpp
index 68a03d2..49244ec 100644
--- a/xlnt/source/detail/cryptography/xlsx_crypto_producer.hpp
+++ b/xlnt/source/detail/cryptography/xlsx_crypto_producer.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/default_case.hpp b/xlnt/source/detail/default_case.hpp
index f1f8953..e7c147e 100644
--- a/xlnt/source/detail/default_case.hpp
+++ b/xlnt/source/detail/default_case.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2017 Thomas Fussell
+// Copyright (c) 2016-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/external/include_libstudxml.hpp b/xlnt/source/detail/external/include_libstudxml.hpp
index ec8493a..ec1c18e 100644
--- a/xlnt/source/detail/external/include_libstudxml.hpp
+++ b/xlnt/source/detail/external/include_libstudxml.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/external/include_windows.hpp b/xlnt/source/detail/external/include_windows.hpp
index 737321a..62e77b4 100644
--- a/xlnt/source/detail/external/include_windows.hpp
+++ b/xlnt/source/detail/external/include_windows.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/header_footer/header_footer_code.cpp b/xlnt/source/detail/header_footer/header_footer_code.cpp
index efbe7b9..f97ef65 100644
--- a/xlnt/source/detail/header_footer/header_footer_code.cpp
+++ b/xlnt/source/detail/header_footer/header_footer_code.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -22,6 +22,7 @@
// @author: see AUTHORS file
#include
+#include
namespace xlnt {
namespace detail {
@@ -359,6 +360,11 @@ std::array, 3> decode_header_footer(const std::s
case hf_code::text_single_underline:
{
+ if (!current_run.second.is_set())
+ {
+ current_run.second = xlnt::font();
+ }
+ current_run.second.get().underline(font::underline_style::single);
break;
}
@@ -527,9 +533,24 @@ std::string encode_header_footer(const rich_text &t, header_footer::location whe
if (run.second.get().has_size())
{
encoded.push_back('&');
- encoded.append(std::to_string(run.second.get().size()));
+ encoded.append(serialize_number_to_string(run.second.get().size()));
+ }
+ if (run.second.get().underlined())
+ {
+ switch (run.second.get().underline())
+ {
+ case font::underline_style::single:
+ case font::underline_style::single_accounting:
+ encoded.append("&U");
+ break;
+ case font::underline_style::double_:
+ case font::underline_style::double_accounting:
+ encoded.append("&E");
+ break;
+ case font::underline_style::none:
+ break;
+ }
}
-
if (run.second.get().has_color())
{
encoded.push_back('&');
diff --git a/xlnt/source/detail/header_footer/header_footer_code.hpp b/xlnt/source/detail/header_footer/header_footer_code.hpp
index 169eb25..96ae506 100644
--- a/xlnt/source/detail/header_footer/header_footer_code.hpp
+++ b/xlnt/source/detail/header_footer/header_footer_code.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/implementations/cell_impl.cpp b/xlnt/source/detail/implementations/cell_impl.cpp
index 900da4e..8be6324 100644
--- a/xlnt/source/detail/implementations/cell_impl.cpp
+++ b/xlnt/source/detail/implementations/cell_impl.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -21,9 +21,10 @@
//
// @license: http://www.opensource.org/licenses/mit-license.php
// @author: see AUTHORS file
+
#include
-#include "cell_impl.hpp"
+#include
namespace xlnt {
namespace detail {
diff --git a/xlnt/source/detail/implementations/cell_impl.hpp b/xlnt/source/detail/implementations/cell_impl.hpp
index fcf4a33..6475677 100644
--- a/xlnt/source/detail/implementations/cell_impl.hpp
+++ b/xlnt/source/detail/implementations/cell_impl.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -27,20 +27,26 @@
#include
#include
-#include
#include
+#include
+#include
#include
+#include
+#include
namespace xlnt {
namespace detail {
-struct format_impl;
struct worksheet_impl;
struct cell_impl
{
cell_impl();
-
+ cell_impl(const cell_impl &other) = default;
+ cell_impl(cell_impl &&other) = default;
+ cell_impl &operator=(const cell_impl &other) = default;
+ cell_impl &operator=(cell_impl &&other) = default;
+
cell_type type_;
worksheet_impl *parent_;
@@ -54,10 +60,25 @@ struct cell_impl
double value_numeric_;
optional formula_;
- optional hyperlink_;
+ optional hyperlink_;
optional format_;
optional comment_;
};
+inline bool operator==(const cell_impl &lhs, const cell_impl &rhs)
+{
+ // not comparing parent
+ return lhs.type_ == rhs.type_
+ && lhs.column_ == rhs.column_
+ && lhs.row_ == rhs.row_
+ && lhs.is_merged_ == rhs.is_merged_
+ && lhs.value_text_ == rhs.value_text_
+ && lhs.value_numeric_ == rhs.value_numeric_
+ && lhs.formula_ == rhs.formula_
+ && lhs.hyperlink_ == rhs.hyperlink_
+ && (lhs.format_.is_set() == rhs.format_.is_set() && (!lhs.format_.is_set() || *lhs.format_.get() == *rhs.format_.get()))
+ && (lhs.comment_.is_set() == rhs.comment_.is_set() && (!lhs.comment_.is_set() || *lhs.comment_.get() == *rhs.comment_.get()));
+}
+
} // namespace detail
} // namespace xlnt
diff --git a/xlnt/source/detail/implementations/conditional_format_impl.hpp b/xlnt/source/detail/implementations/conditional_format_impl.hpp
index 7ea9f3a..2542d97 100644
--- a/xlnt/source/detail/implementations/conditional_format_impl.hpp
+++ b/xlnt/source/detail/implementations/conditional_format_impl.hpp
@@ -20,8 +20,21 @@ struct worksheet_impl;
struct conditional_format_impl
{
stylesheet *parent;
+ worksheet_impl *target_sheet;
+
+ bool operator==(const conditional_format_impl& rhs) const
+ {
+ // not comparing parent or target sheet
+ return target_range == rhs.target_range
+ && priority == rhs.priority
+ && differential_format_id == rhs.differential_format_id
+ && when == rhs.when
+ && border_id == rhs.border_id
+ && fill_id == rhs.fill_id
+ && font_id == rhs.font_id;
+ }
+
range_reference target_range;
- worksheet_impl *target_sheet;
std::size_t priority;
std::size_t differential_format_id;
diff --git a/xlnt/source/detail/implementations/format_impl.hpp b/xlnt/source/detail/implementations/format_impl.hpp
index 8b8e377..d203d56 100644
--- a/xlnt/source/detail/implementations/format_impl.hpp
+++ b/xlnt/source/detail/implementations/format_impl.hpp
@@ -30,22 +30,22 @@ struct format_impl
std::size_t id;
optional alignment_id;
- bool alignment_applied = false;
+ optional alignment_applied;
optional border_id;
- bool border_applied = false;
+ optional border_applied;
optional fill_id;
- bool fill_applied = false;
+ optional fill_applied;
optional font_id;
- bool font_applied = false;
+ optional font_applied;
optional number_format_id;
- bool number_format_applied = false;
+ optional number_format_applied;
optional protection_id;
- bool protection_applied = false;
+ optional protection_applied;
bool pivot_button_ = false;
bool quote_prefix_ = false;
diff --git a/xlnt/source/detail/implementations/style_impl.hpp b/xlnt/source/detail/implementations/style_impl.hpp
index 49153ae..c05ec88 100644
--- a/xlnt/source/detail/implementations/style_impl.hpp
+++ b/xlnt/source/detail/implementations/style_impl.hpp
@@ -22,6 +22,30 @@ struct style_impl
{
stylesheet *parent;
+ bool operator==(const style_impl& rhs) const
+ {
+ return name == rhs.name
+ && formatting_record_id == rhs.formatting_record_id
+ && custom_builtin == rhs.custom_builtin
+ && hidden_style == rhs.hidden_style
+ && builtin_id == rhs.builtin_id
+ && outline_style == rhs.outline_style
+ && alignment_id == rhs.alignment_id
+ && alignment_applied == rhs.alignment_applied
+ && border_id == rhs.border_id
+ && border_applied == rhs.border_applied
+ && fill_id == rhs.fill_id
+ && fill_applied == rhs.fill_applied
+ && font_id == rhs.font_id
+ && font_applied == rhs.font_applied
+ && number_format_id == rhs.number_format_id
+ && number_format_applied == number_format_applied
+ && protection_id == rhs.protection_id
+ && protection_applied == rhs.protection_applied
+ && pivot_button_ == rhs.pivot_button_
+ && quote_prefix_ == rhs.quote_prefix_;
+ }
+
std::string name;
std::size_t formatting_record_id;
@@ -32,22 +56,22 @@ struct style_impl
optional outline_style;
optional alignment_id;
- bool alignment_applied = false;
+ optional alignment_applied;
optional border_id;
- bool border_applied = false;
+ optional border_applied;
optional fill_id;
- bool fill_applied = false;
+ optional fill_applied;
optional font_id;
- bool font_applied = false;
+ optional font_applied;
optional number_format_id;
- bool number_format_applied = false;
+ optional number_format_applied;
optional protection_id;
- bool protection_applied = false;
+ optional protection_applied;
bool pivot_button_ = false;
bool quote_prefix_ = false;
diff --git a/xlnt/source/detail/implementations/stylesheet.hpp b/xlnt/source/detail/implementations/stylesheet.hpp
index 3f9e2d8..8ccc597 100644
--- a/xlnt/source/detail/implementations/stylesheet.hpp
+++ b/xlnt/source/detail/implementations/stylesheet.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
// Copyright (c) 2010-2015 openpyxl
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -401,23 +401,21 @@ struct stylesheet
{
auto iter = format_impls.begin();
bool added = false;
+ pattern.references = 0;
auto id = find_or_add(format_impls, pattern, &added);
std::advance(iter, static_cast::difference_type>(id));
auto &result = *iter;
- if (added)
- {
- result.references = 0;
- }
-
result.parent = this;
result.id = id;
result.references++;
if (id != pattern.id)
{
- pattern.references -= pattern.references > 0 ? 1 : 0;
+ iter = format_impls.begin();
+ std::advance(iter, static_cast::difference_type>(pattern.id));
+ iter->references -= iter->references > 0 ? 1 : 0;
garbage_collect();
}
@@ -432,7 +430,7 @@ struct stylesheet
return find_or_create(new_format);
}
- format_impl *find_or_create_with(format_impl *pattern, const alignment &new_alignment, bool applied)
+ format_impl *find_or_create_with(format_impl *pattern, const alignment &new_alignment, optional applied)
{
format_impl new_format = *pattern;
new_format.alignment_id = find_or_add(alignments, new_alignment);
@@ -441,7 +439,7 @@ struct stylesheet
return find_or_create(new_format);
}
- format_impl *find_or_create_with(format_impl *pattern, const border &new_border, bool applied)
+ format_impl *find_or_create_with(format_impl *pattern, const border &new_border, optional applied)
{
format_impl new_format = *pattern;
new_format.border_id = find_or_add(borders, new_border);
@@ -450,7 +448,7 @@ struct stylesheet
return find_or_create(new_format);
}
- format_impl *find_or_create_with(format_impl *pattern, const fill &new_fill, bool applied)
+ format_impl *find_or_create_with(format_impl *pattern, const fill &new_fill, optional applied)
{
format_impl new_format = *pattern;
new_format.fill_id = find_or_add(fills, new_fill);
@@ -459,7 +457,7 @@ struct stylesheet
return find_or_create(new_format);
}
- format_impl *find_or_create_with(format_impl *pattern, const font &new_font, bool applied)
+ format_impl *find_or_create_with(format_impl *pattern, const font &new_font, optional applied)
{
format_impl new_format = *pattern;
new_format.font_id = find_or_add(fonts, new_font);
@@ -468,7 +466,7 @@ struct stylesheet
return find_or_create(new_format);
}
- format_impl *find_or_create_with(format_impl *pattern, const number_format &new_number_format, bool applied)
+ format_impl *find_or_create_with(format_impl *pattern, const number_format &new_number_format, optional applied)
{
format_impl new_format = *pattern;
if (new_number_format.id() >= 164)
@@ -481,7 +479,7 @@ struct stylesheet
return find_or_create(new_format);
}
- format_impl *find_or_create_with(format_impl *pattern, const protection &new_protection, bool applied)
+ format_impl *find_or_create_with(format_impl *pattern, const protection &new_protection, optional applied)
{
format_impl new_format = *pattern;
new_format.protection_id = find_or_add(protections, new_protection);
@@ -529,13 +527,34 @@ struct stylesheet
}
workbook *parent;
+
+ bool operator==(const stylesheet& rhs) const
+ {
+ // no equality on parent as there is only 1 stylesheet per borkbook hence would always be false
+ return garbage_collection_enabled == rhs.garbage_collection_enabled
+ && known_fonts_enabled == rhs.known_fonts_enabled
+ && conditional_format_impls == rhs.conditional_format_impls
+ && format_impls == rhs.format_impls
+ && style_impls == rhs.style_impls
+ && style_names == rhs.style_names
+ && default_slicer_style == rhs.default_slicer_style
+ && alignments == rhs.alignments
+ && borders == rhs.borders
+ && fills == rhs.fills
+ && fonts == rhs.fonts
+ && number_formats == rhs.number_formats
+ && protections == rhs.protections
+ && colors == rhs.colors;
+ }
bool garbage_collection_enabled = true;
+ bool known_fonts_enabled = false;
std::list conditional_format_impls;
std::list format_impls;
std::unordered_map style_impls;
std::vector style_names;
+ optional default_slicer_style;
std::vector alignments;
std::vector borders;
diff --git a/xlnt/source/detail/implementations/workbook_impl.hpp b/xlnt/source/detail/implementations/workbook_impl.hpp
index 64d15cf..13dd194 100644
--- a/xlnt/source/detail/implementations/workbook_impl.hpp
+++ b/xlnt/source/detail/implementations/workbook_impl.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -29,6 +29,7 @@
#include
#include
+#include
#include
#include
#include
@@ -46,14 +47,15 @@ struct worksheet_impl;
struct workbook_impl
{
- workbook_impl() : base_date_(calendar::windows_1900)
- {
- }
+ workbook_impl() : base_date_(calendar::windows_1900)
+ {
+ }
workbook_impl(const workbook_impl &other)
: active_sheet_index_(other.active_sheet_index_),
worksheets_(other.worksheets_),
- shared_strings_(other.shared_strings_),
+ shared_strings_ids_(other.shared_strings_ids_),
+ shared_strings_values_(other.shared_strings_values_),
stylesheet_(other.stylesheet_),
manifest_(other.manifest_),
theme_(other.theme_),
@@ -71,15 +73,15 @@ struct workbook_impl
active_sheet_index_ = other.active_sheet_index_;
worksheets_.clear();
std::copy(other.worksheets_.begin(), other.worksheets_.end(), back_inserter(worksheets_));
- shared_strings_.clear();
- std::copy(other.shared_strings_.begin(), other.shared_strings_.end(), std::back_inserter(shared_strings_));
- theme_ = other.theme_;
+ shared_strings_ids_ = other.shared_strings_ids_;
+ shared_strings_values_ = other.shared_strings_values_;
+ theme_ = other.theme_;
manifest_ = other.manifest_;
- sheet_title_rel_id_map_ = other.sheet_title_rel_id_map_;
- view_ = other.view_;
- code_name_ = other.code_name_;
- file_version_ = other.file_version_;
+ sheet_title_rel_id_map_ = other.sheet_title_rel_id_map_;
+ view_ = other.view_;
+ code_name_ = other.code_name_;
+ file_version_ = other.file_version_;
core_properties_ = other.core_properties_;
extended_properties_ = other.extended_properties_;
@@ -88,16 +90,41 @@ struct workbook_impl
return *this;
}
+ bool operator==(const workbook_impl &other)
+ {
+ return active_sheet_index_ == other.active_sheet_index_
+ && worksheets_ == other.worksheets_
+ && shared_strings_ids_ == other.shared_strings_ids_
+ && stylesheet_ == other.stylesheet_
+ && base_date_ == other.base_date_
+ && title_ == other.title_
+ && manifest_ == other.manifest_
+ && theme_ == other.theme_
+ && images_ == other.images_
+ && core_properties_ == other.core_properties_
+ && extended_properties_ == other.extended_properties_
+ && custom_properties_ == other.custom_properties_
+ && sheet_title_rel_id_map_ == other.sheet_title_rel_id_map_
+ && view_ == other.view_
+ && code_name_ == other.code_name_
+ && file_version_ == other.file_version_
+ && calculation_properties_ == other.calculation_properties_
+ && abs_path_ == other.abs_path_
+ && arch_id_flags_ == other.arch_id_flags_
+ && extensions_ == other.extensions_;
+ }
+
optional active_sheet_index_;
std::list worksheets_;
- std::vector shared_strings_;
+ std::unordered_map shared_strings_ids_;
+ std::map shared_strings_values_;
optional stylesheet_;
calendar base_date_;
optional title_;
-
+
manifest manifest_;
optional theme_;
std::unordered_map> images_;
@@ -106,7 +133,7 @@ struct workbook_impl
std::vector> extended_properties_;
std::vector> custom_properties_;
- std::unordered_map sheet_title_rel_id_map_;
+ std::unordered_map sheet_title_rel_id_map_;
optional view_;
optional code_name_;
@@ -117,10 +144,21 @@ struct workbook_impl
std::size_t last_edited;
std::size_t lowest_edited;
std::size_t rup_build;
+
+ bool operator==(const file_version_t& rhs) const
+ {
+ return app_name == rhs.app_name
+ && last_edited == rhs.last_edited
+ && lowest_edited == rhs.lowest_edited
+ && rup_build == rhs.rup_build;
+ }
};
-
+
optional file_version_;
optional calculation_properties_;
+ optional abs_path_;
+ optional arch_id_flags_;
+ optional extensions_;
};
} // namespace detail
diff --git a/xlnt/source/detail/implementations/worksheet_impl.hpp b/xlnt/source/detail/implementations/worksheet_impl.hpp
index 9c6ec27..cb3be2f 100644
--- a/xlnt/source/detail/implementations/worksheet_impl.hpp
+++ b/xlnt/source/detail/implementations/worksheet_impl.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -27,14 +27,19 @@
#include
#include
-#include
+#include
#include
-#include
-#include
-#include
#include
#include
+#include
+#include
+#include
#include
+#include
+#include
+#include
+#include
+#include
namespace xlnt {
@@ -62,23 +67,16 @@ struct worksheet_impl
id_ = other.id_;
title_ = other.title_;
+ format_properties_ = other.format_properties_;
column_properties_ = other.column_properties_;
row_properties_ = other.row_properties_;
cell_map_ = other.cell_map_;
-
- for (auto &row : cell_map_)
- {
- for (auto &cell : row.second)
- {
- cell.second.parent_ = this;
- }
- }
-
page_setup_ = other.page_setup_;
auto_filter_ = other.auto_filter_;
page_margins_ = other.page_margins_;
merged_cells_ = other.merged_cells_;
named_ranges_ = other.named_ranges_;
+ phonetic_properties_ = other.phonetic_properties_;
header_footer_ = other.header_footer_;
print_title_cols_ = other.print_title_cols_;
print_title_rows_ = other.print_title_rows_;
@@ -86,13 +84,53 @@ struct worksheet_impl
views_ = other.views_;
column_breaks_ = other.column_breaks_;
row_breaks_ = other.row_breaks_;
+ extension_list_ = other.extension_list_;
+ sheet_properties_ = other.sheet_properties_;
+ print_options_ = other.print_options_;
+
+ for (auto &row : cell_map_)
+ {
+ for (auto &cell : row.second)
+ {
+ cell.second.parent_ = this;
+ }
+ }
}
workbook *parent_;
+ bool operator==(const worksheet_impl& rhs) const
+ {
+ return id_ == rhs.id_
+ && title_ == rhs.title_
+ && format_properties_ == rhs.format_properties_
+ && column_properties_ == rhs.column_properties_
+ && row_properties_ == rhs.row_properties_
+ && cell_map_ == rhs.cell_map_
+ && page_setup_ == rhs.page_setup_
+ && auto_filter_ == rhs.auto_filter_
+ && page_margins_ == rhs.page_margins_
+ && merged_cells_ == rhs.merged_cells_
+ && named_ranges_ == rhs.named_ranges_
+ && phonetic_properties_ == rhs.phonetic_properties_
+ && header_footer_ == rhs.header_footer_
+ && print_title_cols_ == rhs.print_title_cols_
+ && print_title_rows_ == rhs.print_title_rows_
+ && print_area_ == rhs.print_area_
+ && views_ == rhs.views_
+ && column_breaks_ == rhs.column_breaks_
+ && row_breaks_ == rhs.row_breaks_
+ && comments_ == rhs.comments_
+ && print_options_ == rhs.print_options_
+ && sheet_properties_ == rhs.sheet_properties_
+ && extension_list_ == rhs.extension_list_;
+ }
+
std::size_t id_;
std::string title_;
+ sheet_format_properties format_properties_;
+
std::unordered_map column_properties_;
std::unordered_map row_properties_;
@@ -104,6 +142,7 @@ struct worksheet_impl
std::vector merged_cells_;
std::unordered_map named_ranges_;
+ optional phonetic_properties_;
optional header_footer_;
std::string print_title_cols_;
@@ -117,6 +156,10 @@ struct worksheet_impl
std::vector row_breaks_;
std::unordered_map comments_;
+ optional print_options_;
+ optional sheet_properties_;
+
+ optional extension_list_;
};
} // namespace detail
diff --git a/xlnt/source/detail/number_format/number_formatter.cpp b/xlnt/source/detail/number_format/number_formatter.cpp
index 8ef8453..5b0d5d4 100644
--- a/xlnt/source/detail/number_format/number_formatter.cpp
+++ b/xlnt/source/detail/number_format/number_formatter.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/number_format/number_formatter.hpp b/xlnt/source/detail/number_format/number_formatter.hpp
index 02ede6b..4c3e149 100644
--- a/xlnt/source/detail/number_format/number_formatter.hpp
+++ b/xlnt/source/detail/number_format/number_formatter.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/serialization/custom_value_traits.cpp b/xlnt/source/detail/serialization/custom_value_traits.cpp
index e31be3f..2eaf849 100644
--- a/xlnt/source/detail/serialization/custom_value_traits.cpp
+++ b/xlnt/source/detail/serialization/custom_value_traits.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2017 Thomas Fussell
+// Copyright (c) 2016-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -343,5 +343,19 @@ std::string to_string(pane_state state)
default_case("frozen");
}
+std::string to_string(orientation orientation)
+{
+ switch (orientation)
+ {
+ case orientation::default_orientation:
+ return "default";
+ case orientation::landscape:
+ return "landscape";
+ case orientation::portrait:
+ return "portrait";
+ }
+ default_case("default");
+}
+
} // namespace detail
} // namespace xlnt
diff --git a/xlnt/source/detail/serialization/custom_value_traits.hpp b/xlnt/source/detail/serialization/custom_value_traits.hpp
index a5ac300..aa283a0 100644
--- a/xlnt/source/detail/serialization/custom_value_traits.hpp
+++ b/xlnt/source/detail/serialization/custom_value_traits.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2017 Thomas Fussell
+// Copyright (c) 2016-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,9 @@
#pragma once
+#include
#include
+#include
#include
#include
@@ -35,6 +37,7 @@
#include
#include
#include
+#include
#include
namespace xlnt {
@@ -74,6 +77,8 @@ std::string to_string(target_mode mode);
std::string to_string(pane_state state);
+std::string to_string(orientation state);
+
template
static T from_string(const std::string &string_value);
@@ -168,27 +173,57 @@ relationship_type from_string(const std::string &string)
template<>
pattern_fill_type from_string(const std::string &string)
{
- if (string == "darkdown") return pattern_fill_type::darkdown;
- else if (string == "darkgray") return pattern_fill_type::darkgray;
- else if (string == "darkgrid") return pattern_fill_type::darkgrid;
- else if (string == "darkhorizontal") return pattern_fill_type::darkhorizontal;
- else if (string == "darktrellis") return pattern_fill_type::darktrellis;
- else if (string == "darkup") return pattern_fill_type::darkup;
- else if (string == "darkvertical") return pattern_fill_type::darkvertical;
- else if (string == "gray0625") return pattern_fill_type::gray0625;
- else if (string == "gray125") return pattern_fill_type::gray125;
- else if (string == "lightdown") return pattern_fill_type::lightdown;
- else if (string == "lightgray") return pattern_fill_type::lightgray;
- else if (string == "lightgrid") return pattern_fill_type::lightgrid;
- else if (string == "lighthorizontal") return pattern_fill_type::lighthorizontal;
- else if (string == "lighttrellis") return pattern_fill_type::lighttrellis;
- else if (string == "lightup") return pattern_fill_type::lightup;
- else if (string == "lightvertical") return pattern_fill_type::lightvertical;
- else if (string == "mediumgray") return pattern_fill_type::mediumgray;
- else if (string == "none") return pattern_fill_type::none;
- else if (string == "solid") return pattern_fill_type::solid;
-
- default_case(pattern_fill_type::none);
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wexit-time-destructors"
+ static std::unordered_map patternFill {
+ {"darkdown", pattern_fill_type::darkdown },
+ { "darkgray", pattern_fill_type::darkgray },
+ { "darkgrid", pattern_fill_type::darkgrid },
+ { "darkhorizontal", pattern_fill_type::darkhorizontal },
+ { "darktrellis", pattern_fill_type::darktrellis },
+ { "darkup", pattern_fill_type::darkup },
+ { "darkvertical", pattern_fill_type::darkvertical },
+ { "gray0625", pattern_fill_type::gray0625 },
+ { "gray125", pattern_fill_type::gray125 },
+ { "lightdown", pattern_fill_type::lightdown },
+ { "lightgray", pattern_fill_type::lightgray },
+ { "lightgrid", pattern_fill_type::lightgrid },
+ { "lighthorizontal", pattern_fill_type::lighthorizontal },
+ { "lighttrellis", pattern_fill_type::lighttrellis },
+ { "lightup", pattern_fill_type::lightup },
+ { "lightvertical", pattern_fill_type::lightvertical },
+ { "mediumgray", pattern_fill_type::mediumgray },
+ { "none", pattern_fill_type::none },
+ { "solid", pattern_fill_type::solid }
+ };
+#pragma clang diagnostic pop
+
+ auto toLower = [](std::string str) {
+ auto bg{ std::begin (str) };
+ auto en{ std::end (str) };
+ std::transform(bg, en, bg,
+ [](char c) {
+ // static cast to avoid int -> char narrowing warning
+ return static_cast(tolower(c));
+ });
+
+ return str;
+ };
+
+ auto patternLookup = [](const std::string& key) {
+ auto entry { patternFill.find (key) };
+ if (entry != std::end (patternFill)) {
+ return entry->second;
+ }
+ else {
+ // Note: there won't be an error if there is an unsupported pattern
+ return pattern_fill_type::none;
+ }
+ };
+
+ std::string lowerString {toLower (string) };
+
+ return patternLookup (lowerString);
}
template<>
@@ -362,6 +397,15 @@ pane_corner from_string(const std::string &string)
default_case(pane_corner::bottom_left);
}
+template <>
+orientation from_string(const std::string &string)
+{
+ if (string == "default") return orientation::default_orientation;
+ else if (string == "landscape") return orientation::landscape;
+ else if (string == "portrait") return orientation::portrait;
+ default_case(orientation::default);
+}
+
} // namespace detail
} // namespace xlnt
@@ -550,6 +594,20 @@ struct value_traits
}
};
+template <>
+struct value_traits
+{
+ static xlnt::orientation parse(std::string string, const parser &)
+ {
+ return xlnt::detail::from_string(string);
+ }
+
+ static std::string serialize(xlnt::orientation orientation, const serializer &)
+ {
+ return xlnt::detail::to_string(orientation);
+ }
+};
+
} // namespace xml
diff --git a/xlnt/source/detail/serialization/excel_thumbnail.hpp b/xlnt/source/detail/serialization/excel_thumbnail.hpp
index c3699fe..2640e68 100644
--- a/xlnt/source/detail/serialization/excel_thumbnail.hpp
+++ b/xlnt/source/detail/serialization/excel_thumbnail.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2017 Thomas Fussell
+// Copyright (c) 2016-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/serialization/miniz.cpp b/xlnt/source/detail/serialization/miniz.cpp
index 290ff88..f6bf233 100644
--- a/xlnt/source/detail/serialization/miniz.cpp
+++ b/xlnt/source/detail/serialization/miniz.cpp
@@ -2095,7 +2095,7 @@ void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int
for (y = 0; y < h; ++y)
{
tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH);
- tdefl_compress_buffer(pComp, (mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH);
+ tdefl_compress_buffer(pComp, (const mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH);
}
if (tdefl_compress_buffer(pComp, nullptr, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE)
{
diff --git a/xlnt/source/detail/serialization/open_stream.cpp b/xlnt/source/detail/serialization/open_stream.cpp
index 290adcb..fcb6c33 100644
--- a/xlnt/source/detail/serialization/open_stream.cpp
+++ b/xlnt/source/detail/serialization/open_stream.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/serialization/open_stream.hpp b/xlnt/source/detail/serialization/open_stream.hpp
index b69aa20..00f9a71 100644
--- a/xlnt/source/detail/serialization/open_stream.hpp
+++ b/xlnt/source/detail/serialization/open_stream.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Thomas Fussell
+// Copyright (c) 2017-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/serialization/vector_streambuf.cpp b/xlnt/source/detail/serialization/vector_streambuf.cpp
index 24abae7..95b48e7 100644
--- a/xlnt/source/detail/serialization/vector_streambuf.cpp
+++ b/xlnt/source/detail/serialization/vector_streambuf.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2017 Thomas Fussell
+// Copyright (c) 2016-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/serialization/vector_streambuf.hpp b/xlnt/source/detail/serialization/vector_streambuf.hpp
index 482e2fc..2e50761 100644
--- a/xlnt/source/detail/serialization/vector_streambuf.hpp
+++ b/xlnt/source/detail/serialization/vector_streambuf.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2017 Thomas Fussell
+// Copyright (c) 2016-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/xlnt/source/detail/serialization/xlsx_consumer.cpp b/xlnt/source/detail/serialization/xlsx_consumer.cpp
index c7b8bc8..2f29e19 100644
--- a/xlnt/source/detail/serialization/xlsx_consumer.cpp
+++ b/xlnt/source/detail/serialization/xlsx_consumer.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2017 Thomas Fussell
+// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -26,21 +26,22 @@
#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
#include
#include
+#include
#include
#include
#include
#include
#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
namespace std {
@@ -124,6 +125,23 @@ struct number_converter
double result;
};
+using style_id_pair = std::pair;
+
+///
+/// Try to find given xfid value in the styles vector and, if succeeded, set's the optional style.
+///
+void set_style_by_xfid(const std::vector &styles,
+ std::size_t xfid, xlnt::optional &style)
+{
+ for (auto &item : styles)
+ {
+ if (item.second == xfid)
+ {
+ style = item.first.name;
+ }
+ }
+}
+
} // namespace
/*
@@ -181,25 +199,31 @@ cell xlsx_consumer::read_cell()
{
expect_start_element(qn("spreadsheetml", "row"), xml::content::complex); // CT_Row
auto row_index = static_cast(std::stoul(parser().attribute("r")));
+ auto &row_properties = ws.row_properties(row_index);
if (parser().attribute_present("ht"))
{
- ws.row_properties(row_index).height = parser().attribute("ht");
+ row_properties.height = parser().attribute("ht");
}
if (parser().attribute_present("customHeight"))
{
- ws.row_properties(row_index).custom_height = is_true(parser().attribute("customHeight"));
+ row_properties.custom_height = is_true(parser().attribute("customHeight"));
}
if (parser().attribute_present("hidden") && is_true(parser().attribute("hidden")))
{
- ws.row_properties(row_index).hidden = true;
+ row_properties.hidden = true;
}
- skip_attributes({ qn("x14ac", "dyDescent") });
- skip_attributes({ "customFormat", "s", "customFont",
+
+ if (parser().attribute_present(qn("x14ac", "dyDescent")))
+ {
+ row_properties.dy_descent = parser().attribute(qn("x14ac", "dyDescent"));
+ }
+
+ skip_attributes({"customFormat", "s", "customFont",
"outlineLevel", "collapsed", "thickTop", "thickBot",
- "ph", "spans" });
+ "ph", "spans"});
}
if (!in_element(qn("spreadsheetml", "row")))
@@ -209,7 +233,8 @@ cell xlsx_consumer::read_cell()
expect_start_element(qn("spreadsheetml", "c"), xml::content::complex);
- auto cell = streaming_ ? xlnt::cell(streaming_cell_.get())
+ auto cell = streaming_
+ ? xlnt::cell(streaming_cell_.get())
: ws.cell(cell_reference(parser().attribute("r")));
auto reference = cell_reference(parser().attribute("r"));
cell.d_->parent_ = current_worksheet_;
@@ -221,7 +246,7 @@ cell xlsx_consumer::read_cell()
if (parser().attribute_present("s"))
{
- cell.format(target_.format(std::stoull(parser().attribute("s"))));
+ cell.format(target_.format(static_cast(std::stoull(parser().attribute("s")))));
}
auto has_value = false;
@@ -249,8 +274,8 @@ cell xlsx_consumer::read_cell()
has_shared_formula = parser().attribute("t") == "shared";
}
- skip_attributes(
- { "aca", "ref", "dt2D", "dtr", "del1", "del2", "r1", "r2", "ca", "si", "bx" });
+ skip_attributes({"aca", "ref", "dt2D", "dtr", "del1",
+ "del2", "r1", "r2", "ca", "si", "bx"});
formula_value_string = read_text();
}
@@ -342,13 +367,13 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
auto title = std::find_if(target_.d_->sheet_title_rel_id_map_.begin(),
target_.d_->sheet_title_rel_id_map_.end(),
[&](const std::pair &p) {
- return p.second == rel_id;
- })->first;
+ return p.second == rel_id;
+ })->first;
auto ws = worksheet(current_worksheet_);
expect_start_element(qn("spreadsheetml", "worksheet"), xml::content::complex); // CT_Worksheet
- skip_attributes({ qn("mc", "Ignorable") });
+ skip_attributes({qn("mc", "Ignorable")});
while (in_element(qn("spreadsheetml", "worksheet")))
{
@@ -356,6 +381,44 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
if (current_worksheet_element == qn("spreadsheetml", "sheetPr")) // CT_SheetPr 0-1
{
+ sheet_pr props;
+ if (parser().attribute_present("syncHorizontal"))
+ { // optional, boolean, false
+ props.sync_horizontal.set(parser().attribute("syncHorizontal"));
+ }
+ if (parser().attribute_present("syncVertical"))
+ { // optional, boolean, false
+ props.sync_vertical.set(parser().attribute("syncVertical"));
+ }
+ if (parser().attribute_present("syncRef"))
+ { // optional, ST_Ref, false
+ props.sync_ref.set(cell_reference(parser().attribute("syncRef")));
+ }
+ if (parser().attribute_present("transitionEvaluation"))
+ { // optional, boolean, false
+ props.transition_evaluation.set(parser().attribute("transitionEvaluation"));
+ }
+ if (parser().attribute_present("transitionEntry"))
+ { // optional, boolean, false
+ props.transition_entry.set(parser().attribute("transitionEntry"));
+ }
+ if (parser().attribute_present("published"))
+ { // optional, boolean, true
+ props.published.set(parser().attribute("published"));
+ }
+ if (parser().attribute_present("codeName"))
+ { // optional, string
+ props.code_name.set(parser().attribute("codeName"));
+ }
+ if (parser().attribute_present("filterMode"))
+ { // optional, boolean, false
+ props.filter_mode.set(parser().attribute("filterMode"));
+ }
+ if (parser().attribute_present("enableFormatConditionsCalculation"))
+ { // optional, boolean, true
+ props.enable_format_condition_calculation.set(parser().attribute("enableFormatConditionsCalculation"));
+ }
+ ws.d_->sheet_properties_.set(props);
while (in_element(current_worksheet_element))
{
auto sheet_pr_child_element = expect_start_element(xml::content::simple);
@@ -383,16 +446,6 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
expect_end_element(sheet_pr_child_element);
}
-
- skip_attribute("syncHorizontal"); // optional, boolean, false
- skip_attribute("syncVertical"); // optional, boolean, false
- skip_attribute("syncRef"); // optional, ST_Ref, false
- skip_attribute("transitionEvaluation"); // optional, boolean, false
- skip_attribute("transitionEntry"); // optional, boolean, false
- skip_attribute("published"); // optional, boolean, true
- skip_attribute("codeName"); // optional, string
- skip_attribute("filterMode"); // optional, boolean, false
- skip_attribute("enableFormatConditionsCalculation"); // optional, boolean, true
}
else if (current_worksheet_element == qn("spreadsheetml", "dimension")) // CT_SheetDimension 0-1
{
@@ -411,22 +464,33 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
{
new_view.show_grid_lines(is_true(parser().attribute("showGridLines")));
}
+ if (parser().attribute_present("topLeftCell"))
+ {
+ new_view.top_left_cell(cell_reference(parser().attribute("topLeftCell")));
+ }
if (parser().attribute_present("defaultGridColor")) // default="true"
{
new_view.default_grid_color(is_true(parser().attribute("defaultGridColor")));
}
- if (parser().attribute_present("view") && parser().attribute("view") != "normal")
+ if (parser().attribute_present("view")
+ && parser().attribute("view") != "normal")
{
new_view.type(parser().attribute("view") == "pageBreakPreview"
- ? sheet_view_type::page_break_preview
- : sheet_view_type::page_layout);
+ ? sheet_view_type::page_break_preview
+ : sheet_view_type::page_layout);
}
- skip_attributes({ "windowProtection", "showFormulas", "showRowColHeaders", "showZeros", "rightToLeft",
- "tabSelected", "showRuler", "showOutlineSymbols", "showWhiteSpace", "view", "topLeftCell",
- "colorId", "zoomScale", "zoomScaleNormal", "zoomScaleSheetLayoutView", "zoomScalePageLayoutView" });
+ if (parser().attribute_present("tabSelected")
+ && is_true(parser().attribute("tabSelected")))
+ {
+ target_.d_->view_.get().active_tab = ws.id() - 1;
+ }
+
+ skip_attributes({"windowProtection", "showFormulas", "showRowColHeaders", "showZeros", "rightToLeft", "showRuler", "showOutlineSymbols", "showWhiteSpace",
+ "view", "topLeftCell", "colorId", "zoomScale", "zoomScaleNormal", "zoomScaleSheetLayoutView",
+ "zoomScalePageLayoutView"});
while (in_element(qn("spreadsheetml", "sheetView")))
{
@@ -471,7 +535,13 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
{
current_selection.active_cell(parser().attribute("activeCell"));
}
-
+
+ if (parser().attribute_present("sqref"))
+ {
+ const auto sqref = range_reference(parser().attribute("sqref"));
+ current_selection.sqref(sqref);
+ }
+
current_selection.pane(pane_corner::top_left);
new_view.add_selection(current_selection);
@@ -501,7 +571,29 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
}
else if (current_worksheet_element == qn("spreadsheetml", "sheetFormatPr")) // CT_SheetFormatPr 0-1
{
- skip_remaining_content(current_worksheet_element);
+ if (parser().attribute_present("baseColWidth"))
+ {
+ ws.d_->format_properties_.base_col_width =
+ parser().attribute("baseColWidth");
+ }
+ if (parser().attribute_present("defaultColWidth"))
+ {
+ ws.d_->format_properties_.default_column_width =
+ parser().attribute("defaultColWidth");
+ }
+ if (parser().attribute_present("defaultRowHeight"))
+ {
+ ws.d_->format_properties_.default_row_height =
+ parser().attribute("defaultRowHeight");
+ }
+
+ if (parser().attribute_present(qn("x14ac", "dyDescent")))
+ {
+ ws.d_->format_properties_.dy_descent =
+ parser().attribute(qn("x14ac", "dyDescent"));
+ }
+
+ skip_attributes();
}
else if (current_worksheet_element == qn("spreadsheetml", "cols")) // CT_Cols 0+
{
@@ -509,29 +601,37 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
{
expect_start_element(qn("spreadsheetml", "col"), xml::content::simple);
- skip_attributes({ "bestFit", "collapsed", "outlineLevel" });
+ skip_attributes(std::vector{"collapsed", "outlineLevel"});
auto min = static_cast(std::stoull(parser().attribute("min")));
auto max = static_cast(std::stoull(parser().attribute("max")));
- optional width;
-
- if (parser().attribute_present("width"))
- {
- width = (parser().attribute("width") * 7 - 5) / 7;
- }
-
- optional column_style;
-
- if (parser().attribute_present("style"))
- {
- column_style = parser().attribute("style");
- }
+ // avoid uninitialised warnings in GCC by using a lambda to make the conditional initialisation
+ optional width = [](xml::parser &p) -> xlnt::optional {
+ if (p.attribute_present("width"))
+ {
+ return (p.attribute("width") * 7 - 5) / 7;
+ }
+ return xlnt::optional();
+ }(parser());
+ // avoid uninitialised warnings in GCC by using a lambda to make the conditional initialisation
+ optional column_style = [](xml::parser &p) -> xlnt::optional {
+ if (p.attribute_present("style"))
+ {
+ return p.attribute("style");
+ }
+ return xlnt::optional();
+ }(parser());
auto custom = parser().attribute_present("customWidth")
- ? is_true(parser().attribute("customWidth")) : false;
+ ? is_true(parser().attribute("customWidth"))
+ : false;
auto hidden = parser().attribute_present("hidden")
- ? is_true(parser().attribute("hidden")) : false;
+ ? is_true(parser().attribute("hidden"))
+ : false;
+ auto best_fit = parser().attribute_present("bestFit")
+ ? is_true(parser().attribute("bestFit"))
+ : false;
expect_end_element(qn("spreadsheetml", "col"));
@@ -551,6 +651,7 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
props.hidden = hidden;
props.custom_width = custom;
+ props.best_fit = best_fit;
ws.add_column_properties(column, props);
}
}
@@ -581,26 +682,40 @@ void xlsx_consumer::read_worksheet_sheetdata()
{
expect_start_element(qn("spreadsheetml", "row"), xml::content::complex); // CT_Row
auto row_index = parser().attribute("r");
+ auto &row_properties = ws.row_properties(row_index);
if (parser().attribute_present("ht"))
{
- ws.row_properties(row_index).height = parser().attribute("ht");
+ row_properties.height = parser().attribute("ht");
}
if (parser().attribute_present("customHeight"))
{
- ws.row_properties(row_index).custom_height = is_true(parser().attribute("customHeight"));
+ row_properties.custom_height = is_true(parser().attribute("customHeight"));
}
if (parser().attribute_present("hidden") && is_true(parser().attribute("hidden")))
{
- ws.row_properties(row_index).hidden = true;
+ row_properties.hidden = true;
}
- skip_attributes({ qn("x14ac", "dyDescent") });
- skip_attributes({ "customFormat", "s", "customFont",
+ if (parser().attribute_present(qn("x14ac", "dyDescent")))
+ {
+ row_properties.dy_descent = parser().attribute(qn("x14ac", "dyDescent"));
+ }
+
+ if (parser().attribute_present("s"))
+ {
+ row_properties.style.set(static_cast(std::stoull(parser().attribute("s"))));
+ }
+ if (parser().attribute_present("customFormat"))
+ {
+ row_properties.custom_format.set(parser().attribute("customFormat"));
+ }
+
+ skip_attributes({"customFont",
"outlineLevel", "collapsed", "thickTop", "thickBot",
- "ph", "spans" });
+ "ph", "spans"});
while (in_element(qn("spreadsheetml", "row")))
{
@@ -612,7 +727,7 @@ void xlsx_consumer::read_worksheet_sheetdata()
if (parser().attribute_present("s"))
{
- cell.format(target_.format(std::stoull(parser().attribute("s"))));
+ cell.format(target_.format(static_cast(std::stoull(parser().attribute("s")))));
}
auto has_value = false;
@@ -641,7 +756,7 @@ void xlsx_consumer::read_worksheet_sheetdata()
}
skip_attributes(
- { "aca", "ref", "dt2D", "dtr", "del1", "del2", "r1", "r2", "ca", "si", "bx" });
+ {"aca", "ref", "dt2D", "dtr", "del1", "del2", "r1", "r2", "ca", "si", "bx"});
formula_value_string = read_text();
}
@@ -696,7 +811,6 @@ void xlsx_consumer::read_worksheet_sheetdata()
cell.error(value_string);
}
}
-
}
expect_end_element(qn("spreadsheetml", "row"));
@@ -774,7 +888,16 @@ worksheet xlsx_consumer::read_worksheet_end(const std::string &rel_id)
}
else if (current_worksheet_element == qn("spreadsheetml", "phoneticPr")) // CT_PhoneticPr 0-1
{
- skip_remaining_content(current_worksheet_element);
+ phonetic_pr phonetic_properties(parser().attribute("fontId"));
+ if (parser().attribute_present("type"))
+ {
+ phonetic_properties.type(phonetic_pr::type_from_string(parser().attribute("type")));
+ }
+ if (parser().attribute_present("alignment"))
+ {
+ phonetic_properties.alignment(phonetic_pr::alignment_from_string(parser().attribute("alignment")));
+ }
+ current_worksheet_->phonetic_properties_.set(phonetic_properties);
}
else if (current_worksheet_element == qn("spreadsheetml", "conditionalFormatting")) // CT_ConditionalFormatting 0+
{
@@ -786,8 +909,9 @@ worksheet xlsx_consumer::read_worksheet_end(const std::string &rel_id)
}
else if (current_worksheet_element == qn("spreadsheetml", "hyperlinks")) // CT_Hyperlinks 0-1
{
- while (in_element(qn("spreadsheetml", "hyperlinks")))
+ while (in_element(current_worksheet_element))
{
+ // CT_Hyperlink
expect_start_element(qn("spreadsheetml", "hyperlink"), xml::content::simple);
auto cell = ws.cell(parser().attribute("ref"));
@@ -800,16 +924,66 @@ worksheet xlsx_consumer::read_worksheet_end(const std::string &rel_id)
if (hyperlink_rel != hyperlinks.end())
{
- cell.hyperlink(hyperlink_rel->target().path().string());
+ auto url = hyperlink_rel->target().path().string();
+
+ if (cell.has_value())
+ {
+ cell.hyperlink(url, cell.value());
+ }
+ else
+ {
+ cell.hyperlink(url);
+ }
}
}
+ else if (parser().attribute_present("location"))
+ {
+ auto hyperlink = hyperlink_impl();
+
+ auto location = parser().attribute("location");
+ hyperlink.relationship = relationship("", relationship_type::hyperlink,
+ uri(""), uri(location), target_mode::internal);
+
+ if (parser().attribute_present("display"))
+ {
+ hyperlink.display = parser().attribute("display");
+ }
+
+ if (parser().attribute_present("tooltip"))
+ {
+ hyperlink.tooltip = parser().attribute("tooltip");
+ }
+
+ cell.d_->hyperlink_ = hyperlink;
+ }
- skip_attributes({ "location", "tooltip", "display" });
expect_end_element(qn("spreadsheetml", "hyperlink"));
}
}
else if (current_worksheet_element == qn("spreadsheetml", "printOptions")) // CT_PrintOptions 0-1
{
+ print_options opts;
+ if (parser().attribute_present("gridLines"))
+ {
+ opts.print_grid_lines.set(parser().attribute("gridLines"));
+ }
+ if (parser().attribute_present("gridLinesSet"))
+ {
+ opts.print_grid_lines.set(parser().attribute("gridLinesSet"));
+ }
+ if (parser().attribute_present("headings"))
+ {
+ opts.print_grid_lines.set(parser().attribute("headings"));
+ }
+ if (parser().attribute_present("horizontalCentered"))
+ {
+ opts.print_grid_lines.set(parser().attribute("horizontalCentered"));
+ }
+ if (parser().attribute_present("verticalCentered"))
+ {
+ opts.print_grid_lines.set(parser().attribute("verticalCentered"));
+ }
+ ws.d_->print_options_.set(opts);
skip_remaining_content(current_worksheet_element);
}
else if (current_worksheet_element == qn("spreadsheetml", "pageMargins")) // CT_PageMargins 0-1
@@ -827,20 +1001,34 @@ worksheet xlsx_consumer::read_worksheet_end(const std::string &rel_id)
}
else if (current_worksheet_element == qn("spreadsheetml", "pageSetup")) // CT_PageSetup 0-1
{
+ page_setup setup;
+ if (parser().attribute_present("orientation"))
+ {
+ setup.orientation_.set(parser().attribute