1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
11 #include <svl/IndexedStyleSheets.hxx>
12 #include <svl/style.hxx>
20 const size_t NUMBER_OF_FAMILIES
= 7;
21 size_t family_to_index(SfxStyleFamily family
)
24 case SfxStyleFamily::Char
:
26 case SfxStyleFamily::Para
:
28 case SfxStyleFamily::Frame
:
30 case SfxStyleFamily::Page
:
32 case SfxStyleFamily::Pseudo
:
34 case SfxStyleFamily::Table
:
36 case SfxStyleFamily::All
:
40 assert(false); // only for compiler warning. all cases are handled in the switch
47 IndexedStyleSheets::IndexedStyleSheets()
49 for (size_t i
= 0; i
< NUMBER_OF_FAMILIES
; i
++) {
50 mStyleSheetPositionsByFamily
.emplace_back();
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
);
65 IndexedStyleSheets::Reindex()
67 mPositionsByName
.clear();
68 mStyleSheetPositionsByFamily
.clear();
69 for (size_t i
= 0; i
< NUMBER_OF_FAMILIES
; i
++) {
70 mStyleSheetPositionsByFamily
.emplace_back();
74 for (const auto& rxStyleSheet
: mStyleSheets
) {
75 SfxStyleSheetBase
* p
= rxStyleSheet
.get();
82 IndexedStyleSheets::GetNumberOfStyleSheets() const
84 return mStyleSheets
.size();
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);
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
);
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
);
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
)) {
136 if (behavior
== SearchBehavior::ReturnFirst
) {
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
);
156 IndexedStyleSheets::GetNthStyleSheetThatMatchesPredicate(
158 StyleSheetPredicate
& predicate
,
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
)) {
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
);
187 IndexedStyleSheets::Clear(StyleSheetDisposer
& disposer
)
189 for (auto& rxStyleSheet
: mStyleSheets
) {
190 disposer
.Dispose(rxStyleSheet
);
192 mStyleSheets
.clear();
193 mPositionsByName
.clear();
196 IndexedStyleSheets::~IndexedStyleSheets()
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
)
213 IndexedStyleSheets::GetStyleSheetByPosition(unsigned pos
)
215 if( pos
< mStyleSheets
.size() )
216 return mStyleSheets
.at(pos
).get();
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
));
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: */