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 23008 : 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 23008 : mnCount( 0 ), mnName( 0 ), maStrPrefix( rStrPrefix ), mbAsFamily( bAsFamily )
54 23008 : {}
55 :
56 38158 : XMLAutoStyleFamily::XMLAutoStyleFamily( sal_Int32 nFamily ) :
57 38158 : mnFamily(nFamily), mnCount(0), mnName(0), mbAsFamily(false) {}
58 :
59 61166 : XMLAutoStyleFamily::~XMLAutoStyleFamily() {}
60 :
61 56 : void XMLAutoStyleFamily::ClearEntries()
62 : {
63 56 : maParentSet.clear();
64 56 : }
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 : &((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(((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((*reinterpret_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((*reinterpret_cast<const sal_Int8*>(data))));
113 0 : break;
114 : case typelib_TypeClass_SHORT:
115 0 : result.append(OUString::number((*reinterpret_cast<const sal_Int16*>(data))));
116 0 : break;
117 : case typelib_TypeClass_LONG:
118 0 : result.append(OUString::number((*reinterpret_cast<const sal_Int32*>(data))));
119 0 : break;
120 : case typelib_TypeClass_HYPER:
121 0 : result.append(OUString::number((*reinterpret_cast<const sal_Int64*>(data))));
122 0 : break;
123 : case typelib_TypeClass_UNSIGNED_SHORT:
124 0 : result.append(OUString::number((*reinterpret_cast<const sal_uInt16*>(data))));
125 0 : break;
126 : case typelib_TypeClass_UNSIGNED_LONG:
127 0 : result.append(OUString::number((*reinterpret_cast<const sal_uInt32*>(data)), 16));
128 0 : break;
129 : case typelib_TypeClass_UNSIGNED_HYPER:
130 0 : result.append(OUString::number((*reinterpret_cast<const sal_uInt64*>(data)), 16));
131 0 : break;
132 : case typelib_TypeClass_FLOAT:
133 0 : result.append(OUString::number((*reinterpret_cast<const float*>(data))));
134 0 : break;
135 : case typelib_TypeClass_DOUBLE:
136 0 : result.append(OUString::number((*reinterpret_cast<const double*>(data))));
137 0 : break;
138 : case typelib_TypeClass_CHAR:
139 0 : result.append("U+");
140 0 : result.append(OUString::number((*reinterpret_cast<const sal_uInt16*>(data))));
141 0 : break;
142 : case typelib_TypeClass_STRING:
143 0 : result.append(*reinterpret_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((*reinterpret_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((void*)any.getValue(), any.pType);
169 : }
170 :
171 : // Class SvXMLAutoStylePoolProperties_Impl
172 : // ctor class SvXMLAutoStylePoolProperties_Impl
173 :
174 7072 : XMLAutoStylePoolProperties::XMLAutoStylePoolProperties( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties, OUString& rParentName )
175 : : maProperties( rProperties ),
176 7072 : mnPos ( rFamilyData.mnCount )
177 : {
178 7072 : static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL);
179 :
180 7072 : if (bHack)
181 : {
182 0 : OUStringBuffer aStemBuffer(32);
183 0 : aStemBuffer.append( rFamilyData.maStrPrefix );
184 :
185 0 : if (rParentName != "")
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 == "")
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 7072 : OUStringBuffer sBuffer( 7 );
241 14144 : do
242 : {
243 7072 : rFamilyData.mnName++;
244 7072 : sBuffer.append( rFamilyData.maStrPrefix );
245 7072 : sBuffer.append( OUString::number( rFamilyData.mnName ) );
246 7072 : msName = sBuffer.makeStringAndClear();
247 : }
248 21216 : while (rFamilyData.maNameSet.find(msName) != rFamilyData.maNameSet.end());
249 : }
250 7072 : }
251 :
252 219852 : bool operator<( const XMLAutoStyleFamily& r1, const XMLAutoStyleFamily& r2)
253 : {
254 219852 : return r1.mnFamily < r2.mnFamily;
255 : }
256 :
257 :
258 9842 : XMLAutoStylePoolParent::~XMLAutoStylePoolParent()
259 : {
260 9842 : }
261 :
262 : // Adds a array of XMLPropertyState ( vector< XMLPropertyState > ) to list
263 : // if not added, yet.
264 :
265 7924 : bool XMLAutoStylePoolParent::Add( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties, OUString& rName, bool bDontSeek )
266 : {
267 7924 : bool bAdded = false;
268 7924 : XMLAutoStylePoolProperties *pProperties = 0;
269 7924 : sal_Int32 nProperties = rProperties.size();
270 7924 : size_t i = 0;
271 27194 : for (size_t n = maPropertiesList.size(); i < n; ++i)
272 : {
273 24790 : XMLAutoStylePoolProperties* pIS = &maPropertiesList[i];
274 24790 : if( nProperties > (sal_Int32)pIS->GetProperties().size() )
275 : {
276 15192 : continue;
277 : }
278 9598 : else if( nProperties < (sal_Int32)pIS->GetProperties().size() )
279 : {
280 4668 : break;
281 : }
282 4930 : else if( !bDontSeek && rFamilyData.mxMapper->Equals( pIS->GetProperties(), rProperties ) )
283 : {
284 852 : pProperties = pIS;
285 852 : break;
286 : }
287 : }
288 :
289 7924 : if( !pProperties )
290 : {
291 7072 : pProperties = new XMLAutoStylePoolProperties( rFamilyData, rProperties, msParent );
292 7072 : PropertiesListType::iterator it = maPropertiesList.begin();
293 7072 : ::std::advance( it, i );
294 7072 : maPropertiesList.insert( it, pProperties );
295 7072 : bAdded = true;
296 : }
297 :
298 7924 : rName = pProperties->GetName();
299 :
300 7924 : return bAdded;
301 : }
302 :
303 :
304 : // Adds a array of XMLPropertyState ( vector< XMLPropertyState > ) with a given name.
305 : // If the name exists already, nothing is done. If a style with a different name and
306 : // the same properties exists, a new one is added (like with bDontSeek).
307 :
308 :
309 0 : bool XMLAutoStylePoolParent::AddNamed( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties, const OUString& rName )
310 : {
311 0 : bool bAdded = false;
312 0 : sal_Int32 nProperties = rProperties.size();
313 0 : size_t i = 0;
314 0 : for (size_t n = maPropertiesList.size(); i < n; ++i)
315 : {
316 0 : XMLAutoStylePoolProperties* pIS = &maPropertiesList[i];
317 0 : if( nProperties > (sal_Int32)pIS->GetProperties().size() )
318 : {
319 0 : continue;
320 : }
321 0 : else if( nProperties < (sal_Int32)pIS->GetProperties().size() )
322 : {
323 0 : break;
324 : }
325 : }
326 :
327 0 : if (rFamilyData.maNameSet.find(rName) == rFamilyData.maNameSet.end())
328 : {
329 : XMLAutoStylePoolProperties* pProperties =
330 0 : new XMLAutoStylePoolProperties( rFamilyData, rProperties, msParent );
331 : // ignore the generated name
332 0 : pProperties->SetName( rName );
333 0 : PropertiesListType::iterator it = maPropertiesList.begin();
334 0 : ::std::advance( it, i );
335 0 : maPropertiesList.insert( it, pProperties );
336 0 : bAdded = true;
337 : }
338 :
339 0 : return bAdded;
340 : }
341 :
342 :
343 : // Search for a array of XMLPropertyState ( vector< XMLPropertyState > ) in list
344 :
345 :
346 668 : OUString XMLAutoStylePoolParent::Find( const XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties ) const
347 : {
348 668 : OUString sName;
349 668 : vector< XMLPropertyState>::size_type nItems = rProperties.size();
350 1326 : for (size_t i = 0, n = maPropertiesList.size(); i < n; ++i)
351 : {
352 1226 : const XMLAutoStylePoolProperties* pIS = &maPropertiesList[i];
353 1226 : if( nItems > pIS->GetProperties().size() )
354 : {
355 484 : continue;
356 : }
357 742 : else if( nItems < pIS->GetProperties().size() )
358 : {
359 68 : break;
360 : }
361 674 : else if( rFamilyData.mxMapper->Equals( pIS->GetProperties(), rProperties ) )
362 : {
363 500 : sName = pIS->GetName();
364 500 : break;
365 : }
366 : }
367 :
368 668 : return sName;
369 : }
370 :
371 15379 : bool XMLAutoStylePoolParent::operator< (const XMLAutoStylePoolParent& rOther) const
372 : {
373 15379 : return msParent < rOther.msParent;
374 : }
375 :
376 : // Class SvXMLAutoStylePool_Impl
377 : // ctor/dtor class SvXMLAutoStylePool_Impl
378 :
379 4002 : SvXMLAutoStylePoolP_Impl::SvXMLAutoStylePoolP_Impl( SvXMLExport& rExp)
380 4002 : : rExport( rExp )
381 : {
382 4002 : }
383 :
384 4002 : SvXMLAutoStylePoolP_Impl::~SvXMLAutoStylePoolP_Impl()
385 : {
386 4002 : }
387 :
388 : // Adds stylefamily-information to sorted list
389 :
390 23008 : void SvXMLAutoStylePoolP_Impl::AddFamily(
391 : sal_Int32 nFamily,
392 : const OUString& rStrName,
393 : const rtl::Reference < SvXMLExportPropertyMapper > & rMapper,
394 : const OUString& rStrPrefix,
395 : bool bAsFamily )
396 : {
397 : // store family in a list if not already stored
398 23008 : sal_uInt16 nExportFlags = GetExport().getExportFlags();
399 23008 : bool bStylesOnly = (nExportFlags & EXPORT_STYLES) != 0 && (nExportFlags & EXPORT_CONTENT) == 0;
400 :
401 23008 : OUString aPrefix( rStrPrefix );
402 23008 : if( bStylesOnly )
403 : {
404 6534 : aPrefix = OUString( 'M' );
405 6534 : aPrefix += rStrPrefix;
406 : }
407 :
408 : #if OSL_DEBUG_LEVEL > 0
409 : XMLAutoStyleFamily aTemporary( nFamily );
410 : FamilySetType::iterator aFind = maFamilySet.find(aTemporary);
411 : if( aFind != maFamilySet.end() )
412 : {
413 : // FIXME: do we really intend to replace the previous nFamily
414 : // entry in this case ?
415 : SAL_WARN_IF( aFind->mxMapper != rMapper, "xmloff",
416 : "Adding duplicate family " << rStrName <<
417 : " with mismatching mapper ! " <<
418 : typeid(*aFind->mxMapper.get()).name() << " " <<
419 : typeid(*rMapper.get()).name() );
420 : }
421 : #endif
422 :
423 23008 : XMLAutoStyleFamily *pFamily = new XMLAutoStyleFamily( nFamily, rStrName, rMapper, aPrefix, bAsFamily );
424 23008 : maFamilySet.insert(pFamily);
425 23008 : }
426 :
427 4 : void SvXMLAutoStylePoolP_Impl::SetFamilyPropSetMapper(
428 : sal_Int32 nFamily,
429 : const rtl::Reference < SvXMLExportPropertyMapper > & rMapper )
430 : {
431 :
432 4 : XMLAutoStyleFamily aTemporary( nFamily );
433 4 : FamilySetType::iterator aFind = maFamilySet.find(aTemporary);
434 4 : if (aFind != maFamilySet.end())
435 4 : aFind->mxMapper = rMapper;
436 4 : }
437 :
438 : // Adds a name to list
439 21968 : void SvXMLAutoStylePoolP_Impl::RegisterName( sal_Int32 nFamily, const OUString& rName )
440 : {
441 21968 : XMLAutoStyleFamily aTmp( nFamily );
442 21968 : FamilySetType::iterator aFind = maFamilySet.find(aTmp);
443 : DBG_ASSERT( aFind != maFamilySet.end(),
444 : "SvXMLAutoStylePool_Impl::RegisterName: unknown family" );
445 21968 : if (aFind != maFamilySet.end())
446 : {
447 : // SAL_DEBUG("SvXMLAutoStylePoolP_Impl::RegisterName: " << nFamily << ", '" << rName << "'");
448 21968 : aFind->maNameSet.insert(rName);
449 21968 : }
450 21968 : }
451 :
452 :
453 : // Retrieve the list of registered names
454 :
455 :
456 126 : void SvXMLAutoStylePoolP_Impl::GetRegisteredNames(
457 : uno::Sequence<sal_Int32>& rFamilies,
458 : uno::Sequence<OUString>& rNames )
459 : {
460 : // collect registered names + families
461 126 : vector<sal_Int32> aFamilies;
462 252 : vector<OUString> aNames;
463 :
464 : // iterate over families
465 1260 : for (FamilySetType::iterator aJ = maFamilySet.begin(); aJ != maFamilySet.end(); ++aJ)
466 : {
467 1134 : XMLAutoStyleFamily &rFamily = *aJ;
468 :
469 : // iterate over names
470 11990 : for (XMLAutoStyleFamily::NameSetType::const_iterator aI = rFamily.maNameSet.begin(); aI != rFamily.maNameSet.end(); ++aI)
471 : {
472 10856 : aFamilies.push_back( rFamily.mnFamily );
473 10856 : aNames.push_back( *aI );
474 : }
475 : }
476 :
477 : // copy the families + names into the sequence types
478 : DBG_ASSERT( aFamilies.size() == aNames.size(), "families != names" );
479 :
480 126 : rFamilies.realloc( aFamilies.size() );
481 126 : std::copy( aFamilies.begin(), aFamilies.end(), rFamilies.getArray() );
482 :
483 126 : rNames.realloc( aNames.size() );
484 252 : std::copy( aNames.begin(), aNames.end(), rNames.getArray() );
485 126 : }
486 :
487 : // Adds a array of XMLPropertyState ( vector< XMLPropertyState > ) to list
488 : // if not added, yet.
489 :
490 7924 : bool SvXMLAutoStylePoolP_Impl::Add(
491 : OUString& rName, sal_Int32 nFamily, const OUString& rParentName,
492 : const ::std::vector< XMLPropertyState >& rProperties, bool bDontSeek )
493 : {
494 7924 : XMLAutoStyleFamily aTemporary( nFamily );
495 7924 : FamilySetType::iterator aFind = maFamilySet.find(aTemporary);
496 : DBG_ASSERT(aFind != maFamilySet.end(), "SvXMLAutoStylePool_Impl::Add: unknown family");
497 :
498 7924 : if (aFind == maFamilySet.end())
499 0 : return false;
500 :
501 7924 : XMLAutoStyleFamily &rFamily = *aFind;
502 :
503 15848 : XMLAutoStylePoolParent aTmp(rParentName);
504 7924 : XMLAutoStyleFamily::ParentSetType::iterator it2 = rFamily.maParentSet.find(aTmp);
505 7924 : if (it2 == rFamily.maParentSet.end())
506 : {
507 : std::pair<XMLAutoStyleFamily::ParentSetType::iterator,bool> r =
508 1030 : rFamily.maParentSet.insert(new XMLAutoStylePoolParent(rParentName));
509 1030 : it2 = r.first;
510 : }
511 :
512 7924 : XMLAutoStylePoolParent& rParent = *it2;
513 :
514 7924 : bool bRet = false;
515 7924 : if (rParent.Add(rFamily, rProperties, rName, bDontSeek))
516 : {
517 7072 : rFamily.mnCount++;
518 7072 : bRet = true;
519 : }
520 :
521 15848 : return bRet;
522 : }
523 :
524 0 : bool SvXMLAutoStylePoolP_Impl::AddNamed(
525 : const OUString& rName, sal_Int32 nFamily, const OUString& rParentName,
526 : const ::std::vector< XMLPropertyState >& rProperties )
527 : {
528 : // get family and parent the same way as in Add()
529 :
530 0 : XMLAutoStyleFamily aTemporary( nFamily );
531 0 : FamilySetType::iterator aFind = maFamilySet.find(aTemporary);
532 : DBG_ASSERT(aFind != maFamilySet.end(), "SvXMLAutoStylePool_Impl::Add: unknown family");
533 :
534 0 : if (aFind == maFamilySet.end())
535 0 : return false;
536 :
537 0 : XMLAutoStyleFamily &rFamily = *aFind;
538 :
539 0 : XMLAutoStylePoolParent aTmp(rParentName);
540 0 : XMLAutoStyleFamily::ParentSetType::iterator it2 = rFamily.maParentSet.find(aTmp);
541 0 : if (it2 == rFamily.maParentSet.end())
542 : {
543 : std::pair<XMLAutoStyleFamily::ParentSetType::iterator,bool> r =
544 0 : rFamily.maParentSet.insert(new XMLAutoStylePoolParent(rParentName));
545 0 : it2 = r.first;
546 : }
547 :
548 0 : XMLAutoStylePoolParent& rParent = *it2;
549 :
550 0 : bool bRet = false;
551 0 : if (rParent.AddNamed(rFamily, rProperties, rName))
552 : {
553 0 : rFamily.mnCount++;
554 0 : bRet = true;
555 : }
556 :
557 0 : return bRet;
558 : }
559 :
560 :
561 : // Search for a array of XMLPropertyState ( vector< XMLPropertyState > ) in list
562 :
563 :
564 888 : OUString SvXMLAutoStylePoolP_Impl::Find( sal_Int32 nFamily,
565 : const OUString& rParent,
566 : const vector< XMLPropertyState >& rProperties ) const
567 : {
568 888 : OUString sName;
569 :
570 1776 : XMLAutoStyleFamily aTemporary( nFamily );
571 888 : FamilySetType::const_iterator const iter = maFamilySet.find(aTemporary);
572 : OSL_ENSURE(iter != maFamilySet.end(), "SvXMLAutoStylePool_Impl::Find: unknown family");
573 :
574 888 : if (iter != maFamilySet.end())
575 : {
576 888 : XMLAutoStyleFamily const& rFamily = *iter;
577 888 : XMLAutoStylePoolParent aTmp( rParent );
578 888 : XMLAutoStyleFamily::ParentSetType::const_iterator it2 = rFamily.maParentSet.find(aTmp);
579 888 : if (it2 != rFamily.maParentSet.end())
580 : {
581 668 : sName = it2->Find(rFamily, rProperties);
582 888 : }
583 : }
584 :
585 1776 : return sName;
586 : }
587 :
588 : namespace {
589 :
590 : struct AutoStylePoolExport
591 : {
592 : const OUString* mpParent;
593 : XMLAutoStylePoolProperties* mpProperties;
594 :
595 7074 : 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 7374 : 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 7374 : XMLAutoStyleFamily aTmp( nFamily );
618 7374 : FamilySetType::const_iterator aFind = maFamilySet.find(aTmp);
619 : DBG_ASSERT( aFind != maFamilySet.end(),
620 : "SvXMLAutoStylePool_Impl::exportXML: unknown family" );
621 7374 : if (aFind == maFamilySet.end())
622 0 : return;
623 :
624 7374 : const XMLAutoStyleFamily &rFamily = *aFind;
625 7374 : sal_uInt32 nCount = rFamily.mnCount;
626 :
627 7374 : if (!nCount)
628 6376 : return;
629 :
630 : // create, initialize and fill helper-structure (SvXMLAutoStylePoolProperties_Impl)
631 : // which contains a parent-name and a SvXMLAutoStylePoolProperties_Impl
632 1996 : std::vector<AutoStylePoolExport> aExpStyles(nCount);
633 :
634 998 : XMLAutoStyleFamily::ParentSetType::iterator it = rFamily.maParentSet.begin(), itEnd = rFamily.maParentSet.end();
635 2028 : for (; it != itEnd; ++it)
636 : {
637 1030 : XMLAutoStylePoolParent& rParent = *it;
638 1030 : size_t nProperties = rParent.GetPropertiesList().size();
639 8104 : for( size_t j = 0; j < nProperties; j++ )
640 : {
641 : XMLAutoStylePoolProperties* pProperties =
642 7074 : &rParent.GetPropertiesList()[j];
643 7074 : sal_uLong nPos = pProperties->GetPos();
644 : DBG_ASSERT( nPos < nCount,
645 : "SvXMLAutoStylePool_Impl::exportXML: wrong position" );
646 7074 : if( nPos < nCount )
647 : {
648 : DBG_ASSERT( !aExpStyles[nPos].mpProperties,
649 : "SvXMLAutoStylePool_Impl::exportXML: double position" );
650 7074 : aExpStyles[nPos].mpProperties = pProperties;
651 7074 : aExpStyles[nPos].mpParent = &rParent.GetParent();
652 : }
653 : }
654 : }
655 :
656 998 : static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL);
657 :
658 998 : if (bHack)
659 : {
660 :
661 0 : std::sort(aExpStyles.begin(), aExpStyles.end(), StyleComparator());
662 :
663 0 : for (size_t i = 0; i < nCount; i++)
664 : {
665 0 : OUString oldName = aExpStyles[i].mpProperties->GetName();
666 0 : sal_Int32 dashIx = oldName.indexOf('-');
667 0 : OUString newName = (dashIx > 0 ? oldName.copy(0, dashIx) : oldName) + OUString::number(i);
668 : // SAL_DEBUG("renaming '" << oldName << "' -> '" << newName << "'");
669 0 : aExpStyles[i].mpProperties->SetName(newName);
670 0 : }
671 : }
672 :
673 :
674 : // create string to export for each XML-style. That means for each property-list
675 :
676 1996 : OUString aStrFamilyName = rFamily.maStrFamilyName;
677 :
678 8072 : for( size_t i = 0; i < nCount; i++ )
679 : {
680 : DBG_ASSERT( aExpStyles[i].mpProperties,
681 : "SvXMLAutoStylePool_Impl::exportXML: empty position" );
682 :
683 7074 : if( aExpStyles[i].mpProperties )
684 : {
685 7074 : GetExport().AddAttribute(
686 : XML_NAMESPACE_STYLE, XML_NAME,
687 14148 : aExpStyles[i].mpProperties->GetName() );
688 :
689 7074 : bool bExtensionNamespace = false;
690 7074 : if( rFamily.mbAsFamily )
691 : {
692 6904 : GetExport().AddAttribute(
693 6904 : XML_NAMESPACE_STYLE, XML_FAMILY, aStrFamilyName );
694 20624 : if(aStrFamilyName != "graphic" &&
695 13684 : aStrFamilyName != "presentation" &&
696 6780 : aStrFamilyName != "chart" )
697 498 : bExtensionNamespace = true;
698 : }
699 :
700 7074 : if( !aExpStyles[i].mpParent->isEmpty() )
701 : {
702 244 : GetExport().AddAttribute(
703 : XML_NAMESPACE_STYLE, XML_PARENT_STYLE_NAME,
704 244 : GetExport().EncodeStyleName(
705 732 : *aExpStyles[i].mpParent ) );
706 : }
707 :
708 7074 : OUString sName;
709 7074 : if( rFamily.mbAsFamily )
710 6904 : sName = GetXMLToken(XML_STYLE);
711 : else
712 170 : sName = rFamily.maStrFamilyName;
713 :
714 : pAntiImpl->exportStyleAttributes(
715 7074 : GetExport().GetAttrList(),
716 : nFamily,
717 7074 : aExpStyles[i].mpProperties->GetProperties(),
718 7074 : *rFamily.mxMapper.get()
719 7074 : , GetExport().GetMM100UnitConverter(),
720 7074 : GetExport().GetNamespaceMap()
721 14148 : );
722 :
723 7074 : SvXMLElementExport aElem( GetExport(),
724 : XML_NAMESPACE_STYLE, sName,
725 14148 : true, true );
726 :
727 7074 : sal_Int32 nStart(-1);
728 7074 : sal_Int32 nEnd(-1);
729 7074 : if (nFamily == XML_STYLE_FAMILY_PAGE_MASTER)
730 : {
731 170 : nStart = 0;
732 170 : sal_Int32 nIndex = 0;
733 : rtl::Reference< XMLPropertySetMapper > aPropMapper =
734 170 : rFamily.mxMapper->getPropertySetMapper();
735 : sal_Int16 nContextID;
736 16150 : while(nIndex < aPropMapper->GetEntryCount() && nEnd == -1)
737 : {
738 15810 : nContextID = aPropMapper->GetEntryContextId( nIndex );
739 15810 : if (nContextID && ((nContextID & CTF_PM_FLAGMASK) != XML_PM_CTF_START))
740 170 : nEnd = nIndex;
741 15810 : nIndex++;
742 : }
743 170 : if (nEnd == -1)
744 0 : nEnd = nIndex;
745 : }
746 :
747 : rFamily.mxMapper->exportXML(
748 7074 : GetExport(),
749 7074 : aExpStyles[i].mpProperties->GetProperties(),
750 14148 : nStart, nEnd, XML_EXPORT_FLAG_IGN_WS, bExtensionNamespace );
751 :
752 : pAntiImpl->exportStyleContent(
753 7074 : GetExport().GetDocHandler(),
754 : nFamily,
755 7074 : aExpStyles[i].mpProperties->GetProperties(),
756 7074 : *rFamily.mxMapper.get(),
757 7074 : GetExport().GetMM100UnitConverter(),
758 7074 : GetExport().GetNamespaceMap()
759 21222 : );
760 : }
761 998 : }
762 : }
763 :
764 14 : void SvXMLAutoStylePoolP_Impl::ClearEntries()
765 : {
766 70 : for (FamilySetType::iterator aI = maFamilySet.begin(); aI != maFamilySet.end(); ++aI)
767 56 : aI->ClearEntries();
768 14 : }
769 :
770 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|