bump product version to 6.3.0.0.beta1
[LibreOffice.git] / svl / source / items / IndexedStyleSheets.cxx
blob233c10e56093158d80ce4a15627ba0c0d4cb96b7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
11 #include <svl/IndexedStyleSheets.hxx>
12 #include <svl/style.hxx>
14 #include <stdexcept>
15 #include <algorithm>
16 #include <utility>
19 namespace {
20 const size_t NUMBER_OF_FAMILIES = 7;
21 size_t family_to_index(SfxStyleFamily family)
23 switch (family) {
24 case SfxStyleFamily::Char:
25 return 0;
26 case SfxStyleFamily::Para:
27 return 1;
28 case SfxStyleFamily::Frame:
29 return 2;
30 case SfxStyleFamily::Page:
31 return 3;
32 case SfxStyleFamily::Pseudo:
33 return 4;
34 case SfxStyleFamily::Table:
35 return 5;
36 case SfxStyleFamily::All:
37 return 6;
38 default: break;
40 assert(false); // only for compiler warning. all cases are handled in the switch
41 return 0;
45 namespace svl {
47 IndexedStyleSheets::IndexedStyleSheets()
49 for (size_t i = 0; i < NUMBER_OF_FAMILIES; i++) {
50 mStyleSheetPositionsByFamily.emplace_back();
54 void
55 IndexedStyleSheets::Register(const SfxStyleSheetBase& style, unsigned pos)
57 mPositionsByName.insert(std::make_pair(style.GetName(), pos));
58 size_t position = family_to_index(style.GetFamily());
59 mStyleSheetPositionsByFamily.at(position).push_back(pos);
60 size_t positionForFamilyAll = family_to_index(SfxStyleFamily::All);
61 mStyleSheetPositionsByFamily.at(positionForFamilyAll).push_back(pos);
64 void
65 IndexedStyleSheets::Reindex()
67 mPositionsByName.clear();
68 mStyleSheetPositionsByFamily.clear();
69 for (size_t i = 0; i < NUMBER_OF_FAMILIES; i++) {
70 mStyleSheetPositionsByFamily.emplace_back();
73 unsigned i = 0;
74 for (const auto& rxStyleSheet : mStyleSheets) {
75 SfxStyleSheetBase* p = rxStyleSheet.get();
76 Register(*p, i);
77 ++i;
81 unsigned
82 IndexedStyleSheets::GetNumberOfStyleSheets() const
84 return mStyleSheets.size();
87 void
88 IndexedStyleSheets::AddStyleSheet(const rtl::Reference< SfxStyleSheetBase >& style)
90 if (!HasStyleSheet(style)) {
91 mStyleSheets.push_back(style);
92 // since we just added an element to the vector, we can safely do -1 as it will always be >= 1
93 Register(*style, mStyleSheets.size()-1);
97 bool
98 IndexedStyleSheets::RemoveStyleSheet(const rtl::Reference< SfxStyleSheetBase >& style)
100 std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(style->GetName());
101 for (MapType::const_iterator it = range.first; it != range.second; ++it)
103 unsigned pos = it->second;
104 if (mStyleSheets.at(pos) == style)
106 mStyleSheets.erase(mStyleSheets.begin() + pos);
107 Reindex();
108 return true;
111 return false;
114 std::vector<unsigned>
115 IndexedStyleSheets::FindPositionsByName(const OUString& name) const
117 std::vector<unsigned> r;
118 std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(name);
119 for (MapType::const_iterator it = range.first; it != range.second; ++it) {
120 r.push_back(it->second);
122 return r;
125 std::vector<unsigned>
126 IndexedStyleSheets::FindPositionsByNameAndPredicate(const OUString& name,
127 StyleSheetPredicate& predicate, SearchBehavior behavior) const
129 std::vector<unsigned> r;
130 auto range = mPositionsByName.equal_range(name);
131 for (auto it = range.first; it != range.second; ++it) {
132 unsigned pos = it->second;
133 SfxStyleSheetBase *ssheet = mStyleSheets.at(pos).get();
134 if (predicate.Check(*ssheet)) {
135 r.push_back(pos);
136 if (behavior == SearchBehavior::ReturnFirst) {
137 break;
141 return r;
145 unsigned
146 IndexedStyleSheets::GetNumberOfStyleSheetsWithPredicate(StyleSheetPredicate& predicate) const
148 return std::count_if(mStyleSheets.begin(), mStyleSheets.end(),
149 [&predicate](const rtl::Reference<SfxStyleSheetBase>& rxStyleSheet) {
150 const SfxStyleSheetBase *ssheet = rxStyleSheet.get();
151 return predicate.Check(*ssheet);
155 SfxStyleSheetBase*
156 IndexedStyleSheets::GetNthStyleSheetThatMatchesPredicate(
157 unsigned n,
158 StyleSheetPredicate& predicate,
159 unsigned startAt)
161 SfxStyleSheetBase* retval = nullptr;
162 unsigned matching = 0;
163 for (VectorType::const_iterator it = mStyleSheets.begin()+startAt; it != mStyleSheets.end(); ++it) {
164 SfxStyleSheetBase *ssheet = it->get();
165 if (predicate.Check(*ssheet)) {
166 if (matching == n) {
167 retval = it->get();
168 break;
170 ++matching;
173 return retval;
176 unsigned
177 IndexedStyleSheets::FindStyleSheetPosition(const SfxStyleSheetBase& style) const
179 VectorType::const_iterator it = std::find(mStyleSheets.begin(), mStyleSheets.end(), &style);
180 if (it == mStyleSheets.end()) {
181 throw std::runtime_error("IndexedStyleSheets::FindStylePosition Looked for style not in index");
183 return std::distance(mStyleSheets.begin(), it);
186 void
187 IndexedStyleSheets::Clear(StyleSheetDisposer& disposer)
189 for (auto& rxStyleSheet : mStyleSheets) {
190 disposer.Dispose(rxStyleSheet);
192 mStyleSheets.clear();
193 mPositionsByName.clear();
196 IndexedStyleSheets::~IndexedStyleSheets()
200 bool
201 IndexedStyleSheets::HasStyleSheet(const rtl::Reference< SfxStyleSheetBase >& style) const
203 std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(style->GetName());
204 for (MapType::const_iterator it = range.first; it != range.second; ++it)
206 if (mStyleSheets.at(it->second) == style)
207 return true;
209 return false;
212 SfxStyleSheetBase*
213 IndexedStyleSheets::GetStyleSheetByPosition(unsigned pos)
215 if( pos < mStyleSheets.size() )
216 return mStyleSheets.at(pos).get();
217 return nullptr;
220 void
221 IndexedStyleSheets::ApplyToAllStyleSheets(StyleSheetCallback& callback) const
223 for (const auto& rxStyleSheet : mStyleSheets) {
224 callback.DoIt(*rxStyleSheet);
228 std::vector<unsigned>
229 IndexedStyleSheets::FindPositionsByPredicate(StyleSheetPredicate& predicate) const
231 std::vector<unsigned> r;
232 for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
233 if (predicate.Check(**it)) {
234 r.push_back(std::distance(mStyleSheets.begin(), it));
237 return r;
240 const std::vector<unsigned>&
241 IndexedStyleSheets::GetStyleSheetPositionsByFamily(SfxStyleFamily e) const
243 size_t position = family_to_index(e);
244 return mStyleSheetPositionsByFamily.at(position);
247 } /* namespace svl */
249 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */