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 <com/sun/star/container/XNameContainer.hpp>
21 : #include <com/sun/star/xml/AttributeData.hpp>
22 : #include <com/sun/star/beans/XPropertyState.hpp>
23 : #include <com/sun/star/beans/XMultiPropertySet.hpp>
24 : #include <com/sun/star/beans/XTolerantMultiPropertySet.hpp>
25 : #include <com/sun/star/beans/TolerantPropertySetResultType.hpp>
26 : #include <rtl/ustrbuf.hxx>
27 : #include <list>
28 : #include <map>
29 :
30 : #include <xmloff/xmlexppr.hxx>
31 : #include <xmloff/xmltoken.hxx>
32 : #include <xmloff/attrlist.hxx>
33 : #include <xmloff/nmspmap.hxx>
34 : #include <xmloff/xmlnmspe.hxx>
35 : #include <xmloff/xmlexp.hxx>
36 : #include <xmloff/xmlprmap.hxx>
37 : #include <xmloff/maptype.hxx>
38 : #include <xmloff/xmltypes.hxx>
39 : #include <xmloff/xmlprhdl.hxx>
40 :
41 : using namespace ::std;
42 : using namespace ::com::sun::star;
43 : using namespace ::com::sun::star::beans;
44 : using namespace ::com::sun::star::uno;
45 : using namespace ::com::sun::star::lang;
46 : using namespace ::xmloff::token;
47 :
48 : #define GET_PROP_TYPE( f ) static_cast<sal_uInt16>((f & XML_TYPE_PROP_MASK) >> XML_TYPE_PROP_SHIFT)
49 : #define ENTRY(t) { GET_PROP_TYPE(XML_TYPE_PROP_##t), XML_##t##_PROPERTIES }
50 :
51 : namespace {
52 :
53 : struct XMLPropTokens_Impl
54 : {
55 : sal_uInt16 nType;
56 : XMLTokenEnum eToken;
57 : };
58 :
59 : const sal_uInt16 MAX_PROP_TYPES =
60 : (XML_TYPE_PROP_END >> XML_TYPE_PROP_SHIFT) -
61 : (XML_TYPE_PROP_START >> XML_TYPE_PROP_SHIFT);
62 :
63 : XMLPropTokens_Impl aPropTokens[MAX_PROP_TYPES] =
64 : {
65 : ENTRY(CHART),
66 : ENTRY(GRAPHIC),
67 : ENTRY(TABLE),
68 : ENTRY(TABLE_COLUMN),
69 : ENTRY(TABLE_ROW),
70 : ENTRY(TABLE_CELL),
71 : ENTRY(LIST_LEVEL),
72 : ENTRY(PARAGRAPH),
73 : ENTRY(TEXT),
74 : ENTRY(DRAWING_PAGE),
75 : ENTRY(PAGE_LAYOUT),
76 : ENTRY(HEADER_FOOTER),
77 : ENTRY(RUBY),
78 : ENTRY(SECTION)
79 : };
80 :
81 : // public methods
82 :
83 : // Take all properties of the XPropertySet which are also found in the
84 : // XMLPropertyMapEntry-array and which are not set to their default-value,
85 : // if a state is available.
86 : // After that I call the method 'ContextFilter'.
87 :
88 : typedef std::list<XMLPropertyState> XMLPropertyStateList_Impl;
89 :
90 24816 : class XMLPropertyStates_Impl
91 : {
92 : XMLPropertyStateList_Impl aPropStates;
93 : XMLPropertyStateList_Impl::iterator aLastItr;
94 : sal_uInt32 nCount;
95 : public:
96 : XMLPropertyStates_Impl();
97 : void AddPropertyState(const XMLPropertyState& rPropState);
98 : void FillPropertyStateVector(std::vector<XMLPropertyState>& rVector);
99 : };
100 :
101 24816 : XMLPropertyStates_Impl::XMLPropertyStates_Impl() :
102 : aPropStates(),
103 24816 : nCount(0)
104 : {
105 24816 : aLastItr = aPropStates.begin();
106 24816 : }
107 :
108 210262 : void XMLPropertyStates_Impl::AddPropertyState(
109 : const XMLPropertyState& rPropState)
110 : {
111 210262 : XMLPropertyStateList_Impl::iterator aItr = aPropStates.begin();
112 210262 : bool bInserted(false);
113 210262 : if (nCount)
114 : {
115 193228 : if (aLastItr->mnIndex < rPropState.mnIndex)
116 120936 : aItr = ++aLastItr;
117 : }
118 1227226 : do
119 : {
120 : // TODO: one path required only
121 508482 : if (aItr == aPropStates.end())
122 : {
123 81246 : aLastItr = aPropStates.insert(aPropStates.end(), rPropState);
124 81246 : bInserted = true;
125 81246 : nCount++;
126 : }
127 427236 : else if (aItr->mnIndex > rPropState.mnIndex)
128 : {
129 129016 : aLastItr = aPropStates.insert(aItr, rPropState);
130 129016 : bInserted = true;
131 129016 : nCount++;
132 : }
133 : }
134 1315184 : while(!bInserted && (aItr++ != aPropStates.end()));
135 210262 : }
136 :
137 24816 : void XMLPropertyStates_Impl::FillPropertyStateVector(
138 : std::vector<XMLPropertyState>& rVector)
139 : {
140 24816 : if (nCount)
141 : {
142 17034 : rVector.resize(nCount, XMLPropertyState(-1));
143 17034 : ::std::copy( aPropStates.begin(), aPropStates.end(), rVector.begin() );
144 : }
145 24816 : }
146 :
147 2831442 : class FilterPropertyInfo_Impl
148 : {
149 : const OUString sApiName;
150 : std::list<sal_uInt32> aIndexes;
151 :
152 : public:
153 :
154 : FilterPropertyInfo_Impl( const OUString& rApiName,
155 : const sal_uInt32 nIndex);
156 :
157 12328520 : const OUString& GetApiName() const { return sApiName; }
158 671880 : std::list<sal_uInt32>& GetIndexes() { return aIndexes; }
159 :
160 : // for sort
161 4757968 : bool operator< ( const FilterPropertyInfo_Impl& rArg ) const
162 : {
163 4757968 : return (GetApiName() < rArg.GetApiName());
164 : }
165 : };
166 :
167 943840 : FilterPropertyInfo_Impl::FilterPropertyInfo_Impl(
168 : const OUString& rApiName,
169 : const sal_uInt32 nIndex ) :
170 943840 : sApiName( rApiName )
171 : {
172 943840 : aIndexes.push_back(nIndex);
173 943840 : }
174 :
175 : typedef std::list<FilterPropertyInfo_Impl> FilterPropertyInfoList_Impl;
176 :
177 : class FilterPropertiesInfo_Impl
178 : {
179 : sal_uInt32 nCount;
180 : FilterPropertyInfoList_Impl aPropInfos;
181 : FilterPropertyInfoList_Impl::iterator aLastItr;
182 :
183 : Sequence <OUString> *pApiNames;
184 :
185 : public:
186 : FilterPropertiesInfo_Impl();
187 : ~FilterPropertiesInfo_Impl();
188 :
189 : void AddProperty(const OUString& rApiName, const sal_uInt32 nIndex);
190 : const uno::Sequence<OUString>& GetApiNames();
191 : void FillPropertyStateArray(
192 : vector< XMLPropertyState >& rPropStates,
193 : const Reference< XPropertySet >& xPropSet,
194 : const rtl::Reference< XMLPropertySetMapper >& maPropMapper,
195 : const bool bDefault = false);
196 24868 : sal_uInt32 GetPropertyCount() const { return nCount; }
197 : };
198 :
199 10484 : FilterPropertiesInfo_Impl::FilterPropertiesInfo_Impl() :
200 : nCount(0),
201 : aPropInfos(),
202 10484 : pApiNames( 0 )
203 : {
204 10484 : aLastItr = aPropInfos.begin();
205 10484 : }
206 :
207 20956 : FilterPropertiesInfo_Impl::~FilterPropertiesInfo_Impl()
208 : {
209 10478 : delete pApiNames;
210 10478 : }
211 :
212 943840 : void FilterPropertiesInfo_Impl::AddProperty(
213 : const OUString& rApiName, const sal_uInt32 nIndex)
214 : {
215 943840 : aPropInfos.push_back(FilterPropertyInfo_Impl(rApiName, nIndex));
216 943840 : nCount++;
217 :
218 : OSL_ENSURE( !pApiNames, "performance warning: API names already retrieved" );
219 943840 : if( pApiNames )
220 : {
221 0 : delete pApiNames;
222 0 : pApiNames = NULL;
223 : }
224 943840 : }
225 :
226 24816 : const uno::Sequence<OUString>& FilterPropertiesInfo_Impl::GetApiNames()
227 : {
228 : OSL_ENSURE(nCount == aPropInfos.size(), "wrong property count");
229 24816 : if( !pApiNames )
230 : {
231 : // we have to do three things:
232 : // 1) sort API names,
233 : // 2) merge duplicates,
234 : // 3) construct sequence
235 :
236 : // sort names
237 10464 : aPropInfos.sort();
238 :
239 : // merge duplicates
240 10464 : if ( nCount > 1 )
241 : {
242 10318 : FilterPropertyInfoList_Impl::iterator aOld = aPropInfos.begin();
243 10318 : FilterPropertyInfoList_Impl::iterator aEnd = aPropInfos.end();
244 10318 : FilterPropertyInfoList_Impl::iterator aCurrent = aOld;
245 10318 : ++aCurrent;
246 :
247 954012 : while ( aCurrent != aEnd )
248 : {
249 : // equal to next element?
250 933376 : if ( aOld->GetApiName().equals( aCurrent->GetApiName() ) )
251 : {
252 : // if equal: merge index lists
253 200814 : aOld->GetIndexes().merge( aCurrent->GetIndexes() );
254 : // erase element, and continue with next
255 200814 : aCurrent = aPropInfos.erase( aCurrent );
256 200814 : nCount--;
257 : }
258 : else
259 : {
260 : // remember old element and continue with next
261 732562 : aOld = aCurrent;
262 732562 : ++aCurrent;
263 : }
264 : }
265 : }
266 :
267 : // construct sequence
268 10464 : pApiNames = new Sequence < OUString >( nCount );
269 10464 : OUString *pNames = pApiNames->getArray();
270 10464 : FilterPropertyInfoList_Impl::iterator aItr = aPropInfos.begin();
271 10464 : FilterPropertyInfoList_Impl::iterator aEnd = aPropInfos.end();
272 753490 : for ( ; aItr != aEnd; ++aItr, ++pNames)
273 743026 : *pNames = aItr->GetApiName();
274 : }
275 :
276 24816 : return *pApiNames;
277 : }
278 :
279 24816 : void FilterPropertiesInfo_Impl::FillPropertyStateArray(
280 : vector< XMLPropertyState >& rPropStates,
281 : const Reference< XPropertySet >& rPropSet,
282 : const rtl::Reference< XMLPropertySetMapper >& rPropMapper,
283 : const bool bDefault )
284 : {
285 24816 : XMLPropertyStates_Impl aPropStates;
286 :
287 24816 : const uno::Sequence<OUString>& rApiNames = GetApiNames();
288 :
289 49632 : Reference < XTolerantMultiPropertySet > xTolPropSet( rPropSet, UNO_QUERY );
290 24816 : if (xTolPropSet.is())
291 : {
292 4900 : if (!bDefault)
293 : {
294 4900 : Sequence < beans::GetDirectPropertyTolerantResult > aResults(xTolPropSet->getDirectPropertyValuesTolerant(rApiNames));
295 4900 : sal_Int32 nResultCount(aResults.getLength());
296 4900 : if (nResultCount > 0)
297 : {
298 562 : const beans::GetDirectPropertyTolerantResult *pResults = aResults.getConstArray();
299 562 : FilterPropertyInfoList_Impl::iterator aPropIter(aPropInfos.begin());
300 562 : XMLPropertyState aNewProperty( -1 );
301 562 : sal_uInt32 i = 0;
302 20652 : while (nResultCount > 0 && i < nCount)
303 : {
304 19528 : if (pResults->Name == aPropIter->GetApiName())
305 : {
306 1416 : aNewProperty.mnIndex = -1;
307 1416 : aNewProperty.maValue = pResults->Value;
308 :
309 9078 : for( std::list<sal_uInt32>::iterator aIndexItr(aPropIter->GetIndexes().begin());
310 6052 : aIndexItr != aPropIter->GetIndexes().end();
311 : ++aIndexItr )
312 : {
313 1610 : aNewProperty.mnIndex = *aIndexItr;
314 1610 : aPropStates.AddPropertyState( aNewProperty );
315 : }
316 1416 : ++pResults;
317 1416 : --nResultCount;
318 : }
319 19528 : ++aPropIter;
320 19528 : ++i;
321 562 : }
322 4900 : }
323 : }
324 : else
325 : {
326 0 : Sequence < beans::GetPropertyTolerantResult > aResults(xTolPropSet->getPropertyValuesTolerant(rApiNames));
327 : OSL_ENSURE( rApiNames.getLength() == aResults.getLength(), "wrong implemented XTolerantMultiPropertySet" );
328 0 : const beans::GetPropertyTolerantResult *pResults = aResults.getConstArray();
329 0 : FilterPropertyInfoList_Impl::iterator aPropIter(aPropInfos.begin());
330 0 : XMLPropertyState aNewProperty( -1 );
331 0 : sal_uInt32 nResultCount(aResults.getLength());
332 : OSL_ENSURE( nCount == nResultCount, "wrong implemented XTolerantMultiPropertySet??" );
333 0 : for( sal_uInt32 i = 0; i < nResultCount; ++i )
334 : {
335 0 : if ((pResults->Result == beans::TolerantPropertySetResultType::SUCCESS) &&
336 0 : ((pResults->State == PropertyState_DIRECT_VALUE) || (pResults->State == PropertyState_DEFAULT_VALUE)))
337 : {
338 0 : aNewProperty.mnIndex = -1;
339 0 : aNewProperty.maValue = pResults->Value;
340 :
341 0 : for( std::list<sal_uInt32>::iterator aIndexItr(aPropIter->GetIndexes().begin());
342 0 : aIndexItr != aPropIter->GetIndexes().end();
343 : ++aIndexItr )
344 : {
345 0 : aNewProperty.mnIndex = *aIndexItr;
346 0 : aPropStates.AddPropertyState( aNewProperty );
347 : }
348 : }
349 0 : ++pResults;
350 0 : ++aPropIter;
351 0 : }
352 : }
353 : }
354 : else
355 : {
356 19916 : Sequence < PropertyState > aStates;
357 19916 : const PropertyState *pStates = 0;
358 39832 : Reference< XPropertyState > xPropState( rPropSet, UNO_QUERY );
359 19916 : if( xPropState.is() )
360 : {
361 19880 : aStates = xPropState->getPropertyStates( rApiNames );
362 19880 : pStates = aStates.getConstArray();
363 : }
364 :
365 39832 : Reference < XMultiPropertySet > xMultiPropSet( rPropSet, UNO_QUERY );
366 19916 : if( xMultiPropSet.is() && !bDefault )
367 : {
368 18828 : Sequence < Any > aValues;
369 18828 : if( pStates )
370 : {
371 : // step 1: get value count
372 18792 : sal_uInt32 nValueCount = 0;
373 : sal_uInt32 i;
374 :
375 1232538 : for( i = 0; i < nCount; ++i, ++pStates )
376 : {
377 1213746 : if( (*pStates == PropertyState_DIRECT_VALUE)/* || (bDefault && (*pStates == PropertyState_DEFAULT_VALUE))*/ )
378 169356 : nValueCount++;
379 : }
380 :
381 18792 : if( nValueCount )
382 : {
383 : // step 2: collect property names
384 15484 : Sequence < OUString > aAPINames( nValueCount );
385 15484 : OUString *pAPINames = aAPINames.getArray();
386 :
387 30968 : ::std::vector< FilterPropertyInfoList_Impl::iterator > aPropIters;
388 15484 : aPropIters.reserve( nValueCount );
389 :
390 15484 : FilterPropertyInfoList_Impl::iterator aItr = aPropInfos.begin();
391 : OSL_ENSURE(aItr != aPropInfos.end(),"Invalid iterator!");
392 :
393 15484 : pStates = aStates.getConstArray();
394 15484 : i = 0;
395 961762 : while( i < nValueCount )
396 : {
397 930794 : if( (*pStates == PropertyState_DIRECT_VALUE)/* || (bDefault && (*pStates == PropertyState_DEFAULT_VALUE))*/ )
398 : {
399 169356 : *pAPINames++ = aItr->GetApiName();
400 169356 : aPropIters.push_back( aItr );
401 169356 : ++i;
402 : }
403 930794 : ++aItr;
404 930794 : ++pStates;
405 : }
406 :
407 15484 : aValues = xMultiPropSet->getPropertyValues( aAPINames );
408 15484 : const Any *pValues = aValues.getConstArray();
409 :
410 : ::std::vector< FilterPropertyInfoList_Impl::iterator >::const_iterator
411 15484 : pPropIter = aPropIters.begin();
412 :
413 30968 : XMLPropertyState aNewProperty( -1 );
414 184840 : for( i = 0; i < nValueCount; ++i )
415 : {
416 169356 : aNewProperty.mnIndex = -1;
417 169356 : aNewProperty.maValue = *pValues;
418 :
419 169356 : const ::std::list< sal_uInt32 >& rIndexes( (*pPropIter)->GetIndexes() );
420 1077582 : for ( std::list<sal_uInt32>::const_iterator aIndexItr = rIndexes.begin();
421 718388 : aIndexItr != rIndexes.end();
422 : ++aIndexItr
423 : )
424 : {
425 189838 : aNewProperty.mnIndex = *aIndexItr;
426 189838 : aPropStates.AddPropertyState( aNewProperty );
427 : }
428 :
429 169356 : ++pPropIter;
430 169356 : ++pValues;
431 15484 : }
432 : }
433 : }
434 : else
435 : {
436 36 : aValues = xMultiPropSet->getPropertyValues( rApiNames );
437 36 : const Any *pValues = aValues.getConstArray();
438 :
439 36 : FilterPropertyInfoList_Impl::iterator aItr = aPropInfos.begin();
440 180 : for(sal_uInt32 i = 0; i < nCount; ++i)
441 : {
442 : // The value is stored in the PropertySet itself, add to list.
443 144 : XMLPropertyState aNewProperty( -1 );
444 144 : aNewProperty.maValue = *pValues;
445 144 : ++pValues;
446 864 : for( std::list<sal_uInt32>::iterator aIndexItr =
447 144 : aItr->GetIndexes().begin();
448 576 : aIndexItr != aItr->GetIndexes().end();
449 : ++aIndexItr )
450 : {
451 144 : aNewProperty.mnIndex = *aIndexItr;
452 144 : aPropStates.AddPropertyState( aNewProperty );
453 : }
454 144 : ++aItr;
455 144 : }
456 18828 : }
457 : }
458 : else
459 : {
460 1088 : FilterPropertyInfoList_Impl::iterator aItr = aPropInfos.begin();
461 103594 : for(sal_uInt32 i = 0; i < nCount; ++i)
462 : {
463 : bool bDirectValue =
464 102506 : !pStates || *pStates == PropertyState_DIRECT_VALUE;
465 102506 : if( bDirectValue || bDefault )
466 : {
467 : // The value is stored in the PropertySet itself, add to list.
468 29230 : bool bGotValue = false;
469 29230 : XMLPropertyState aNewProperty( -1 );
470 200376 : for( std::list<sal_uInt32>::const_iterator aIndexItr =
471 29230 : aItr->GetIndexes().begin();
472 133584 : aIndexItr != aItr->GetIndexes().end();
473 : ++aIndexItr )
474 : {
475 56980 : if( bDirectValue ||
476 19418 : (rPropMapper->GetEntryFlags( *aIndexItr ) &
477 : MID_FLAG_DEFAULT_ITEM_EXPORT) != 0 )
478 : {
479 : try
480 : {
481 18670 : if( !bGotValue )
482 : {
483 27844 : aNewProperty.maValue =
484 27844 : rPropSet->getPropertyValue( aItr->GetApiName() );
485 13922 : bGotValue = true;
486 : }
487 18670 : aNewProperty.mnIndex = *aIndexItr;
488 18670 : aPropStates.AddPropertyState( aNewProperty );
489 : }
490 0 : catch( UnknownPropertyException& )
491 : {
492 : // might be a problem of getImplemenetationId
493 : OSL_ENSURE( false, "unknown property in getPropertyValue" );
494 : }
495 :
496 : }
497 29230 : }
498 : }
499 :
500 102506 : ++aItr;
501 102506 : if( pStates )
502 102506 : ++pStates;
503 : }
504 19916 : }
505 : }
506 49632 : aPropStates.FillPropertyStateVector(rPropStates);
507 24816 : }
508 :
509 : }
510 :
511 24086 : struct SvXMLExportPropertyMapper::Impl
512 : {
513 : typedef std::map<css::uno::Reference<css::beans::XPropertySetInfo>, FilterPropertiesInfo_Impl*> CacheType;
514 : CacheType maCache;
515 :
516 : rtl::Reference<SvXMLExportPropertyMapper> mxNextMapper;
517 : rtl::Reference<XMLPropertySetMapper> mxPropMapper;
518 :
519 : OUString maStyleName;
520 :
521 24056 : ~Impl()
522 24056 : {
523 24056 : CacheType::iterator it = maCache.begin(), itEnd = maCache.end();
524 34470 : for (; it != itEnd; ++it)
525 10414 : delete it->second;
526 24056 : }
527 : };
528 :
529 : // ctor/dtor , class SvXMLExportPropertyMapper
530 :
531 24086 : SvXMLExportPropertyMapper::SvXMLExportPropertyMapper(
532 : const rtl::Reference< XMLPropertySetMapper >& rMapper ) :
533 24086 : mpImpl(new Impl)
534 : {
535 24086 : mpImpl->mxPropMapper = rMapper;
536 24086 : }
537 :
538 52072 : SvXMLExportPropertyMapper::~SvXMLExportPropertyMapper()
539 : {
540 24056 : delete mpImpl;
541 28016 : }
542 :
543 4684 : void SvXMLExportPropertyMapper::ChainExportMapper(
544 : const rtl::Reference< SvXMLExportPropertyMapper>& rMapper )
545 : {
546 : // add map entries from rMapper to current map
547 4684 : mpImpl->mxPropMapper->AddMapperEntry( rMapper->getPropertySetMapper() );
548 : // rMapper uses the same map as 'this'
549 4684 : rMapper->mpImpl->mxPropMapper = mpImpl->mxPropMapper;
550 :
551 : // set rMapper as last mapper in current chain
552 4684 : rtl::Reference< SvXMLExportPropertyMapper > xNext = mpImpl->mxNextMapper;
553 4684 : if( xNext.is())
554 : {
555 3476 : while (xNext->mpImpl->mxNextMapper.is())
556 0 : xNext = xNext->mpImpl->mxNextMapper;
557 1738 : xNext->mpImpl->mxNextMapper = rMapper;
558 : }
559 : else
560 2946 : mpImpl->mxNextMapper = rMapper;
561 :
562 : // if rMapper was already chained, correct
563 : // map pointer of successors
564 4684 : xNext = rMapper;
565 :
566 9368 : while (xNext->mpImpl->mxNextMapper.is())
567 : {
568 0 : xNext = xNext->mpImpl->mxNextMapper;
569 0 : xNext->mpImpl->mxPropMapper = mpImpl->mxPropMapper;
570 4684 : }
571 4684 : }
572 :
573 24486 : std::vector<XMLPropertyState> SvXMLExportPropertyMapper::Filter(
574 : const uno::Reference<beans::XPropertySet>& rPropSet, bool bEnableFoFontFamily ) const
575 : {
576 24486 : return _Filter(rPropSet, false, bEnableFoFontFamily);
577 : }
578 :
579 382 : std::vector<XMLPropertyState> SvXMLExportPropertyMapper::FilterDefaults(
580 : const uno::Reference<beans::XPropertySet>& rPropSet, bool bEnableFoFontFamily ) const
581 : {
582 382 : return _Filter(rPropSet, true, bEnableFoFontFamily);
583 : }
584 :
585 24868 : vector<XMLPropertyState> SvXMLExportPropertyMapper::_Filter(
586 : const Reference<XPropertySet>& xPropSet, bool bDefault, bool bEnableFoFontFamily ) const
587 : {
588 24868 : vector< XMLPropertyState > aPropStateArray;
589 :
590 : // Retrieve XPropertySetInfo and XPropertyState
591 49736 : Reference< XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo() );
592 24868 : if( !xInfo.is() )
593 0 : return aPropStateArray;
594 :
595 24868 : sal_Int32 nProps = mpImpl->mxPropMapper->GetEntryCount();
596 :
597 24868 : FilterPropertiesInfo_Impl *pFilterInfo = 0;
598 :
599 24868 : Impl::CacheType::iterator aIter = mpImpl->maCache.find(xInfo);
600 24868 : if (aIter != mpImpl->maCache.end())
601 14384 : pFilterInfo = (*aIter).second;
602 :
603 24868 : bool bDelInfo = false;
604 24868 : if( !pFilterInfo )
605 : {
606 10484 : const SvtSaveOptions::ODFDefaultVersion nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
607 10484 : pFilterInfo = new FilterPropertiesInfo_Impl;
608 4101912 : for( sal_Int32 i=0; i < nProps; i++ )
609 : {
610 : // Are we allowed to ask for the property? (MID_FLAG_NO_PROP..)
611 : // Does the PropertySet contain name of mpEntries-array ?
612 4091428 : const OUString& rAPIName = mpImpl->mxPropMapper->GetEntryAPIName( i );
613 4091428 : const sal_Int32 nFlags = mpImpl->mxPropMapper->GetEntryFlags( i );
614 9079936 : if( (0 == (nFlags & MID_FLAG_NO_PROPERTY_EXPORT)) &&
615 8089336 : ( (0 != (nFlags & MID_FLAG_MUST_EXIST)) ||
616 4044668 : xInfo->hasPropertyByName( rAPIName ) ) )
617 : {
618 : const SvtSaveOptions::ODFDefaultVersion nEarliestODFVersionForExport(
619 943840 : mpImpl->mxPropMapper->GetEarliestODFVersionForExport(i));
620 943840 : if( nCurrentVersion >= nEarliestODFVersionForExport
621 0 : || nCurrentVersion == SvtSaveOptions::ODFVER_UNKNOWN
622 0 : || nEarliestODFVersionForExport == SvtSaveOptions::ODFVER_UNKNOWN )
623 943840 : pFilterInfo->AddProperty(rAPIName, i);
624 : }
625 : }
626 :
627 : // Check whether the property set info is destroyed if it is assigned to
628 : // a weak reference only; If it is destroyed, then every instance of
629 : // getPropertySetInfo returns a new object; such property set infos must
630 : // not be cached:
631 10484 : WeakReference < XPropertySetInfo > xWeakInfo( xInfo );
632 10484 : xInfo = 0;
633 10484 : xInfo = xWeakInfo;
634 10484 : if( xInfo.is() )
635 : {
636 10420 : mpImpl->maCache.insert(Impl::CacheType::value_type(xInfo, pFilterInfo));
637 : }
638 : else
639 64 : bDelInfo = true;
640 : }
641 :
642 24868 : if( pFilterInfo->GetPropertyCount() )
643 : {
644 : try
645 : {
646 : pFilterInfo->FillPropertyStateArray(
647 24816 : aPropStateArray, xPropSet, mpImpl->mxPropMapper, bDefault);
648 : }
649 0 : catch( UnknownPropertyException& )
650 : {
651 : // might be a problem of getImplemenetationId
652 : OSL_ENSURE( false, "unknown property in getPropertyStates" );
653 : }
654 : }
655 :
656 : // Call centext-filter
657 24868 : if( !aPropStateArray.empty() )
658 17034 : ContextFilter(bEnableFoFontFamily, aPropStateArray, xPropSet);
659 :
660 : // Have to do if we change from a vector to a list or something like that
661 :
662 24868 : if( bDelInfo )
663 64 : delete pFilterInfo;
664 :
665 24868 : return aPropStateArray;
666 : }
667 :
668 46142 : void SvXMLExportPropertyMapper::ContextFilter(
669 : bool bEnableFoFontFamily,
670 : vector< XMLPropertyState >& rProperties,
671 : Reference< XPropertySet > rPropSet ) const
672 : {
673 : // Derived class could implement this.
674 46142 : if (mpImpl->mxNextMapper.is())
675 29222 : mpImpl->mxNextMapper->ContextFilter(bEnableFoFontFamily, rProperties, rPropSet);
676 46142 : }
677 :
678 : // Compares two Sequences of XMLPropertyState:
679 : // 1.Number of elements equal ?
680 : // 2.Index of each element equal ? (So I know whether the propertynames are the same)
681 : // 3.Value of each element equal ?
682 5600 : bool SvXMLExportPropertyMapper::Equals(
683 : const vector< XMLPropertyState >& aProperties1,
684 : const vector< XMLPropertyState >& aProperties2 ) const
685 : {
686 5600 : bool bRet = true;
687 5600 : sal_uInt32 nCount = aProperties1.size();
688 :
689 5600 : if( nCount == aProperties2.size() )
690 : {
691 5600 : sal_uInt32 nIndex = 0;
692 36458 : while( bRet && nIndex < nCount )
693 : {
694 25258 : const XMLPropertyState& rProp1 = aProperties1[ nIndex ];
695 25258 : const XMLPropertyState& rProp2 = aProperties2[ nIndex ];
696 :
697 : // Compare index. If equal, compare value
698 25258 : if( rProp1.mnIndex == rProp2.mnIndex )
699 : {
700 23676 : if( rProp1.mnIndex != -1 )
701 : {
702 : // Now compare values
703 20610 : if ( (mpImpl->mxPropMapper->GetEntryType( rProp1.mnIndex ) &
704 : XML_TYPE_BUILDIN_CMP ) != 0 )
705 : // simple type ( binary compare )
706 11588 : bRet = ( rProp1.maValue == rProp2.maValue );
707 : else
708 : // complex type ( ask for compare-function )
709 : bRet = mpImpl->mxPropMapper->GetPropertyHandler(
710 9022 : rProp1.mnIndex )->equals( rProp1.maValue,
711 9022 : rProp2.maValue );
712 : }
713 : }
714 : else
715 1582 : bRet = false;
716 :
717 25258 : nIndex++;
718 : }
719 : }
720 : else
721 0 : bRet = false;
722 :
723 5600 : return bRet;
724 : }
725 :
726 : /** fills the given attribute list with the items in the given set
727 : void SvXMLExportPropertyMapper::exportXML( SvXMLAttributeList& rAttrList,
728 : const ::std::vector< XMLPropertyState >& rProperties,
729 : const SvXMLUnitConverter& rUnitConverter,
730 : const SvXMLNamespaceMap& rNamespaceMap,
731 : sal_uInt16 nFlags ) const
732 : {
733 : _exportXML( rAttrList, rProperties, rUnitConverter, rNamespaceMap,
734 : nFlags, 0, -1, -1 );
735 : }
736 :
737 : void SvXMLExportPropertyMapper::exportXML( SvXMLAttributeList& rAttrList,
738 : const ::std::vector< XMLPropertyState >& rProperties,
739 : const SvXMLUnitConverter& rUnitConverter,
740 : const SvXMLNamespaceMap& rNamespaceMap,
741 : sal_Int32 nPropMapStartIdx, sal_Int32 nPropMapEndIdx,
742 : sal_uInt16 nFlags ) const
743 : {
744 : _exportXML( rAttrList, rProperties, rUnitConverter, rNamespaceMap,
745 : nFlags, 0, nPropMapStartIdx, nPropMapEndIdx );
746 : }
747 : */
748 :
749 1704 : void SvXMLExportPropertyMapper::exportXML(
750 : SvXMLExport& rExport,
751 : const ::std::vector< XMLPropertyState >& rProperties,
752 : sal_uInt16 nFlags ) const
753 : {
754 1704 : exportXML( rExport, rProperties, -1, -1, nFlags );
755 1704 : }
756 :
757 9118 : void SvXMLExportPropertyMapper::exportXML(
758 : SvXMLExport& rExport,
759 : const ::std::vector< XMLPropertyState >& rProperties,
760 : sal_Int32 nPropMapStartIdx, sal_Int32 nPropMapEndIdx,
761 : sal_uInt16 nFlags, bool bExtensionNamespace ) const
762 : {
763 9118 : sal_uInt16 nPropTypeFlags = 0;
764 136770 : for( sal_uInt16 i=0; i<MAX_PROP_TYPES; ++i )
765 : {
766 127652 : sal_uInt16 nPropType = aPropTokens[i].nType;
767 127652 : if( 0==i || (nPropTypeFlags & (1 << nPropType)) != 0 )
768 : {
769 21730 : std::vector<sal_uInt16> aIndexArray;
770 :
771 : _exportXML( nPropType, nPropTypeFlags,
772 21730 : rExport.GetAttrList(), rProperties,
773 21730 : rExport.GetMM100UnitConverter(),
774 21730 : rExport.GetNamespaceMap(),
775 : nFlags, &aIndexArray,
776 43460 : nPropMapStartIdx, nPropMapEndIdx );
777 :
778 48544 : if( rExport.GetAttrList().getLength() > 0L ||
779 26814 : (nFlags & XML_EXPORT_FLAG_EMPTY) != 0 ||
780 5084 : !aIndexArray.empty() )
781 : {
782 16658 : sal_uInt16 nNamespace = XML_NAMESPACE_STYLE;
783 16658 : if(bExtensionNamespace && aPropTokens[i].eToken ==
784 : xmloff::token::XML_GRAPHIC_PROPERTIES)
785 40 : nNamespace = XML_NAMESPACE_LO_EXT;
786 : SvXMLElementExport aElem( rExport, nNamespace,
787 : aPropTokens[i].eToken,
788 16658 : (nFlags & XML_EXPORT_FLAG_IGN_WS) != 0,
789 16658 : false );
790 :
791 16658 : exportElementItems( rExport, rProperties, nFlags, aIndexArray );
792 21730 : }
793 : }
794 : }
795 9118 : }
796 :
797 : /** this method is called for every item that has the
798 : MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
799 160 : void SvXMLExportPropertyMapper::handleSpecialItem(
800 : SvXMLAttributeList& rAttrList,
801 : const XMLPropertyState& rProperty,
802 : const SvXMLUnitConverter& rUnitConverter,
803 : const SvXMLNamespaceMap& rNamespaceMap,
804 : const ::std::vector< XMLPropertyState > *pProperties,
805 : sal_uInt32 nIdx ) const
806 : {
807 : OSL_ENSURE(mpImpl->mxNextMapper.is(), "special item not handled in xml export");
808 160 : if (mpImpl->mxNextMapper.is())
809 112 : mpImpl->mxNextMapper->handleSpecialItem(
810 112 : rAttrList, rProperty, rUnitConverter, rNamespaceMap, pProperties, nIdx);
811 160 : }
812 :
813 : /** this method is called for every item that has the
814 : MID_FLAG_ELEMENT_EXPORT flag set */
815 94 : void SvXMLExportPropertyMapper::handleElementItem(
816 : SvXMLExport& rExport,
817 : const XMLPropertyState& rProperty,
818 : sal_uInt16 nFlags,
819 : const ::std::vector< XMLPropertyState > *pProperties,
820 : sal_uInt32 nIdx ) const
821 : {
822 : OSL_ENSURE(mpImpl->mxNextMapper.is(), "element item not handled in xml export");
823 94 : if (mpImpl->mxNextMapper.is())
824 94 : mpImpl->mxNextMapper->handleElementItem(rExport, rProperty, nFlags, pProperties, nIdx);
825 94 : }
826 :
827 : // protected methods
828 :
829 : /** fills the given attribute list with the items in the given set */
830 21730 : void SvXMLExportPropertyMapper::_exportXML(
831 : sal_uInt16 nPropType, sal_uInt16& rPropTypeFlags,
832 : SvXMLAttributeList& rAttrList,
833 : const ::std::vector< XMLPropertyState >& rProperties,
834 : const SvXMLUnitConverter& rUnitConverter,
835 : const SvXMLNamespaceMap& rNamespaceMap,
836 : sal_uInt16 nFlags,
837 : std::vector<sal_uInt16>* pIndexArray,
838 : sal_Int32 nPropMapStartIdx, sal_Int32 nPropMapEndIdx ) const
839 : {
840 21730 : const sal_uInt32 nCount = rProperties.size();
841 21730 : sal_uInt32 nIndex = 0;
842 :
843 21730 : if( -1 == nPropMapStartIdx )
844 20836 : nPropMapStartIdx = 0;
845 21730 : if( -1 == nPropMapEndIdx )
846 20836 : nPropMapEndIdx = mpImpl->mxPropMapper->GetEntryCount();
847 :
848 383840 : while( nIndex < nCount )
849 : {
850 340380 : sal_Int32 nPropMapIdx = rProperties[nIndex].mnIndex;
851 340380 : if( nPropMapIdx >= nPropMapStartIdx &&
852 : nPropMapIdx < nPropMapEndIdx )// valid entry?
853 : {
854 265628 : sal_uInt32 nEFlags = mpImpl->mxPropMapper->GetEntryFlags(nPropMapIdx);
855 265628 : sal_uInt16 nEPType = GET_PROP_TYPE(nEFlags);
856 : OSL_ENSURE(nEPType >= (XML_TYPE_PROP_START >> XML_TYPE_PROP_SHIFT),
857 : "no prop type specified");
858 265628 : rPropTypeFlags |= (1 << nEPType);
859 265628 : if( nEPType == nPropType )
860 : {
861 : // we have a valid map entry here, so lets use it...
862 95006 : if( ( nEFlags & MID_FLAG_ELEMENT_ITEM_EXPORT ) != 0 )
863 : {
864 : // element items do not add any properties,
865 : // we export it later
866 1336 : if( pIndexArray )
867 : {
868 1336 : pIndexArray->push_back( (sal_uInt16)nIndex );
869 : }
870 : }
871 : else
872 : {
873 93670 : _exportXML( rAttrList, rProperties[nIndex], rUnitConverter,
874 187340 : rNamespaceMap, nFlags, &rProperties, nIndex );
875 : }
876 : }
877 : }
878 :
879 340380 : nIndex++;
880 : }
881 21730 : }
882 :
883 93670 : void SvXMLExportPropertyMapper::_exportXML(
884 : SvXMLAttributeList& rAttrList,
885 : const XMLPropertyState& rProperty,
886 : const SvXMLUnitConverter& rUnitConverter,
887 : const SvXMLNamespaceMap& rNamespaceMap,
888 : sal_uInt16 /*nFlags*/,
889 : const ::std::vector< XMLPropertyState > *pProperties,
890 : sal_uInt32 nIdx ) const
891 : {
892 93670 : if ((mpImpl->mxPropMapper->GetEntryFlags(rProperty.mnIndex) & MID_FLAG_SPECIAL_ITEM_EXPORT) != 0)
893 : {
894 6488 : uno::Reference< container::XNameContainer > xAttrContainer;
895 6488 : if( (rProperty.maValue >>= xAttrContainer) && xAttrContainer.is() )
896 : {
897 46 : SvXMLNamespaceMap *pNewNamespaceMap = 0;
898 46 : const SvXMLNamespaceMap *pNamespaceMap = &rNamespaceMap;
899 :
900 46 : uno::Sequence< OUString > aAttribNames( xAttrContainer->getElementNames() );
901 46 : const OUString* pAttribName = aAttribNames.getConstArray();
902 :
903 46 : const sal_Int32 nCount = aAttribNames.getLength();
904 :
905 92 : OUStringBuffer sNameBuffer;
906 92 : xml::AttributeData aData;
907 46 : for( sal_Int32 i=0; i < nCount; i++, pAttribName++ )
908 : {
909 0 : xAttrContainer->getByName( *pAttribName ) >>= aData;
910 0 : OUString sAttribName( *pAttribName );
911 :
912 : // extract namespace prefix from attribute name if it exists
913 0 : OUString sPrefix;
914 : const sal_Int32 nColonPos =
915 0 : pAttribName->indexOf( ':' );
916 0 : if( nColonPos != -1 )
917 0 : sPrefix = pAttribName->copy( 0, nColonPos );
918 :
919 0 : if( !sPrefix.isEmpty() )
920 : {
921 0 : OUString sNamespace( aData.Namespace );
922 :
923 : // if the prefix isn't defined yet or has another meaning,
924 : // we have to redefine it now.
925 0 : sal_uInt16 nKey = pNamespaceMap->GetKeyByPrefix( sPrefix );
926 0 : if( USHRT_MAX == nKey || pNamespaceMap->GetNameByKey( nKey ) != sNamespace )
927 : {
928 0 : bool bAddNamespace = false;
929 0 : if( USHRT_MAX == nKey )
930 : {
931 : // The prefix is unused, so it is sufficient
932 : // to add it to the namespace map.
933 0 : bAddNamespace = true;
934 : }
935 : else
936 : {
937 : // check if there is a prefix registered for the
938 : // namepsace URI
939 0 : nKey = pNamespaceMap->GetKeyByName( sNamespace );
940 0 : if( XML_NAMESPACE_UNKNOWN == nKey )
941 : {
942 : // There is no prefix for the namespace, so
943 : // we have to generate one and have to add it.
944 0 : sal_Int32 n=0;
945 0 : OUString sOrigPrefix( sPrefix );
946 0 : do
947 : {
948 0 : sNameBuffer.append( sOrigPrefix );
949 0 : sNameBuffer.append( ++n );
950 0 : sPrefix = sNameBuffer.makeStringAndClear();
951 0 : nKey = pNamespaceMap->GetKeyByPrefix( sPrefix );
952 : }
953 : while( nKey != USHRT_MAX );
954 :
955 0 : bAddNamespace = true;
956 : }
957 : else
958 : {
959 : // If there is a prefix for the namespace,
960 : // we reuse that.
961 0 : sPrefix = pNamespaceMap->GetPrefixByKey( nKey );
962 : }
963 : // In any case, the attribute name has to be adapted.
964 0 : sNameBuffer.append( sPrefix + ":" + pAttribName->copy( nColonPos+1 ) );
965 0 : sAttribName = sNameBuffer.makeStringAndClear();
966 : }
967 :
968 0 : if( bAddNamespace )
969 : {
970 0 : if( !pNewNamespaceMap )
971 : {
972 0 : pNewNamespaceMap = new SvXMLNamespaceMap( rNamespaceMap );
973 0 : pNamespaceMap = pNewNamespaceMap;
974 : }
975 0 : pNewNamespaceMap->Add( sPrefix, sNamespace );
976 0 : sNameBuffer.append( GetXMLToken(XML_XMLNS) + ":" + sPrefix );
977 : rAttrList.AddAttribute( sNameBuffer.makeStringAndClear(),
978 0 : sNamespace );
979 : }
980 0 : }
981 : }
982 0 : OUString sOldValue( rAttrList.getValueByName( sAttribName ) );
983 : OSL_ENSURE( sOldValue.isEmpty(), "alien attribute exists already" );
984 : OSL_ENSURE(aData.Type == GetXMLToken(XML_CDATA), "different type to our default type which should be written out");
985 0 : if( sOldValue.isEmpty() )
986 0 : rAttrList.AddAttribute( sAttribName, aData.Value );
987 0 : }
988 :
989 92 : delete pNewNamespaceMap;
990 : }
991 : else
992 : {
993 : handleSpecialItem( rAttrList, rProperty, rUnitConverter,
994 6442 : rNamespaceMap, pProperties, nIdx );
995 6488 : }
996 : }
997 87182 : else if ((mpImpl->mxPropMapper->GetEntryFlags(rProperty.mnIndex) & MID_FLAG_ELEMENT_ITEM_EXPORT ) == 0)
998 : {
999 87182 : OUString aValue;
1000 : const OUString sName = rNamespaceMap.GetQNameByKey(
1001 87182 : mpImpl->mxPropMapper->GetEntryNameSpace(rProperty.mnIndex),
1002 261546 : mpImpl->mxPropMapper->GetEntryXMLName(rProperty.mnIndex));
1003 :
1004 87182 : bool bRemove = false;
1005 87182 : if ((mpImpl->mxPropMapper->GetEntryFlags( rProperty.mnIndex ) & MID_FLAG_MERGE_ATTRIBUTE) != 0)
1006 : {
1007 8142 : aValue = rAttrList.getValueByName( sName );
1008 8142 : bRemove = true;
1009 : }
1010 :
1011 87182 : if (mpImpl->mxPropMapper->exportXML(aValue, rProperty, rUnitConverter))
1012 : {
1013 70658 : if( bRemove )
1014 6962 : rAttrList.RemoveAttribute( sName );
1015 70658 : rAttrList.AddAttribute( sName, aValue );
1016 87182 : }
1017 : }
1018 93670 : }
1019 :
1020 16658 : void SvXMLExportPropertyMapper::exportElementItems(
1021 : SvXMLExport& rExport,
1022 : const ::std::vector< XMLPropertyState >& rProperties,
1023 : sal_uInt16 nFlags,
1024 : const std::vector<sal_uInt16>& rIndexArray ) const
1025 : {
1026 16658 : const sal_uInt16 nCount = rIndexArray.size();
1027 :
1028 16658 : bool bItemsExported = false;
1029 17994 : for( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
1030 : {
1031 1336 : const sal_uInt16 nElement = rIndexArray[nIndex];
1032 :
1033 : OSL_ENSURE( 0 != (mpImpl->mxPropMapper->GetEntryFlags(
1034 : rProperties[nElement].mnIndex ) & MID_FLAG_ELEMENT_ITEM_EXPORT),
1035 : "wrong mid flag!" );
1036 :
1037 1336 : rExport.IgnorableWhitespace();
1038 1336 : handleElementItem( rExport, rProperties[nElement],
1039 2672 : nFlags, &rProperties, nElement );
1040 1336 : bItemsExported = true;
1041 : }
1042 :
1043 16658 : if( bItemsExported )
1044 1336 : rExport.IgnorableWhitespace();
1045 16658 : }
1046 :
1047 572412 : const rtl::Reference<XMLPropertySetMapper>& SvXMLExportPropertyMapper::getPropertySetMapper() const
1048 : {
1049 572412 : return mpImpl->mxPropMapper;
1050 : }
1051 :
1052 2736 : void SvXMLExportPropertyMapper::SetStyleName( const OUString& rStyleName )
1053 : {
1054 2736 : mpImpl->maStyleName = rStyleName;
1055 2736 : }
1056 :
1057 40 : const OUString& SvXMLExportPropertyMapper::GetStyleName() const
1058 : {
1059 40 : return mpImpl->maStyleName;
1060 : }
1061 :
1062 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|