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 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "swstylemanager.hxx"
21 : #include <svl/stylepool.hxx>
22 : #include <doc.hxx>
23 : #include <charfmt.hxx>
24 : #include <docary.hxx>
25 : #include <swtypes.hxx>
26 : #include <istyleaccess.hxx>
27 : #include <unordered_map>
28 :
29 : typedef std::unordered_map< OUString,
30 : StylePool::SfxItemSet_Pointer_t,
31 : OUStringHash,
32 : std::equal_to< OUString > > SwStyleNameCache;
33 :
34 403 : class SwStyleCache
35 : {
36 : SwStyleNameCache mMap;
37 : public:
38 403 : SwStyleCache() {}
39 3006 : void addStyleName( StylePool::SfxItemSet_Pointer_t pStyle )
40 3006 : { mMap[ StylePool::nameOf(pStyle) ] = pStyle; }
41 : void addCompletePool( StylePool& rPool );
42 7285 : StylePool::SfxItemSet_Pointer_t getByName( const OUString& rName ) { return mMap[rName]; }
43 : };
44 :
45 0 : void SwStyleCache::addCompletePool( StylePool& rPool )
46 : {
47 0 : IStylePoolIteratorAccess *pIter = rPool.createIterator();
48 0 : StylePool::SfxItemSet_Pointer_t pStyle = pIter->getNext();
49 0 : while( pStyle.get() )
50 : {
51 0 : OUString aName( StylePool::nameOf(pStyle) );
52 0 : mMap[ aName ] = pStyle;
53 0 : pStyle = pIter->getNext();
54 0 : }
55 0 : delete pIter;
56 0 : }
57 :
58 : class SwStyleManager : public IStyleAccess
59 : {
60 : StylePool aAutoCharPool;
61 : StylePool aAutoParaPool;
62 : SwStyleCache *mpCharCache;
63 : SwStyleCache *mpParaCache;
64 :
65 : public:
66 : // accept empty item set for ignorable paragraph items.
67 2958 : explicit SwStyleManager( SfxItemSet* pIgnorableParagraphItems )
68 : : aAutoCharPool(),
69 : aAutoParaPool( pIgnorableParagraphItems ),
70 : mpCharCache(0),
71 2958 : mpParaCache(0)
72 2958 : {}
73 : virtual ~SwStyleManager();
74 : virtual StylePool::SfxItemSet_Pointer_t getAutomaticStyle( const SfxItemSet& rSet,
75 : IStyleAccess::SwAutoStyleFamily eFamily ) SAL_OVERRIDE;
76 : virtual StylePool::SfxItemSet_Pointer_t getByName( const OUString& rName,
77 : IStyleAccess::SwAutoStyleFamily eFamily ) SAL_OVERRIDE;
78 : virtual void getAllStyles( std::vector<StylePool::SfxItemSet_Pointer_t> &rStyles,
79 : IStyleAccess::SwAutoStyleFamily eFamily ) SAL_OVERRIDE;
80 : virtual StylePool::SfxItemSet_Pointer_t cacheAutomaticStyle( const SfxItemSet& rSet,
81 : SwAutoStyleFamily eFamily ) SAL_OVERRIDE;
82 : virtual void clearCaches() SAL_OVERRIDE;
83 : };
84 :
85 2958 : IStyleAccess *createStyleManager( SfxItemSet* pIgnorableParagraphItems )
86 : {
87 2958 : return new SwStyleManager( pIgnorableParagraphItems );
88 : }
89 :
90 8847 : SwStyleManager::~SwStyleManager()
91 : {
92 2949 : delete mpCharCache;
93 2949 : delete mpParaCache;
94 5898 : }
95 :
96 291 : void SwStyleManager::clearCaches()
97 : {
98 291 : delete mpCharCache;
99 291 : mpCharCache = 0;
100 291 : delete mpParaCache;
101 291 : mpParaCache = 0;
102 291 : }
103 :
104 205612 : StylePool::SfxItemSet_Pointer_t SwStyleManager::getAutomaticStyle( const SfxItemSet& rSet,
105 : IStyleAccess::SwAutoStyleFamily eFamily )
106 : {
107 205612 : StylePool& rAutoPool = eFamily == IStyleAccess::AUTO_STYLE_CHAR ? aAutoCharPool : aAutoParaPool;
108 205612 : return rAutoPool.insertItemSet( rSet );
109 : }
110 :
111 3006 : StylePool::SfxItemSet_Pointer_t SwStyleManager::cacheAutomaticStyle( const SfxItemSet& rSet,
112 : IStyleAccess::SwAutoStyleFamily eFamily )
113 : {
114 3006 : StylePool& rAutoPool = eFamily == IStyleAccess::AUTO_STYLE_CHAR ? aAutoCharPool : aAutoParaPool;
115 3006 : StylePool::SfxItemSet_Pointer_t pStyle = rAutoPool.insertItemSet( rSet );
116 : SwStyleCache* &rpCache = eFamily == IStyleAccess::AUTO_STYLE_CHAR ?
117 3006 : mpCharCache : mpParaCache;
118 3006 : if( !rpCache )
119 403 : rpCache = new SwStyleCache();
120 3006 : rpCache->addStyleName( pStyle );
121 3006 : return pStyle;
122 : }
123 :
124 7285 : StylePool::SfxItemSet_Pointer_t SwStyleManager::getByName( const OUString& rName,
125 : IStyleAccess::SwAutoStyleFamily eFamily )
126 : {
127 7285 : StylePool& rAutoPool = eFamily == IStyleAccess::AUTO_STYLE_CHAR ? aAutoCharPool : aAutoParaPool;
128 7285 : SwStyleCache* &rpCache = eFamily == IStyleAccess::AUTO_STYLE_CHAR ? mpCharCache : mpParaCache;
129 7285 : if( !rpCache )
130 0 : rpCache = new SwStyleCache();
131 7285 : StylePool::SfxItemSet_Pointer_t pStyle = rpCache->getByName( rName );
132 7285 : if( !pStyle.get() )
133 : {
134 : // Ok, ok, it's allowed to ask for uncached styles (from UNO) but it should not be done
135 : // during loading a document
136 : OSL_FAIL( "Don't ask for uncached styles" );
137 0 : rpCache->addCompletePool( rAutoPool );
138 0 : pStyle = rpCache->getByName( rName );
139 : }
140 7285 : return pStyle;
141 : }
142 :
143 152 : void SwStyleManager::getAllStyles( std::vector<StylePool::SfxItemSet_Pointer_t> &rStyles,
144 : IStyleAccess::SwAutoStyleFamily eFamily )
145 : {
146 152 : StylePool& rAutoPool = eFamily == IStyleAccess::AUTO_STYLE_CHAR ? aAutoCharPool : aAutoParaPool;
147 : // setup <StylePool> iterator, which skips unused styles and ignorable items
148 152 : IStylePoolIteratorAccess *pIter = rAutoPool.createIterator( true, true );
149 152 : StylePool::SfxItemSet_Pointer_t pStyle = pIter->getNext();
150 578 : while( pStyle.get() )
151 : {
152 274 : rStyles.push_back( pStyle );
153 :
154 274 : pStyle = pIter->getNext();
155 : }
156 152 : delete pIter;
157 329 : }
158 :
159 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|