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