Branch data TLA Line data Source code
1 : : // Copyright (c) 2014-2022 Thomas Fussell
2 : : // Copyright (c) 2010-2015 openpyxl
3 : : // Copyright (c) 2024-2025 xlnt-community
4 : : //
5 : : // Permission is hereby granted, free of charge, to any person obtaining a copy
6 : : // of this software and associated documentation files (the "Software"), to deal
7 : : // in the Software without restriction, including without limitation the rights
8 : : // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : : // copies of the Software, and to permit persons to whom the Software is
10 : : // furnished to do so, subject to the following conditions:
11 : : //
12 : : // The above copyright notice and this permission notice shall be included in
13 : : // all copies or substantial portions of the Software.
14 : : //
15 : : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : : // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : : // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : : // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : : // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : : // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : : // THE SOFTWARE
22 : : //
23 : : // @license: http://www.opensource.org/licenses/mit-license.php
24 : : // @author: see AUTHORS file
25 : : #pragma once
26 : :
27 : : #include <algorithm>
28 : : #include <list>
29 : : #include <string>
30 : : #include <vector>
31 : :
32 : : #include <detail/implementations/conditional_format_impl.hpp>
33 : : #include <detail/implementations/format_impl.hpp>
34 : : #include <detail/implementations/style_impl.hpp>
35 : : #include <xlnt/cell/cell.hpp>
36 : : #include <xlnt/styles/conditional_format.hpp>
37 : : #include <xlnt/styles/format.hpp>
38 : : #include <xlnt/styles/style.hpp>
39 : : #include <xlnt/utils/exceptions.hpp>
40 : : #include <xlnt/workbook/workbook.hpp>
41 : : #include <xlnt/workbook/worksheet_iterator.hpp>
42 : : #include <xlnt/worksheet/worksheet.hpp>
43 : :
44 : : namespace xlnt {
45 : : namespace detail {
46 : :
47 : : struct stylesheet
48 : : {
49 :CBC 312 : class format create_format(bool default_format)
50 : : {
51 : 312 : format_impls.emplace_back();
52 : 312 : auto &impl = format_impls.back();
53 : :
54 : 312 : impl->parent = this;
55 : 312 : impl->id = format_impls.size() - 1;
56 : :
57 [ - + ]: 312 : if (default_format)
58 [ # # ]:UBC 0 : this->default_format_impl = impl;
59 : :
60 [ + + ]:CBC 312 : return xlnt::format(impl);
61 : : }
62 : :
63 : 256 : void default_format(const format &format)
64 : : {
65 : 256 : default_format_impl = format.d_;
66 : 256 : }
67 : :
68 : 884 : class xlnt::format format(std::size_t index)
69 : : {
70 : 884 : auto iter = format_impls.begin();
71 : 884 : std::advance(iter, static_cast<std::list<format_impl>::difference_type>(index));
72 : :
73 [ + + ]: 884 : return xlnt::format(*iter);
74 : : }
75 : :
76 : 945 : class style create_style(const std::string &name)
77 : : {
78 [ + ]: 945 : auto &impl = style_impls.emplace(name, style_impl()).first->second;
79 : :
80 : 945 : impl.parent = this;
81 : 945 : impl.name = name;
82 : :
83 : 945 : impl.border_id = 0;
84 : 945 : impl.fill_id = 0;
85 : 945 : impl.font_id = 0;
86 : 945 : impl.number_format_id = 0;
87 : :
88 : 945 : style_names.push_back(name);
89 [ + ]: 945 : return xlnt::style(&impl);
90 : : }
91 : :
92 : 257 : class style create_builtin_style(const std::size_t builtin_id)
93 : : {
94 : : // From Annex G.2
95 : : static const auto names = std::unordered_map<std::size_t , std::string>
96 : : {
97 :UBC 0 : { 0, "Normal" },
98 : 0 : { 1, "RowLevel_1" },
99 : 0 : { 2, "ColLevel_1" },
100 : 0 : { 3, "Comma" },
101 : 0 : { 4, "Currency" },
102 : 0 : { 5, "Percent" },
103 : 0 : { 6, "Comma [0]" },
104 : 0 : { 7, "Currency [0]" },
105 : 0 : { 8, "Hyperlink" },
106 : 0 : { 9, "Followed Hyperlink" },
107 : 0 : { 10, "Note" },
108 : 0 : { 11, "Warning Text" },
109 : 0 : { 15, "Title" },
110 : 0 : { 16, "Heading 1" },
111 : 0 : { 17, "Heading 2" },
112 : 0 : { 18, "Heading 3" },
113 : 0 : { 19, "Heading 4" },
114 : 0 : { 20, "Input" },
115 : 0 : { 21, "Output"},
116 : 0 : { 22, "Calculation"},
117 : 0 : { 22, "Calculation" },
118 : 0 : { 23, "Check Cell" },
119 : 0 : { 24, "Linked Cell" },
120 : 0 : { 25, "Total" },
121 : 0 : { 26, "Good" },
122 : 0 : { 27, "Bad" },
123 : 0 : { 28, "Neutral" },
124 : 0 : { 29, "Accent1" },
125 : 0 : { 30, "20% - Accent1" },
126 : 0 : { 31, "40% - Accent1" },
127 : 0 : { 32, "60% - Accent1" },
128 : 0 : { 33, "Accent2" },
129 : 0 : { 34, "20% - Accent2" },
130 : 0 : { 35, "40% - Accent2" },
131 : 0 : { 36, "60% - Accent2" },
132 : 0 : { 37, "Accent3" },
133 : 0 : { 38, "20% - Accent3" },
134 : 0 : { 39, "40% - Accent3" },
135 : 0 : { 40, "60% - Accent3" },
136 : 0 : { 41, "Accent4" },
137 : 0 : { 42, "20% - Accent4" },
138 : 0 : { 43, "40% - Accent4" },
139 : 0 : { 44, "60% - Accent4" },
140 : 0 : { 45, "Accent5" },
141 : 0 : { 46, "20% - Accent5" },
142 : 0 : { 47, "40% - Accent5" },
143 : 0 : { 48, "60% - Accent5" },
144 : 0 : { 49, "Accent6" },
145 : 0 : { 50, "20% - Accent6" },
146 : 0 : { 51, "40% - Accent6" },
147 : 0 : { 52, "60% - Accent6" },
148 : 0 : { 53, "Explanatory Text" }
149 [ + + + - :CBC 320 : };
+ + + - -
- - ]
150 : :
151 [ + + ]: 257 : auto new_style = create_style(names.at(builtin_id));
152 [ + ]: 257 : new_style.d_->builtin_id = builtin_id;
153 : :
154 : 257 : return new_style;
155 [ + + + + : 1 : }
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + - -
- - ]
156 : :
157 : 10 : class style style(const std::string &name)
158 : : {
159 [ + + + ]: 10 : if (!has_style(name)) throw key_not_found();
160 [ + + ]: 9 : return xlnt::style(&style_impls[name]);
161 : : }
162 : :
163 : 12 : bool has_style(const std::string &name)
164 : : {
165 : 12 : return style_impls.count(name) > 0;
166 : : }
167 : :
168 : 17 : std::size_t next_custom_number_format_id() const
169 : : {
170 : 17 : std::size_t id = 164;
171 : :
172 [ + + ]: 41 : for (const auto &nf : number_formats)
173 : : {
174 [ + + + ]: 24 : if (nf.id() >= id)
175 : : {
176 [ + ]: 7 : id = nf.id() + 1;
177 : : }
178 : : }
179 : :
180 : 17 : return id;
181 : : }
182 : :
183 : : template<typename T, typename C>
184 : 1598 : std::size_t find_or_add(C &container, const T &item)
185 : : {
186 : : #pragma GCC diagnostic push
187 : : #pragma GCC diagnostic ignored "-Wsign-conversion"
188 [ + ]: 1598 : auto iter = std::find(container.begin(), container.end(), item);
189 [ + + ]: 1598 : if (iter != container.end())
190 : : {
191 : 1578 : return std::size_t(iter - container.begin());
192 : : }
193 [ + ]: 20 : iter = container.emplace(container.end(), item);
194 : 20 : return std::size_t(iter - container.begin());
195 : : #pragma GCC diagnostic pop
196 : : }
197 : :
198 : : template<typename T>
199 : 175 : std::unordered_map<std::size_t, std::size_t> garbage_collect(
200 : : const std::unordered_map<std::size_t, std::size_t> &reference_counts,
201 : : std::vector<T> &container)
202 : : {
203 : 175 : std::unordered_map<std::size_t, std::size_t> id_map;
204 : 175 : std::size_t unreferenced = 0;
205 : 175 : const auto original_size = container.size();
206 : :
207 [ + + ]: 409 : for (std::size_t i = 0; i < original_size; ++i)
208 : : {
209 [ + ]: 234 : id_map[i] = i - unreferenced;
210 : :
211 [ + + + + : 234 : if (reference_counts.count(i) == 0 || reference_counts.at(i) == 0)
- + + + ]
212 : : {
213 [ + ]: 2 : container.erase(container.begin() + static_cast<typename std::vector<T>::difference_type>(i - unreferenced));
214 : 2 : unreferenced++;
215 : : }
216 : : }
217 : :
218 : 175 : return id_map;
219 :UBC 0 : }
220 : :
221 :CBC 323 : void garbage_collect()
222 : : {
223 [ + + ]: 323 : if (!garbage_collection_enabled) return;
224 : :
225 : 35 : auto format_iter = format_impls.begin();
226 [ + + ]: 148 : while (format_iter != format_impls.end())
227 : : {
228 : 113 : auto &impl = **format_iter;
229 : :
230 [ + + ]: 113 : if (impl.is_used())
231 : : {
232 : 76 : ++format_iter;
233 : : }
234 : : else
235 : : {
236 : 37 : format_iter = format_impls.erase(format_iter);
237 : : }
238 : : }
239 : :
240 : 35 : std::size_t new_id = 0;
241 : :
242 : 35 : std::unordered_map<std::size_t, std::size_t> alignment_reference_counts;
243 : 35 : std::unordered_map<std::size_t, std::size_t> border_reference_counts;
244 : 35 : std::unordered_map<std::size_t, std::size_t> fill_reference_counts;
245 : 35 : std::unordered_map<std::size_t, std::size_t> font_reference_counts;
246 : 35 : std::unordered_map<std::size_t, std::size_t> number_format_reference_counts;
247 : 35 : std::unordered_map<std::size_t, std::size_t> protection_reference_counts;
248 : :
249 [ + ]: 35 : fill_reference_counts[0]++;
250 [ + ]: 35 : fill_reference_counts[1]++;
251 : :
252 [ + + ]: 111 : for (auto &format_item : format_impls)
253 : : {
254 : 76 : auto& impl = *format_item;
255 : 76 : impl.id = new_id++;
256 : :
257 [ - + ]: 76 : if (impl.alignment_id.is_set())
258 : : {
259 [ # # ]:LBC (1) : alignment_reference_counts[impl.alignment_id.get()]++;
260 : : }
261 : :
262 [ + + ]:CBC 76 : if (impl.border_id.is_set())
263 : : {
264 [ + + ]: 35 : border_reference_counts[impl.border_id.get()]++;
265 : : }
266 : :
267 [ + + ]: 76 : if (impl.fill_id.is_set())
268 : : {
269 [ + + ]: 42 : fill_reference_counts[impl.fill_id.get()]++;
270 : : }
271 : :
272 [ + + ]: 76 : if (impl.font_id.is_set())
273 : : {
274 [ + + ]: 64 : font_reference_counts[impl.font_id.get()]++;
275 : : }
276 : :
277 [ + + ]: 76 : if (impl.number_format_id.is_set())
278 : : {
279 [ + + ]: 41 : number_format_reference_counts[impl.number_format_id.get()]++;
280 : : }
281 : :
282 [ - + ]: 76 : if (impl.protection_id.is_set())
283 : : {
284 [ # # ]:UBC 0 : protection_reference_counts[impl.protection_id.get()]++;
285 : : }
286 : : }
287 : :
288 [ + + ]:CBC 118 : for (auto &name_impl_pair : style_impls)
289 : : {
290 : 83 : auto &impl = name_impl_pair.second;
291 : :
292 [ - + ]: 83 : if (impl.alignment_id.is_set())
293 : : {
294 [ # # ]:UBC 0 : alignment_reference_counts[impl.alignment_id.get()]++;
295 : : }
296 : :
297 [ + - ]:CBC 83 : if (impl.border_id.is_set())
298 : : {
299 [ + + ]: 83 : border_reference_counts[impl.border_id.get()]++;
300 : : }
301 : :
302 [ + - ]: 83 : if (impl.fill_id.is_set())
303 : : {
304 [ + + ]: 83 : fill_reference_counts[impl.fill_id.get()]++;
305 : : }
306 : :
307 [ + - ]: 83 : if (impl.font_id.is_set())
308 : : {
309 [ + + ]: 83 : font_reference_counts[impl.font_id.get()]++;
310 : : }
311 : :
312 [ + - ]: 83 : if (impl.number_format_id.is_set())
313 : : {
314 [ + + ]: 83 : number_format_reference_counts[impl.number_format_id.get()]++;
315 : : }
316 : :
317 [ - + ]: 83 : if (impl.protection_id.is_set())
318 : : {
319 [ # # ]:UBC 0 : protection_reference_counts[impl.protection_id.get()]++;
320 : : }
321 : : }
322 : :
323 [ + ]:CBC 35 : auto alignment_id_map = garbage_collect(alignment_reference_counts, alignments);
324 [ + ]: 35 : auto border_id_map = garbage_collect(border_reference_counts, borders);
325 [ + ]: 35 : auto fill_id_map = garbage_collect(fill_reference_counts, fills);
326 [ + ]: 35 : auto font_id_map = garbage_collect(font_reference_counts, fonts);
327 [ + ]: 35 : auto protection_id_map = garbage_collect(protection_reference_counts, protections);
328 : :
329 [ + + ]: 111 : for (auto &format_item : format_impls)
330 : : {
331 : 76 : auto& impl = *format_item;
332 : :
333 [ - + ]: 76 : if (impl.alignment_id.is_set())
334 : : {
335 [ # # # ]:LBC (1) : impl.alignment_id = alignment_id_map[impl.alignment_id.get()];
336 : : }
337 : :
338 [ + + ]:CBC 76 : if (impl.border_id.is_set())
339 : : {
340 [ + + + ]: 35 : impl.border_id = border_id_map[impl.border_id.get()];
341 : : }
342 : :
343 [ + + ]: 76 : if (impl.fill_id.is_set())
344 : : {
345 [ + + + ]: 42 : impl.fill_id = fill_id_map[impl.fill_id.get()];
346 : : }
347 : :
348 [ + + ]: 76 : if (impl.font_id.is_set())
349 : : {
350 [ + + + ]: 64 : impl.font_id = font_id_map[impl.font_id.get()];
351 : : }
352 : :
353 [ - + ]: 76 : if (impl.protection_id.is_set())
354 : : {
355 [ # # # ]:UBC 0 : impl.protection_id = protection_id_map[impl.protection_id.get()];
356 : : }
357 : : }
358 : :
359 [ + + ]:CBC 118 : for (auto &name_impl : style_impls)
360 : : {
361 : 83 : auto &impl = name_impl.second;
362 : :
363 [ - + ]: 83 : if (impl.alignment_id.is_set())
364 : : {
365 [ # # # ]:UBC 0 : impl.alignment_id = alignment_id_map[impl.alignment_id.get()];
366 : : }
367 : :
368 [ + - ]:CBC 83 : if (impl.border_id.is_set())
369 : : {
370 [ + + + ]: 83 : impl.border_id = border_id_map[impl.border_id.get()];
371 : : }
372 : :
373 [ + - ]: 83 : if (impl.fill_id.is_set())
374 : : {
375 [ + + + ]: 83 : impl.fill_id = fill_id_map[impl.fill_id.get()];
376 : : }
377 : :
378 [ + - ]: 83 : if (impl.font_id.is_set())
379 : : {
380 [ + + + ]: 83 : impl.font_id = font_id_map[impl.font_id.get()];
381 : : }
382 : :
383 [ - + ]: 83 : if (impl.protection_id.is_set())
384 : : {
385 [ # # # ]:UBC 0 : impl.protection_id = protection_id_map[impl.protection_id.get()];
386 : : }
387 : : }
388 :CBC 35 : }
389 : :
390 : 1111 : format_impl_ptr find_or_create(format_impl &pattern)
391 : : {
392 : 1111 : std::size_t id = 0;
393 : 1111 : auto iter = format_impls.begin();
394 [ + + + + : 1229 : while (iter != format_impls.end() && !(**iter == pattern))
+ + ]
395 : : {
396 : 118 : ++id;
397 : 118 : ++iter;
398 : : }
399 [ + + ]: 1111 : if (iter == format_impls.end())
400 : : {
401 [ + ]: 7 : iter = format_impls.emplace(format_impls.end(), pattern);
402 : : }
403 : 1111 : auto &result = *iter;
404 : :
405 : 1111 : result->parent = this;
406 : 1111 : result->id = id;
407 : :
408 [ + ]: 2222 : return result;
409 : : }
410 : :
411 : 5 : format_impl_ptr find_or_create_with(format_impl_ptr& pattern, const std::string &style_name)
412 : : {
413 [ + ]: 5 : format_impl new_format = *pattern;
414 [ + ]: 5 : new_format.style = style_name;
415 [ + - ]: 5 : if (!pattern->is_shared())
416 : : {
417 [ + ]: 5 : *pattern = new_format;
418 : : }
419 [ + ]: 10 : return find_or_create(new_format);
420 : 5 : }
421 : :
422 : 1 : format_impl_ptr find_or_create_with(format_impl_ptr& pattern, const alignment &new_alignment, optional<bool> applied)
423 : : {
424 [ + ]: 1 : format_impl new_format = *pattern;
425 [ + ]: 1 : new_format.alignment_id = find_or_add(alignments, new_alignment);
426 [ + ]: 1 : new_format.alignment_applied = applied;
427 [ + - ]: 1 : if (!pattern->is_shared())
428 : : {
429 [ + ]: 1 : *pattern = new_format;
430 : : }
431 [ + ]: 2 : return find_or_create(new_format);
432 : 1 : }
433 : :
434 : 262 : format_impl_ptr find_or_create_with(format_impl_ptr& pattern, const border &new_border, optional<bool> applied)
435 : : {
436 [ + ]: 262 : format_impl new_format = *pattern;
437 [ + ]: 262 : new_format.border_id = find_or_add(borders, new_border);
438 [ + ]: 262 : new_format.border_applied = applied;
439 [ + + ]: 262 : if (!pattern->is_shared())
440 : : {
441 [ + ]: 260 : *pattern = new_format;
442 : : }
443 [ + ]: 524 : return find_or_create(new_format);
444 : 262 : }
445 : :
446 : 274 : format_impl_ptr find_or_create_with(format_impl_ptr& pattern, const fill &new_fill, optional<bool> applied)
447 : : {
448 [ + ]: 274 : format_impl new_format = *pattern;
449 [ + ]: 274 : new_format.fill_id = find_or_add(fills, new_fill);
450 [ + ]: 274 : new_format.fill_applied = applied;
451 [ + + ]: 274 : if (!pattern->is_shared())
452 : : {
453 [ + ]: 268 : *pattern = new_format;
454 : : }
455 [ + ]: 548 : return find_or_create(new_format);
456 : 274 : }
457 : :
458 : 286 : format_impl_ptr find_or_create_with(format_impl_ptr& pattern, const font &new_font, optional<bool> applied)
459 : : {
460 [ + ]: 286 : format_impl new_format = *pattern;
461 [ + ]: 286 : new_format.font_id = find_or_add(fonts, new_font);
462 [ + ]: 286 : new_format.font_applied = applied;
463 [ + + ]: 286 : if (!pattern->is_shared())
464 : : {
465 [ + ]: 283 : *pattern = new_format;
466 : : }
467 [ + ]: 572 : return find_or_create(new_format);
468 : 286 : }
469 : :
470 : 282 : format_impl_ptr find_or_create_with(format_impl_ptr& pattern, const number_format &new_number_format, optional<bool> applied)
471 : : {
472 [ + ]: 282 : format_impl new_format = *pattern;
473 [ + + + + : 282 : if (new_number_format.has_id() && new_number_format.id() < 164)
+ + + + ]
474 : : {
475 [ + ]: 266 : new_format.number_format_id = new_number_format.id();
476 : : }
477 : : else
478 : : {
479 [ + ]: 16 : auto iter = std::find(number_formats.begin(), number_formats.end(), new_number_format);
480 [ + + ]: 16 : if (iter == number_formats.end())
481 : : {
482 [ + ]: 13 : std::size_t new_id = next_custom_number_format_id();
483 [ + ]: 13 : iter = number_formats.emplace(number_formats.end(), new_number_format);
484 [ + ]: 13 : iter->id(new_id);
485 : : }
486 [ + ]: 16 : new_format.number_format_id = iter->id();
487 : : }
488 [ + ]: 282 : new_format.number_format_applied = applied;
489 [ + + ]: 282 : if (!pattern->is_shared())
490 : : {
491 [ + ]: 276 : *pattern = new_format;
492 : : }
493 [ + ]: 564 : return find_or_create(new_format);
494 : 282 : }
495 : :
496 : 1 : format_impl_ptr find_or_create_with(format_impl_ptr& pattern, const protection &new_protection, optional<bool> applied)
497 : : {
498 [ + ]: 1 : format_impl new_format = *pattern;
499 [ + ]: 1 : new_format.protection_id = find_or_add(protections, new_protection);
500 [ + ]: 1 : new_format.protection_applied = applied;
501 [ + - ]: 1 : if (!pattern->is_shared())
502 : : {
503 [ + ]: 1 : *pattern = new_format;
504 : : }
505 [ + ]: 2 : return find_or_create(new_format);
506 : 1 : }
507 : :
508 : 177 : std::size_t style_index(const std::string &name) const
509 : : {
510 : 177 : return static_cast<std::size_t>(std::distance(style_names.begin(),
511 : 177 : std::find(style_names.begin(), style_names.end(), name)));
512 : : }
513 : :
514 : : void clear()
515 : : {
516 : : conditional_format_impls.clear();
517 : : format_impls.clear();
518 : :
519 : : style_impls.clear();
520 : : style_names.clear();
521 : :
522 : : alignments.clear();
523 : : borders.clear();
524 : : fills.clear();
525 : : fonts.clear();
526 : : number_formats.clear();
527 : : protections.clear();
528 : :
529 : : colors.clear();
530 : : }
531 : :
532 : 1 : conditional_format add_conditional_format_rule(worksheet_impl *ws, const range_reference &ref, const condition &when)
533 : : {
534 [ + + ]: 1 : conditional_format_impls.push_back(conditional_format_impl());
535 : :
536 : 1 : auto &impl = conditional_format_impls.back();
537 : 1 : impl.when = when;
538 : 1 : impl.parent = this;
539 : 1 : impl.target_sheet = ws;
540 : 1 : impl.target_range = ref;
541 : 1 : impl.differential_format_id = conditional_format_impls.size() - 1;
542 : :
543 [ + ]: 1 : return xlnt::conditional_format(&impl);
544 : : }
545 : :
546 : : std::weak_ptr<workbook_impl> parent;
547 : :
548 : 8 : bool operator==(const stylesheet& rhs) const
549 : : {
550 : : // no equality on parent as there is only 1 stylesheet per workbook hence would always be false
551 : 8 : return garbage_collection_enabled == rhs.garbage_collection_enabled
552 [ + - ]: 8 : && known_fonts_enabled == rhs.known_fonts_enabled
553 [ + - ]: 8 : && conditional_format_impls == rhs.conditional_format_impls
554 [ + - ]: 8 : && format_impls == rhs.format_impls
555 [ + - ]: 8 : && style_impls == rhs.style_impls
556 [ + - ]: 8 : && style_names == rhs.style_names
557 [ + - ]: 8 : && default_slicer_style == rhs.default_slicer_style
558 [ + - ]: 8 : && alignments == rhs.alignments
559 [ + - ]: 8 : && borders == rhs.borders
560 [ + - ]: 8 : && fills == rhs.fills
561 [ + - ]: 8 : && fonts == rhs.fonts
562 [ + - ]: 8 : && number_formats == rhs.number_formats
563 [ + - ]: 8 : && protections == rhs.protections
564 [ + - + - ]: 16 : && colors == rhs.colors;
565 : : }
566 : :
567 : : bool operator!=(const stylesheet& rhs) const
568 : : {
569 : : return !(*this == rhs);
570 : : }
571 : :
572 :GNC 343 : stylesheet() = default;
573 : : stylesheet(const stylesheet &) = default;
574 : 341 : stylesheet(stylesheet &&) = default;
575 : : stylesheet &operator=(const stylesheet &) = default;
576 : 1 : stylesheet &operator=(stylesheet &&) = default;
577 : :
578 : 684 : ~stylesheet() noexcept
579 : : {
580 : 684 : garbage_collection_enabled = false;
581 : 684 : }
582 : :
583 : : bool garbage_collection_enabled = true;
584 : : bool known_fonts_enabled = false;
585 : :
586 : : std::list<conditional_format_impl> conditional_format_impls;
587 : : std::list<format_impl_list_item> format_impls;
588 : : std::unordered_map<std::string, style_impl> style_impls;
589 : : std::vector<std::string> style_names;
590 : : optional<std::string> default_slicer_style;
591 : : detail::format_impl_ptr default_format_impl;
592 : :
593 : : std::vector<alignment> alignments;
594 : : std::vector<border> borders;
595 : : std::vector<fill> fills;
596 : : std::vector<font> fonts;
597 : : std::vector<number_format> number_formats;
598 : : std::vector<protection> protections;
599 : :
600 : : std::vector<color> colors;
601 : : };
602 : :
603 : : } // namespace detail
604 : : } // namespace xlnt
|