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();
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
);
64 IndexedStyleSheets::Reindex()
66 mPositionsByName
.clear();
67 mStyleSheetPositionsByFamily
.clear();
68 for (size_t i
= 0; i
< NUMBER_OF_FAMILIES
; i
++) {
69 mStyleSheetPositionsByFamily
.emplace_back();
73 for (const auto& rxStyleSheet
: mStyleSheets
) {
74 SfxStyleSheetBase
* p
= rxStyleSheet
.get();
80 sal_Int32
IndexedStyleSheets::GetNumberOfStyleSheets() const
82 return mStyleSheets
.size();
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);
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
);
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
);
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
)) {
132 if (behavior
== SearchBehavior::ReturnFirst
) {
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
);
152 IndexedStyleSheets::GetNthStyleSheetThatMatchesPredicate(
154 StyleSheetPredicate
& predicate
,
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
)) {
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
);
182 IndexedStyleSheets::Clear(StyleSheetDisposer
& disposer
)
184 for (const auto& rxStyleSheet
: mStyleSheets
) {
185 disposer
.Dispose(rxStyleSheet
);
187 mStyleSheets
.clear();
188 mPositionsByName
.clear();
191 IndexedStyleSheets::~IndexedStyleSheets()
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
)
208 IndexedStyleSheets::GetStyleSheetByPosition(sal_Int32 pos
)
210 if( pos
< static_cast<sal_Int32
>(mStyleSheets
.size()) )
211 return mStyleSheets
.at(pos
).get();
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
));
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: */