1 // Copyright (c) 2014-2020 Thomas Fussell 2 // Copyright (c) 2010-2015 openpyxl 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM, 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 // THE SOFTWARE 21 // 22 // @license: http://www.opensource.org/licenses/mit-license.php 23 // @author: see AUTHORS file 24 25 #pragma once 26 27 #include <cstdint> 28 #include <string> 29 #include <unordered_map> 30 31 #include <xlnt/xlnt_config.hpp> 32 #include <xlnt/cell/rich_text.hpp> 33 #include <xlnt/utils/scoped_enum_hash.hpp> 34 35 namespace xlnt { 36 37 /// <summary> 38 /// Represents the header and footer of a sheet in a workbook. 39 /// </summary> 40 class XLNT_API header_footer 41 { 42 public: 43 /// <summary> 44 /// Enumerates the three possible locations of a header or footer. 45 /// </summary> 46 enum class location 47 { 48 left, 49 center, 50 right 51 }; 52 53 // General Properties 54 55 /// <summary> 56 /// True if any text has been added for a header at any location on any page. 57 /// </summary> 58 bool has_header() const; 59 60 /// <summary> 61 /// True if any text has been added for a footer at any location on any page. 62 /// </summary> 63 bool has_footer() const; 64 65 /// <summary> 66 /// True if headers and footers should align to the page margins. 67 /// </summary> 68 bool align_with_margins() const; 69 70 /// <summary> 71 /// Set to true if headers and footers should align to the page margins. 72 /// Set to false if headers and footers should align to the edge of the page. 73 /// </summary> 74 header_footer &align_with_margins(bool align); 75 76 /// <summary> 77 /// True if headers and footers differ based on page number. 78 /// </summary> 79 bool different_odd_even() const; 80 81 /// <summary> 82 /// True if headers and footers are different on the first page. 83 /// </summary> 84 bool different_first() const; 85 86 /// <summary> 87 /// True if headers and footers should scale to match the worksheet. 88 /// </summary> 89 bool scale_with_doc() const; 90 91 /// <summary> 92 /// Set to true if headers and footers should scale to match the worksheet. 93 /// </summary> 94 header_footer &scale_with_doc(bool scale); 95 96 // Normal Header 97 98 /// <summary> 99 /// True if any text has been added at the given location on any page. 100 /// </summary> 101 bool has_header(location where) const; 102 103 /// <summary> 104 /// Remove all headers from all pages. 105 /// </summary> 106 void clear_header(); 107 108 /// <summary> 109 /// Remove header at the given location on any page. 110 /// </summary> 111 void clear_header(location where); 112 113 /// <summary> 114 /// Add a header at the given location with the given text. 115 /// </summary> 116 header_footer &header(location where, const std::string &text); 117 118 /// <summary> 119 /// Add a header at the given location with the given text. 120 /// </summary> 121 header_footer &header(location where, const rich_text &text); 122 123 /// <summary> 124 /// Get the text of the header at the given location. If headers are 125 /// different on odd and even pages, the odd header will be returned. 126 /// </summary> 127 rich_text header(location where) const; 128 129 // First Page Header 130 131 /// <summary> 132 /// True if a header has been set for the first page at any location. 133 /// </summary> 134 bool has_first_page_header() const; 135 136 /// <summary> 137 /// True if a header has been set for the first page at the given location. 138 /// </summary> 139 bool has_first_page_header(location where) const; 140 141 /// <summary> 142 /// Remove all headers from the first page. 143 /// </summary> 144 void clear_first_page_header(); 145 146 /// <summary> 147 /// Remove header from the first page at the given location. 148 /// </summary> 149 void clear_first_page_header(location where); 150 151 /// <summary> 152 /// Add a header on the first page at the given location with the given text. 153 /// </summary> 154 header_footer &first_page_header(location where, const rich_text &text); 155 156 /// <summary> 157 /// Get the text of the first page header at the given location. If no first 158 /// page header has been set, the general header for that location will 159 /// be returned. 160 /// </summary> 161 rich_text first_page_header(location where) const; 162 163 // Odd/Even Header 164 165 /// <summary> 166 /// True if different headers have been set for odd and even pages. 167 /// </summary> 168 bool has_odd_even_header() const; 169 170 /// <summary> 171 /// True if different headers have been set for odd and even pages at the given location. 172 /// </summary> 173 bool has_odd_even_header(location where) const; 174 175 /// <summary> 176 /// Remove odd/even headers at all locations. 177 /// </summary> 178 void clear_odd_even_header(); 179 180 /// <summary> 181 /// Remove odd/even headers at the given location. 182 /// </summary> 183 void clear_odd_even_header(location where); 184 185 /// <summary> 186 /// Add a header for odd pages at the given location with the given text. 187 /// </summary> 188 header_footer &odd_even_header(location where, const rich_text &odd, const rich_text &even); 189 190 /// <summary> 191 /// Get the text of the odd page header at the given location. If no odd 192 /// page header has been set, the general header for that location will 193 /// be returned. 194 /// </summary> 195 rich_text odd_header(location where) const; 196 197 /// <summary> 198 /// Get the text of the even page header at the given location. If no even 199 /// page header has been set, the general header for that location will 200 /// be returned. 201 /// </summary> 202 rich_text even_header(location where) const; 203 204 // Normal Footer 205 206 /// <summary> 207 /// True if any text has been added at the given location on any page. 208 /// </summary> 209 bool has_footer(location where) const; 210 211 /// <summary> 212 /// Remove all footers from all pages. 213 /// </summary> 214 void clear_footer(); 215 216 /// <summary> 217 /// Remove footer at the given location on any page. 218 /// </summary> 219 void clear_footer(location where); 220 221 /// <summary> 222 /// Add a footer at the given location with the given text. 223 /// </summary> 224 header_footer &footer(location where, const std::string &text); 225 226 /// <summary> 227 /// Add a footer at the given location with the given text. 228 /// </summary> 229 header_footer &footer(location where, const rich_text &text); 230 231 /// <summary> 232 /// Get the text of the footer at the given location. If footers are 233 /// different on odd and even pages, the odd footer will be returned. 234 /// </summary> 235 rich_text footer(location where) const; 236 237 // First Page footer 238 239 /// <summary> 240 /// True if a footer has been set for the first page at any location. 241 /// </summary> 242 bool has_first_page_footer() const; 243 244 /// <summary> 245 /// True if a footer has been set for the first page at the given location. 246 /// </summary> 247 bool has_first_page_footer(location where) const; 248 249 /// <summary> 250 /// Remove all footers from the first page. 251 /// </summary> 252 void clear_first_page_footer(); 253 254 /// <summary> 255 /// Remove footer from the first page at the given location. 256 /// </summary> 257 void clear_first_page_footer(location where); 258 259 /// <summary> 260 /// Add a footer on the first page at the given location with the given text. 261 /// </summary> 262 header_footer &first_page_footer(location where, const rich_text &text); 263 264 /// <summary> 265 /// Get the text of the first page footer at the given location. If no first 266 /// page footer has been set, the general footer for that location will 267 /// be returned. 268 /// </summary> 269 rich_text first_page_footer(location where) const; 270 271 // Odd/Even Footer 272 273 /// <summary> 274 /// True if different footers have been set for odd and even pages. 275 /// </summary> 276 bool has_odd_even_footer() const; 277 278 /// <summary> 279 /// True if different footers have been set for odd and even pages at the given location. 280 /// </summary> 281 bool has_odd_even_footer(location where) const; 282 283 /// <summary> 284 /// Remove odd/even footers at all locations. 285 /// </summary> 286 void clear_odd_even_footer(); 287 288 /// <summary> 289 /// Remove odd/even footers at the given location. 290 /// </summary> 291 void clear_odd_even_footer(location where); 292 293 /// <summary> 294 /// Add a footer for odd pages at the given location with the given text. 295 /// </summary> 296 header_footer &odd_even_footer(location where, const rich_text &odd, const rich_text &even); 297 298 /// <summary> 299 /// Get the text of the odd page footer at the given location. If no odd 300 /// page footer has been set, the general footer for that location will 301 /// be returned. 302 /// </summary> 303 rich_text odd_footer(location where) const; 304 305 /// <summary> 306 /// Get the text of the even page footer at the given location. If no even 307 /// page footer has been set, the general footer for that location will 308 /// be returned. 309 /// </summary> 310 rich_text even_footer(location where) const; 311 312 bool operator==(const header_footer &rhs) const; 313 314 private: 315 bool align_with_margins_ = false; 316 bool different_odd_even_ = false; 317 bool scale_with_doc_ = false; 318 319 using container = std::unordered_map<location, rich_text, scoped_enum_hash<location>>; 320 321 container odd_headers_; 322 container even_headers_; 323 container first_headers_; 324 container odd_footers_; 325 container even_footers_; 326 container first_footers_; 327 }; 328 329 } // namespace xlnt 330