bump product version to 5.0.4.1
[LibreOffice.git] / svl / source / items / IndexedStyleSheets.cxx
blobdc5b8ed3baf353941524dbea23b1693136f4f6c8
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>
18 using rtl::OUString;
21 namespace {
22 const size_t NUMBER_OF_FAMILIES = 6;
23 size_t family_to_index(SfxStyleFamily family)
25 switch (family) {
26 case SFX_STYLE_FAMILY_CHAR:
27 return 0;
28 case SFX_STYLE_FAMILY_PARA:
29 return 1;
30 case SFX_STYLE_FAMILY_FRAME:
31 return 2;
32 case SFX_STYLE_FAMILY_PAGE:
33 return 3;
34 case SFX_STYLE_FAMILY_PSEUDO:
35 return 4;
36 case SFX_STYLE_FAMILY_ALL:
37 return 5;
39 assert(false); // only for compiler warning. all cases are handled in the switch
40 return 0;
44 namespace svl {
46 IndexedStyleSheets::IndexedStyleSheets()
48 for (size_t i = 0; i < NUMBER_OF_FAMILIES; i++) {
49 mStyleSheetPositionsByFamily.push_back(std::vector<unsigned>());
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(SFX_STYLE_FAMILY_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.push_back(std::vector<unsigned>());
73 unsigned i = 0;
74 for (VectorType::const_iterator it = mStyleSheets.begin();
75 it != mStyleSheets.end(); ++it) {
76 SfxStyleSheetBase* p = it->get();
77 Register(*p, i);
78 ++i;
82 unsigned
83 IndexedStyleSheets::GetNumberOfStyleSheets() const
85 return mStyleSheets.size();
88 void
89 IndexedStyleSheets::AddStyleSheet(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);
98 bool
99 IndexedStyleSheets::RemoveStyleSheet(rtl::Reference< SfxStyleSheetBase > style)
101 rtl::OUString styleName = style->GetName();
102 std::vector<unsigned> positions = FindPositionsByName(styleName);
103 bool found = false;
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) {
108 found = true;
109 stylePosition = *it;
110 break;
114 if (found) {
115 mStyleSheets.erase(mStyleSheets.begin() + stylePosition);
116 Reindex();
118 return found;
121 std::vector<unsigned>
122 IndexedStyleSheets::FindPositionsByName(const rtl::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);
129 return r;
132 std::vector<unsigned>
133 IndexedStyleSheets::FindPositionsByNameAndPredicate(const rtl::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)) {
142 r.push_back(pos);
143 if (behavior == RETURN_FIRST) {
144 break;
148 return r;
152 unsigned
153 IndexedStyleSheets::GetNumberOfStyleSheetsWithPredicate(StyleSheetPredicate& predicate) const
155 unsigned r = 0;
156 for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
157 const SfxStyleSheetBase *ssheet = it->get();
158 if (predicate.Check(*ssheet)) {
159 ++r;
162 return r;
165 rtl::Reference<SfxStyleSheetBase>
166 IndexedStyleSheets::GetNthStyleSheetThatMatchesPredicate(
167 unsigned n,
168 StyleSheetPredicate& predicate,
169 unsigned startAt)
171 rtl::Reference<SfxStyleSheetBase> retval;
172 unsigned matching = 0;
173 for (VectorType::iterator it = mStyleSheets.begin()+startAt; it != mStyleSheets.end(); ++it) {
174 SfxStyleSheetBase *ssheet = it->get();
175 if (predicate.Check(*ssheet)) {
176 if (matching == n) {
177 retval = *it;
178 break;
180 ++matching;
183 return retval;
186 unsigned
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);
196 void
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()
209 bool
210 IndexedStyleSheets::HasStyleSheet(rtl::Reference< SfxStyleSheetBase > style) const
212 rtl::OUString styleName = style->GetName();
213 std::vector<unsigned> positions = FindPositionsByName(styleName);
214 for (std::vector<unsigned>::const_iterator it = positions.begin();
215 it != positions.end(); ++it) {
216 if (mStyleSheets.at(*it) == style) {
217 return true;
220 return false;
223 rtl::Reference< SfxStyleSheetBase >
224 IndexedStyleSheets::GetStyleSheetByPosition(unsigned pos)
226 if( pos < mStyleSheets.size() )
227 return mStyleSheets.at(pos);
228 return NULL;
231 void
232 IndexedStyleSheets::ApplyToAllStyleSheets(StyleSheetCallback& callback) const
234 for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
235 callback.DoIt(**it);
239 std::vector<unsigned>
240 IndexedStyleSheets::FindPositionsByPredicate(StyleSheetPredicate& predicate) const
242 std::vector<unsigned> r;
243 for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
244 if (predicate.Check(**it)) {
245 r.push_back(std::distance(mStyleSheets.begin(), it));
248 return r;
251 const std::vector<unsigned>&
252 IndexedStyleSheets::GetStyleSheetPositionsByFamily(SfxStyleFamily e) const
254 size_t position = family_to_index(e);
255 return mStyleSheetPositionsByFamily.at(position);
258 } /* namespace svl */
260 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */