mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
begin refining headers and footers, remove dependency on pugixml
This commit is contained in:
parent
860ad43506
commit
e1157625a5
46
.gitmodules
vendored
46
.gitmodules
vendored
@ -1,35 +1,29 @@
|
||||
[submodule "third-party/libstudxml"]
|
||||
path = third-party/libstudxml
|
||||
url = http://scm.codesynthesis.com/libstudxml/libstudxml.git
|
||||
branch = master
|
||||
ignore = dirty
|
||||
path = third-party/libstudxml
|
||||
url = http://scm.codesynthesis.com/libstudxml/libstudxml.git
|
||||
branch = master
|
||||
ignore = dirty
|
||||
|
||||
[submodule "third-party/cxxtest"]
|
||||
path = third-party/cxxtest
|
||||
url = https://github.com/CxxTest/cxxtest
|
||||
branch = master
|
||||
ignore = dirty
|
||||
path = third-party/cxxtest
|
||||
url = https://github.com/CxxTest/cxxtest
|
||||
branch = master
|
||||
ignore = dirty
|
||||
|
||||
[submodule "third-party/utfcpp"]
|
||||
path = third-party/utfcpp
|
||||
url = https://github.com/nemtrif/utfcpp
|
||||
branch = master
|
||||
ignore = dirty
|
||||
|
||||
[submodule "third-party/pugixml"]
|
||||
path = third-party/pugixml
|
||||
url = https://github.com/zeux/pugixml
|
||||
branch = master
|
||||
ignore = dirty
|
||||
path = third-party/utfcpp
|
||||
url = https://github.com/nemtrif/utfcpp
|
||||
branch = master
|
||||
ignore = dirty
|
||||
|
||||
[submodule "third-party/botan"]
|
||||
path = third-party/botan
|
||||
url = https://github.com/randombit/botan
|
||||
branch = master
|
||||
ignore = dirty
|
||||
path = third-party/botan
|
||||
url = https://github.com/randombit/botan
|
||||
branch = master
|
||||
ignore = dirty
|
||||
|
||||
[submodule "third-party/zlib"]
|
||||
path = third-party/zlib
|
||||
url = https://github.com/madler/zlib.git
|
||||
branch = develop
|
||||
ignore = dirty
|
||||
path = third-party/zlib
|
||||
url = https://github.com/madler/zlib.git
|
||||
branch = develop
|
||||
ignore = dirty
|
||||
|
@ -62,9 +62,8 @@ xlnt requires the following libraries which are all distributed under permissive
|
||||
- [pole v0.5](https://github.com/catlan/pole) (BSD 2-Clause License)
|
||||
- [partio v1.1.0](https://github.com/wdas/partio) (BSD 3-Clause License with specific non-attribution clause)
|
||||
|
||||
Additionally, the xlnt test suite (bin/xlnt.test) requires two extra libraries. This test executable is separate from the main xlnt library assembly so the terms of these libraries' licenses should not apply to users of solely the xlnt library:
|
||||
Additionally, the xlnt test suite (bin/xlnt.test) requires an extra testing library. This test executable is separate from the main xlnt library assembly so the terms of this library's license should not apply to users of solely the xlnt library:
|
||||
- [cxxtest v4.4](http://cxxtest.com/) (LGPLv3 License)
|
||||
- [pugixml v1.7](http://pugixml.org/) (MIT License)
|
||||
|
||||
Initialize the submodules from the HEAD of their respective Git repositories with this command called from the xlnt root directory:
|
||||
```bash
|
||||
|
@ -369,11 +369,6 @@ public:
|
||||
|
||||
// printing
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string describing this cell like <Cell Sheet.A1>.
|
||||
/// </summary>
|
||||
std::string to_repr() const;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string representing the value of this cell. If the data type is not a string,
|
||||
/// it will be converted according to the number format.
|
||||
|
@ -38,6 +38,21 @@ namespace xlnt {
|
||||
class XLNT_API formatted_text
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
formatted_text() = default;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
formatted_text(const std::string &plain_text);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
formatted_text(const text_run &single_run);
|
||||
|
||||
/// <summary>
|
||||
/// Remove all text runs from this text.
|
||||
/// </summary>
|
||||
@ -74,6 +89,11 @@ public:
|
||||
/// </summary>
|
||||
bool operator==(const formatted_text &rhs) const;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this text has a single unformatted run with text equal to rhs.
|
||||
/// </summary>
|
||||
bool operator==(const std::string &rhs) const;
|
||||
|
||||
private:
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -63,7 +63,7 @@ public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void string(const std::string &string);
|
||||
text_run &string(const std::string &string);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -78,7 +78,7 @@ public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void size(std::size_t size);
|
||||
text_run &size(std::size_t size);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -93,7 +93,7 @@ public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void color(const class color &new_color);
|
||||
text_run &color(const class color &new_color);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -108,7 +108,7 @@ public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void font(const std::string &font);
|
||||
text_run &font(const std::string &font);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -123,7 +123,7 @@ public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void family(std::size_t family);
|
||||
text_run &family(std::size_t family);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -138,7 +138,7 @@ public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void scheme(const std::string &scheme);
|
||||
text_run &scheme(const std::string &scheme);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -148,7 +148,7 @@ public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void bold(bool bold);
|
||||
text_run &bold(bool bold);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -168,7 +168,7 @@ public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void underline(font::underline_style style);
|
||||
text_run &underline(font::underline_style style);
|
||||
|
||||
private:
|
||||
/// <summary>
|
||||
|
@ -1,97 +0,0 @@
|
||||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
// Copyright (c) 2010-2015 openpyxl
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
/// <summary>
|
||||
/// Worksheet footer
|
||||
/// </summary>
|
||||
class XLNT_API footer
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
footer();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void text(const std::string &text);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void font_name(const std::string &font_name);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void font_size(std::size_t font_size);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void font_color(const std::string &font_color);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
bool is_default() const;
|
||||
|
||||
private:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
bool default_;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
std::string text_;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
std::string font_name_;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
std::size_t font_size_;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
std::string font_color_;
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
@ -1,97 +0,0 @@
|
||||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
// Copyright (c) 2010-2015 openpyxl
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
/// <summary>
|
||||
/// Worksheet header
|
||||
/// </summary>
|
||||
class XLNT_API header
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
header();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void text(const std::string &text);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void font_name(const std::string &font_name);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void font_size(std::size_t font_size);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void font_color(const std::string &font_color);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
bool is_default() const;
|
||||
|
||||
private:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
bool default_;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
std::string text_;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
std::string font_name_;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
std::size_t font_size_;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
std::string font_color_;
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
@ -26,79 +26,297 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
#include <xlnt/worksheet/footer.hpp>
|
||||
#include <xlnt/worksheet/header.hpp>
|
||||
#include <xlnt/cell/formatted_text.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
/// <summary>
|
||||
/// Worksheet header and footer for all six possible positions.
|
||||
/// </summary>
|
||||
class XLNT_API header_footer
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
header_footer();
|
||||
enum class location
|
||||
{
|
||||
left,
|
||||
center,
|
||||
right
|
||||
};
|
||||
|
||||
// General Properties
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// True if any text has been added for a header at any location on any page.
|
||||
/// </summary>
|
||||
header &left_header();
|
||||
bool has_header() const;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// True if any text has been added for a footer at any location on any page.
|
||||
/// </summary>
|
||||
header ¢er_header();
|
||||
bool has_footer() const;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// True if headers and footers should align to the page margins.
|
||||
/// </summary>
|
||||
header &right_header();
|
||||
bool align_with_margins() const;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Set to true if headers and footers should align to the page margins.
|
||||
/// Set to false if headers and footers should align to the edge of the page.
|
||||
/// </summary>
|
||||
footer &left_footer();
|
||||
header_footer &align_with_margins(bool align);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// True if headers and footers differ based on page number.
|
||||
/// </summary>
|
||||
footer ¢er_footer();
|
||||
bool different_odd_even() const;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// True if headers and footers are different on the first page.
|
||||
/// </summary>
|
||||
footer &right_footer();
|
||||
bool different_first() const;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// True if headers and footers should scale to match the worksheet.
|
||||
/// </summary>
|
||||
bool is_default_header() const;
|
||||
bool scale_with_doc() const;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Set to true if headers and footers should scale to match the worksheet.
|
||||
/// </summary>
|
||||
bool is_default_footer() const;
|
||||
header_footer &scale_with_doc(bool scale);
|
||||
|
||||
|
||||
// Normal Header
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// True if any text has been added at the given location on any page.
|
||||
/// </summary>
|
||||
bool is_default() const;
|
||||
bool has_header(location where) const;
|
||||
|
||||
/// <summary>
|
||||
/// Remove all headers from all pages.
|
||||
/// </summary>
|
||||
void clear_header();
|
||||
|
||||
/// <summary>
|
||||
/// Remove header at the given location on any page.
|
||||
/// </summary>
|
||||
void clear_header(location where);
|
||||
|
||||
/// <summary>
|
||||
/// Add a header at the given location with the given text.
|
||||
/// </summary>
|
||||
header_footer &header(location where, const std::string &text);
|
||||
|
||||
/// <summary>
|
||||
/// Add a header at the given location with the given text.
|
||||
/// </summary>
|
||||
header_footer &header(location where, const formatted_text &text);
|
||||
|
||||
/// <summary>
|
||||
/// Get the text of the header at the given location. If headers are
|
||||
/// different on odd and even pages, the odd header will be returned.
|
||||
/// </summary>
|
||||
formatted_text header(location where) const;
|
||||
|
||||
// First Page Header
|
||||
|
||||
/// <summary>
|
||||
/// True if a header has been set for the first page at any location.
|
||||
/// </summary>
|
||||
bool has_first_page_header() const;
|
||||
|
||||
/// <summary>
|
||||
/// True if a header has been set for the first page at the given location.
|
||||
/// </summary>
|
||||
bool has_first_page_header(location where) const;
|
||||
|
||||
/// <summary>
|
||||
/// Remove all headers from the first page.
|
||||
/// </summary>
|
||||
void clear_first_page_header();
|
||||
|
||||
/// <summary>
|
||||
/// Remove header from the first page at the given location.
|
||||
/// </summary>
|
||||
void clear_first_page_header(location where);
|
||||
|
||||
/// <summary>
|
||||
/// Add a header on the first page at the given location with the given text.
|
||||
/// </summary>
|
||||
header_footer &first_page_header(location where, const formatted_text &text);
|
||||
|
||||
/// <summary>
|
||||
/// Get the text of the first page header at the given location. If no first
|
||||
/// page header has been set, the general header for that location will
|
||||
/// be returned.
|
||||
/// </summary>
|
||||
formatted_text first_page_header(location where) const;
|
||||
|
||||
|
||||
// Odd/Even Header
|
||||
|
||||
/// <summary>
|
||||
/// True if different headers have been set for odd and even pages.
|
||||
/// </summary>
|
||||
bool has_odd_even_header() const;
|
||||
|
||||
/// <summary>
|
||||
/// True if different headers have been set for odd and even pages at the given location.
|
||||
/// </summary>
|
||||
bool has_odd_even_header(location where) const;
|
||||
|
||||
/// <summary>
|
||||
/// Remove odd/even headers at all locations.
|
||||
/// </summary>
|
||||
void clear_odd_even_header();
|
||||
|
||||
/// <summary>
|
||||
/// Remove odd/even headers at the given location.
|
||||
/// </summary>
|
||||
void clear_odd_even_header(location where);
|
||||
|
||||
/// <summary>
|
||||
/// Add a header for odd pages at the given location with the given text.
|
||||
/// </summary>
|
||||
header_footer &odd_even_header(location where, const formatted_text &odd, const formatted_text &even);
|
||||
|
||||
/// <summary>
|
||||
/// Get the text of the odd page header at the given location. If no odd
|
||||
/// page header has been set, the general header for that location will
|
||||
/// be returned.
|
||||
/// </summary>
|
||||
formatted_text odd_header(location where) const;
|
||||
|
||||
/// <summary>
|
||||
/// Get the text of the even page header at the given location. If no even
|
||||
/// page header has been set, the general header for that location will
|
||||
/// be returned.
|
||||
/// </summary>
|
||||
formatted_text even_header(location where) const;
|
||||
|
||||
|
||||
// Normal Footer
|
||||
|
||||
/// <summary>
|
||||
/// True if any text has been added at the given location on any page.
|
||||
/// </summary>
|
||||
bool has_footer(location where) const;
|
||||
|
||||
/// <summary>
|
||||
/// Remove all footers from all pages.
|
||||
/// </summary>
|
||||
void clear_footer();
|
||||
|
||||
/// <summary>
|
||||
/// Remove footer at the given location on any page.
|
||||
/// </summary>
|
||||
void clear_footer(location where);
|
||||
|
||||
/// <summary>
|
||||
/// Add a footer at the given location with the given text.
|
||||
/// </summary>
|
||||
header_footer &footer(location where, const std::string &text);
|
||||
|
||||
/// <summary>
|
||||
/// Add a footer at the given location with the given text.
|
||||
/// </summary>
|
||||
header_footer &footer(location where, const formatted_text &text);
|
||||
|
||||
/// <summary>
|
||||
/// Get the text of the footer at the given location. If footers are
|
||||
/// different on odd and even pages, the odd footer will be returned.
|
||||
/// </summary>
|
||||
formatted_text footer(location where) const;
|
||||
|
||||
// First Page footer
|
||||
|
||||
/// <summary>
|
||||
/// True if a footer has been set for the first page at any location.
|
||||
/// </summary>
|
||||
bool has_first_page_footer() const;
|
||||
|
||||
/// <summary>
|
||||
/// True if a footer has been set for the first page at the given location.
|
||||
/// </summary>
|
||||
bool has_first_page_footer(location where) const;
|
||||
|
||||
/// <summary>
|
||||
/// Remove all footers from the first page.
|
||||
/// </summary>
|
||||
void clear_first_page_footer();
|
||||
|
||||
/// <summary>
|
||||
/// Remove footer from the first page at the given location.
|
||||
/// </summary>
|
||||
void clear_first_page_footer(location where);
|
||||
|
||||
/// <summary>
|
||||
/// Add a footer on the first page at the given location with the given text.
|
||||
/// </summary>
|
||||
header_footer &first_page_footer(location where, const formatted_text &text);
|
||||
|
||||
/// <summary>
|
||||
/// Get the text of the first page footer at the given location. If no first
|
||||
/// page footer has been set, the general footer for that location will
|
||||
/// be returned.
|
||||
/// </summary>
|
||||
formatted_text first_page_footer(location where) const;
|
||||
|
||||
|
||||
// Odd/Even Footer
|
||||
|
||||
/// <summary>
|
||||
/// True if different footers have been set for odd and even pages.
|
||||
/// </summary>
|
||||
bool has_odd_even_footer() const;
|
||||
|
||||
/// <summary>
|
||||
/// True if different footers have been set for odd and even pages at the given location.
|
||||
/// </summary>
|
||||
bool has_odd_even_footer(location where) const;
|
||||
|
||||
/// <summary>
|
||||
/// Remove odd/even footers at all locations.
|
||||
/// </summary>
|
||||
void clear_odd_even_footer();
|
||||
|
||||
/// <summary>
|
||||
/// Remove odd/even footers at the given location.
|
||||
/// </summary>
|
||||
void clear_odd_even_footer(location where);
|
||||
|
||||
/// <summary>
|
||||
/// Add a footer for odd pages at the given location with the given text.
|
||||
/// </summary>
|
||||
header_footer &odd_even_footer(location where, const formatted_text &odd, const formatted_text &even);
|
||||
|
||||
/// <summary>
|
||||
/// Get the text of the odd page footer at the given location. If no odd
|
||||
/// page footer has been set, the general footer for that location will
|
||||
/// be returned.
|
||||
/// </summary>
|
||||
formatted_text odd_footer(location where) const;
|
||||
|
||||
/// <summary>
|
||||
/// Get the text of the even page footer at the given location. If no even
|
||||
/// page footer has been set, the general footer for that location will
|
||||
/// be returned.
|
||||
/// </summary>
|
||||
formatted_text even_footer(location where) const;
|
||||
|
||||
private:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
header left_header_, right_header_, center_header_;
|
||||
bool align_with_margins_ = false;
|
||||
bool different_odd_even_ = false;
|
||||
bool scale_with_doc_ = false;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
footer left_footer_, right_footer_, center_footer_;
|
||||
std::unordered_map<location, formatted_text> odd_headers_;
|
||||
std::unordered_map<location, formatted_text> even_headers_;
|
||||
std::unordered_map<location, formatted_text> first_headers_;
|
||||
std::unordered_map<location, formatted_text> odd_footers_;
|
||||
std::unordered_map<location, formatted_text> even_footers_;
|
||||
std::unordered_map<location, formatted_text> first_footers_;
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
#include <xlnt/cell/index_types.hpp>
|
||||
#include <xlnt/packaging/relationship.hpp>
|
||||
#include <xlnt/worksheet/header_footer.hpp>
|
||||
#include <xlnt/worksheet/page_margins.hpp>
|
||||
#include <xlnt/worksheet/page_setup.hpp>
|
||||
#include <xlnt/worksheet/sheet_view.hpp>
|
||||
@ -46,6 +45,8 @@ class cell_vector;
|
||||
class column_properties;
|
||||
class comment;
|
||||
class const_range_iterator;
|
||||
class footer;
|
||||
class header;
|
||||
class range;
|
||||
class range_iterator;
|
||||
class range_reference;
|
||||
@ -101,11 +102,6 @@ public:
|
||||
/// </summary>
|
||||
worksheet(const worksheet &rhs);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
std::string to_string() const;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@ -360,11 +356,6 @@ public:
|
||||
/// </summary>
|
||||
range_reference calculate_dimension() const;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
bool has_dimension() const;
|
||||
|
||||
// cell merge
|
||||
|
||||
/// <summary>
|
||||
@ -538,11 +529,6 @@ public:
|
||||
/// </summary>
|
||||
void page_margins(const class page_margins &margins);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
bool has_format_properties() const;
|
||||
|
||||
// auto filter
|
||||
|
||||
/// <summary>
|
||||
@ -575,23 +561,6 @@ public:
|
||||
/// </summary>
|
||||
bool has_auto_filter() const;
|
||||
|
||||
// comments
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void increment_comments();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void decrement_comments();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
std::size_t comment_count() const;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@ -600,12 +569,17 @@ public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
xlnt::header_footer &header_footer();
|
||||
bool has_header_footer() const;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
const xlnt::header_footer &header_footer() const;
|
||||
class header_footer header_footer() const;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void header_footer(const class header_footer &new_header_footer);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -77,8 +77,7 @@
|
||||
#include <xlnt/worksheet/column_properties.hpp>
|
||||
#include <xlnt/worksheet/const_cell_iterator.hpp>
|
||||
#include <xlnt/worksheet/const_range_iterator.hpp>
|
||||
#include <xlnt/worksheet/footer.hpp>
|
||||
#include <xlnt/worksheet/header.hpp>
|
||||
#include <xlnt/worksheet/header_footer.hpp>
|
||||
#include <xlnt/worksheet/header_footer.hpp>
|
||||
#include <xlnt/worksheet/major_order.hpp>
|
||||
#include <xlnt/worksheet/orientation.hpp>
|
||||
|
@ -458,11 +458,6 @@ cell &cell::operator=(const cell &rhs)
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string cell::to_repr() const
|
||||
{
|
||||
return "<Cell " + worksheet().title() + "." + reference().to_string() + ">";
|
||||
}
|
||||
|
||||
std::string cell::hyperlink() const
|
||||
{
|
||||
return d_->hyperlink_.get();
|
||||
|
@ -28,6 +28,16 @@
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
formatted_text::formatted_text(const std::string &plain_text)
|
||||
: formatted_text(text_run(plain_text))
|
||||
{
|
||||
}
|
||||
|
||||
formatted_text::formatted_text(const text_run &single_run)
|
||||
{
|
||||
add_run(single_run);
|
||||
}
|
||||
|
||||
void formatted_text::clear()
|
||||
{
|
||||
runs_.clear();
|
||||
@ -106,4 +116,9 @@ bool formatted_text::operator==(const formatted_text &rhs) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool formatted_text::operator==(const std::string &rhs) const
|
||||
{
|
||||
return *this == formatted_text(rhs);
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
@ -314,16 +314,7 @@ public:
|
||||
TS_ASSERT(!cell.is_date());
|
||||
TS_ASSERT(cell.number_format().format_string() == "[hh]:mm:ss");
|
||||
}
|
||||
|
||||
void test_repr()
|
||||
{
|
||||
xlnt::workbook wb;
|
||||
auto ws = wb.active_sheet();
|
||||
auto cell = ws.cell(xlnt::cell_reference(1, 1));
|
||||
|
||||
TS_ASSERT(cell.to_repr() == "<Cell Sheet1.A1>");
|
||||
}
|
||||
|
||||
|
||||
void test_cell_offset()
|
||||
{
|
||||
xlnt::workbook wb;
|
||||
|
@ -39,9 +39,10 @@ std::string text_run::string() const
|
||||
return string_;
|
||||
}
|
||||
|
||||
void text_run::string(const std::string &string)
|
||||
text_run &text_run::string(const std::string &string)
|
||||
{
|
||||
string_ = string;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool text_run::has_formatting() const
|
||||
@ -59,7 +60,7 @@ std::size_t text_run::size() const
|
||||
return font_.get().size();
|
||||
}
|
||||
|
||||
void text_run::size(std::size_t size)
|
||||
text_run &text_run::size(std::size_t size)
|
||||
{
|
||||
if (!font_.is_set())
|
||||
{
|
||||
@ -67,6 +68,8 @@ void text_run::size(std::size_t size)
|
||||
}
|
||||
|
||||
font_.get().size(size);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool text_run::has_color() const
|
||||
@ -79,7 +82,7 @@ color text_run::color() const
|
||||
return font_.get().color();
|
||||
}
|
||||
|
||||
void text_run::color(const class color &new_color)
|
||||
text_run &text_run::color(const class color &new_color)
|
||||
{
|
||||
if (!font_.is_set())
|
||||
{
|
||||
@ -87,6 +90,8 @@ void text_run::color(const class color &new_color)
|
||||
}
|
||||
|
||||
font_.get().color(new_color);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool text_run::has_font() const
|
||||
@ -99,7 +104,7 @@ std::string text_run::font() const
|
||||
return font_.get().name();
|
||||
}
|
||||
|
||||
void text_run::font(const std::string &font)
|
||||
text_run &text_run::font(const std::string &font)
|
||||
{
|
||||
if (!font_.is_set())
|
||||
{
|
||||
@ -107,6 +112,8 @@ void text_run::font(const std::string &font)
|
||||
}
|
||||
|
||||
font_.get().name(font);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool text_run::has_family() const
|
||||
@ -119,7 +126,7 @@ std::size_t text_run::family() const
|
||||
return font_.get().family();
|
||||
}
|
||||
|
||||
void text_run::family(std::size_t family)
|
||||
text_run &text_run::family(std::size_t family)
|
||||
{
|
||||
if (!font_.is_set())
|
||||
{
|
||||
@ -127,6 +134,8 @@ void text_run::family(std::size_t family)
|
||||
}
|
||||
|
||||
font_.get().family(family);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool text_run::has_scheme() const
|
||||
@ -139,7 +148,7 @@ std::string text_run::scheme() const
|
||||
return font_.get().scheme();
|
||||
}
|
||||
|
||||
void text_run::scheme(const std::string &scheme)
|
||||
text_run &text_run::scheme(const std::string &scheme)
|
||||
{
|
||||
if (!font_.is_set())
|
||||
{
|
||||
@ -147,6 +156,8 @@ void text_run::scheme(const std::string &scheme)
|
||||
}
|
||||
|
||||
font_.get().scheme(scheme);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool text_run::bold() const
|
||||
@ -154,7 +165,7 @@ bool text_run::bold() const
|
||||
return font_.is_set() && font_.get().bold();
|
||||
}
|
||||
|
||||
void text_run::bold(bool bold)
|
||||
text_run &text_run::bold(bool bold)
|
||||
{
|
||||
if (!font_.is_set())
|
||||
{
|
||||
@ -162,9 +173,11 @@ void text_run::bold(bool bold)
|
||||
}
|
||||
|
||||
font_.get().bold(bold);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void text_run::underline(font::underline_style style)
|
||||
text_run &text_run::underline(font::underline_style style)
|
||||
{
|
||||
if (!font_.is_set())
|
||||
{
|
||||
@ -172,6 +185,8 @@ void text_run::underline(font::underline_style style)
|
||||
}
|
||||
|
||||
font_.get().underline(style);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <xlnt/worksheet/range_reference.hpp>
|
||||
#include <xlnt/worksheet/sheet_view.hpp>
|
||||
#include <xlnt/worksheet/column_properties.hpp>
|
||||
#include <xlnt/worksheet/header_footer.hpp>
|
||||
#include <xlnt/worksheet/row_properties.hpp>
|
||||
|
||||
#include <detail/cell_impl.hpp>
|
||||
@ -46,8 +47,7 @@ struct worksheet_impl
|
||||
worksheet_impl(workbook *parent_workbook, std::size_t id, const std::string &title)
|
||||
: parent_(parent_workbook),
|
||||
id_(id),
|
||||
title_(title),
|
||||
comment_count_(0)
|
||||
title_(title)
|
||||
{
|
||||
}
|
||||
|
||||
@ -59,11 +59,13 @@ struct worksheet_impl
|
||||
void operator=(const worksheet_impl &other)
|
||||
{
|
||||
parent_ = other.parent_;
|
||||
|
||||
id_ = other.id_;
|
||||
title_ = other.title_;
|
||||
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)
|
||||
@ -71,46 +73,43 @@ struct worksheet_impl
|
||||
cell.second.parent_ = this;
|
||||
}
|
||||
}
|
||||
relationships_ = other.relationships_;
|
||||
has_page_setup_ = other.has_page_setup_;
|
||||
|
||||
page_setup_ = other.page_setup_;
|
||||
auto_filter_ = other.auto_filter_;
|
||||
has_page_margins_ = other.has_page_margins_;
|
||||
page_margins_ = other.page_margins_;
|
||||
merged_cells_ = other.merged_cells_;
|
||||
named_ranges_ = other.named_ranges_;
|
||||
comment_count_ = other.comment_count_;
|
||||
header_footer_ = other.header_footer_;
|
||||
print_title_cols_ = other.print_title_cols_;
|
||||
print_title_rows_ = other.print_title_rows_;
|
||||
print_area_ = other.print_area_;
|
||||
views_ = other.views_;
|
||||
has_dimension_ = other.has_dimension_;
|
||||
has_format_properties_ = other.has_format_properties_;
|
||||
}
|
||||
|
||||
workbook *parent_;
|
||||
|
||||
std::size_t id_;
|
||||
std::string title_;
|
||||
|
||||
std::unordered_map<column_t, column_properties> column_properties_;
|
||||
std::unordered_map<row_t, row_properties> row_properties_;
|
||||
|
||||
std::unordered_map<row_t, std::unordered_map<column_t, cell_impl>> cell_map_;
|
||||
std::vector<relationship> relationships_;
|
||||
bool has_page_setup_ = false;
|
||||
page_setup page_setup_;
|
||||
range_reference auto_filter_;
|
||||
bool has_page_margins_ = false;
|
||||
page_margins page_margins_;
|
||||
|
||||
optional<page_setup> page_setup_;
|
||||
optional<range_reference> auto_filter_;
|
||||
optional<page_margins> page_margins_;
|
||||
std::vector<range_reference> merged_cells_;
|
||||
std::unordered_map<std::string, named_range> named_ranges_;
|
||||
std::size_t comment_count_;
|
||||
header_footer header_footer_;
|
||||
|
||||
optional<header_footer> header_footer_;
|
||||
|
||||
std::string print_title_cols_;
|
||||
std::string print_title_rows_;
|
||||
range_reference print_area_;
|
||||
|
||||
optional<range_reference> print_area_;
|
||||
|
||||
std::vector<sheet_view> views_;
|
||||
bool has_dimension_ = false;
|
||||
bool has_format_properties_ = false;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
@ -1378,12 +1378,47 @@ void xlsx_consumer::read_worksheet(const std::string &rel_id)
|
||||
|
||||
if (current_worksheet_element == xml::qname(xmlns, "sheetPr")) // CT_SheetPr 0-1
|
||||
{
|
||||
skip_remaining_content(current_worksheet_element);
|
||||
while (in_element(current_worksheet_element))
|
||||
{
|
||||
auto sheet_pr_child_element = expect_start_element(xml::content::simple);
|
||||
|
||||
if (sheet_pr_child_element == xml::qname(xmlns, "tabColor")) // CT_Color 0-1
|
||||
{
|
||||
read_color();
|
||||
}
|
||||
else if (sheet_pr_child_element == xml::qname(xmlns, "outlinePr")) // CT_OutlinePr 0-1
|
||||
{
|
||||
skip_attribute("applyStyles"); // optional, boolean, false
|
||||
skip_attribute("summaryBelow"); // optional, boolean, true
|
||||
skip_attribute("summaryRight"); // optional, boolean, true
|
||||
skip_attribute("showOutlineSymbols"); // optional, boolean, true
|
||||
}
|
||||
else if (sheet_pr_child_element == xml::qname(xmlns, "pageSetUpPr")) // CT_PageSetUpPr 0-1
|
||||
{
|
||||
skip_attribute("autoPageBreaks"); // optional, boolean, true
|
||||
skip_attribute("fitToPage"); // optional, boolean, false
|
||||
}
|
||||
else
|
||||
{
|
||||
unexpected_element(sheet_pr_child_element);
|
||||
}
|
||||
|
||||
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 == xml::qname(xmlns, "dimension")) // CT_SheetDimension 0-1
|
||||
{
|
||||
full_range = xlnt::range_reference(parser().attribute("ref"));
|
||||
ws.d_->has_dimension_ = true;
|
||||
}
|
||||
else if (current_worksheet_element == xml::qname(xmlns, "sheetViews")) // CT_SheetViews 0-1
|
||||
{
|
||||
@ -1471,7 +1506,6 @@ void xlsx_consumer::read_worksheet(const std::string &rel_id)
|
||||
}
|
||||
else if (current_worksheet_element == xml::qname(xmlns, "sheetFormatPr")) // CT_SheetFormatPr 0-1
|
||||
{
|
||||
ws.d_->has_format_properties_ = true;
|
||||
skip_remaining_content(current_worksheet_element);
|
||||
}
|
||||
else if (current_worksheet_element == xml::qname(xmlns, "cols")) // CT_Cols 0+
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <xlnt/workbook/const_worksheet_iterator.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
#include <xlnt/workbook/workbook_view.hpp>
|
||||
#include <xlnt/worksheet/header_footer.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
|
||||
using namespace std::string_literals;
|
||||
@ -1820,14 +1821,11 @@ void xlsx_producer::write_worksheet(const relationship &rel)
|
||||
serializer().end_element(xmlns, "sheetPr");
|
||||
}
|
||||
|
||||
if (ws.has_dimension())
|
||||
{
|
||||
serializer().start_element(xmlns, "dimension");
|
||||
const auto dimension = ws.calculate_dimension();
|
||||
serializer().attribute("ref", dimension.is_single_cell()
|
||||
? dimension.top_left().to_string() : dimension.to_string());
|
||||
serializer().end_element(xmlns, "dimension");
|
||||
}
|
||||
serializer().start_element(xmlns, "dimension");
|
||||
const auto dimension = ws.calculate_dimension();
|
||||
serializer().attribute("ref", dimension.is_single_cell()
|
||||
? dimension.top_left().to_string() : dimension.to_string());
|
||||
serializer().end_element(xmlns, "dimension");
|
||||
|
||||
if (ws.has_view())
|
||||
{
|
||||
@ -1892,13 +1890,10 @@ void xlsx_producer::write_worksheet(const relationship &rel)
|
||||
serializer().end_element(xmlns, "sheetViews");
|
||||
}
|
||||
|
||||
if (ws.has_format_properties())
|
||||
{
|
||||
serializer().start_element(xmlns, "sheetFormatPr");
|
||||
serializer().attribute("baseColWidth", "10");
|
||||
serializer().attribute("defaultRowHeight", "16");
|
||||
serializer().end_element(xmlns, "sheetFormatPr");
|
||||
}
|
||||
serializer().start_element(xmlns, "sheetFormatPr");
|
||||
serializer().attribute("baseColWidth", "10");
|
||||
serializer().attribute("defaultRowHeight", "16");
|
||||
serializer().end_element(xmlns, "sheetFormatPr");
|
||||
|
||||
bool has_column_properties = false;
|
||||
|
||||
@ -2205,20 +2200,111 @@ void xlsx_producer::write_worksheet(const relationship &rel)
|
||||
serializer().end_element(xmlns, "pageSetup");
|
||||
}
|
||||
|
||||
if (!ws.header_footer().is_default())
|
||||
if (ws.has_header_footer())
|
||||
{
|
||||
// todo: this shouldn't be hardcoded
|
||||
static const auto header_text = new std::string(
|
||||
"&L&\"Calibri,Regular\"&K000000Left Header Text&C&\"Arial,Regular\"&6&K445566Center Header "
|
||||
"Text&R&\"Arial,Bold\"&8&K112233Right Header Text");
|
||||
static const auto footer_text = new std::string(
|
||||
"&L&\"Times New Roman,Regular\"&10&K445566Left Footer Text_x000D_And &D and &T&C&\"Times New "
|
||||
"Roman,Bold\"&12&K778899Center Footer Text &Z&F on &A&R&\"Times New Roman,Italic\"&14&KAABBCCRight Footer "
|
||||
"Text &P of &N");
|
||||
const auto hf = ws.header_footer();
|
||||
|
||||
serializer().start_element(xmlns, "headerFooter");
|
||||
serializer().element(xmlns, "oddHeader", *header_text);
|
||||
serializer().element(xmlns, "oddFooter", *footer_text);
|
||||
|
||||
auto odd_header = std::string();
|
||||
auto odd_footer = std::string();
|
||||
auto even_header = std::string();
|
||||
auto even_footer = std::string();
|
||||
auto first_header = std::string();
|
||||
auto first_footer = std::string();
|
||||
|
||||
const auto encode_text = [](const formatted_text &t, header_footer::location where)
|
||||
{
|
||||
const auto location_code_map = std::unordered_map<xlnt::header_footer::location, std::string>
|
||||
{
|
||||
{ xlnt::header_footer::location::left, "&L" },
|
||||
{ xlnt::header_footer::location::center, "&C" },
|
||||
{ xlnt::header_footer::location::right, "&R" },
|
||||
};
|
||||
|
||||
return location_code_map.at(where) + t.plain_text();
|
||||
};
|
||||
|
||||
const auto locations =
|
||||
{
|
||||
header_footer::location::left,
|
||||
header_footer::location::center,
|
||||
header_footer::location::right
|
||||
};
|
||||
|
||||
for (auto location : locations)
|
||||
{
|
||||
if (hf.different_odd_even())
|
||||
{
|
||||
if (hf.has_odd_even_header(location))
|
||||
{
|
||||
odd_header.append(encode_text(hf.odd_header(location), location));
|
||||
even_header.append(encode_text(hf.even_header(location), location));
|
||||
}
|
||||
|
||||
if (hf.has_odd_even_footer(location))
|
||||
{
|
||||
odd_footer.append(encode_text(hf.odd_footer(location), location));
|
||||
even_footer.append(encode_text(hf.even_footer(location), location));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hf.has_header(location))
|
||||
{
|
||||
odd_header.append(encode_text(hf.header(location), location));
|
||||
}
|
||||
|
||||
if (hf.has_footer(location))
|
||||
{
|
||||
odd_footer.append(encode_text(hf.footer(location), location));
|
||||
}
|
||||
}
|
||||
|
||||
if (hf.different_first())
|
||||
{
|
||||
if (hf.has_first_page_header(location))
|
||||
{
|
||||
first_header.append(encode_text(hf.first_page_header(location), location));
|
||||
}
|
||||
|
||||
if (hf.has_first_page_footer(location))
|
||||
{
|
||||
first_footer.append(encode_text(hf.first_page_footer(location), location));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!odd_header.empty())
|
||||
{
|
||||
serializer().element(xmlns, "oddHeader", odd_header);
|
||||
}
|
||||
|
||||
if (!odd_footer.empty())
|
||||
{
|
||||
serializer().element(xmlns, "oddFooter", odd_footer);
|
||||
}
|
||||
|
||||
if (!even_header.empty())
|
||||
{
|
||||
serializer().element(xmlns, "evenHeader", even_header);
|
||||
}
|
||||
|
||||
if (!even_footer.empty())
|
||||
{
|
||||
serializer().element(xmlns, "evenFooter", even_footer);
|
||||
}
|
||||
|
||||
if (!first_header.empty())
|
||||
{
|
||||
serializer().element(xmlns, "firstHeader", first_header);
|
||||
}
|
||||
|
||||
if (!first_footer.empty())
|
||||
{
|
||||
serializer().element(xmlns, "firstFooter", first_footer);
|
||||
}
|
||||
|
||||
serializer().end_element(xmlns, "headerFooter");
|
||||
}
|
||||
|
||||
|
24
source/utils/tests/test_tests.hpp
Normal file
24
source/utils/tests/test_tests.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <helpers/xml_helper.hpp>
|
||||
|
||||
class test_tests : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_compare()
|
||||
{
|
||||
TS_ASSERT(!xml_helper::compare_xml_exact("<a/>", "<b/>", true));
|
||||
TS_ASSERT(!xml_helper::compare_xml_exact("<a/>", "<a b=\"4\"/>", true));
|
||||
TS_ASSERT(!xml_helper::compare_xml_exact("<a b=\"3\"/>", "<a/>", true));
|
||||
TS_ASSERT(!xml_helper::compare_xml_exact("<a c=\"4\"/>", "<a b=\"4\"/>", true));
|
||||
TS_ASSERT(!xml_helper::compare_xml_exact("<a b=\"3\"/>", "<a b=\"4\"/>", true));
|
||||
TS_ASSERT(!xml_helper::compare_xml_exact("<a>text</a>", "<a>txet</a>", true));
|
||||
TS_ASSERT(!xml_helper::compare_xml_exact("<a>text</a>", "<a><b>txet</b></a>", true));
|
||||
TS_ASSERT(xml_helper::compare_xml_exact("<a/>", "<a> </a>", true));
|
||||
TS_ASSERT(xml_helper::compare_xml_exact("<a b=\"3\"/>", "<a b=\"3\"></a>", true));
|
||||
TS_ASSERT(xml_helper::compare_xml_exact("<a>text</a>", "<a>text</a>", true));
|
||||
}
|
||||
};
|
@ -59,6 +59,7 @@
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
#include <xlnt/workbook/workbook_view.hpp>
|
||||
#include <xlnt/workbook/worksheet_iterator.hpp>
|
||||
#include <xlnt/worksheet/header_footer.hpp>
|
||||
#include <xlnt/worksheet/range.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
|
||||
@ -200,8 +201,6 @@ workbook workbook::empty_excel()
|
||||
margins.header(0.3);
|
||||
margins.footer(0.3);
|
||||
ws.page_margins(margins);
|
||||
ws.d_->has_dimension_ = true;
|
||||
ws.d_->has_format_properties_ = true;
|
||||
|
||||
sheet_view view;
|
||||
ws.add_view(view);
|
||||
@ -282,12 +281,10 @@ workbook workbook::empty_libre_office()
|
||||
wb.d_->sheet_title_rel_id_map_[title] = ws_rel;
|
||||
|
||||
auto ws = wb.sheet_by_index(0);
|
||||
ws.d_->has_format_properties_ = true;
|
||||
|
||||
sheet_view view;
|
||||
ws.add_view(view);
|
||||
|
||||
ws.d_->has_dimension_ = true;
|
||||
page_margins margins;
|
||||
margins.left(0.7875);
|
||||
margins.right(0.7875);
|
||||
@ -297,8 +294,11 @@ workbook workbook::empty_libre_office()
|
||||
margins.footer(0.7875);
|
||||
ws.page_margins(margins);
|
||||
ws.page_setup(page_setup());
|
||||
ws.header_footer().center_header().font_name("&C&\"Times New Roman\"&12&A");
|
||||
ws.header_footer().center_footer().font_name("&C&\"Times New Roman\"&12Page &B");
|
||||
ws.header_footer(xlnt::header_footer()
|
||||
.header(header_footer::location::center,
|
||||
formatted_text(text_run("&A").font("Times New Roman").size(12)))
|
||||
.footer(header_footer::location::center,
|
||||
formatted_text(text_run("Page &B").font("Times New Roman").size(12))));
|
||||
ws.add_column_properties(1, column_properties());
|
||||
|
||||
wb.d_->stylesheet_ = detail::stylesheet();
|
||||
@ -769,6 +769,11 @@ void workbook::load(std::istream &stream)
|
||||
|
||||
void workbook::load(const std::vector<std::uint8_t> &data)
|
||||
{
|
||||
if (data.size() < 22) // the shortest ZIP file is 22 bytes
|
||||
{
|
||||
throw xlnt::exception("file is empty or malformed");
|
||||
}
|
||||
|
||||
xlnt::detail::vector_istreambuf data_buffer(data);
|
||||
std::istream data_stream(&data_buffer);
|
||||
load(data_stream);
|
||||
@ -783,6 +788,12 @@ void workbook::load(const path &filename)
|
||||
{
|
||||
std::ifstream file_stream;
|
||||
open_stream(file_stream, filename.string());
|
||||
|
||||
if (!file_stream.good())
|
||||
{
|
||||
throw xlnt::exception("file not found " + filename.string());
|
||||
}
|
||||
|
||||
load(file_stream);
|
||||
}
|
||||
|
||||
@ -795,11 +806,22 @@ void workbook::load(const path &filename, const std::string &password)
|
||||
{
|
||||
std::ifstream file_stream;
|
||||
open_stream(file_stream, filename.string());
|
||||
|
||||
if (!file_stream.good())
|
||||
{
|
||||
throw xlnt::exception("file not found " + filename.string());
|
||||
}
|
||||
|
||||
return load(file_stream, password);
|
||||
}
|
||||
|
||||
void workbook::load(const std::vector<std::uint8_t> &data, const std::string &password)
|
||||
{
|
||||
if (data.size() < 22) // the shortest ZIP file is 22 bytes
|
||||
{
|
||||
throw xlnt::exception("file is empty or malformed");
|
||||
}
|
||||
|
||||
xlnt::detail::vector_istreambuf data_buffer(data);
|
||||
std::istream data_stream(&data_buffer);
|
||||
load(data_stream, password);
|
||||
|
@ -1,57 +0,0 @@
|
||||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
// Copyright (c) 2010-2015 openpyxl
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#include <xlnt/worksheet/footer.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
void footer::text(const std::string &text)
|
||||
{
|
||||
default_ = false;
|
||||
text_ = text;
|
||||
}
|
||||
|
||||
void footer::font_name(const std::string &font_name)
|
||||
{
|
||||
default_ = false;
|
||||
font_name_ = font_name;
|
||||
}
|
||||
|
||||
void footer::font_size(std::size_t font_size)
|
||||
{
|
||||
default_ = false;
|
||||
font_size_ = font_size;
|
||||
}
|
||||
|
||||
void footer::font_color(const std::string &font_color)
|
||||
{
|
||||
default_ = false;
|
||||
font_color_ = font_color;
|
||||
}
|
||||
|
||||
bool footer::is_default() const
|
||||
{
|
||||
return default_;
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
@ -1,57 +0,0 @@
|
||||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
// Copyright (c) 2010-2015 openpyxl
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#include <xlnt/worksheet/header.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
void header::text(const std::string &text)
|
||||
{
|
||||
default_ = false;
|
||||
text_ = text;
|
||||
}
|
||||
|
||||
void header::font_name(const std::string &font_name)
|
||||
{
|
||||
default_ = false;
|
||||
font_name_ = font_name;
|
||||
}
|
||||
|
||||
void header::font_size(std::size_t font_size)
|
||||
{
|
||||
default_ = false;
|
||||
font_size_ = font_size;
|
||||
}
|
||||
|
||||
void header::font_color(const std::string &font_color)
|
||||
{
|
||||
default_ = false;
|
||||
font_color_ = font_color;
|
||||
}
|
||||
|
||||
bool header::is_default() const
|
||||
{
|
||||
return default_;
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
@ -21,46 +21,278 @@
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
|
||||
#include <xlnt/worksheet/header_footer.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
header &header_footer::left_header()
|
||||
bool header_footer::has_header() const
|
||||
{
|
||||
return left_header_;
|
||||
}
|
||||
header &header_footer::center_header()
|
||||
{
|
||||
return center_header_;
|
||||
}
|
||||
header &header_footer::right_header()
|
||||
{
|
||||
return right_header_;
|
||||
}
|
||||
footer &header_footer::left_footer()
|
||||
{
|
||||
return left_footer_;
|
||||
}
|
||||
footer &header_footer::center_footer()
|
||||
{
|
||||
return center_footer_;
|
||||
}
|
||||
footer &header_footer::right_footer()
|
||||
{
|
||||
return right_footer_;
|
||||
return !odd_headers_.empty() || !even_headers_.empty() || has_first_page_header();
|
||||
}
|
||||
|
||||
bool header_footer::is_default_header() const
|
||||
bool header_footer::has_footer() const
|
||||
{
|
||||
return left_header_.is_default() && center_header_.is_default() && right_header_.is_default();
|
||||
return !odd_headers_.empty() || !even_headers_.empty() || has_first_page_footer();
|
||||
}
|
||||
bool header_footer::is_default_footer() const
|
||||
|
||||
bool header_footer::align_with_margins() const
|
||||
{
|
||||
return left_footer_.is_default() && center_footer_.is_default() && right_footer_.is_default();
|
||||
return align_with_margins_;
|
||||
}
|
||||
bool header_footer::is_default() const
|
||||
|
||||
header_footer &header_footer::align_with_margins(bool align)
|
||||
{
|
||||
return is_default_header() && is_default_footer();
|
||||
align_with_margins_ = align;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool header_footer::different_odd_even() const
|
||||
{
|
||||
return different_odd_even_;
|
||||
}
|
||||
|
||||
bool header_footer::different_first() const
|
||||
{
|
||||
return first_headers_.empty() || !first_footers_.empty();
|
||||
}
|
||||
|
||||
bool header_footer::scale_with_doc() const
|
||||
{
|
||||
return scale_with_doc_;
|
||||
}
|
||||
|
||||
header_footer &header_footer::scale_with_doc(bool scale)
|
||||
{
|
||||
scale_with_doc_ = scale;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Normal Header
|
||||
|
||||
bool header_footer::has_header(location where) const
|
||||
{
|
||||
return odd_headers_.count(where) > 0 || has_first_page_header(where);
|
||||
}
|
||||
|
||||
void header_footer::clear_header()
|
||||
{
|
||||
odd_headers_.clear();
|
||||
even_headers_.clear();
|
||||
first_headers_.clear();
|
||||
}
|
||||
|
||||
void header_footer::clear_header(location where)
|
||||
{
|
||||
odd_headers_.erase(where);
|
||||
even_headers_.erase(where);
|
||||
first_headers_.erase(where);
|
||||
}
|
||||
|
||||
header_footer &header_footer::header(location where, const std::string &text)
|
||||
{
|
||||
return header(where, formatted_text(text));
|
||||
}
|
||||
|
||||
header_footer &header_footer::header(location where, const formatted_text &text)
|
||||
{
|
||||
odd_headers_[where] = text;
|
||||
return *this;
|
||||
}
|
||||
|
||||
formatted_text header_footer::header(location where) const
|
||||
{
|
||||
return odd_headers_.at(where);
|
||||
}
|
||||
|
||||
// First Page Header
|
||||
|
||||
bool header_footer::has_first_page_header() const
|
||||
{
|
||||
return !first_headers_.empty();
|
||||
}
|
||||
|
||||
bool header_footer::has_first_page_header(location where) const
|
||||
{
|
||||
return first_headers_.count(where) > 0;
|
||||
}
|
||||
|
||||
void header_footer::clear_first_page_header()
|
||||
{
|
||||
first_headers_.clear();
|
||||
}
|
||||
|
||||
void header_footer::clear_first_page_header(location where)
|
||||
{
|
||||
first_headers_.erase(where);
|
||||
}
|
||||
|
||||
header_footer &header_footer::first_page_header(location where, const formatted_text &text)
|
||||
{
|
||||
first_headers_[where] = text;
|
||||
return *this;
|
||||
}
|
||||
|
||||
formatted_text header_footer::first_page_header(location where) const
|
||||
{
|
||||
return first_headers_.at(where);
|
||||
}
|
||||
|
||||
// Odd/Even Header
|
||||
|
||||
bool header_footer::has_odd_even_header() const
|
||||
{
|
||||
return different_odd_even() && !odd_headers_.empty();
|
||||
}
|
||||
|
||||
bool header_footer::has_odd_even_header(location where) const
|
||||
{
|
||||
return different_odd_even() && odd_headers_.count(where) > 0;
|
||||
}
|
||||
|
||||
void header_footer::clear_odd_even_header()
|
||||
{
|
||||
odd_headers_.clear();
|
||||
even_headers_.clear();
|
||||
different_odd_even_ = false;
|
||||
}
|
||||
|
||||
void header_footer::clear_odd_even_header(location where)
|
||||
{
|
||||
odd_headers_.erase(where);
|
||||
even_headers_.erase(where);
|
||||
}
|
||||
|
||||
header_footer &header_footer::odd_even_header(location where, const formatted_text &odd, const formatted_text &even)
|
||||
{
|
||||
odd_headers_[where] = odd;
|
||||
even_headers_[where] = even;
|
||||
different_odd_even_ = true;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
formatted_text header_footer::odd_header(location where) const
|
||||
{
|
||||
return odd_headers_.at(where);
|
||||
}
|
||||
|
||||
formatted_text header_footer::even_header(location where) const
|
||||
{
|
||||
return even_headers_.at(where);
|
||||
}
|
||||
|
||||
// Normal Footer
|
||||
|
||||
bool header_footer::has_footer(location where) const
|
||||
{
|
||||
return odd_footers_.count(where) > 0;
|
||||
}
|
||||
|
||||
void header_footer::clear_footer()
|
||||
{
|
||||
odd_footers_.clear();
|
||||
even_footers_.clear();
|
||||
first_footers_.clear();
|
||||
}
|
||||
|
||||
void header_footer::clear_footer(location where)
|
||||
{
|
||||
odd_footers_.erase(where);
|
||||
even_footers_.erase(where);
|
||||
first_footers_.erase(where);
|
||||
}
|
||||
|
||||
header_footer &header_footer::footer(location where, const std::string &text)
|
||||
{
|
||||
return footer(where, formatted_text(text));
|
||||
}
|
||||
|
||||
header_footer &header_footer::footer(location where, const formatted_text &text)
|
||||
{
|
||||
odd_footers_[where] = text;
|
||||
return *this;
|
||||
}
|
||||
|
||||
formatted_text header_footer::footer(location where) const
|
||||
{
|
||||
return odd_footers_.at(where);
|
||||
}
|
||||
|
||||
// First Page footer
|
||||
|
||||
bool header_footer::has_first_page_footer() const
|
||||
{
|
||||
return different_first() && !first_footers_.empty();
|
||||
}
|
||||
|
||||
bool header_footer::has_first_page_footer(location where) const
|
||||
{
|
||||
return different_first() && first_footers_.count(where) > 0;
|
||||
}
|
||||
|
||||
void header_footer::clear_first_page_footer()
|
||||
{
|
||||
first_footers_.clear();
|
||||
}
|
||||
|
||||
void header_footer::clear_first_page_footer(location where)
|
||||
{
|
||||
first_footers_.erase(where);
|
||||
}
|
||||
|
||||
header_footer &header_footer::first_page_footer(location where, const formatted_text &text)
|
||||
{
|
||||
first_footers_[where] = text;
|
||||
return *this;
|
||||
}
|
||||
|
||||
formatted_text header_footer::first_page_footer(location where) const
|
||||
{
|
||||
return first_footers_.at(where);
|
||||
}
|
||||
|
||||
// Odd/Even Footer
|
||||
|
||||
bool header_footer::has_odd_even_footer() const
|
||||
{
|
||||
return different_odd_even() && !even_footers_.empty();
|
||||
}
|
||||
|
||||
bool header_footer::has_odd_even_footer(location where) const
|
||||
{
|
||||
return different_odd_even() && even_footers_.count(where) > 0;
|
||||
}
|
||||
|
||||
void header_footer::clear_odd_even_footer()
|
||||
{
|
||||
odd_footers_.clear();
|
||||
even_footers_.clear();
|
||||
}
|
||||
|
||||
void header_footer::clear_odd_even_footer(location where)
|
||||
{
|
||||
odd_footers_.erase(where);
|
||||
even_footers_.erase(where);
|
||||
}
|
||||
|
||||
header_footer &header_footer::odd_even_footer(location where, const formatted_text &odd, const formatted_text &even)
|
||||
{
|
||||
odd_footers_[where] = odd;
|
||||
even_footers_[where] = even;
|
||||
different_odd_even_ = true;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
formatted_text header_footer::odd_footer(location where) const
|
||||
{
|
||||
return odd_footers_.at(where);
|
||||
}
|
||||
|
||||
formatted_text header_footer::even_footer(location where) const
|
||||
{
|
||||
return even_footers_.at(where);
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
@ -3,8 +3,6 @@
|
||||
#include <iostream>
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <xlnt/worksheet/footer.hpp>
|
||||
#include <xlnt/worksheet/header.hpp>
|
||||
#include <xlnt/worksheet/header_footer.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
@ -392,7 +390,7 @@ public:
|
||||
TS_ASSERT_EQUALS(ws.auto_filter(), "A1:F1");
|
||||
|
||||
ws.clear_auto_filter();
|
||||
TS_ASSERT_EQUALS(ws.has_auto_filter(), false);
|
||||
TS_ASSERT(!ws.has_auto_filter());
|
||||
|
||||
ws.auto_filter("c1:g9");
|
||||
TS_ASSERT_EQUALS(ws.auto_filter(), "C1:G9");
|
||||
@ -869,43 +867,51 @@ public:
|
||||
|
||||
void test_header()
|
||||
{
|
||||
xlnt::workbook wb;
|
||||
auto ws = wb.active_sheet();
|
||||
xlnt::header_footer hf;
|
||||
using hf_loc = xlnt::header_footer::location;
|
||||
|
||||
auto &header_footer = ws.header_footer();
|
||||
|
||||
for (auto header_pointer : { &header_footer.left_header(),
|
||||
&header_footer.center_header(), &header_footer.right_header() })
|
||||
for (auto location : { hf_loc::left, hf_loc::center, hf_loc::right })
|
||||
{
|
||||
auto &header = *header_pointer;
|
||||
TS_ASSERT(!hf.has_header(location));
|
||||
TS_ASSERT(!hf.has_odd_even_header(location));
|
||||
TS_ASSERT(!hf.has_first_page_header(location));
|
||||
|
||||
hf.header(location, "abc");
|
||||
|
||||
TS_ASSERT(header.is_default());
|
||||
header.text("abc");
|
||||
header.font_name("def");
|
||||
header.font_size(121);
|
||||
header.font_color("ghi");
|
||||
TS_ASSERT(!header.is_default());
|
||||
TS_ASSERT(hf.has_header(location));
|
||||
TS_ASSERT(!hf.has_odd_even_header(location));
|
||||
TS_ASSERT(!hf.has_first_page_header(location));
|
||||
|
||||
TS_ASSERT_EQUALS(hf.header(location), "abc");
|
||||
|
||||
hf.clear_header(location);
|
||||
|
||||
TS_ASSERT(!hf.has_header(location));
|
||||
}
|
||||
}
|
||||
|
||||
void test_footer()
|
||||
{
|
||||
xlnt::workbook wb;
|
||||
auto ws = wb.active_sheet();
|
||||
xlnt::header_footer hf;
|
||||
using hf_loc = xlnt::header_footer::location;
|
||||
|
||||
auto &header_footer = ws.header_footer();
|
||||
|
||||
for (auto header_pointer : { &header_footer.left_footer(),
|
||||
&header_footer.center_footer(), &header_footer.right_footer() })
|
||||
for (auto location : { hf_loc::left, hf_loc::center, hf_loc::right })
|
||||
{
|
||||
auto &header = *header_pointer;
|
||||
TS_ASSERT(!hf.has_footer(location));
|
||||
TS_ASSERT(!hf.has_odd_even_footer(location));
|
||||
TS_ASSERT(!hf.has_first_page_footer(location));
|
||||
|
||||
hf.footer(location, "abc");
|
||||
|
||||
TS_ASSERT(header.is_default());
|
||||
header.text("abc");
|
||||
header.font_name("def");
|
||||
header.font_size(121);
|
||||
header.font_color("ghi");
|
||||
TS_ASSERT(!header.is_default());
|
||||
TS_ASSERT(hf.has_footer(location));
|
||||
TS_ASSERT(!hf.has_odd_even_footer(location));
|
||||
TS_ASSERT(!hf.has_first_page_footer(location));
|
||||
|
||||
TS_ASSERT_EQUALS(hf.footer(location), "abc");
|
||||
|
||||
hf.clear_footer(location);
|
||||
|
||||
TS_ASSERT(!hf.has_footer(location));
|
||||
}
|
||||
}
|
||||
|
||||
@ -943,14 +949,6 @@ public:
|
||||
margins.right(5);
|
||||
}
|
||||
|
||||
void test_to_string()
|
||||
{
|
||||
xlnt::workbook wb;
|
||||
auto ws = wb.active_sheet();
|
||||
auto ws_string = ws.to_string();
|
||||
TS_ASSERT_EQUALS(ws_string, "<Worksheet \"Sheet1\">");
|
||||
}
|
||||
|
||||
void test_garbage_collect()
|
||||
{
|
||||
xlnt::workbook wb;
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <xlnt/worksheet/range.hpp>
|
||||
#include <xlnt/worksheet/range_iterator.hpp>
|
||||
#include <xlnt/worksheet/range_reference.hpp>
|
||||
#include <xlnt/worksheet/header_footer.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
|
||||
#include <detail/cell_impl.hpp>
|
||||
@ -132,23 +133,22 @@ std::vector<range_reference> worksheet::merged_ranges() const
|
||||
|
||||
bool worksheet::has_page_margins() const
|
||||
{
|
||||
return d_->has_page_margins_;
|
||||
return d_->page_margins_.is_set();
|
||||
}
|
||||
|
||||
bool worksheet::has_page_setup() const
|
||||
{
|
||||
return d_->has_page_setup_;
|
||||
return d_->page_setup_.is_set();
|
||||
}
|
||||
|
||||
page_margins worksheet::page_margins() const
|
||||
{
|
||||
return d_->page_margins_;
|
||||
return d_->page_margins_.get();
|
||||
}
|
||||
|
||||
void worksheet::page_margins(const class page_margins &margins)
|
||||
{
|
||||
d_->page_margins_ = margins;
|
||||
d_->has_page_margins_ = true;
|
||||
}
|
||||
|
||||
void worksheet::auto_filter(const std::string &reference_string)
|
||||
@ -168,38 +168,32 @@ void worksheet::auto_filter(const xlnt::range &range)
|
||||
|
||||
range_reference worksheet::auto_filter() const
|
||||
{
|
||||
return d_->auto_filter_;
|
||||
return d_->auto_filter_.get();
|
||||
}
|
||||
|
||||
bool worksheet::has_auto_filter() const
|
||||
{
|
||||
return d_->auto_filter_.width() > 0;
|
||||
return d_->auto_filter_.is_set();
|
||||
}
|
||||
|
||||
void worksheet::clear_auto_filter()
|
||||
{
|
||||
d_->auto_filter_ = range_reference(1, 1, 1, 1);
|
||||
d_->auto_filter_.clear();
|
||||
}
|
||||
|
||||
void worksheet::page_setup(const struct page_setup &setup)
|
||||
{
|
||||
d_->has_page_setup_ = true;
|
||||
d_->page_setup_ = setup;
|
||||
}
|
||||
|
||||
page_setup worksheet::page_setup() const
|
||||
{
|
||||
if (!d_->has_page_setup_)
|
||||
if (!has_page_setup())
|
||||
{
|
||||
throw invalid_attribute();
|
||||
}
|
||||
|
||||
return d_->page_setup_;
|
||||
}
|
||||
|
||||
std::string worksheet::to_string() const
|
||||
{
|
||||
return "<Worksheet \"" + d_->title_ + "\">";
|
||||
return d_->page_setup_.get();
|
||||
}
|
||||
|
||||
workbook &worksheet::workbook()
|
||||
@ -499,16 +493,6 @@ column_t worksheet::highest_column() const
|
||||
return highest;
|
||||
}
|
||||
|
||||
bool worksheet::has_dimension() const
|
||||
{
|
||||
return d_->has_dimension_;
|
||||
}
|
||||
|
||||
bool worksheet::has_format_properties() const
|
||||
{
|
||||
return d_->has_format_properties_;
|
||||
}
|
||||
|
||||
range_reference worksheet::calculate_dimension() const
|
||||
{
|
||||
return range_reference(lowest_column(), lowest_row(), highest_column(), highest_row());
|
||||
@ -746,10 +730,8 @@ bool worksheet::compare(const worksheet &other, bool reference) const
|
||||
// todo: missing some comparisons
|
||||
|
||||
if(d_->auto_filter_ == other.d_->auto_filter_
|
||||
&& d_->comment_count_ == other.d_->comment_count_
|
||||
&& d_->views_ == other.d_->views_
|
||||
&& d_->merged_cells_ == other.d_->merged_cells_
|
||||
&& d_->relationships_ == other.d_->relationships_)
|
||||
&& d_->merged_cells_ == other.d_->merged_cells_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -816,41 +798,9 @@ void worksheet::reserve(std::size_t n)
|
||||
d_->cell_map_.reserve(n);
|
||||
}
|
||||
|
||||
void worksheet::increment_comments()
|
||||
{
|
||||
d_->comment_count_++;
|
||||
}
|
||||
|
||||
void worksheet::decrement_comments()
|
||||
{
|
||||
d_->comment_count_--;
|
||||
}
|
||||
|
||||
std::size_t worksheet::comment_count() const
|
||||
{
|
||||
return d_->comment_count_;
|
||||
}
|
||||
|
||||
header_footer &worksheet::header_footer()
|
||||
{
|
||||
return d_->header_footer_;
|
||||
}
|
||||
|
||||
const header_footer &worksheet::header_footer() const
|
||||
{
|
||||
return d_->header_footer_;
|
||||
}
|
||||
|
||||
header_footer::header_footer()
|
||||
{
|
||||
}
|
||||
|
||||
header::header() : default_(true), font_size_(12)
|
||||
{
|
||||
}
|
||||
|
||||
footer::footer() : default_(true), font_size_(12)
|
||||
class header_footer worksheet::header_footer() const
|
||||
{
|
||||
return d_->header_footer_.get();
|
||||
}
|
||||
|
||||
void worksheet::parent(xlnt::workbook &wb)
|
||||
@ -1062,7 +1012,7 @@ void worksheet::print_area(const std::string &print_area)
|
||||
|
||||
range_reference worksheet::print_area() const
|
||||
{
|
||||
return d_->print_area_;
|
||||
return d_->print_area_.get();
|
||||
}
|
||||
|
||||
bool worksheet::has_view() const
|
||||
@ -1085,4 +1035,14 @@ void worksheet::register_comments_in_manifest()
|
||||
workbook().register_comments_in_manifest(*this);
|
||||
}
|
||||
|
||||
bool worksheet::has_header_footer() const
|
||||
{
|
||||
return d_->header_footer_.is_set();
|
||||
}
|
||||
|
||||
void worksheet::header_footer(const class header_footer &hf)
|
||||
{
|
||||
d_->header_footer_ = hf;
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
@ -9,10 +9,11 @@ endif()
|
||||
|
||||
include_directories(${LIBRARY_INCLUDE_DIR})
|
||||
include_directories(${LIBRARY_SOURCE_DIR})
|
||||
include_directories(${LIBRARY_SOURCE_DIR}/detail)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${THIRD_PARTY_DIR}/cxxtest)
|
||||
include_directories(${THIRD_PARTY_DIR}/libstudxml)
|
||||
include_directories(${THIRD_PARTY_DIR}/utfcpp/source)
|
||||
include_directories(${THIRD_PARTY_DIR}/pugixml/src)
|
||||
include_directories(${THIRD_PARTY_DIR}/zlib)
|
||||
|
||||
file(GLOB CELL_TESTS ${LIBRARY_SOURCE_DIR}/cell/tests/test_*.hpp)
|
||||
@ -34,11 +35,6 @@ set(TESTS ${CELL_TESTS} ${CHARTS_TESTS} ${CHARTSHEET_TESTS} ${DRAWING_TESTS}
|
||||
${FORMULA_TESTS} ${PACKAGING_TESTS} ${STYLES_TESTS} ${UTILS_TESTS}
|
||||
${WORKBOOK_TESTS} ${WORKSHEET_TESTS})
|
||||
|
||||
set(PUGIXML
|
||||
${THIRD_PARTY_DIR}/pugixml/src/pugixml.cpp
|
||||
${THIRD_PARTY_DIR}/pugixml/src/pugixml.hpp
|
||||
${THIRD_PARTY_DIR}/pugixml/src/pugiconfig.hpp)
|
||||
|
||||
file(GLOB TEST_HELPERS_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/helpers/*.hpp)
|
||||
file(GLOB TEST_HELPERS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/helpers/*.cpp)
|
||||
|
||||
@ -52,11 +48,10 @@ if(COVERAGE)
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov --coverage")
|
||||
endif()
|
||||
|
||||
add_executable(${PROJECT_NAME} ${TEST_HELPERS} ${TESTS} ${RUNNER} ${PUGIXML} $<TARGET_OBJECTS:xlnt.third-party> ${XLNT_ZIP})
|
||||
add_executable(${PROJECT_NAME} ${TEST_HELPERS} ${TESTS} ${RUNNER} $<TARGET_OBJECTS:xlnt.third-party> ${XLNT_ZIP})
|
||||
|
||||
source_group(helpers FILES ${TEST_HELPERS})
|
||||
source_group(xlnt\\detail FILES ${XLNT_ZIP})
|
||||
source_group(third-party\\pugixml FILES ${PUGIXML})
|
||||
source_group(tests\\cell FILES ${CELL_TESTS})
|
||||
source_group(tests\\charts FILES ${CHARTS_TESTS})
|
||||
source_group(tests\\chartsheet FILES ${CHARTSHEET_TESTS})
|
||||
|
@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
#include <pugixml.hpp>
|
||||
|
||||
#include <detail/include_libstudxml.hpp>
|
||||
#include <detail/vector_streambuf.hpp>
|
||||
#include <detail/zip.hpp>
|
||||
#include <helpers/path_helper.hpp>
|
||||
#include <xlnt/packaging/manifest.hpp>
|
||||
@ -34,165 +35,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static bool compare_content_types(const pugi::xml_document &left, const pugi::xml_document &right)
|
||||
{
|
||||
auto left_types_node = left.child("Types");
|
||||
auto right_types_node = right.child("Types");
|
||||
|
||||
if (!left_types_node || !right_types_node)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto left_children = left_types_node.children();
|
||||
auto left_length = std::distance(left_children.begin(), left_children.end());
|
||||
|
||||
auto right_children = right_types_node.children();
|
||||
auto right_length = std::distance(right_children.begin(), right_children.end());
|
||||
|
||||
if (left_length != right_length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto left_child : left_children)
|
||||
{
|
||||
std::string associated_attribute_name;
|
||||
|
||||
if (std::string(left_child.name()) == "Default")
|
||||
{
|
||||
associated_attribute_name = "Extension";
|
||||
}
|
||||
else if (std::string(left_child.name()) == "Override")
|
||||
{
|
||||
associated_attribute_name = "PartName";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("invalid xml");
|
||||
}
|
||||
|
||||
std::string left_attribute_value(left_child.attribute(associated_attribute_name.c_str()).value());
|
||||
pugi::xml_node matching_right_child;
|
||||
|
||||
for (const auto right_child : right_types_node.children(left_child.name()))
|
||||
{
|
||||
std::string right_attribute_value(right_child.attribute(associated_attribute_name.c_str()).value());
|
||||
|
||||
if (left_attribute_value == right_attribute_value)
|
||||
{
|
||||
matching_right_child = right_child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!matching_right_child
|
||||
|| !left_child.attribute("ContentType")
|
||||
|| !matching_right_child.attribute("ContentType"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string left_child_type(left_child.attribute("ContentType").value());
|
||||
std::string right_child_type(matching_right_child.attribute("ContentType").value());
|
||||
|
||||
if (left_child_type != right_child_type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool compare_relationships_xml(const pugi::xml_document &left, const pugi::xml_document &right)
|
||||
{
|
||||
auto left_relationships_node = left.child("Relationships");
|
||||
auto right_relationships_node = right.child("Relationships");
|
||||
|
||||
if (!left_relationships_node || !right_relationships_node)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto left_children = left_relationships_node.children();
|
||||
auto left_length = std::distance(left_children.begin(), left_children.end());
|
||||
|
||||
auto right_children = right_relationships_node.children();
|
||||
auto right_length = std::distance(right_children.begin(), right_children.end());
|
||||
|
||||
if (left_length != right_length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto left_child : left_children)
|
||||
{
|
||||
std::string left_rel_id(left_child.attribute("Id").value());
|
||||
pugi::xml_node matching_right_child;
|
||||
|
||||
for (const auto right_child : right_children)
|
||||
{
|
||||
std::string right_rel_id(right_child.attribute("Id").value());
|
||||
|
||||
if (left_rel_id == right_rel_id)
|
||||
{
|
||||
matching_right_child = right_child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!matching_right_child
|
||||
|| !left_child.attribute("Type")
|
||||
|| !left_child.attribute("Target")
|
||||
|| !matching_right_child.attribute("Type")
|
||||
|| !matching_right_child.attribute("Target"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((std::string(left_child.attribute("Type").value())
|
||||
!= std::string(left_child.attribute("Type").value()))
|
||||
|| (std::string(left_child.attribute("Target").value())
|
||||
!= std::string(left_child.attribute("Target").value())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool compare_theme_xml(const pugi::xml_document &left, const pugi::xml_document &right)
|
||||
{
|
||||
return compare_xml_exact(left, right);
|
||||
}
|
||||
|
||||
static bool compare_styles_xml(const pugi::xml_document &left, const pugi::xml_document &right)
|
||||
{
|
||||
return compare_xml_exact(left, right);
|
||||
}
|
||||
|
||||
static bool compare_workbook_xml(const pugi::xml_document &left, const pugi::xml_document &right)
|
||||
{
|
||||
return compare_xml_exact(left, right);
|
||||
}
|
||||
|
||||
static bool compare_worksheet_xml(const pugi::xml_document &left, const pugi::xml_document &right)
|
||||
{
|
||||
return compare_xml_exact(left, right);
|
||||
}
|
||||
|
||||
static bool compare_core_properties_xml(const pugi::xml_document &left, const pugi::xml_document &right)
|
||||
{
|
||||
return compare_xml_exact(left, right);
|
||||
}
|
||||
|
||||
static bool compare_extended_properties_xml(const pugi::xml_document &left, const pugi::xml_document &right)
|
||||
{
|
||||
return compare_xml_exact(left, right);
|
||||
}
|
||||
|
||||
static bool compare_files(const std::string &left,
|
||||
const std::string &right, const std::string &content_type)
|
||||
{
|
||||
@ -204,71 +46,124 @@ public:
|
||||
|
||||
if (is_xml)
|
||||
{
|
||||
pugi::xml_document left_document;
|
||||
left_document.load(left.c_str());
|
||||
|
||||
pugi::xml_document right_document;
|
||||
right_document.load(right.c_str());
|
||||
|
||||
if (content_type == "[Content_Types].xml")
|
||||
{
|
||||
return compare_content_types(left_document, right_document);
|
||||
}
|
||||
else if (content_type == "application/vnd.openxmlformats-package.relationships+xml")
|
||||
{
|
||||
return compare_relationships_xml(left_document, right_document);
|
||||
}
|
||||
else if (content_type == "application/vnd.openxmlformats-officedocument.theme+xml")
|
||||
{
|
||||
return compare_theme_xml(left_document, right_document);
|
||||
}
|
||||
else if (content_type == "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml")
|
||||
{
|
||||
return compare_styles_xml(left_document, right_document);
|
||||
}
|
||||
else if (content_type == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml")
|
||||
{
|
||||
return compare_workbook_xml(left_document, right_document);
|
||||
}
|
||||
else if (content_type == "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml")
|
||||
{
|
||||
return compare_worksheet_xml(left_document, right_document);
|
||||
}
|
||||
else if (content_type == "application/vnd.openxmlformats-package.core-properties+xml")
|
||||
{
|
||||
return compare_core_properties_xml(left_document, right_document);
|
||||
}
|
||||
else if (content_type == "application/vnd.openxmlformats-officedocument.extended-properties+xml")
|
||||
{
|
||||
return compare_extended_properties_xml(left_document, right_document);
|
||||
}
|
||||
|
||||
return compare_xml_exact(left_document, right_document);
|
||||
return compare_xml_exact(left, right);
|
||||
}
|
||||
|
||||
return left == right;
|
||||
}
|
||||
|
||||
static bool compare_xml_exact(const pugi::xml_document &left, const pugi::xml_document &right)
|
||||
static bool compare_xml_exact(const std::string &left, const std::string &right, bool suppress_debug_info = false)
|
||||
{
|
||||
auto result = compare_xml_nodes(left, right);
|
||||
xml::parser left_parser(left.data(), left.size(), "left");
|
||||
xml::parser right_parser(right.data(), right.size(), "right");
|
||||
|
||||
if (!result)
|
||||
bool difference = false;
|
||||
auto right_iter = right_parser.begin();
|
||||
|
||||
auto is_whitespace = [](const std::string &v)
|
||||
{
|
||||
return v.find_first_not_of("\n ") == std::string::npos;
|
||||
};
|
||||
|
||||
for (auto left_event : left_parser)
|
||||
{
|
||||
if (left_event == xml::parser::event_type::characters
|
||||
&& is_whitespace(left_parser.value())) continue;
|
||||
|
||||
if (right_iter == right_parser.end())
|
||||
{
|
||||
difference = true;
|
||||
break;
|
||||
}
|
||||
|
||||
auto right_event = *right_iter;
|
||||
|
||||
while (right_iter != right_parser.end()
|
||||
&& right_event == xml::parser::event_type::characters
|
||||
&& is_whitespace(right_parser.value()))
|
||||
{
|
||||
++right_iter;
|
||||
right_event = *right_iter;
|
||||
}
|
||||
|
||||
if (left_event != right_event)
|
||||
{
|
||||
difference = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (left_event == xml::parser::event_type::start_element)
|
||||
{
|
||||
auto left_attr_map = left_parser.attribute_map();
|
||||
auto right_attr_map = right_parser.attribute_map();
|
||||
|
||||
for (auto attr : left_attr_map)
|
||||
{
|
||||
if (right_attr_map.find(attr.first) == right_attr_map.end())
|
||||
{
|
||||
difference = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (attr.second.value != right_attr_map.at(attr.first).value)
|
||||
{
|
||||
difference = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto attr : right_attr_map)
|
||||
{
|
||||
if (left_attr_map.find(attr.first) == left_attr_map.end())
|
||||
{
|
||||
difference = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (attr.second.value != left_attr_map.at(attr.first).value)
|
||||
{
|
||||
difference = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (difference)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (left_parser.qname() != right_parser.qname())
|
||||
{
|
||||
difference = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (left_event == xml::parser::event_type::characters)
|
||||
{
|
||||
if (left_parser.value() != right_parser.value())
|
||||
{
|
||||
difference = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++right_iter;
|
||||
}
|
||||
|
||||
if (difference && !suppress_debug_info)
|
||||
{
|
||||
std::cout << "documents don't match" << std::endl;
|
||||
|
||||
std::cout << "left:" << std::endl;
|
||||
left.save(std::cout);
|
||||
std::cout << left;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "right:" << std::endl;
|
||||
right.save(std::cout);
|
||||
std::cout << right;
|
||||
std::cout << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !difference;
|
||||
}
|
||||
|
||||
static bool string_matches_workbook_part(const std::string &expected,
|
||||
@ -318,21 +213,6 @@ public:
|
||||
return compare_files(file.read_contents(), contents, content_type);
|
||||
}
|
||||
|
||||
static bool file_matches_document(const xlnt::path &expected,
|
||||
const pugi::xml_document &observed, const std::string &content_type)
|
||||
{
|
||||
return string_matches_document(expected.read_contents(), observed, content_type);
|
||||
}
|
||||
|
||||
static bool string_matches_document(const std::string &string,
|
||||
const pugi::xml_document &document, const std::string &content_type)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
document.save(ss);
|
||||
|
||||
return compare_files(string, ss.str(), content_type);
|
||||
}
|
||||
|
||||
static bool xlsx_archives_match(const std::vector<std::uint8_t> &left, const std::vector<std::uint8_t> &right)
|
||||
{
|
||||
xlnt::detail::vector_istreambuf left_buffer(left);
|
||||
@ -432,112 +312,4 @@ public:
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
static comparison_result compare_xml_nodes(const pugi::xml_node &left, const pugi::xml_node &right)
|
||||
{
|
||||
std::string left_name(left.name());
|
||||
std::string right_name(right.name());
|
||||
|
||||
if(left_name != right_name)
|
||||
{
|
||||
return {difference_type::names_differ, left_name, right_name};
|
||||
}
|
||||
|
||||
for(const auto &left_attribute : left.attributes())
|
||||
{
|
||||
std::string attribute_name(left_attribute.name());
|
||||
auto right_attribute = right.attribute(attribute_name.c_str());
|
||||
|
||||
// pugixml doesn't handle namespaces correctly
|
||||
bool special_exception = left_name == "mc:AlternateContent"
|
||||
&& attribute_name == "xmlns:mc";
|
||||
|
||||
if(!right_attribute && !special_exception)
|
||||
{
|
||||
return {difference_type::missing_attribute, attribute_name, "((empty))"};
|
||||
}
|
||||
|
||||
std::string left_attribute_value(left_attribute.value());
|
||||
std::string right_attribute_value(right_attribute.value());
|
||||
|
||||
if(left_attribute_value != right_attribute_value && !special_exception)
|
||||
{
|
||||
return {difference_type::attribute_values_differ, left_attribute_value, right_attribute_value};
|
||||
}
|
||||
}
|
||||
|
||||
for(const auto &right_attribute : right.attributes())
|
||||
{
|
||||
std::string attribute_name(right_attribute.name());
|
||||
auto left_attribute = left.attribute(attribute_name.c_str());
|
||||
|
||||
// pugixml doesn't handle namespaces correctly
|
||||
bool special_exception = left_name == "mc:AlternateContent"
|
||||
&& attribute_name == "xmlns:mc";
|
||||
|
||||
if(!left_attribute && !special_exception)
|
||||
{
|
||||
return {difference_type::missing_attribute, "((empty))", attribute_name};
|
||||
}
|
||||
|
||||
std::string left_attribute_value(left_attribute.value());
|
||||
std::string right_attribute_value(right_attribute.value());
|
||||
|
||||
if(left_attribute_value != right_attribute_value && !special_exception)
|
||||
{
|
||||
return {difference_type::attribute_values_differ, left_attribute_value, right_attribute_value};
|
||||
}
|
||||
}
|
||||
|
||||
if(left.text())
|
||||
{
|
||||
std::string left_text(left.text().get());
|
||||
|
||||
if(!right.text())
|
||||
{
|
||||
return {difference_type::missing_text, left_text, "((empty))"};
|
||||
}
|
||||
|
||||
std::string right_text(right.text().get());
|
||||
|
||||
if(left_text != right_text)
|
||||
{
|
||||
return {difference_type::text_values_differ, left_text, right_text};
|
||||
}
|
||||
}
|
||||
else if(right.text())
|
||||
{
|
||||
return {difference_type::text_values_differ, "((empty))", right.text().get()};
|
||||
}
|
||||
|
||||
auto right_children = right.children();
|
||||
auto right_child_iter = right_children.begin();
|
||||
|
||||
for(auto left_child : left.children())
|
||||
{
|
||||
std::string left_child_name(left_child.name());
|
||||
|
||||
if(right_child_iter == right_children.end())
|
||||
{
|
||||
return {difference_type::child_order_differs, left_child_name, "((end))"};
|
||||
}
|
||||
|
||||
auto right_child = *right_child_iter;
|
||||
right_child_iter++;
|
||||
|
||||
auto child_comparison_result = compare_xml_nodes(left_child, right_child);
|
||||
|
||||
if(!child_comparison_result)
|
||||
{
|
||||
return child_comparison_result;
|
||||
}
|
||||
}
|
||||
|
||||
if(right_child_iter != right_children.end())
|
||||
{
|
||||
return {difference_type::child_order_differs, "((end))", right_child_iter->name()};
|
||||
}
|
||||
|
||||
return {difference_type::equivalent, "", ""};
|
||||
}
|
||||
};
|
||||
|
1
third-party/pugixml
vendored
1
third-party/pugixml
vendored
@ -1 +0,0 @@
|
||||
Subproject commit a832e8a5eff11f58a00ca41ec51ff3895b0da165
|
Loading…
x
Reference in New Issue
Block a user