xref: /AOO41X/main/xmloff/source/text/XMLTextListAutoStylePool.cxx (revision 63bba73cc51e0afb45f8a8d578158724bb5afee8)
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_xmloff.hxx"
26 #include <tools/debug.hxx>
27 #include <svl/cntnrsrt.hxx>
28 #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
29 #include <com/sun/star/container/XNamed.hpp>
30 #include <com/sun/star/container/XIndexReplace.hpp>
31 #include <rtl/ustrbuf.hxx>
32 #include <xmloff/xmlnume.hxx>
33 #include "xmloff/XMLTextListAutoStylePool.hxx"
34 #include <xmloff/xmlexp.hxx>
35 
36 using ::rtl::OUString;
37 using ::rtl::OUStringBuffer;
38 
39 using namespace ::com::sun::star;
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::beans;
42 using namespace ::com::sun::star::container;
43 using namespace ::com::sun::star::style;
44 
45 
XMLTextListAutoStylePoolNameCmp_Impl(const OUString & r1,const OUString & r2)46 int XMLTextListAutoStylePoolNameCmp_Impl( const OUString& r1,
47                                           const OUString& r2 )
48 {
49     return (int)r1.compareTo( r2 );
50 }
51 
52 DECLARE_CONTAINER_SORT_DEL( XMLTextListAutoStylePoolNames_Impl,
53                             OUString )
54 IMPL_CONTAINER_SORT( XMLTextListAutoStylePoolNames_Impl,
55                      OUString,
56                      XMLTextListAutoStylePoolNameCmp_Impl )
57 
58 class XMLTextListAutoStylePoolEntry_Impl
59 {
60     OUString    sName;
61     OUString    sInternalName;
62     Reference < XIndexReplace > xNumRules;
63     sal_uInt32  nPos;
64     sal_Bool    bIsNamed;
65 
66 
67 public:
68 
69     XMLTextListAutoStylePoolEntry_Impl(
70             sal_uInt32 nPos,
71             const Reference < XIndexReplace > & rNumRules,
72             XMLTextListAutoStylePoolNames_Impl& rNames,
73             const OUString& rPrefix,
74             sal_uInt32& rName );
75 
XMLTextListAutoStylePoolEntry_Impl(const Reference<XIndexReplace> & rNumRules)76     XMLTextListAutoStylePoolEntry_Impl(
77             const Reference < XIndexReplace > & rNumRules ) :
78         xNumRules( rNumRules ),
79         nPos( 0 ),
80         bIsNamed( sal_False )
81     {
82         Reference < XNamed > xNamed( xNumRules, UNO_QUERY );
83         if( xNamed.is() )
84         {
85             sInternalName = xNamed->getName();
86             bIsNamed = sal_True;
87         }
88     }
89 
XMLTextListAutoStylePoolEntry_Impl(const OUString & rInternalName)90     XMLTextListAutoStylePoolEntry_Impl(
91             const OUString& rInternalName ) :
92         sInternalName( rInternalName ),
93         nPos( 0 ),
94         bIsNamed( sal_True )
95     {
96     }
97 
GetName() const98     const OUString& GetName() const { return sName; }
GetInternalName() const99     const OUString& GetInternalName() const { return sInternalName; }
GetNumRules() const100     const Reference < XIndexReplace > & GetNumRules() const { return xNumRules; }
GetPos() const101     sal_uInt32 GetPos() const { return nPos; }
IsNamed() const102     sal_Bool IsNamed() const { return bIsNamed; }
103 };
104 
XMLTextListAutoStylePoolEntry_Impl(sal_uInt32 nP,const Reference<XIndexReplace> & rNumRules,XMLTextListAutoStylePoolNames_Impl & rNames,const OUString & rPrefix,sal_uInt32 & rName)105 XMLTextListAutoStylePoolEntry_Impl::XMLTextListAutoStylePoolEntry_Impl(
106         sal_uInt32 nP,
107         const Reference < XIndexReplace > & rNumRules,
108         XMLTextListAutoStylePoolNames_Impl& rNames,
109         const OUString& rPrefix,
110         sal_uInt32& rName ) :
111     xNumRules( rNumRules ),
112     nPos( nP ),
113     bIsNamed( sal_False )
114 {
115     Reference < XNamed > xNamed( xNumRules, UNO_QUERY );
116     if( xNamed.is() )
117     {
118         sInternalName = xNamed->getName();
119         bIsNamed = sal_True;
120     }
121 
122     // create a name that hasn't been used before. The created name has not
123     // to be added to the array, because it will never tried again
124     OUStringBuffer sBuffer( 7 );
125     do
126     {
127         rName++;
128         sBuffer.append( rPrefix );
129         sBuffer.append( (sal_Int32)rName );
130         sName = sBuffer.makeStringAndClear();
131     }
132     while( rNames.Seek_Entry( &sName, 0 ) );
133 }
134 
XMLTextListAutoStylePoolEntryCmp_Impl(const XMLTextListAutoStylePoolEntry_Impl & r1,const XMLTextListAutoStylePoolEntry_Impl & r2)135 int XMLTextListAutoStylePoolEntryCmp_Impl(
136         const XMLTextListAutoStylePoolEntry_Impl& r1,
137         const XMLTextListAutoStylePoolEntry_Impl& r2 )
138 {
139     int nRet;
140     if( r1.IsNamed() )
141     {
142         if( r2.IsNamed() )
143             nRet = (int)r1.GetInternalName().compareTo( r2.GetInternalName());
144         else
145             nRet = -1;
146     }
147     else
148     {
149         if( r2.IsNamed() )
150             nRet = 1;
151         else
152             nRet = (int)(r1.GetNumRules().get() - r2.GetNumRules().get());
153     }
154 
155     return nRet;
156 }
157 
158 typedef XMLTextListAutoStylePoolEntry_Impl *XMLTextListAutoStylePoolEntryPtr;
DECLARE_CONTAINER_SORT(XMLTextListAutoStylePool_Impl,XMLTextListAutoStylePoolEntry_Impl)159 DECLARE_CONTAINER_SORT( XMLTextListAutoStylePool_Impl,
160                         XMLTextListAutoStylePoolEntry_Impl )
161 IMPL_CONTAINER_SORT( XMLTextListAutoStylePool_Impl,
162                      XMLTextListAutoStylePoolEntry_Impl,
163                      XMLTextListAutoStylePoolEntryCmp_Impl )
164 
165 XMLTextListAutoStylePool::XMLTextListAutoStylePool( SvXMLExport& rExp ) :
166     rExport( rExp ),
167     sPrefix( RTL_CONSTASCII_USTRINGPARAM("L") ),
168     pPool( new XMLTextListAutoStylePool_Impl( 5, 5 ) ),
169     pNames( new XMLTextListAutoStylePoolNames_Impl( 5, 5 ) ),
170     nName( 0 )
171 {
172     Reference<ucb::XAnyCompareFactory> xCompareFac( rExp.GetModel(), uno::UNO_QUERY );
173     if( xCompareFac.is() )
174         mxNumRuleCompare = xCompareFac->createAnyCompareByName( OUString( RTL_CONSTASCII_USTRINGPARAM( "NumberingRules" ) ) );
175     sal_uInt16 nExportFlags = rExport.getExportFlags();
176     sal_Bool bStylesOnly = (nExportFlags & EXPORT_STYLES) != 0 && (nExportFlags & EXPORT_CONTENT) == 0;
177     if( bStylesOnly )
178         sPrefix = OUString( RTL_CONSTASCII_USTRINGPARAM("ML") );
179 
180 }
181 
~XMLTextListAutoStylePool()182 XMLTextListAutoStylePool::~XMLTextListAutoStylePool()
183 {
184     // The XMLTextListAutoStylePoolEntry_Impl object in the pool need delete explicitly in dtor.
185     sal_uLong nCount = pPool->Count();
186     while ( nCount-- )
187         delete pPool->Remove(nCount);
188     delete pPool;
189 
190     nCount = pNames->Count();
191     while ( nCount-- )
192         delete pNames->Remove(nCount);
193     delete pNames;
194 }
195 
RegisterName(const OUString & rName)196 void XMLTextListAutoStylePool::RegisterName( const OUString& rName )
197 {
198     OUString *pName = new OUString( rName );
199     if( !pNames->Insert( pName ) )
200         delete pName;
201 }
202 
HasName(const OUString & rName) const203 sal_Bool XMLTextListAutoStylePool::HasName( const OUString& rName ) const
204 {
205     return pNames->Seek_Entry( &rName, 0 );
206 }
207 
Find(XMLTextListAutoStylePoolEntry_Impl * pEntry) const208 sal_uInt32 XMLTextListAutoStylePool::Find( XMLTextListAutoStylePoolEntry_Impl* pEntry ) const
209 {
210     sal_uLong nPos;
211     if( !pEntry->IsNamed() && mxNumRuleCompare.is() )
212     {
213         const sal_uInt32 nCount = pPool->Count();
214 
215         uno::Any aAny1, aAny2;
216         aAny1 <<= pEntry->GetNumRules();
217 
218         for( nPos = 0; nPos < nCount; nPos++ )
219         {
220             aAny2 <<= pPool->GetObject(nPos)->GetNumRules();
221 
222             if( mxNumRuleCompare->compare( aAny1, aAny2 ) == 0 )
223                 return nPos;
224         }
225     }
226     else if( pPool->Seek_Entry( pEntry, &nPos ) )
227     {
228         return nPos;
229     }
230 
231     return (sal_uInt32)-1;
232 }
233 
Add(const Reference<XIndexReplace> & rNumRules)234 OUString XMLTextListAutoStylePool::Add(
235             const Reference < XIndexReplace > & rNumRules )
236 {
237     OUString sName;
238     XMLTextListAutoStylePoolEntry_Impl aTmp( rNumRules );
239 
240     sal_uInt32 nPos = Find( &aTmp );
241     if( nPos != (sal_uInt32)-1 )
242     {
243         sName = pPool->GetObject( nPos )->GetName();
244     }
245     else
246     {
247         XMLTextListAutoStylePoolEntry_Impl *pEntry =
248             new XMLTextListAutoStylePoolEntry_Impl( pPool->Count(),
249                                                rNumRules, *pNames, sPrefix,
250                                                nName );
251         pPool->Insert( pEntry );
252         sName = pEntry->GetName();
253     }
254 
255     return sName;
256 }
257 
Find(const Reference<XIndexReplace> & rNumRules) const258 ::rtl::OUString XMLTextListAutoStylePool::Find(
259             const Reference < XIndexReplace > & rNumRules ) const
260 {
261     OUString sName;
262     XMLTextListAutoStylePoolEntry_Impl aTmp( rNumRules );
263 
264     sal_uInt32 nPos = Find( &aTmp );
265     if( nPos != (sal_uInt32)-1 )
266         sName = pPool->GetObject( nPos )->GetName();
267 
268     return sName;
269 }
270 
Find(const OUString & rInternalName) const271 ::rtl::OUString XMLTextListAutoStylePool::Find(
272             const OUString& rInternalName ) const
273 {
274     OUString sName;
275     XMLTextListAutoStylePoolEntry_Impl aTmp( rInternalName );
276     sal_uInt32 nPos = Find( &aTmp );
277     if( nPos != (sal_uInt32)-1 )
278         sName = pPool->GetObject( nPos )->GetName();
279 
280     return sName;
281 }
282 
exportXML() const283 void XMLTextListAutoStylePool::exportXML() const
284 {
285     sal_uInt32 nCount = pPool->Count();
286     if( !nCount )
287         return;
288 
289     XMLTextListAutoStylePoolEntry_Impl **aExpEntries =
290         new XMLTextListAutoStylePoolEntryPtr[nCount];
291 
292     sal_uInt32 i;
293     for( i=0; i < nCount; i++ )
294     {
295         aExpEntries[i] = 0;
296     }
297     for( i=0; i < nCount; i++ )
298     {
299         XMLTextListAutoStylePoolEntry_Impl *pEntry = pPool->GetObject(i);
300         DBG_ASSERT( pEntry->GetPos() < nCount, "Illegal pos" );
301         aExpEntries[pEntry->GetPos()] = pEntry;
302     }
303 
304     SvxXMLNumRuleExport aNumRuleExp( rExport );
305 
306     for( i=0; i < nCount; i++ )
307     {
308         XMLTextListAutoStylePoolEntry_Impl *pEntry = aExpEntries[i];
309         aNumRuleExp.exportNumberingRule( pEntry->GetName(),
310                                          pEntry->GetNumRules() );
311     }
312     delete [] aExpEntries;
313 }
314 
315 
316