Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : */
9 :
10 :
11 : #include <svl/IndexedStyleSheets.hxx>
12 : #include <svl/style.hxx>
13 :
14 : #include <stdexcept>
15 : #include <algorithm>
16 : #include <utility>
17 :
18 : using rtl::OUString;
19 :
20 :
21 : namespace {
22 : const size_t NUMBER_OF_FAMILIES = 6;
23 468548 : size_t family_to_index(SfxStyleFamily family)
24 : {
25 468548 : switch (family) {
26 : case SFX_STYLE_FAMILY_CHAR:
27 18 : return 0;
28 : case SFX_STYLE_FAMILY_PARA:
29 73226 : return 1;
30 : case SFX_STYLE_FAMILY_FRAME:
31 89624 : return 2;
32 : case SFX_STYLE_FAMILY_PAGE:
33 83138 : return 3;
34 : case SFX_STYLE_FAMILY_PSEUDO:
35 32382 : return 4;
36 : case SFX_STYLE_FAMILY_ALL:
37 190160 : return 5;
38 : }
39 : assert(false); // only for compiler warning. all cases are handled in the switch
40 0 : return 0;
41 : }
42 : }
43 :
44 : namespace svl {
45 :
46 4606 : IndexedStyleSheets::IndexedStyleSheets()
47 : {
48 32242 : for (size_t i = 0; i < NUMBER_OF_FAMILIES; i++) {
49 27636 : mStyleSheetPositionsByFamily.push_back(std::vector<unsigned>());
50 : }
51 4606 : ;}
52 :
53 :
54 : void
55 190159 : IndexedStyleSheets::Register(const SfxStyleSheetBase& style, unsigned pos)
56 : {
57 190159 : mPositionsByName.insert(std::make_pair(style.GetName(), pos));
58 190159 : size_t position = family_to_index(style.GetFamily());
59 190159 : mStyleSheetPositionsByFamily.at(position).push_back(pos);
60 190159 : size_t positionForFamilyAll = family_to_index(SFX_STYLE_FAMILY_ALL);
61 190159 : mStyleSheetPositionsByFamily.at(positionForFamilyAll).push_back(pos);
62 190159 : }
63 :
64 : void
65 2071 : IndexedStyleSheets::Reindex()
66 : {
67 2071 : mPositionsByName.clear();
68 2071 : mStyleSheetPositionsByFamily.clear();
69 14497 : for (size_t i = 0; i < NUMBER_OF_FAMILIES; i++) {
70 12426 : mStyleSheetPositionsByFamily.push_back(std::vector<unsigned>());
71 : }
72 :
73 2071 : unsigned i = 0;
74 499563 : for (VectorType::const_iterator it = mStyleSheets.begin();
75 333042 : it != mStyleSheets.end(); ++it) {
76 164450 : SfxStyleSheetBase* p = it->get();
77 164450 : Register(*p, i);
78 164450 : ++i;
79 : }
80 2071 : }
81 :
82 : unsigned
83 1051 : IndexedStyleSheets::GetNumberOfStyleSheets() const
84 : {
85 1051 : return mStyleSheets.size();
86 : }
87 :
88 : void
89 25710 : IndexedStyleSheets::AddStyleSheet(rtl::Reference< SfxStyleSheetBase > style)
90 : {
91 25710 : if (!HasStyleSheet(style)) {
92 25709 : 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 25709 : Register(*style, mStyleSheets.size()-1);
95 : }
96 25710 : }
97 :
98 : bool
99 3 : IndexedStyleSheets::RemoveStyleSheet(rtl::Reference< SfxStyleSheetBase > style)
100 : {
101 3 : rtl::OUString styleName = style->GetName();
102 6 : std::vector<unsigned> positions = FindPositionsByName(styleName);
103 3 : bool found = false;
104 3 : unsigned stylePosition = 0;
105 9 : for (std::vector<unsigned>::const_iterator it = positions.begin();
106 6 : it != positions.end(); ++it) {
107 2 : if (mStyleSheets.at(*it) == style) {
108 2 : found = true;
109 2 : stylePosition = *it;
110 2 : break;
111 : }
112 : }
113 :
114 3 : if (found) {
115 2 : mStyleSheets.erase(mStyleSheets.begin() + stylePosition);
116 2 : Reindex();
117 : }
118 6 : return found;
119 : }
120 :
121 : std::vector<unsigned>
122 25719 : IndexedStyleSheets::FindPositionsByName(const rtl::OUString& name) const
123 : {
124 25719 : std::vector<unsigned> r;
125 25719 : std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(name);
126 26750 : for (MapType::const_iterator it = range.first; it != range.second; ++it) {
127 1031 : r.push_back(it->second);
128 : }
129 25719 : return r;
130 : }
131 :
132 : std::vector<unsigned>
133 338121 : IndexedStyleSheets::FindPositionsByNameAndPredicate(const rtl::OUString& name,
134 : StyleSheetPredicate& predicate, SearchBehavior behavior) const
135 : {
136 338121 : std::vector<unsigned> r;
137 338121 : MapType::const_iterator it = mPositionsByName.find(name);
138 373967 : for (/**/; it != mPositionsByName.end(); ++it) {
139 289817 : unsigned pos = it->second;
140 289817 : SfxStyleSheetBase *ssheet = mStyleSheets.at(pos).get();
141 289817 : if (predicate.Check(*ssheet)) {
142 253974 : r.push_back(pos);
143 253974 : if (behavior == RETURN_FIRST) {
144 253971 : break;
145 : }
146 : }
147 : }
148 338121 : return r;
149 : }
150 :
151 :
152 : unsigned
153 0 : IndexedStyleSheets::GetNumberOfStyleSheetsWithPredicate(StyleSheetPredicate& predicate) const
154 : {
155 0 : unsigned r = 0;
156 0 : for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
157 0 : const SfxStyleSheetBase *ssheet = it->get();
158 0 : if (predicate.Check(*ssheet)) {
159 0 : ++r;
160 : }
161 : }
162 0 : return r;
163 : }
164 :
165 : rtl::Reference<SfxStyleSheetBase>
166 0 : IndexedStyleSheets::GetNthStyleSheetThatMatchesPredicate(
167 : unsigned n,
168 : StyleSheetPredicate& predicate,
169 : unsigned startAt)
170 : {
171 0 : rtl::Reference<SfxStyleSheetBase> retval;
172 0 : unsigned matching = 0;
173 0 : for (VectorType::iterator it = mStyleSheets.begin()+startAt; it != mStyleSheets.end(); ++it) {
174 0 : SfxStyleSheetBase *ssheet = it->get();
175 0 : if (predicate.Check(*ssheet)) {
176 0 : if (matching == n) {
177 0 : retval = *it;
178 0 : break;
179 : }
180 0 : ++matching;
181 : }
182 : }
183 0 : return retval;
184 : }
185 :
186 : unsigned
187 1 : IndexedStyleSheets::FindStyleSheetPosition(const SfxStyleSheetBase& style) const
188 : {
189 1 : VectorType::const_iterator it = std::find(mStyleSheets.begin(), mStyleSheets.end(), &style);
190 1 : if (it == mStyleSheets.end()) {
191 0 : throw std::runtime_error("IndexedStyleSheets::FindStylePosition Looked for style not in index");
192 : }
193 1 : return std::distance(mStyleSheets.begin(), it);
194 : }
195 :
196 : void
197 4869 : IndexedStyleSheets::Clear(StyleSheetDisposer& disposer)
198 : {
199 30092 : for (VectorType::iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
200 25223 : disposer.Dispose(*it);
201 : }
202 4869 : mStyleSheets.clear();
203 4869 : mPositionsByName.clear();
204 4869 : }
205 :
206 4563 : IndexedStyleSheets::~IndexedStyleSheets()
207 4563 : {;}
208 :
209 : bool
210 25714 : IndexedStyleSheets::HasStyleSheet(rtl::Reference< SfxStyleSheetBase > style) const
211 : {
212 25714 : rtl::OUString styleName = style->GetName();
213 51428 : std::vector<unsigned> positions = FindPositionsByName(styleName);
214 80208 : for (std::vector<unsigned>::const_iterator it = positions.begin();
215 53472 : it != positions.end(); ++it) {
216 1025 : if (mStyleSheets.at(*it) == style) {
217 3 : return true;
218 : }
219 : }
220 51425 : return false;
221 : }
222 :
223 : rtl::Reference< SfxStyleSheetBase >
224 329092 : IndexedStyleSheets::GetStyleSheetByPosition(unsigned pos)
225 : {
226 329092 : if( pos < mStyleSheets.size() )
227 329092 : return mStyleSheets.at(pos);
228 0 : return NULL;
229 : }
230 :
231 : void
232 0 : IndexedStyleSheets::ApplyToAllStyleSheets(StyleSheetCallback& callback) const
233 : {
234 0 : for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
235 0 : callback.DoIt(**it);
236 : }
237 0 : }
238 :
239 : std::vector<unsigned>
240 0 : IndexedStyleSheets::FindPositionsByPredicate(StyleSheetPredicate& predicate) const
241 : {
242 0 : std::vector<unsigned> r;
243 0 : for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
244 0 : if (predicate.Check(**it)) {
245 0 : r.push_back(std::distance(mStyleSheets.begin(), it));
246 : }
247 : }
248 0 : return r;
249 : }
250 :
251 : const std::vector<unsigned>&
252 88230 : IndexedStyleSheets::GetStyleSheetPositionsByFamily(SfxStyleFamily e) const
253 : {
254 88230 : size_t position = family_to_index(e);
255 88230 : return mStyleSheetPositionsByFamily.at(position);
256 : }
257 :
258 : } /* namespace svl */
259 :
260 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|