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