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 <utility>
16 :
17 : using rtl::OUString;
18 :
19 :
20 : namespace {
21 : const size_t NUMBER_OF_FAMILIES = 6;
22 428888 : size_t family_to_index(SfxStyleFamily family)
23 : {
24 428888 : switch (family) {
25 : case SFX_STYLE_FAMILY_CHAR:
26 36 : return 0;
27 : case SFX_STYLE_FAMILY_PARA:
28 73270 : return 1;
29 : case SFX_STYLE_FAMILY_FRAME:
30 85030 : return 2;
31 : case SFX_STYLE_FAMILY_PAGE:
32 72050 : return 3;
33 : case SFX_STYLE_FAMILY_PSEUDO:
34 28252 : return 4;
35 : case SFX_STYLE_FAMILY_ALL:
36 170250 : return 5;
37 : }
38 : assert(false); // only for compiler warning. all cases are handled in the switch
39 0 : return 0;
40 : }
41 : }
42 :
43 : namespace svl {
44 :
45 7762 : IndexedStyleSheets::IndexedStyleSheets()
46 : {
47 54334 : for (size_t i = 0; i < NUMBER_OF_FAMILIES; i++) {
48 46572 : mStyleSheetPositionsByFamily.push_back(std::vector<unsigned>());
49 : }
50 7762 : ;}
51 :
52 :
53 : void
54 170248 : IndexedStyleSheets::Register(const SfxStyleSheetBase& style, unsigned pos)
55 : {
56 170248 : mPositionsByName.insert(std::make_pair(style.GetName(), pos));
57 170248 : size_t position = family_to_index(style.GetFamily());
58 170248 : mStyleSheetPositionsByFamily.at(position).push_back(pos);
59 170248 : size_t positionForFamilyAll = family_to_index(SFX_STYLE_FAMILY_ALL);
60 170248 : mStyleSheetPositionsByFamily.at(positionForFamilyAll).push_back(pos);
61 170248 : }
62 :
63 : void
64 1678 : IndexedStyleSheets::Reindex()
65 : {
66 1678 : mPositionsByName.clear();
67 1678 : mStyleSheetPositionsByFamily.clear();
68 11746 : for (size_t i = 0; i < NUMBER_OF_FAMILIES; i++) {
69 10068 : mStyleSheetPositionsByFamily.push_back(std::vector<unsigned>());
70 : }
71 :
72 1678 : unsigned i = 0;
73 402222 : for (VectorType::const_iterator it = mStyleSheets.begin();
74 268148 : it != mStyleSheets.end(); ++it) {
75 132396 : SfxStyleSheetBase* p = it->get();
76 132396 : Register(*p, i);
77 132396 : ++i;
78 : }
79 1678 : }
80 :
81 : unsigned
82 1628 : IndexedStyleSheets::GetNumberOfStyleSheets() const
83 : {
84 1628 : return mStyleSheets.size();
85 : }
86 :
87 : void
88 37854 : IndexedStyleSheets::AddStyleSheet(rtl::Reference< SfxStyleSheetBase > style)
89 : {
90 37854 : if (!HasStyleSheet(style)) {
91 37852 : 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 37852 : Register(*style, mStyleSheets.size()-1);
94 : }
95 37854 : }
96 :
97 : bool
98 6 : IndexedStyleSheets::RemoveStyleSheet(rtl::Reference< SfxStyleSheetBase > style)
99 : {
100 6 : rtl::OUString styleName = style->GetName();
101 12 : std::vector<unsigned> positions = FindPositionsByName(styleName);
102 6 : bool found = false;
103 6 : unsigned stylePosition = 0;
104 18 : for (std::vector<unsigned>::const_iterator it = positions.begin();
105 12 : it != positions.end(); ++it) {
106 4 : if (mStyleSheets.at(*it) == style) {
107 4 : found = true;
108 4 : stylePosition = *it;
109 4 : break;
110 : }
111 : }
112 :
113 6 : if (found) {
114 4 : mStyleSheets.erase(mStyleSheets.begin() + stylePosition);
115 4 : Reindex();
116 : }
117 12 : return found;
118 : }
119 :
120 : std::vector<unsigned>
121 37872 : IndexedStyleSheets::FindPositionsByName(const rtl::OUString& name) const
122 : {
123 37872 : std::vector<unsigned> r;
124 37872 : std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(name);
125 39422 : for (MapType::const_iterator it = range.first; it != range.second; ++it) {
126 1550 : r.push_back(it->second);
127 : }
128 37872 : return r;
129 : }
130 :
131 : std::vector<unsigned>
132 458538 : IndexedStyleSheets::FindPositionsByNameAndPredicate(const rtl::OUString& name,
133 : StyleSheetPredicate& predicate, SearchBehavior behavior) const
134 : {
135 458538 : std::vector<unsigned> r;
136 458538 : MapType::const_iterator it = mPositionsByName.find(name);
137 516438 : for (/**/; it != mPositionsByName.end(); ++it) {
138 401998 : unsigned pos = it->second;
139 401998 : SfxStyleSheetBase *ssheet = mStyleSheets.at(pos).get();
140 401998 : if (predicate.Check(*ssheet)) {
141 344104 : r.push_back(pos);
142 344104 : if (behavior == RETURN_FIRST) {
143 344098 : break;
144 : }
145 : }
146 : }
147 458538 : return r;
148 : }
149 :
150 :
151 : unsigned
152 0 : IndexedStyleSheets::GetNumberOfStyleSheetsWithPredicate(StyleSheetPredicate& predicate) const
153 : {
154 0 : unsigned r = 0;
155 0 : for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
156 0 : const SfxStyleSheetBase *ssheet = it->get();
157 0 : if (predicate.Check(*ssheet)) {
158 0 : ++r;
159 : }
160 : }
161 0 : return r;
162 : }
163 :
164 : rtl::Reference<SfxStyleSheetBase>
165 0 : IndexedStyleSheets::GetNthStyleSheetThatMatchesPredicate(
166 : unsigned n,
167 : StyleSheetPredicate& predicate,
168 : unsigned startAt)
169 : {
170 0 : rtl::Reference<SfxStyleSheetBase> retval;
171 0 : unsigned matching = 0;
172 0 : for (VectorType::iterator it = mStyleSheets.begin()+startAt; it != mStyleSheets.end(); ++it) {
173 0 : SfxStyleSheetBase *ssheet = it->get();
174 0 : if (predicate.Check(*ssheet)) {
175 0 : if (matching == n) {
176 0 : retval = *it;
177 0 : break;
178 : }
179 0 : ++matching;
180 : }
181 : }
182 0 : return retval;
183 : }
184 :
185 : unsigned
186 2 : IndexedStyleSheets::FindStyleSheetPosition(const SfxStyleSheetBase& style) const
187 : {
188 2 : VectorType::const_iterator it = std::find(mStyleSheets.begin(), mStyleSheets.end(), &style);
189 2 : if (it == mStyleSheets.end()) {
190 0 : throw std::runtime_error("IndexedStyleSheets::FindStylePosition Looked for style not in index");
191 : }
192 2 : return std::distance(mStyleSheets.begin(), it);
193 : }
194 :
195 : void
196 8133 : IndexedStyleSheets::Clear(StyleSheetDisposer& disposer)
197 : {
198 45933 : for (VectorType::iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
199 37800 : disposer.Dispose(*it);
200 : }
201 8133 : mStyleSheets.clear();
202 8133 : mPositionsByName.clear();
203 8133 : }
204 :
205 7709 : IndexedStyleSheets::~IndexedStyleSheets()
206 7709 : {;}
207 :
208 : bool
209 37862 : IndexedStyleSheets::HasStyleSheet(rtl::Reference< SfxStyleSheetBase > style) const
210 : {
211 37862 : rtl::OUString styleName = style->GetName();
212 75724 : std::vector<unsigned> positions = FindPositionsByName(styleName);
213 118182 : for (std::vector<unsigned>::const_iterator it = positions.begin();
214 78788 : it != positions.end(); ++it) {
215 1538 : if (mStyleSheets.at(*it) == style) {
216 6 : return true;
217 : }
218 : }
219 75718 : return false;
220 : }
221 :
222 : rtl::Reference< SfxStyleSheetBase >
223 418108 : IndexedStyleSheets::GetStyleSheetByPosition(unsigned pos)
224 : {
225 418108 : if( pos < mStyleSheets.size() )
226 418108 : return mStyleSheets.at(pos);
227 0 : return NULL;
228 : }
229 :
230 : void
231 0 : IndexedStyleSheets::ApplyToAllStyleSheets(StyleSheetCallback& callback) const
232 : {
233 0 : for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
234 0 : callback.DoIt(**it);
235 : }
236 0 : }
237 :
238 : std::vector<unsigned>
239 0 : IndexedStyleSheets::FindPositionsByPredicate(StyleSheetPredicate& predicate) const
240 : {
241 0 : std::vector<unsigned> r;
242 0 : for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
243 0 : if (predicate.Check(**it)) {
244 0 : r.push_back(std::distance(mStyleSheets.begin(), it));
245 : }
246 : }
247 0 : return r;
248 : }
249 :
250 : const std::vector<unsigned>&
251 88392 : IndexedStyleSheets::GetStyleSheetPositionsByFamily(SfxStyleFamily e) const
252 : {
253 88392 : size_t position = family_to_index(e);
254 88392 : return mStyleSheetPositionsByFamily.at(position);
255 : }
256 :
257 : } /* namespace svl */
258 :
259 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|