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