Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <algorithm>
21 :
22 : #include <rtl/ustrbuf.hxx>
23 : #include <tools/debug.hxx>
24 : #include <xmloff/PageMasterStyleMap.hxx>
25 : #include <xmloff/attrlist.hxx>
26 : #include <xmloff/families.hxx>
27 : #include <xmloff/nmspmap.hxx>
28 : #include <xmloff/xmlaustp.hxx>
29 : #include <xmloff/xmlexp.hxx>
30 : #include <xmloff/xmlexppr.hxx>
31 : #include <xmloff/xmlnmspe.hxx>
32 : #include <xmloff/xmlprmap.hxx>
33 : #include <xmloff/xmltoken.hxx>
34 :
35 : #include "impastpl.hxx"
36 :
37 : using namespace ::std;
38 :
39 : using namespace ::com::sun::star;
40 : using namespace ::xmloff::token;
41 :
42 : // Class XMLAutoStyleFamily
43 : // ctor/dtor class XMLAutoStyleFamily
44 :
45 0 : XMLAutoStyleFamily::XMLAutoStyleFamily(
46 : sal_Int32 nFamily,
47 : const OUString& rStrName,
48 : const UniReference < SvXMLExportPropertyMapper > &rMapper,
49 : const OUString& rStrPrefix,
50 : bool bAsFamily ) :
51 : mnFamily( nFamily ), maStrFamilyName( rStrName), mxMapper( rMapper ),
52 0 : mnCount( 0 ), mnName( 0 ), maStrPrefix( rStrPrefix ), mbAsFamily( bAsFamily )
53 0 : {}
54 :
55 0 : XMLAutoStyleFamily::XMLAutoStyleFamily( sal_Int32 nFamily ) :
56 0 : mnFamily(nFamily), mnCount(0), mnName(0), mbAsFamily(false) {}
57 :
58 0 : XMLAutoStyleFamily::~XMLAutoStyleFamily() {}
59 :
60 0 : void XMLAutoStyleFamily::ClearEntries()
61 : {
62 0 : maParentSet.clear();
63 0 : }
64 :
65 : static OUString
66 : data2string(void *data,
67 : const typelib_TypeDescriptionReference *type);
68 :
69 : static OUString
70 0 : struct2string(void *data,
71 : const typelib_TypeDescription *type)
72 : {
73 : assert(type->eTypeClass == typelib_TypeClass_STRUCT);
74 :
75 0 : OUStringBuffer result;
76 :
77 0 : result.append("{");
78 :
79 : const typelib_CompoundTypeDescription *compoundType =
80 0 : &((const typelib_StructTypeDescription*) type)->aBase;
81 :
82 0 : for (int i = 0; i < compoundType->nMembers; i++)
83 : {
84 0 : if (i > 0)
85 0 : result.append(":");
86 0 : result.append(compoundType->ppMemberNames[i]);
87 0 : result.append("=");
88 0 : result.append(data2string(((char *)data)+compoundType->pMemberOffsets[i],
89 0 : compoundType->ppTypeRefs[i]));
90 : }
91 :
92 0 : result.append("}");
93 :
94 0 : return result.makeStringAndClear();
95 : }
96 :
97 : static OUString
98 0 : data2string(void *data,
99 : const typelib_TypeDescriptionReference *type)
100 : {
101 0 : OUStringBuffer result;
102 :
103 0 : switch (type->eTypeClass)
104 : {
105 : case typelib_TypeClass_VOID:
106 0 : break;
107 : case typelib_TypeClass_BOOLEAN:
108 0 : result.append((*reinterpret_cast<const sal_Bool*>(data) == sal_False ) ? OUString("false") : OUString("true"));
109 0 : break;
110 : case typelib_TypeClass_BYTE:
111 0 : result.append(OUString::number((*reinterpret_cast<const sal_Int8*>(data))));
112 0 : break;
113 : case typelib_TypeClass_SHORT:
114 0 : result.append(OUString::number((*reinterpret_cast<const sal_Int16*>(data))));
115 0 : break;
116 : case typelib_TypeClass_LONG:
117 0 : result.append(OUString::number((*reinterpret_cast<const sal_Int32*>(data))));
118 0 : break;
119 : case typelib_TypeClass_HYPER:
120 0 : result.append(OUString::number((*reinterpret_cast<const sal_Int64*>(data))));
121 0 : break;
122 : case typelib_TypeClass_UNSIGNED_SHORT:
123 0 : result.append(OUString::number((*reinterpret_cast<const sal_uInt16*>(data))));
124 0 : break;
125 : case typelib_TypeClass_UNSIGNED_LONG:
126 0 : result.append(OUString::number((*reinterpret_cast<const sal_uInt32*>(data)), 16));
127 0 : break;
128 : case typelib_TypeClass_UNSIGNED_HYPER:
129 0 : result.append(OUString::number((*reinterpret_cast<const sal_uInt64*>(data)), 16));
130 0 : break;
131 : case typelib_TypeClass_FLOAT:
132 0 : result.append(OUString::number((*reinterpret_cast<const float*>(data))));
133 0 : break;
134 : case typelib_TypeClass_DOUBLE:
135 0 : result.append(OUString::number((*reinterpret_cast<const double*>(data))));
136 0 : break;
137 : case typelib_TypeClass_CHAR:
138 0 : result.append("U+");
139 0 : result.append(OUString::number((*reinterpret_cast<const sal_uInt16*>(data))));
140 0 : break;
141 : case typelib_TypeClass_STRING:
142 0 : result.append(*reinterpret_cast<OUString*>(data));
143 0 : break;
144 : case typelib_TypeClass_TYPE:
145 : case typelib_TypeClass_SEQUENCE:
146 : case typelib_TypeClass_EXCEPTION:
147 : case typelib_TypeClass_INTERFACE:
148 0 : result.append("wtf");
149 0 : break;
150 : case typelib_TypeClass_STRUCT:
151 0 : result.append(struct2string(data, type->pType));
152 0 : break;
153 : case typelib_TypeClass_ENUM:
154 0 : result.append(OUString::number((*reinterpret_cast<const sal_Int32*>(data))));
155 0 : break;
156 : default:
157 : assert(false); // this cannot happen I hope
158 0 : break;
159 : }
160 :
161 0 : return result.makeStringAndClear();
162 : }
163 :
164 : static OUString
165 0 : any2string(uno::Any any)
166 : {
167 0 : return data2string((void*)any.getValue(), any.pType);
168 : }
169 :
170 : // Class SvXMLAutoStylePoolProperties_Impl
171 : // ctor class SvXMLAutoStylePoolProperties_Impl
172 :
173 0 : XMLAutoStylePoolProperties::XMLAutoStylePoolProperties( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties, OUString& rParentName )
174 : : maProperties( rProperties ),
175 0 : mnPos ( rFamilyData.mnCount )
176 : {
177 0 : static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL);
178 :
179 0 : if (bHack)
180 : {
181 0 : OUStringBuffer aStemBuffer(32);
182 0 : aStemBuffer.append( rFamilyData.maStrPrefix );
183 :
184 0 : if (rParentName != "")
185 : {
186 0 : aStemBuffer.append("-");
187 0 : aStemBuffer.append(rParentName);
188 : }
189 :
190 : // Create a name based on the properties used
191 0 : for( size_t i = 0, n = maProperties.size(); i < n; ++i )
192 : {
193 0 : XMLPropertyState& rState = maProperties[i];
194 0 : if (rState.mnIndex == -1)
195 0 : continue;
196 0 : OUString sXMLName(rFamilyData.mxMapper->getPropertySetMapper()->GetEntryXMLName(rState.mnIndex));
197 0 : if (sXMLName == "")
198 0 : continue;
199 0 : aStemBuffer.append("-");
200 0 : aStemBuffer.append(OUString::number(rFamilyData.mxMapper->getPropertySetMapper()->GetEntryNameSpace(rState.mnIndex)));
201 0 : aStemBuffer.append(":");
202 0 : aStemBuffer.append(sXMLName);
203 0 : aStemBuffer.append("=");
204 0 : aStemBuffer.append(any2string(rState.maValue));
205 0 : }
206 :
207 : #if 0
208 : // Finally append an incremental counter in an attempt to make identical
209 : // styles always come out in the same order. Will see if this works.
210 : aStemBuffer.append("-z");
211 : static sal_Int32 nCounter = 0;
212 : aStemBuffer.append(OUString::number(nCounter++));
213 : #endif
214 :
215 : // create a name that hasn't been used before. The created name has not
216 : // to be added to the array, because it will never tried again
217 0 : OUStringBuffer aTry( aStemBuffer );
218 :
219 0 : msName = aTry.makeStringAndClear();
220 0 : bool bWarned = false;
221 0 : while (rFamilyData.maNameSet.find(msName) !=
222 0 : rFamilyData.maNameSet.end())
223 : {
224 0 : if (!bWarned)
225 : SAL_WARN("xmloff", "Overlapping style name for " << msName);
226 0 : bWarned = true;
227 0 : rFamilyData.mnName++;
228 0 : aTry.append( aStemBuffer );
229 0 : aTry.append( "-" );
230 0 : aTry.append( OUString::number( rFamilyData.mnName ) );
231 0 : msName = aTry.makeStringAndClear();
232 : }
233 0 : rFamilyData.maNameSet.insert(msName);
234 : }
235 : else
236 : {
237 : // create a name that hasn't been used before. The created name has not
238 : // to be added to the array, because it will never tried again
239 0 : OUStringBuffer sBuffer( 7 );
240 0 : do
241 : {
242 0 : rFamilyData.mnName++;
243 0 : sBuffer.append( rFamilyData.maStrPrefix );
244 0 : sBuffer.append( OUString::number( rFamilyData.mnName ) );
245 0 : msName = sBuffer.makeStringAndClear();
246 : }
247 0 : while (rFamilyData.maNameSet.find(msName) != rFamilyData.maNameSet.end());
248 : }
249 0 : }
250 :
251 0 : bool operator<( const XMLAutoStyleFamily& r1, const XMLAutoStyleFamily& r2)
252 : {
253 0 : return r1.mnFamily < r2.mnFamily;
254 : }
255 :
256 :
257 0 : XMLAutoStylePoolParent::~XMLAutoStylePoolParent()
258 : {
259 0 : }
260 :
261 : // Adds a array of XMLPropertyState ( vector< XMLPropertyState > ) to list
262 : // if not added, yet.
263 :
264 0 : sal_Bool XMLAutoStylePoolParent::Add( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties, OUString& rName, bool bDontSeek )
265 : {
266 0 : sal_Bool bAdded = sal_False;
267 0 : XMLAutoStylePoolProperties *pProperties = 0;
268 0 : sal_Int32 nProperties = rProperties.size();
269 0 : size_t i = 0;
270 0 : for (size_t n = maPropertiesList.size(); i < n; ++i)
271 : {
272 0 : XMLAutoStylePoolProperties* pIS = &maPropertiesList[i];
273 0 : if( nProperties > (sal_Int32)pIS->GetProperties().size() )
274 : {
275 0 : continue;
276 : }
277 0 : else if( nProperties < (sal_Int32)pIS->GetProperties().size() )
278 : {
279 0 : break;
280 : }
281 0 : else if( !bDontSeek && rFamilyData.mxMapper->Equals( pIS->GetProperties(), rProperties ) )
282 : {
283 0 : pProperties = pIS;
284 0 : break;
285 : }
286 : }
287 :
288 0 : if( !pProperties )
289 : {
290 0 : pProperties = new XMLAutoStylePoolProperties( rFamilyData, rProperties, msParent );
291 0 : PropertiesListType::iterator it = maPropertiesList.begin();
292 0 : ::std::advance( it, i );
293 0 : maPropertiesList.insert( it, pProperties );
294 0 : bAdded = sal_True;
295 : }
296 :
297 0 : rName = pProperties->GetName();
298 :
299 0 : return bAdded;
300 : }
301 :
302 :
303 : // Adds a array of XMLPropertyState ( vector< XMLPropertyState > ) with a given name.
304 : // If the name exists already, nothing is done. If a style with a different name and
305 : // the same properties exists, a new one is added (like with bDontSeek).
306 :
307 :
308 0 : sal_Bool XMLAutoStylePoolParent::AddNamed( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties, const OUString& rName )
309 : {
310 0 : sal_Bool bAdded = sal_False;
311 0 : sal_Int32 nProperties = rProperties.size();
312 0 : size_t i = 0;
313 0 : for (size_t n = maPropertiesList.size(); i < n; ++i)
314 : {
315 0 : XMLAutoStylePoolProperties* pIS = &maPropertiesList[i];
316 0 : if( nProperties > (sal_Int32)pIS->GetProperties().size() )
317 : {
318 0 : continue;
319 : }
320 0 : else if( nProperties < (sal_Int32)pIS->GetProperties().size() )
321 : {
322 0 : break;
323 : }
324 : }
325 :
326 0 : if (rFamilyData.maNameSet.find(rName) == rFamilyData.maNameSet.end())
327 : {
328 : XMLAutoStylePoolProperties* pProperties =
329 0 : new XMLAutoStylePoolProperties( rFamilyData, rProperties, msParent );
330 : // ignore the generated name
331 0 : pProperties->SetName( rName );
332 0 : PropertiesListType::iterator it = maPropertiesList.begin();
333 0 : ::std::advance( it, i );
334 0 : maPropertiesList.insert( it, pProperties );
335 0 : bAdded = sal_True;
336 : }
337 :
338 0 : return bAdded;
339 : }
340 :
341 :
342 : // Search for a array of XMLPropertyState ( vector< XMLPropertyState > ) in list
343 :
344 :
345 0 : OUString XMLAutoStylePoolParent::Find( const XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties ) const
346 : {
347 0 : OUString sName;
348 0 : vector< XMLPropertyState>::size_type nItems = rProperties.size();
349 0 : for (size_t i = 0, n = maPropertiesList.size(); i < n; ++i)
350 : {
351 0 : const XMLAutoStylePoolProperties* pIS = &maPropertiesList[i];
352 0 : if( nItems > pIS->GetProperties().size() )
353 : {
354 0 : continue;
355 : }
356 0 : else if( nItems < pIS->GetProperties().size() )
357 : {
358 0 : break;
359 : }
360 0 : else if( rFamilyData.mxMapper->Equals( pIS->GetProperties(), rProperties ) )
361 : {
362 0 : sName = pIS->GetName();
363 0 : break;
364 : }
365 : }
366 :
367 0 : return sName;
368 : }
369 :
370 0 : bool XMLAutoStylePoolParent::operator< (const XMLAutoStylePoolParent& rOther) const
371 : {
372 0 : return msParent < rOther.msParent;
373 : }
374 :
375 : // Class SvXMLAutoStylePool_Impl
376 : // ctor/dtor class SvXMLAutoStylePool_Impl
377 :
378 0 : SvXMLAutoStylePoolP_Impl::SvXMLAutoStylePoolP_Impl( SvXMLExport& rExp)
379 0 : : rExport( rExp )
380 : {
381 0 : }
382 :
383 0 : SvXMLAutoStylePoolP_Impl::~SvXMLAutoStylePoolP_Impl()
384 : {
385 0 : }
386 :
387 : // Adds stylefamily-information to sorted list
388 :
389 0 : void SvXMLAutoStylePoolP_Impl::AddFamily(
390 : sal_Int32 nFamily,
391 : const OUString& rStrName,
392 : const UniReference < SvXMLExportPropertyMapper > & rMapper,
393 : const OUString& rStrPrefix,
394 : sal_Bool bAsFamily )
395 : {
396 : // store family in a list if not already stored
397 0 : sal_uInt16 nExportFlags = GetExport().getExportFlags();
398 0 : sal_Bool bStylesOnly = (nExportFlags & EXPORT_STYLES) != 0 && (nExportFlags & EXPORT_CONTENT) == 0;
399 :
400 0 : OUString aPrefix( rStrPrefix );
401 0 : if( bStylesOnly )
402 : {
403 0 : aPrefix = OUString( 'M' );
404 0 : aPrefix += rStrPrefix;
405 : }
406 :
407 : #if OSL_DEBUG_LEVEL > 0
408 : XMLAutoStyleFamily aTemporary( nFamily );
409 : FamilySetType::iterator aFind = maFamilySet.find(aTemporary);
410 : if( aFind != maFamilySet.end() )
411 : {
412 : // FIXME: do we really intend to replace the previous nFamily
413 : // entry in this case ?
414 : SAL_WARN_IF( aFind->mxMapper != rMapper, "xmloff",
415 : "Adding duplicate family " << rStrName <<
416 : " with mismatching mapper ! " <<
417 : typeid(*aFind->mxMapper.get()).name() << " " <<
418 : typeid(*rMapper.get()).name() );
419 : }
420 : #endif
421 :
422 0 : XMLAutoStyleFamily *pFamily = new XMLAutoStyleFamily( nFamily, rStrName, rMapper, aPrefix, bAsFamily );
423 0 : maFamilySet.insert(pFamily);
424 0 : }
425 :
426 0 : void SvXMLAutoStylePoolP_Impl::SetFamilyPropSetMapper(
427 : sal_Int32 nFamily,
428 : const UniReference < SvXMLExportPropertyMapper > & rMapper )
429 : {
430 :
431 0 : XMLAutoStyleFamily aTemporary( nFamily );
432 0 : FamilySetType::iterator aFind = maFamilySet.find(aTemporary);
433 0 : if (aFind != maFamilySet.end())
434 0 : aFind->mxMapper = rMapper;
435 0 : }
436 :
437 : // Adds a name to list
438 0 : void SvXMLAutoStylePoolP_Impl::RegisterName( sal_Int32 nFamily, const OUString& rName )
439 : {
440 0 : XMLAutoStyleFamily aTmp( nFamily );
441 0 : FamilySetType::iterator aFind = maFamilySet.find(aTmp);
442 : DBG_ASSERT( aFind != maFamilySet.end(),
443 : "SvXMLAutoStylePool_Impl::RegisterName: unknown family" );
444 0 : if (aFind != maFamilySet.end())
445 : {
446 : // SAL_DEBUG("SvXMLAutoStylePoolP_Impl::RegisterName: " << nFamily << ", '" << rName << "'");
447 0 : aFind->maNameSet.insert(rName);
448 0 : }
449 0 : }
450 :
451 :
452 : // Retrieve the list of registered names
453 :
454 :
455 0 : void SvXMLAutoStylePoolP_Impl::GetRegisteredNames(
456 : uno::Sequence<sal_Int32>& rFamilies,
457 : uno::Sequence<OUString>& rNames )
458 : {
459 : // collect registered names + families
460 0 : vector<sal_Int32> aFamilies;
461 0 : vector<OUString> aNames;
462 :
463 : // iterate over families
464 0 : for (FamilySetType::iterator aJ = maFamilySet.begin(); aJ != maFamilySet.end(); ++aJ)
465 : {
466 0 : XMLAutoStyleFamily &rFamily = *aJ;
467 :
468 : // iterate over names
469 0 : for (XMLAutoStyleFamily::NameSetType::const_iterator aI = rFamily.maNameSet.begin(); aI != rFamily.maNameSet.end(); ++aI)
470 : {
471 0 : aFamilies.push_back( rFamily.mnFamily );
472 0 : aNames.push_back( *aI );
473 : }
474 : }
475 :
476 : // copy the families + names into the sequence types
477 : DBG_ASSERT( aFamilies.size() == aNames.size(), "families != names" );
478 :
479 0 : rFamilies.realloc( aFamilies.size() );
480 0 : std::copy( aFamilies.begin(), aFamilies.end(), rFamilies.getArray() );
481 :
482 0 : rNames.realloc( aNames.size() );
483 0 : std::copy( aNames.begin(), aNames.end(), rNames.getArray() );
484 0 : }
485 :
486 : // Adds a array of XMLPropertyState ( vector< XMLPropertyState > ) to list
487 : // if not added, yet.
488 :
489 0 : bool SvXMLAutoStylePoolP_Impl::Add(
490 : OUString& rName, sal_Int32 nFamily, const OUString& rParentName,
491 : const ::std::vector< XMLPropertyState >& rProperties, bool bDontSeek )
492 : {
493 0 : XMLAutoStyleFamily aTemporary( nFamily );
494 0 : FamilySetType::iterator aFind = maFamilySet.find(aTemporary);
495 : DBG_ASSERT(aFind != maFamilySet.end(), "SvXMLAutoStylePool_Impl::Add: unknown family");
496 :
497 0 : if (aFind == maFamilySet.end())
498 0 : return false;
499 :
500 0 : XMLAutoStyleFamily &rFamily = *aFind;
501 :
502 0 : XMLAutoStylePoolParent aTmp(rParentName);
503 0 : XMLAutoStyleFamily::ParentSetType::iterator it2 = rFamily.maParentSet.find(aTmp);
504 0 : if (it2 == rFamily.maParentSet.end())
505 : {
506 : std::pair<XMLAutoStyleFamily::ParentSetType::iterator,bool> r =
507 0 : rFamily.maParentSet.insert(new XMLAutoStylePoolParent(rParentName));
508 0 : it2 = r.first;
509 : }
510 :
511 0 : XMLAutoStylePoolParent& rParent = *it2;
512 :
513 0 : bool bRet = false;
514 0 : if (rParent.Add(rFamily, rProperties, rName, bDontSeek))
515 : {
516 0 : rFamily.mnCount++;
517 0 : bRet = true;
518 : }
519 :
520 0 : return bRet;
521 : }
522 :
523 0 : bool SvXMLAutoStylePoolP_Impl::AddNamed(
524 : const OUString& rName, sal_Int32 nFamily, const OUString& rParentName,
525 : const ::std::vector< XMLPropertyState >& rProperties )
526 : {
527 : // get family and parent the same way as in Add()
528 :
529 0 : XMLAutoStyleFamily aTemporary( nFamily );
530 0 : FamilySetType::iterator aFind = maFamilySet.find(aTemporary);
531 : DBG_ASSERT(aFind != maFamilySet.end(), "SvXMLAutoStylePool_Impl::Add: unknown family");
532 :
533 0 : if (aFind == maFamilySet.end())
534 0 : return false;
535 :
536 0 : XMLAutoStyleFamily &rFamily = *aFind;
537 :
538 0 : XMLAutoStylePoolParent aTmp(rParentName);
539 0 : XMLAutoStyleFamily::ParentSetType::iterator it2 = rFamily.maParentSet.find(aTmp);
540 0 : if (it2 == rFamily.maParentSet.end())
541 : {
542 : std::pair<XMLAutoStyleFamily::ParentSetType::iterator,bool> r =
543 0 : rFamily.maParentSet.insert(new XMLAutoStylePoolParent(rParentName));
544 0 : it2 = r.first;
545 : }
546 :
547 0 : XMLAutoStylePoolParent& rParent = *it2;
548 :
549 0 : bool bRet = false;
550 0 : if (rParent.AddNamed(rFamily, rProperties, rName))
551 : {
552 0 : rFamily.mnCount++;
553 0 : bRet = true;
554 : }
555 :
556 0 : return bRet;
557 : }
558 :
559 :
560 : // Search for a array of XMLPropertyState ( vector< XMLPropertyState > ) in list
561 :
562 :
563 0 : OUString SvXMLAutoStylePoolP_Impl::Find( sal_Int32 nFamily,
564 : const OUString& rParent,
565 : const vector< XMLPropertyState >& rProperties ) const
566 : {
567 0 : OUString sName;
568 :
569 0 : XMLAutoStyleFamily aTemporary( nFamily );
570 0 : FamilySetType::const_iterator const iter = maFamilySet.find(aTemporary);
571 : OSL_ENSURE(iter != maFamilySet.end(), "SvXMLAutoStylePool_Impl::Find: unknown family");
572 :
573 0 : if (iter != maFamilySet.end())
574 : {
575 0 : XMLAutoStyleFamily const& rFamily = *iter;
576 0 : XMLAutoStylePoolParent aTmp( rParent );
577 0 : XMLAutoStyleFamily::ParentSetType::const_iterator it2 = rFamily.maParentSet.find(aTmp);
578 0 : if (it2 != rFamily.maParentSet.end())
579 : {
580 0 : sName = it2->Find(rFamily, rProperties);
581 0 : }
582 : }
583 :
584 0 : return sName;
585 : }
586 :
587 : namespace {
588 :
589 : struct AutoStylePoolExport
590 : {
591 : const OUString* mpParent;
592 : XMLAutoStylePoolProperties* mpProperties;
593 :
594 0 : AutoStylePoolExport() : mpParent(NULL), mpProperties(NULL) {}
595 : };
596 :
597 : struct StyleComparator
598 : {
599 0 : bool operator() (const AutoStylePoolExport& a, const AutoStylePoolExport& b)
600 : {
601 0 : return (a.mpProperties->GetName() < b.mpProperties->GetName() ||
602 0 : (a.mpProperties->GetName() == b.mpProperties->GetName() && *a.mpParent < *b.mpParent));
603 : }
604 : };
605 :
606 : }
607 :
608 0 : void SvXMLAutoStylePoolP_Impl::exportXML(
609 : sal_Int32 nFamily,
610 : const uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > &,
611 : const SvXMLUnitConverter&,
612 : const SvXMLNamespaceMap&,
613 : const SvXMLAutoStylePoolP *pAntiImpl) const
614 : {
615 : // Get list of parents for current family (nFamily)
616 0 : XMLAutoStyleFamily aTmp( nFamily );
617 0 : FamilySetType::const_iterator aFind = maFamilySet.find(aTmp);
618 : DBG_ASSERT( aFind != maFamilySet.end(),
619 : "SvXMLAutoStylePool_Impl::exportXML: unknown family" );
620 0 : if (aFind == maFamilySet.end())
621 0 : return;
622 :
623 0 : const XMLAutoStyleFamily &rFamily = *aFind;
624 0 : sal_uInt32 nCount = rFamily.mnCount;
625 :
626 0 : if (!nCount)
627 0 : return;
628 :
629 : // create, initialize and fill helper-structure (SvXMLAutoStylePoolProperties_Impl)
630 : // which contains a parent-name and a SvXMLAutoStylePoolProperties_Impl
631 0 : std::vector<AutoStylePoolExport> aExpStyles(nCount);
632 :
633 0 : XMLAutoStyleFamily::ParentSetType::iterator it = rFamily.maParentSet.begin(), itEnd = rFamily.maParentSet.end();
634 0 : for (; it != itEnd; ++it)
635 : {
636 0 : XMLAutoStylePoolParent& rParent = *it;
637 0 : size_t nProperties = rParent.GetPropertiesList().size();
638 0 : for( size_t j = 0; j < nProperties; j++ )
639 : {
640 : XMLAutoStylePoolProperties* pProperties =
641 0 : &rParent.GetPropertiesList()[j];
642 0 : sal_uLong nPos = pProperties->GetPos();
643 : DBG_ASSERT( nPos < nCount,
644 : "SvXMLAutoStylePool_Impl::exportXML: wrong position" );
645 0 : if( nPos < nCount )
646 : {
647 : DBG_ASSERT( !aExpStyles[nPos].mpProperties,
648 : "SvXMLAutoStylePool_Impl::exportXML: double position" );
649 0 : aExpStyles[nPos].mpProperties = pProperties;
650 0 : aExpStyles[nPos].mpParent = &rParent.GetParent();
651 : }
652 : }
653 : }
654 :
655 0 : static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL);
656 :
657 0 : if (bHack)
658 : {
659 :
660 0 : std::sort(aExpStyles.begin(), aExpStyles.end(), StyleComparator());
661 :
662 0 : for (size_t i = 0; i < nCount; i++)
663 : {
664 0 : OUString oldName = aExpStyles[i].mpProperties->GetName();
665 0 : sal_Int32 dashIx = oldName.indexOf('-');
666 0 : OUString newName = (dashIx > 0 ? oldName.copy(0, dashIx) : oldName) + OUString::number(i);
667 : // SAL_DEBUG("renaming '" << oldName << "' -> '" << newName << "'");
668 0 : aExpStyles[i].mpProperties->SetName(newName);
669 0 : }
670 : }
671 :
672 :
673 : // create string to export for each XML-style. That means for each property-list
674 :
675 0 : OUString aStrFamilyName = rFamily.maStrFamilyName;
676 :
677 0 : for( size_t i = 0; i < nCount; i++ )
678 : {
679 : DBG_ASSERT( aExpStyles[i].mpProperties,
680 : "SvXMLAutoStylePool_Impl::exportXML: empty position" );
681 :
682 0 : if( aExpStyles[i].mpProperties )
683 : {
684 0 : GetExport().AddAttribute(
685 : XML_NAMESPACE_STYLE, XML_NAME,
686 0 : aExpStyles[i].mpProperties->GetName() );
687 :
688 0 : if( rFamily.mbAsFamily )
689 : {
690 0 : GetExport().AddAttribute(
691 0 : XML_NAMESPACE_STYLE, XML_FAMILY, aStrFamilyName );
692 : }
693 :
694 0 : if( !aExpStyles[i].mpParent->isEmpty() )
695 : {
696 0 : GetExport().AddAttribute(
697 : XML_NAMESPACE_STYLE, XML_PARENT_STYLE_NAME,
698 0 : GetExport().EncodeStyleName(
699 0 : *aExpStyles[i].mpParent ) );
700 : }
701 :
702 0 : OUString sName;
703 0 : if( rFamily.mbAsFamily )
704 0 : sName = GetXMLToken(XML_STYLE);
705 : else
706 0 : sName = rFamily.maStrFamilyName;
707 :
708 : pAntiImpl->exportStyleAttributes(
709 0 : GetExport().GetAttrList(),
710 : nFamily,
711 0 : aExpStyles[i].mpProperties->GetProperties(),
712 0 : *rFamily.mxMapper.get()
713 0 : , GetExport().GetMM100UnitConverter(),
714 0 : GetExport().GetNamespaceMap()
715 0 : );
716 :
717 0 : SvXMLElementExport aElem( GetExport(),
718 : XML_NAMESPACE_STYLE, sName,
719 0 : true, true );
720 :
721 0 : sal_Int32 nStart(-1);
722 0 : sal_Int32 nEnd(-1);
723 0 : if (nFamily == XML_STYLE_FAMILY_PAGE_MASTER)
724 : {
725 0 : nStart = 0;
726 0 : sal_Int32 nIndex = 0;
727 : UniReference< XMLPropertySetMapper > aPropMapper =
728 0 : rFamily.mxMapper->getPropertySetMapper();
729 : sal_Int16 nContextID;
730 0 : while(nIndex < aPropMapper->GetEntryCount() && nEnd == -1)
731 : {
732 0 : nContextID = aPropMapper->GetEntryContextId( nIndex );
733 0 : if (nContextID && ((nContextID & CTF_PM_FLAGMASK) != XML_PM_CTF_START))
734 0 : nEnd = nIndex;
735 0 : nIndex++;
736 : }
737 0 : if (nEnd == -1)
738 0 : nEnd = nIndex;
739 : }
740 :
741 : rFamily.mxMapper->exportXML(
742 0 : GetExport(),
743 0 : aExpStyles[i].mpProperties->GetProperties(),
744 0 : nStart, nEnd, XML_EXPORT_FLAG_IGN_WS );
745 :
746 : pAntiImpl->exportStyleContent(
747 0 : GetExport().GetDocHandler(),
748 : nFamily,
749 0 : aExpStyles[i].mpProperties->GetProperties(),
750 0 : *rFamily.mxMapper.get(),
751 0 : GetExport().GetMM100UnitConverter(),
752 0 : GetExport().GetNamespaceMap()
753 0 : );
754 : }
755 0 : }
756 : }
757 :
758 0 : void SvXMLAutoStylePoolP_Impl::ClearEntries()
759 : {
760 0 : for (FamilySetType::iterator aI = maFamilySet.begin(); aI != maFamilySet.end(); ++aI)
761 0 : aI->ClearEntries();
762 0 : }
763 :
764 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|