xref: /trunk/main/xmloff/source/style/impastp4.cxx (revision 870c3792)
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 <xmloff/xmlaustp.hxx>
28 #include <xmloff/xmltoken.hxx>
29 #include <xmloff/nmspmap.hxx>
30 #include "xmloff/xmlnmspe.hxx"
31 #include <xmloff/attrlist.hxx>
32 #include "impastpl.hxx"
33 #include <xmloff/xmlexppr.hxx>
34 #include <xmloff/xmlexp.hxx>
35 #include <xmloff/families.hxx>
36 #ifndef _XMLOFF_PAGEMASTERSTYLEMAP_HXX
37 #include <xmloff/PageMasterStyleMap.hxx>
38 #endif
39 
40 using namespace ::std;
41 using ::rtl::OUString;
42 using ::rtl::OUStringBuffer;
43 
44 using namespace ::com::sun::star;
45 using namespace ::xmloff::token;
46 
47 //#############################################################################
48 //
49 // Class SvXMLAutoStylePool_Impl
50 //
51 
52 ///////////////////////////////////////////////////////////////////////////////
53 //
54 // ctor/dtor class SvXMLAutoStylePool_Impl
55 //
56 
SvXMLAutoStylePoolP_Impl(SvXMLExport & rExp)57 SvXMLAutoStylePoolP_Impl::SvXMLAutoStylePoolP_Impl( SvXMLExport& rExp)
58     :	rExport( rExp ),
59         maFamilyList( 5, 5 )
60 {
61 }
62 
~SvXMLAutoStylePoolP_Impl()63 SvXMLAutoStylePoolP_Impl::~SvXMLAutoStylePoolP_Impl()
64 {
65 	for (;;) {
66         XMLFamilyData_Impl* pData = maFamilyList.Remove( sal_uLong(0) );
67         if (pData == NULL) {
68             break;
69         }
70 		delete pData;
71     }
72 }
73 
74 ///////////////////////////////////////////////////////////////////////////////
75 //
76 // Adds stylefamily-informations to sorted list
77 //
78 
AddFamily(sal_Int32 nFamily,const OUString & rStrName,const UniReference<SvXMLExportPropertyMapper> & rMapper,const OUString & rStrPrefix,sal_Bool bAsFamily)79 void SvXMLAutoStylePoolP_Impl::AddFamily(
80 		sal_Int32 nFamily,
81 		const OUString& rStrName,
82 		const UniReference < SvXMLExportPropertyMapper > & rMapper,
83 	   	const OUString& rStrPrefix,
84 		sal_Bool bAsFamily )
85 {
86 	// store family in a list if not already stored
87 	sal_uLong nPos;
88 
89 	sal_uInt16 nExportFlags = GetExport().getExportFlags();
90 	sal_Bool bStylesOnly = (nExportFlags & EXPORT_STYLES) != 0 && (nExportFlags & EXPORT_CONTENT) == 0;
91 
92 	OUString aPrefix( rStrPrefix );
93 	if( bStylesOnly )
94 	{
95 		aPrefix = OUString( 'M' );
96 		aPrefix += rStrPrefix;
97 	}
98 
99 	XMLFamilyData_Impl *pFamily = new XMLFamilyData_Impl( nFamily, rStrName, rMapper, aPrefix, bAsFamily );
100 	if( !maFamilyList.Seek_Entry( pFamily, &nPos ) )
101 		maFamilyList.Insert( pFamily );
102 	else
103 		delete pFamily;
104 }
105 
106 ///////////////////////////////////////////////////////////////////////////////
107 //
108 // Adds a name to list
109 //
110 
RegisterName(sal_Int32 nFamily,const OUString & rName)111 void SvXMLAutoStylePoolP_Impl::RegisterName( sal_Int32 nFamily, const OUString& rName )
112 {
113 	SvXMLAutoStylePoolNamesP_Impl *pNames = 0;
114 
115 	sal_uLong nPos;
116 	XMLFamilyData_Impl aTmp( nFamily );
117 	if( maFamilyList.Seek_Entry( &aTmp, &nPos ) )
118 		pNames = maFamilyList.GetObject( nPos )->mpNameList;
119 
120 	DBG_ASSERT( pNames,
121 				"SvXMLAutoStylePool_Impl::RegisterName: unknown family" );
122 	if( pNames )
123 	{
124 		OUString *pName = new OUString( rName );
125 		if( !pNames->Insert( pName ) )
126 			delete pName;
127 	}
128 }
129 
130 ///////////////////////////////////////////////////////////////////////////////
131 //
132 // Retrieve the list of registered names
133 //
134 
GetRegisteredNames(uno::Sequence<sal_Int32> & rFamilies,uno::Sequence<OUString> & rNames)135 void SvXMLAutoStylePoolP_Impl::GetRegisteredNames(
136     uno::Sequence<sal_Int32>& rFamilies,
137     uno::Sequence<OUString>& rNames )
138 {
139     // collect registered names + families
140     vector<sal_Int32> aFamilies;
141     vector<OUString> aNames;
142 
143     // iterate over families
144     sal_uInt32 nCount = maFamilyList.Count();
145     for( sal_uInt32 i = 0; i < nCount; i++ )
146     {
147         XMLFamilyData_Impl* pFamily = maFamilyList.GetObject( i );
148 
149         // iterate over names
150         SvXMLAutoStylePoolNamesP_Impl* pNames = pFamily->mpNameList;
151         sal_uInt32 nNames = ( pNames != NULL ) ? pNames->Count() : 0;
152         for( sal_uInt32 j = 0; j < nNames; j++ )
153         {
154             aFamilies.push_back( pFamily->mnFamily );
155             aNames.push_back( *pNames->GetObject( j ) );
156         }
157     }
158 
159     // copy the families + names into the sequence types
160     DBG_ASSERT( aFamilies.size() == aNames.size(), "families != names" );
161 
162     rFamilies.realloc( aFamilies.size() );
163     std::copy( aFamilies.begin(), aFamilies.end(), rFamilies.getArray() );
164 
165     rNames.realloc( aNames.size() );
166     std::copy( aNames.begin(), aNames.end(), rNames.getArray() );
167 }
168 
169 ///////////////////////////////////////////////////////////////////////////////
170 //
171 // Adds a array of XMLPropertyState ( vector< XMLPropertyState > ) to list
172 // if not added, yet.
173 //
174 
175 /*OUString SvXMLAutoStylePoolP_Impl::Add( sal_Int32 nFamily,
176 							 		    const OUString& rParent,
177 									    const vector< XMLPropertyState >& rProperties,
178 									    sal_Bool bCache )*/
Add(OUString & rName,sal_Int32 nFamily,const OUString & rParent,const::std::vector<XMLPropertyState> & rProperties,sal_Bool bCache,bool bDontSeek)179 sal_Bool SvXMLAutoStylePoolP_Impl::Add(OUString& rName, sal_Int32 nFamily,
180 				const OUString& rParent,
181 				const ::std::vector< XMLPropertyState >& rProperties,
182 				sal_Bool bCache,
183                 bool bDontSeek )
184 {
185 	sal_Bool bRet(sal_False);
186 	sal_uLong nPos;
187 
188 	XMLFamilyData_Impl *pFamily = 0;
189 	XMLFamilyData_Impl aTemporary( nFamily );
190 	if( maFamilyList.Seek_Entry( &aTemporary, &nPos ) )
191 	{
192 		pFamily = maFamilyList.GetObject( nPos );
193 	}
194 
195 	DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Add: unknown family" );
196 	if( pFamily )
197 	{
198 		SvXMLAutoStylePoolParentP_Impl aTmp( rParent );
199 		SvXMLAutoStylePoolParentP_Impl *pParent = 0;
200 
201 		SvXMLAutoStylePoolParentsP_Impl *pParents = pFamily->mpParentList;
202 		if( pParents->Seek_Entry( &aTmp, &nPos ) )
203 		{
204 			pParent = pParents->GetObject( nPos );
205 		}
206 		else
207 		{
208 			pParent = new SvXMLAutoStylePoolParentP_Impl( rParent );
209 			pParents->Insert( pParent );
210 		}
211 
212 		if( pParent->Add( pFamily, rProperties, rName, bDontSeek ) )
213 		{
214 			pFamily->mnCount++;
215 			bRet = sal_True;
216 		}
217 
218 		if( bCache )
219 		{
220 			if( !pFamily->pCache )
221 				pFamily->pCache = new SvXMLAutoStylePoolCache_Impl( 256, 256 );
222 			if( pFamily->pCache->Count() < MAX_CACHE_SIZE )
223 				pFamily->pCache->Insert( new OUString( rName ),
224 										 pFamily->pCache->Count() );
225 		}
226 	}
227 
228 	return bRet;
229 }
230 
AddNamed(const OUString & rName,sal_Int32 nFamily,const OUString & rParent,const::std::vector<XMLPropertyState> & rProperties)231 sal_Bool SvXMLAutoStylePoolP_Impl::AddNamed(const OUString& rName, sal_Int32 nFamily,
232                 const OUString& rParent, const ::std::vector< XMLPropertyState >& rProperties )
233 {
234     // get family and parent the same way as in Add()
235     sal_Bool bRet(sal_False);
236     sal_uLong nPos;
237 
238     XMLFamilyData_Impl *pFamily = 0;
239     XMLFamilyData_Impl aTemporary( nFamily );
240     if( maFamilyList.Seek_Entry( &aTemporary, &nPos ) )
241     {
242         pFamily = maFamilyList.GetObject( nPos );
243     }
244 
245     DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Add: unknown family" );
246     if( pFamily )
247     {
248         SvXMLAutoStylePoolParentP_Impl aTmp( rParent );
249         SvXMLAutoStylePoolParentP_Impl *pParent = 0;
250 
251         SvXMLAutoStylePoolParentsP_Impl *pParents = pFamily->mpParentList;
252         if( pParents->Seek_Entry( &aTmp, &nPos ) )
253         {
254             pParent = pParents->GetObject( nPos );
255         }
256         else
257         {
258             pParent = new SvXMLAutoStylePoolParentP_Impl( rParent );
259             pParents->Insert( pParent );
260         }
261 
262         if( pParent->AddNamed( pFamily, rProperties, rName ) )
263         {
264             pFamily->mnCount++;
265             bRet = sal_True;
266         }
267     }
268 
269     return bRet;
270 }
271 
AddToCache(sal_Int32 nFamily,const OUString & rParent)272 OUString SvXMLAutoStylePoolP_Impl::AddToCache( sal_Int32 nFamily,
273 							 		    const OUString& rParent )
274 {
275 	sal_uLong nPos;
276 
277 	XMLFamilyData_Impl *pFamily = 0;
278 	XMLFamilyData_Impl aTmp( nFamily );
279 	if( maFamilyList.Seek_Entry( &aTmp, &nPos ) )
280 	{
281 		pFamily = maFamilyList.GetObject( nPos );
282 	}
283 
284 	DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Add: unknown family" );
285 	if( pFamily )
286 	{
287 		if( !pFamily->pCache )
288 			pFamily->pCache = new SvXMLAutoStylePoolCache_Impl( 256, 256 );
289 		if( pFamily->pCache->Count() < MAX_CACHE_SIZE )
290 			pFamily->pCache->Insert( new OUString( rParent ),
291 									 pFamily->pCache->Count() );
292 	}
293 
294 	return rParent;
295 }
296 ///////////////////////////////////////////////////////////////////////////////
297 //
298 // Search for a array of XMLPropertyState ( vector< XMLPropertyState > ) in list
299 //
300 
Find(sal_Int32 nFamily,const OUString & rParent,const vector<XMLPropertyState> & rProperties) const301 OUString SvXMLAutoStylePoolP_Impl::Find( sal_Int32 nFamily,
302 										 const OUString& rParent,
303 										 const vector< XMLPropertyState >& rProperties ) const
304 {
305 	OUString sName;
306 
307 	sal_uLong nPos;
308 	XMLFamilyData_Impl aTemporary( nFamily );
309 	XMLFamilyData_Impl *pFamily = 0;
310 	if( maFamilyList.Seek_Entry( &aTemporary, &nPos ) )
311 	{
312 		pFamily = maFamilyList.GetObject( nPos );
313 	}
314 
315 	DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Find: unknown family" );
316 
317 	if( pFamily )
318 	{
319 		SvXMLAutoStylePoolParentP_Impl aTmp( rParent );
320 
321 		const SvXMLAutoStylePoolParentsP_Impl* pParents =
322 			pFamily->mpParentList;
323 		if( pParents->Seek_Entry( &aTmp, &nPos ) )
324 			sName = pParents->GetObject( nPos )->Find( pFamily, rProperties );
325 	}
326 
327 	return sName;
328 }
329 
FindAndRemoveCached(sal_Int32 nFamily) const330 OUString SvXMLAutoStylePoolP_Impl::FindAndRemoveCached( sal_Int32 nFamily ) const
331 {
332 	OUString sName;
333 
334 	sal_uLong nPos;
335 	XMLFamilyData_Impl aTmp( nFamily );
336 	XMLFamilyData_Impl *pFamily = 0;
337 	if( maFamilyList.Seek_Entry( &aTmp, &nPos ) )
338 	{
339 		pFamily = maFamilyList.GetObject( nPos );
340 	}
341 
342 	DBG_ASSERT( pFamily, "SvXMLAutoStylePool_Impl::Find: unknown family" );
343 
344 	if( pFamily )
345 	{
346 		DBG_ASSERT( pFamily->pCache, "family doesn't have a cache" );
347 
348 		// The cache may be empty already. This happens if it was filled
349 		// completely.
350 		if( pFamily->pCache && pFamily->pCache->Count() )
351 		{
352 			OUString *pName = pFamily->pCache->Remove( 0UL );
353 			sName = *pName;
354 			delete pName;
355 		}
356 	}
357 
358 	return sName;
359 }
360 
361 ///////////////////////////////////////////////////////////////////////////////
362 //
363 // export
364 //
365 
exportXML(sal_Int32 nFamily,const uno::Reference<::com::sun::star::xml::sax::XDocumentHandler> &,const SvXMLUnitConverter &,const SvXMLNamespaceMap &,const SvXMLAutoStylePoolP * pAntiImpl) const366 void SvXMLAutoStylePoolP_Impl::exportXML(
367 	   	sal_Int32 nFamily,
368 		const uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > &,
369 		const SvXMLUnitConverter&,
370 		const SvXMLNamespaceMap&,
371 		const SvXMLAutoStylePoolP *pAntiImpl) const
372 {
373 	sal_uInt32 nCount = 0;
374 
375 	// Get list of parents for current family (nFamily)
376 	sal_uLong nPos;
377 	XMLFamilyData_Impl aTmp( nFamily );
378 	XMLFamilyData_Impl *pFamily = 0;
379 	if( maFamilyList.Seek_Entry( &aTmp, &nPos ) )
380 	{
381 		pFamily = maFamilyList.GetObject( nPos );
382 		nCount         = pFamily->mnCount;
383 	}
384 
385 	DBG_ASSERT( pFamily,
386 				"SvXMLAutoStylePool_Impl::exportXML: unknown family" );
387 	if( pFamily && nCount > 0 )
388 	{
389 		/////////////////////////////////////////////////////////////////////////////////////
390 		// create, initialize and fill helper-structure (SvXMLAutoStylePoolProperties_Impl)
391 		// which contains a parent-name and a SvXMLAutoStylePoolProperties_Impl
392 		//
393 		const SvXMLAutoStylePoolParentsP_Impl *pParents =
394 			pFamily->mpParentList;
395 
396 		SvXMLAutoStylePoolPExport_Impl* aExpStyles =
397 			new SvXMLAutoStylePoolPExport_Impl[nCount];
398 
399 		sal_uInt32 i;
400 		for( i=0; i < nCount; i++ )
401 		{
402 			aExpStyles[i].mpParent = 0;
403 			aExpStyles[i].mpProperties = 0;
404 		}
405 
406 		sal_uInt32 nParents = pParents->Count();
407 		for( i=0; i < nParents; i++ )
408 		{
409 			const SvXMLAutoStylePoolParentP_Impl* pParent =
410 				pParents->GetObject( i );
411 			sal_uInt32 nProperties = pParent->GetPropertiesList().Count();
412 			for( sal_uInt32 j=0; j < nProperties; j++ )
413 			{
414 				const SvXMLAutoStylePoolPropertiesP_Impl *pProperties =
415 					pParent->GetPropertiesList().GetObject( j );
416 				nPos = pProperties->GetPos();
417 				DBG_ASSERT( nPos < nCount,
418 						"SvXMLAutoStylePool_Impl::exportXML: wrong position" );
419 				if( nPos < nCount )
420 				{
421 					DBG_ASSERT( !aExpStyles[nPos].mpProperties,
422 						"SvXMLAutoStylePool_Impl::exportXML: double position" );
423 					aExpStyles[nPos].mpProperties = pProperties;
424 					aExpStyles[nPos].mpParent = &pParent->GetParent();
425 				}
426 			}
427 		}
428 
429 		/////////////////////////////////////////////////////////////////////////////////////
430 		//
431 		// create string to export for each XML-style. That means for each property-list
432 		//
433 		OUString aStrFamilyName = pFamily->maStrFamilyName;
434 
435 		for( i=0; i<nCount; i++ )
436 		{
437 			DBG_ASSERT( aExpStyles[i].mpProperties,
438 						"SvXMLAutoStylePool_Impl::exportXML: empty position" );
439 
440 			if( aExpStyles[i].mpProperties )
441 			{
442                 GetExport().AddAttribute(
443                     XML_NAMESPACE_STYLE, XML_NAME,
444                     aExpStyles[i].mpProperties->GetName() );
445 
446 				if( pFamily->bAsFamily )
447 				{
448                     GetExport().AddAttribute(
449                         XML_NAMESPACE_STYLE, XML_FAMILY, aStrFamilyName );
450 				}
451 
452 				if( aExpStyles[i].mpParent->getLength() )
453 				{
454                     GetExport().AddAttribute(
455                         XML_NAMESPACE_STYLE, XML_PARENT_STYLE_NAME,
456                     	GetExport().EncodeStyleName(
457 							*aExpStyles[i].mpParent ) );
458 				}
459 
460                 OUString sName;
461 				if( pFamily->bAsFamily )
462 					sName = GetXMLToken(XML_STYLE);
463 				else
464 					sName = pFamily->maStrFamilyName;
465 
466 				pAntiImpl->exportStyleAttributes(
467                     GetExport().GetAttrList(),
468                     nFamily,
469                     aExpStyles[i].mpProperties->GetProperties(),
470                     *pFamily->mxMapper.get()
471 						, GetExport().GetMM100UnitConverter(),
472                         GetExport().GetNamespaceMap()
473                     );
474 
475                 SvXMLElementExport aElem( GetExport(),
476                                           XML_NAMESPACE_STYLE, sName,
477                                           sal_True, sal_True );
478 
479 				sal_Int32 nStart(-1);
480 				sal_Int32 nEnd(-1);
481 				if (nFamily == XML_STYLE_FAMILY_PAGE_MASTER)
482 				{
483 					nStart = 0;
484 					sal_Int32 nIndex = 0;
485 					UniReference< XMLPropertySetMapper > aPropMapper =
486 						pFamily->mxMapper->getPropertySetMapper();
487 					sal_Int16 nContextID;
488 					while(nIndex < aPropMapper->GetEntryCount() && nEnd == -1)
489 					{
490 						nContextID = aPropMapper->GetEntryContextId( nIndex );
491 						if (nContextID && ((nContextID & CTF_PM_FLAGMASK) != XML_PM_CTF_START))
492 							nEnd = nIndex;
493 						nIndex++;
494 					}
495 					if (nEnd == -1)
496 						nEnd = nIndex;
497 				}
498 
499 				pFamily->mxMapper->exportXML(
500                     GetExport(),
501                     aExpStyles[i].mpProperties->GetProperties(),
502                     nStart, nEnd, XML_EXPORT_FLAG_IGN_WS );
503 
504 				pAntiImpl->exportStyleContent(
505                     GetExport().GetDocHandler(),
506                     nFamily,
507                     aExpStyles[i].mpProperties->GetProperties(),
508                     *pFamily->mxMapper.get(),
509                     GetExport().GetMM100UnitConverter(),
510                     GetExport().GetNamespaceMap()
511                     );
512 			}
513 		}
514 
515 		delete[] aExpStyles;
516 	}
517 }
518 
ClearEntries()519 void SvXMLAutoStylePoolP_Impl::ClearEntries()
520 {
521 	for(sal_uInt32 a = 0L; a < maFamilyList.Count(); a++)
522 		maFamilyList[a]->ClearEntries();
523 }
524