1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 
28 #include "swstylemanager.hxx"
29 #include <hash_map>
30 #include <svl/stylepool.hxx>
31 #include <doc.hxx>
32 #include <charfmt.hxx>
33 #include <docary.hxx>
34 #include <swtypes.hxx>
35 #include <istyleaccess.hxx>
36 
37 typedef ::std::hash_map< const ::rtl::OUString,
38                          StylePool::SfxItemSet_Pointer_t,
39                          ::rtl::OUStringHash,
40                          ::std::equal_to< ::rtl::OUString > > SwStyleNameCache;
41 
42 class SwStyleCache
43 {
44     SwStyleNameCache mMap;
45 public:
SwStyleCache()46     SwStyleCache() {}
addStyleName(StylePool::SfxItemSet_Pointer_t pStyle)47     void addStyleName( StylePool::SfxItemSet_Pointer_t pStyle )
48         { mMap[ StylePool::nameOf(pStyle) ] = pStyle; }
49     void addCompletePool( StylePool& rPool );
getByName(const rtl::OUString & rName)50 	StylePool::SfxItemSet_Pointer_t getByName( const rtl::OUString& rName ) { return mMap[rName]; }
51 };
52 
addCompletePool(StylePool & rPool)53 void SwStyleCache::addCompletePool( StylePool& rPool )
54 {
55     IStylePoolIteratorAccess *pIter = rPool.createIterator();
56     StylePool::SfxItemSet_Pointer_t pStyle = pIter->getNext();
57     while( pStyle.get() )
58     {
59         rtl::OUString aName( StylePool::nameOf(pStyle) );
60         mMap[ aName ] = pStyle;
61         pStyle = pIter->getNext();
62     }
63     delete pIter;
64 }
65 
66 class SwStyleManager : public IStyleAccess
67 {
68 	StylePool aAutoCharPool;
69     StylePool aAutoParaPool;
70     SwStyleCache *mpCharCache;
71     SwStyleCache *mpParaCache;
72 
73 public:
74     // --> OD 2008-03-07 #refactorlists#
75     // accept empty item set for ignorable paragraph items.
SwStyleManager(SfxItemSet * pIgnorableParagraphItems)76     SwStyleManager( SfxItemSet* pIgnorableParagraphItems )
77         : aAutoCharPool(),
78           aAutoParaPool( pIgnorableParagraphItems ),
79           mpCharCache(0),
80           mpParaCache(0)
81     {}
82     // <--
83     virtual ~SwStyleManager();
84 	virtual StylePool::SfxItemSet_Pointer_t getAutomaticStyle( const SfxItemSet& rSet,
85                                                                IStyleAccess::SwAutoStyleFamily eFamily );
86 	virtual StylePool::SfxItemSet_Pointer_t getByName( const rtl::OUString& rName,
87                                                                IStyleAccess::SwAutoStyleFamily eFamily );
88     virtual void getAllStyles( std::vector<StylePool::SfxItemSet_Pointer_t> &rStyles,
89                                                                IStyleAccess::SwAutoStyleFamily eFamily );
90 	virtual StylePool::SfxItemSet_Pointer_t cacheAutomaticStyle( const SfxItemSet& rSet,
91                                                                SwAutoStyleFamily eFamily );
92 	virtual void clearCaches();
93 };
94 
createStyleManager(SfxItemSet * pIgnorableParagraphItems)95 IStyleAccess *createStyleManager( SfxItemSet* pIgnorableParagraphItems )
96 {
97     return new SwStyleManager( pIgnorableParagraphItems );
98 }
99 
~SwStyleManager()100 SwStyleManager::~SwStyleManager()
101 {
102     delete mpCharCache;
103     delete mpParaCache;
104 }
105 
clearCaches()106 void SwStyleManager::clearCaches()
107 {
108     delete mpCharCache;
109     mpCharCache = 0;
110     delete mpParaCache;
111     mpParaCache = 0;
112 }
113 
getAutomaticStyle(const SfxItemSet & rSet,IStyleAccess::SwAutoStyleFamily eFamily)114 StylePool::SfxItemSet_Pointer_t SwStyleManager::getAutomaticStyle( const SfxItemSet& rSet,
115                                                                    IStyleAccess::SwAutoStyleFamily eFamily )
116 {
117     StylePool& rAutoPool = eFamily == IStyleAccess::AUTO_STYLE_CHAR ? aAutoCharPool : aAutoParaPool;
118     return rAutoPool.insertItemSet( rSet );
119 }
120 
cacheAutomaticStyle(const SfxItemSet & rSet,IStyleAccess::SwAutoStyleFamily eFamily)121 StylePool::SfxItemSet_Pointer_t SwStyleManager::cacheAutomaticStyle( const SfxItemSet& rSet,
122                                                                    IStyleAccess::SwAutoStyleFamily eFamily )
123 {
124     StylePool& rAutoPool = eFamily == IStyleAccess::AUTO_STYLE_CHAR ? aAutoCharPool : aAutoParaPool;
125     StylePool::SfxItemSet_Pointer_t pStyle = rAutoPool.insertItemSet( rSet );
126     SwStyleCache* &rpCache = eFamily == IStyleAccess::AUTO_STYLE_CHAR ?
127                              mpCharCache : mpParaCache;
128     if( !rpCache )
129         rpCache = new SwStyleCache();
130     rpCache->addStyleName( pStyle );
131     return pStyle;
132 }
133 
getByName(const rtl::OUString & rName,IStyleAccess::SwAutoStyleFamily eFamily)134 StylePool::SfxItemSet_Pointer_t SwStyleManager::getByName( const rtl::OUString& rName,
135                                                            IStyleAccess::SwAutoStyleFamily eFamily )
136 {
137     StylePool& rAutoPool = eFamily == IStyleAccess::AUTO_STYLE_CHAR ? aAutoCharPool : aAutoParaPool;
138     SwStyleCache* &rpCache = eFamily == IStyleAccess::AUTO_STYLE_CHAR ? mpCharCache : mpParaCache;
139     if( !rpCache )
140         rpCache = new SwStyleCache();
141     StylePool::SfxItemSet_Pointer_t pStyle = rpCache->getByName( rName );
142     if( !pStyle.get() )
143     {
144         // Ok, ok, it's allowed to ask for uncached styles (from UNO) but it should not be done
145         // during loading a document
146         ASSERT( false, "Don't ask for uncached styles" );
147         rpCache->addCompletePool( rAutoPool );
148         pStyle = rpCache->getByName( rName );
149     }
150     return pStyle;
151 }
152 
getAllStyles(std::vector<StylePool::SfxItemSet_Pointer_t> & rStyles,IStyleAccess::SwAutoStyleFamily eFamily)153 void SwStyleManager::getAllStyles( std::vector<StylePool::SfxItemSet_Pointer_t> &rStyles,
154                                    IStyleAccess::SwAutoStyleFamily eFamily )
155 {
156     StylePool& rAutoPool = eFamily == IStyleAccess::AUTO_STYLE_CHAR ? aAutoCharPool : aAutoParaPool;
157     // --> OD 2008-03-07 #refactorlists#
158     // setup <StylePool> iterator, which skips unused styles and ignorable items
159     IStylePoolIteratorAccess *pIter = rAutoPool.createIterator( true, true );
160     // <--
161     StylePool::SfxItemSet_Pointer_t pStyle = pIter->getNext();
162     while( pStyle.get() )
163     {
164         rStyles.push_back( pStyle );
165 
166         pStyle = pIter->getNext();
167     }
168     delete pIter;
169 }
170