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