OInterfaceContainerHelper3 needs to be thread-safe
[LibreOffice.git] / svl / source / items / IndexedStyleSheets.cxx
blob57e2dddbf1c1cadfee9cff8e01c46a3008e2d837
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 IndexedStyleSheets::Register(const SfxStyleSheetBase& style, sal_Int32 pos)
56 mPositionsByName.insert(std::make_pair(style.GetName(), pos));
57 size_t position = family_to_index(style.GetFamily());
58 mStyleSheetPositionsByFamily.at(position).push_back(pos);
59 size_t positionForFamilyAll = family_to_index(SfxStyleFamily::All);
60 mStyleSheetPositionsByFamily.at(positionForFamilyAll).push_back(pos);
63 void
64 IndexedStyleSheets::Reindex()
66 mPositionsByName.clear();
67 mStyleSheetPositionsByFamily.clear();
68 for (size_t i = 0; i < NUMBER_OF_FAMILIES; i++) {
69 mStyleSheetPositionsByFamily.emplace_back();
72 sal_Int32 i = 0;
73 for (const auto& rxStyleSheet : mStyleSheets) {
74 SfxStyleSheetBase* p = rxStyleSheet.get();
75 Register(*p, i);
76 ++i;
80 sal_Int32 IndexedStyleSheets::GetNumberOfStyleSheets() const
82 return mStyleSheets.size();
85 void
86 IndexedStyleSheets::AddStyleSheet(const rtl::Reference< SfxStyleSheetBase >& style)
88 if (!HasStyleSheet(style)) {
89 mStyleSheets.push_back(style);
90 // since we just added an element to the vector, we can safely do -1 as it will always be >= 1
91 Register(*style, mStyleSheets.size()-1);
95 bool
96 IndexedStyleSheets::RemoveStyleSheet(const rtl::Reference< SfxStyleSheetBase >& style)
98 std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(style->GetName());
99 for (MapType::const_iterator it = range.first; it != range.second; ++it)
101 sal_Int32 pos = it->second;
102 if (mStyleSheets.at(pos) == style)
104 mStyleSheets.erase(mStyleSheets.begin() + pos);
105 Reindex();
106 return true;
109 return false;
112 std::vector<sal_Int32> IndexedStyleSheets::FindPositionsByName(const OUString& name) const
114 std::vector<sal_Int32> r;
115 std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(name);
116 for (MapType::const_iterator it = range.first; it != range.second; ++it) {
117 r.push_back(it->second);
119 return r;
122 std::vector<sal_Int32> IndexedStyleSheets::FindPositionsByNameAndPredicate(const OUString& name,
123 StyleSheetPredicate& predicate, SearchBehavior behavior) const
125 std::vector<sal_Int32> r;
126 auto range = mPositionsByName.equal_range(name);
127 for (auto it = range.first; it != range.second; ++it) {
128 sal_Int32 pos = it->second;
129 SfxStyleSheetBase *ssheet = mStyleSheets.at(pos).get();
130 if (predicate.Check(*ssheet)) {
131 r.push_back(pos);
132 if (behavior == SearchBehavior::ReturnFirst) {
133 break;
137 return r;
141 sal_Int32
142 IndexedStyleSheets::GetNumberOfStyleSheetsWithPredicate(StyleSheetPredicate& predicate) const
144 return std::count_if(mStyleSheets.begin(), mStyleSheets.end(),
145 [&predicate](const rtl::Reference<SfxStyleSheetBase>& rxStyleSheet) {
146 const SfxStyleSheetBase *ssheet = rxStyleSheet.get();
147 return predicate.Check(*ssheet);
151 SfxStyleSheetBase*
152 IndexedStyleSheets::GetNthStyleSheetThatMatchesPredicate(
153 sal_Int32 n,
154 StyleSheetPredicate& predicate,
155 sal_Int32 startAt)
157 SfxStyleSheetBase* retval = nullptr;
158 sal_Int32 matching = 0;
159 for (VectorType::const_iterator it = mStyleSheets.begin()+startAt; it != mStyleSheets.end(); ++it) {
160 SfxStyleSheetBase *ssheet = it->get();
161 if (predicate.Check(*ssheet)) {
162 if (matching == n) {
163 retval = it->get();
164 break;
166 ++matching;
169 return retval;
172 sal_Int32 IndexedStyleSheets::FindStyleSheetPosition(const SfxStyleSheetBase& style) const
174 VectorType::const_iterator it = std::find(mStyleSheets.begin(), mStyleSheets.end(), &style);
175 if (it == mStyleSheets.end()) {
176 throw std::runtime_error("IndexedStyleSheets::FindStylePosition Looked for style not in index");
178 return std::distance(mStyleSheets.begin(), it);
181 void
182 IndexedStyleSheets::Clear(StyleSheetDisposer& disposer)
184 for (const auto& rxStyleSheet : mStyleSheets) {
185 disposer.Dispose(rxStyleSheet);
187 mStyleSheets.clear();
188 mPositionsByName.clear();
191 IndexedStyleSheets::~IndexedStyleSheets()
195 bool
196 IndexedStyleSheets::HasStyleSheet(const rtl::Reference< SfxStyleSheetBase >& style) const
198 std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(style->GetName());
199 for (MapType::const_iterator it = range.first; it != range.second; ++it)
201 if (mStyleSheets.at(it->second) == style)
202 return true;
204 return false;
207 SfxStyleSheetBase*
208 IndexedStyleSheets::GetStyleSheetByPosition(sal_Int32 pos)
210 if( pos < static_cast<sal_Int32>(mStyleSheets.size()) )
211 return mStyleSheets.at(pos).get();
212 return nullptr;
215 void
216 IndexedStyleSheets::ApplyToAllStyleSheets(StyleSheetCallback& callback) const
218 for (const auto& rxStyleSheet : mStyleSheets) {
219 callback.DoIt(*rxStyleSheet);
223 std::vector<sal_Int32>
224 IndexedStyleSheets::FindPositionsByPredicate(StyleSheetPredicate& predicate) const
226 std::vector<sal_Int32> r;
227 for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
228 if (predicate.Check(**it)) {
229 r.push_back(std::distance(mStyleSheets.begin(), it));
232 return r;
235 const std::vector<sal_Int32>&
236 IndexedStyleSheets::GetStyleSheetPositionsByFamily(SfxStyleFamily e) const
238 size_t position = family_to_index(e);
239 return mStyleSheetPositionsByFamily.at(position);
242 } /* namespace svl */
244 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */