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 (VectorType::const_iterator it
= mStyleSheets
.begin();
75 it
!= mStyleSheets
.end(); ++it
) {
76 SfxStyleSheetBase
* p
= it
->get();
83 IndexedStyleSheets::GetNumberOfStyleSheets() const
85 return mStyleSheets
.size();
89 IndexedStyleSheets::AddStyleSheet(const rtl::Reference
< SfxStyleSheetBase
>& style
)
91 if (!HasStyleSheet(style
)) {
92 mStyleSheets
.push_back(style
);
93 // since we just added an element to the vector, we can safely do -1 as it will always be >= 1
94 Register(*style
, mStyleSheets
.size()-1);
99 IndexedStyleSheets::RemoveStyleSheet(const rtl::Reference
< SfxStyleSheetBase
>& style
)
101 OUString styleName
= style
->GetName();
102 std::vector
<unsigned> positions
= FindPositionsByName(styleName
);
104 unsigned stylePosition
= 0;
105 for (std::vector
<unsigned>::const_iterator it
= positions
.begin();
106 it
!= positions
.end(); ++it
) {
107 if (mStyleSheets
.at(*it
) == style
) {
115 mStyleSheets
.erase(mStyleSheets
.begin() + stylePosition
);
121 std::vector
<unsigned>
122 IndexedStyleSheets::FindPositionsByName(const OUString
& name
) const
124 std::vector
<unsigned> r
;
125 std::pair
<MapType::const_iterator
, MapType::const_iterator
> range
= mPositionsByName
.equal_range(name
);
126 for (MapType::const_iterator it
= range
.first
; it
!= range
.second
; ++it
) {
127 r
.push_back(it
->second
);
132 std::vector
<unsigned>
133 IndexedStyleSheets::FindPositionsByNameAndPredicate(const OUString
& name
,
134 StyleSheetPredicate
& predicate
, SearchBehavior behavior
) const
136 std::vector
<unsigned> r
;
137 MapType::const_iterator it
= mPositionsByName
.find(name
);
138 for (/**/; it
!= mPositionsByName
.end(); ++it
) {
139 unsigned pos
= it
->second
;
140 SfxStyleSheetBase
*ssheet
= mStyleSheets
.at(pos
).get();
141 if (predicate
.Check(*ssheet
)) {
143 if (behavior
== SearchBehavior::ReturnFirst
) {
153 IndexedStyleSheets::GetNumberOfStyleSheetsWithPredicate(StyleSheetPredicate
& predicate
) const
156 for (VectorType::const_iterator it
= mStyleSheets
.begin(); it
!= mStyleSheets
.end(); ++it
) {
157 const SfxStyleSheetBase
*ssheet
= it
->get();
158 if (predicate
.Check(*ssheet
)) {
166 IndexedStyleSheets::GetNthStyleSheetThatMatchesPredicate(
168 StyleSheetPredicate
& predicate
,
171 SfxStyleSheetBase
* retval
= nullptr;
172 unsigned matching
= 0;
173 for (VectorType::const_iterator it
= mStyleSheets
.begin()+startAt
; it
!= mStyleSheets
.end(); ++it
) {
174 SfxStyleSheetBase
*ssheet
= it
->get();
175 if (predicate
.Check(*ssheet
)) {
187 IndexedStyleSheets::FindStyleSheetPosition(const SfxStyleSheetBase
& style
) const
189 VectorType::const_iterator it
= std::find(mStyleSheets
.begin(), mStyleSheets
.end(), &style
);
190 if (it
== mStyleSheets
.end()) {
191 throw std::runtime_error("IndexedStyleSheets::FindStylePosition Looked for style not in index");
193 return std::distance(mStyleSheets
.begin(), it
);
197 IndexedStyleSheets::Clear(StyleSheetDisposer
& disposer
)
199 for (VectorType::iterator it
= mStyleSheets
.begin(); it
!= mStyleSheets
.end(); ++it
) {
200 disposer
.Dispose(*it
);
202 mStyleSheets
.clear();
203 mPositionsByName
.clear();
206 IndexedStyleSheets::~IndexedStyleSheets()
211 IndexedStyleSheets::HasStyleSheet(const rtl::Reference
< SfxStyleSheetBase
>& style
) const
213 OUString styleName
= style
->GetName();
214 std::vector
<unsigned> positions
= FindPositionsByName(styleName
);
215 for (std::vector
<unsigned>::const_iterator it
= positions
.begin();
216 it
!= positions
.end(); ++it
) {
217 if (mStyleSheets
.at(*it
) == style
) {
225 IndexedStyleSheets::GetStyleSheetByPosition(unsigned pos
)
227 if( pos
< mStyleSheets
.size() )
228 return mStyleSheets
.at(pos
).get();
233 IndexedStyleSheets::ApplyToAllStyleSheets(StyleSheetCallback
& callback
) const
235 for (VectorType::const_iterator it
= mStyleSheets
.begin(); it
!= mStyleSheets
.end(); ++it
) {
240 std::vector
<unsigned>
241 IndexedStyleSheets::FindPositionsByPredicate(StyleSheetPredicate
& predicate
) const
243 std::vector
<unsigned> r
;
244 for (VectorType::const_iterator it
= mStyleSheets
.begin(); it
!= mStyleSheets
.end(); ++it
) {
245 if (predicate
.Check(**it
)) {
246 r
.push_back(std::distance(mStyleSheets
.begin(), it
));
252 const std::vector
<unsigned>&
253 IndexedStyleSheets::GetStyleSheetPositionsByFamily(SfxStyleFamily e
) const
255 size_t position
= family_to_index(e
);
256 return mStyleSheetPositionsByFamily
.at(position
);
259 } /* namespace svl */
261 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */