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 : #ifndef INCLUDED_SVL_INDEXEDSTYLESHEETS_HXX
11 : #define INCLUDED_SVL_INDEXEDSTYLESHEETS_HXX
12 :
13 : #include <sal/types.h>
14 :
15 : #include <rsc/rscsfx.hxx>
16 : #include <rtl/ustring.hxx>
17 : #include <rtl/ref.hxx>
18 :
19 : #include <svl/svldllapi.h>
20 :
21 : #include <boost/unordered_map.hpp>
22 : #include <vector>
23 :
24 : class SfxStyleSheetBase;
25 :
26 : namespace svl {
27 :
28 : /** Function object to check whether a style sheet a fulfills specific criteria.
29 : * Derive from this class and override the Check() method.
30 : */
31 458534 : struct StyleSheetPredicate {
32 : virtual bool Check(const SfxStyleSheetBase& styleSheet) = 0;
33 458536 : virtual ~StyleSheetPredicate() {;}
34 : };
35 :
36 : /** Function object for cleanup-Strategy for IndexedSfxStyleSheets::Clear().
37 : * Derive from it and do what is necessary to dispose of a style sheet in Dispose().
38 : */
39 8133 : struct StyleSheetDisposer {
40 : virtual void Dispose(rtl::Reference<SfxStyleSheetBase> styleSheet) = 0;
41 8133 : virtual ~StyleSheetDisposer() {;}
42 : };
43 :
44 : /** Function object to apply a method on all style sheets.
45 : * Derive from it and do whatever you want to with the style sheet in the DoIt() method.
46 : */
47 0 : struct StyleSheetCallback {
48 : virtual void DoIt(const SfxStyleSheetBase& styleSheet) = 0;
49 0 : virtual ~StyleSheetCallback() {;}
50 : };
51 :
52 : /** This class holds SfxStyleSheets and allows for access via an id and a name.
53 : *
54 : * @warning
55 : * The identification of style sheets happens by their name. If the name of a sheet changes,
56 : * it will not be found again! Please call Reindex() after changing a style sheet's name.
57 : *
58 : * @internal
59 : * This class was implemented to mitigate solve #fdo 30770.
60 : * The issue describes an Excel file which takes several hours to open.
61 : * An analysis revealed that the time is spent searching for style sheets with linear scans in an array.
62 : * This class implements access to the style sheets via their name in (usually) constant time.
63 : *
64 : * The return type for most methods is a vector of unsigned integers which denote the position
65 : * of the style sheets in the vector, and not of pointers to style sheets.
66 : * You will need a non-const StyleSheetPool to obtain the actual style sheets.
67 : *
68 : *
69 : * Index-based access is required in several code portions. Hence we have to store the style sheets
70 : * in a vector as well as in a map.
71 : */
72 : class SVL_DLLPUBLIC IndexedStyleSheets SAL_FINAL
73 : {
74 : public:
75 : IndexedStyleSheets();
76 :
77 : /** Destructor.
78 : *
79 : * @internal
80 : * Is explicit because it has to know how to dispose of SfxStyleSheetBase objects.
81 : */
82 : ~IndexedStyleSheets();
83 :
84 : /** Adds a style sheet.
85 : *
86 : * If the style sheet is already contained, this call has no effect.
87 : */
88 : void
89 : AddStyleSheet(rtl::Reference< SfxStyleSheetBase > style);
90 :
91 : /** Removes a style sheet. */
92 : bool
93 : RemoveStyleSheet(rtl::Reference< SfxStyleSheetBase > style);
94 :
95 : /** Check whether a specified style sheet is stored. */
96 : bool
97 : HasStyleSheet(rtl::Reference< SfxStyleSheetBase > style) const;
98 :
99 : /** Obtain the number of style sheets which are held */
100 : unsigned
101 : GetNumberOfStyleSheets() const;
102 :
103 : /** Obtain the number of style sheets for which a certain condition holds */
104 : unsigned
105 : GetNumberOfStyleSheetsWithPredicate(StyleSheetPredicate& predicate) const;
106 :
107 : /** Return the stylesheet by its position.
108 : * You can obtain the position by, e.g., FindStyleSheetPosition()
109 : * @internal
110 : * Method is not const because the returned style sheet is not const
111 : */
112 : rtl::Reference< SfxStyleSheetBase >
113 : GetStyleSheetByPosition(unsigned pos);
114 :
115 : /** Find the position of a provided style.
116 : *
117 : * @throws std::runtime_error if the style has not been found.
118 : */
119 : unsigned
120 : FindStyleSheetPosition(const SfxStyleSheetBase& style) const;
121 :
122 : /** Obtain the positions of all styles which have a given name
123 : */
124 : std::vector<unsigned>
125 : FindPositionsByName(const rtl::OUString& name) const;
126 :
127 : enum SearchBehavior { RETURN_ALL, RETURN_FIRST };
128 : /** Obtain the positions of all styles which have a certain name and fulfill a certain condition.
129 : *
130 : * This method is fast because it can use the name-based index
131 : */
132 : std::vector<unsigned>
133 : FindPositionsByNameAndPredicate(const rtl::OUString& name, StyleSheetPredicate& predicate,
134 : SearchBehavior behavior = RETURN_ALL) const;
135 :
136 : /** Obtain the positions of all styles which fulfill a certain condition.
137 : *
138 : * This method is slow because it cannot use the name-based index
139 : */
140 : std::vector<unsigned>
141 : FindPositionsByPredicate(StyleSheetPredicate& predicate) const;
142 :
143 : /** Execute a callback on all style sheets */
144 : void
145 : ApplyToAllStyleSheets(StyleSheetCallback& callback) const;
146 :
147 : /** Clear the contents of the index.
148 : * The StyleSheetDisposer::Dispose() method is called on each style sheet, e.g., if you want to broadcast
149 : * changes.
150 : */
151 : void
152 : Clear(StyleSheetDisposer& cleanup);
153 :
154 : void
155 : Reindex();
156 :
157 : /** Warning: counting for n starts at 0, i.e., the 0th style sheet is the first that is found. */
158 : rtl::Reference<SfxStyleSheetBase>
159 : GetNthStyleSheetThatMatchesPredicate(unsigned n, StyleSheetPredicate& predicate,
160 : unsigned startAt = 0);
161 :
162 : /** Get the positions of the style sheets which belong to a certain family.
163 : */
164 : const std::vector<unsigned>&
165 : GetStyleSheetPositionsByFamily(SfxStyleFamily) const;
166 :
167 : private:
168 : /** Register the position of a styleName in the index */
169 : void
170 : Register(const SfxStyleSheetBase& style, unsigned pos);
171 :
172 : typedef std::vector<rtl::Reference<SfxStyleSheetBase> > VectorType;
173 : /** Vector with the stylesheets to allow for index-based access.
174 : */
175 : VectorType mStyleSheets;
176 :
177 : /** The map type that is used to store the mapping from strings to ids in mStyleSheets
178 : *
179 : * @internal
180 : * Must be an unordered map. A regular map is too slow for some files. */
181 : typedef boost::unordered_multimap<rtl::OUString, unsigned, rtl::OUStringHash> MapType;
182 :
183 : /** A map which stores the positions of style sheets by their name */
184 : MapType mPositionsByName;
185 :
186 : std::vector<std::vector<unsigned> > mStyleSheetPositionsByFamily;
187 : };
188 :
189 : } /* namespace svl */
190 :
191 : #endif // INCLUDED_SVL_INDEXEDSTYLESHEETS_HXX
192 :
193 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|