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