differential code coverage report with master
Current view: top level - source/detail/implementations - stylesheet.hpp (source / functions) Coverage Total Hit LBC UBC GNC CBC
Current: coverage.info Lines: 78.9 % 294 232 2 60 6 226
Current Date: 2025-12-07 02:01:22 Functions: 100.0 % 34 34 4 30
Baseline: coverage_master.info Branches: 80.3 % 330 265 14 116 530
Baseline Date: 2025-12-07 02:01:21

             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
        

Generated by: LCOV version 2.3.1-beta