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 17194 : 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 17194 : XMLPropertyStates_Impl::XMLPropertyStates_Impl() :
102 : aPropStates(),
103 17194 : nCount(0)
104 : {
105 17194 : aLastItr = aPropStates.begin();
106 17194 : }
107 :
108 134301 : void XMLPropertyStates_Impl::AddPropertyState(
109 : const XMLPropertyState& rPropState)
110 : {
111 134301 : XMLPropertyStateList_Impl::iterator aItr = aPropStates.begin();
112 134301 : bool bInserted(false);
113 134301 : if (nCount)
114 : {
115 123035 : if (aLastItr->mnIndex < rPropState.mnIndex)
116 79506 : aItr = ++aLastItr;
117 : }
118 828067 : do
119 : {
120 : // TODO: one path required only
121 346883 : if (aItr == aPropStates.end())
122 : {
123 50898 : aLastItr = aPropStates.insert(aPropStates.end(), rPropState);
124 50898 : bInserted = true;
125 50898 : nCount++;
126 : }
127 295985 : else if (aItr->mnIndex > rPropState.mnIndex)
128 : {
129 83403 : aLastItr = aPropStates.insert(aItr, rPropState);
130 83403 : bInserted = true;
131 83403 : nCount++;
132 : }
133 : }
134 906348 : while(!bInserted && (aItr++ != aPropStates.end()));
135 134301 : }
136 :
137 17194 : void XMLPropertyStates_Impl::FillPropertyStateVector(
138 : std::vector<XMLPropertyState>& rVector)
139 : {
140 17194 : if (nCount)
141 : {
142 11266 : rVector.resize(nCount, XMLPropertyState(-1));
143 11266 : ::std::copy( aPropStates.begin(), aPropStates.end(), rVector.begin() );
144 : }
145 17194 : }
146 :
147 1700676 : 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 7570334 : const OUString& GetApiName() const { return sApiName; }
158 458115 : std::list<sal_uInt32>& GetIndexes() { return aIndexes; }
159 :
160 : // for sort
161 2904583 : bool operator< ( const FilterPropertyInfo_Impl& rArg ) const
162 : {
163 2904583 : return (GetApiName() < rArg.GetApiName());
164 : }
165 : };
166 :
167 566905 : FilterPropertyInfo_Impl::FilterPropertyInfo_Impl(
168 : const OUString& rApiName,
169 : const sal_uInt32 nIndex ) :
170 566905 : sApiName( rApiName )
171 : {
172 566905 : aIndexes.push_back(nIndex);
173 566905 : }
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 17244 : sal_uInt32 GetPropertyCount() const { return nCount; }
197 : };
198 :
199 6104 : FilterPropertiesInfo_Impl::FilterPropertiesInfo_Impl() :
200 : nCount(0),
201 : aPropInfos(),
202 6104 : pApiNames( 0 )
203 : {
204 6104 : aLastItr = aPropInfos.begin();
205 6104 : }
206 :
207 12202 : FilterPropertiesInfo_Impl::~FilterPropertiesInfo_Impl()
208 : {
209 6101 : delete pApiNames;
210 6101 : }
211 :
212 566905 : void FilterPropertiesInfo_Impl::AddProperty(
213 : const OUString& rApiName, const sal_uInt32 nIndex)
214 : {
215 566905 : aPropInfos.push_back(FilterPropertyInfo_Impl(rApiName, nIndex));
216 566905 : nCount++;
217 :
218 : OSL_ENSURE( !pApiNames, "performance warning: API names already retrieved" );
219 566905 : if( pApiNames )
220 : {
221 0 : delete pApiNames;
222 0 : pApiNames = NULL;
223 : }
224 566905 : }
225 :
226 17194 : const uno::Sequence<OUString>& FilterPropertiesInfo_Impl::GetApiNames()
227 : {
228 : OSL_ENSURE(nCount == aPropInfos.size(), "wrong property count");
229 17194 : 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 6090 : aPropInfos.sort();
238 :
239 : // merge duplicates
240 6090 : if ( nCount > 1 )
241 : {
242 5907 : FilterPropertyInfoList_Impl::iterator aOld = aPropInfos.begin();
243 5907 : FilterPropertyInfoList_Impl::iterator aEnd = aPropInfos.end();
244 5907 : FilterPropertyInfoList_Impl::iterator aCurrent = aOld;
245 5907 : ++aCurrent;
246 :
247 572629 : while ( aCurrent != aEnd )
248 : {
249 : // equal to next element?
250 560815 : if ( aOld->GetApiName().equals( aCurrent->GetApiName() ) )
251 : {
252 : // if equal: merge index lists
253 122067 : aOld->GetIndexes().merge( aCurrent->GetIndexes() );
254 : // erase element, and continue with next
255 122067 : aCurrent = aPropInfos.erase( aCurrent );
256 122067 : nCount--;
257 : }
258 : else
259 : {
260 : // remember old element and continue with next
261 438748 : aOld = aCurrent;
262 438748 : ++aCurrent;
263 : }
264 : }
265 : }
266 :
267 : // construct sequence
268 6090 : pApiNames = new Sequence < OUString >( nCount );
269 6090 : OUString *pNames = pApiNames->getArray();
270 6090 : FilterPropertyInfoList_Impl::iterator aItr = aPropInfos.begin();
271 6090 : FilterPropertyInfoList_Impl::iterator aEnd = aPropInfos.end();
272 450928 : for ( ; aItr != aEnd; ++aItr, ++pNames)
273 444838 : *pNames = aItr->GetApiName();
274 : }
275 :
276 17194 : return *pApiNames;
277 : }
278 :
279 17194 : 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 17194 : XMLPropertyStates_Impl aPropStates;
286 :
287 17194 : const uno::Sequence<OUString>& rApiNames = GetApiNames();
288 :
289 34388 : Reference < XTolerantMultiPropertySet > xTolPropSet( rPropSet, UNO_QUERY );
290 17194 : if (xTolPropSet.is())
291 : {
292 4078 : if (!bDefault)
293 : {
294 4078 : Sequence < beans::GetDirectPropertyTolerantResult > aResults(xTolPropSet->getDirectPropertyValuesTolerant(rApiNames));
295 4078 : sal_Int32 nResultCount(aResults.getLength());
296 4078 : if (nResultCount > 0)
297 : {
298 1148 : const beans::GetDirectPropertyTolerantResult *pResults = aResults.getConstArray();
299 1148 : FilterPropertyInfoList_Impl::iterator aPropIter(aPropInfos.begin());
300 1148 : XMLPropertyState aNewProperty( -1 );
301 1148 : sal_uInt32 i = 0;
302 85258 : while (nResultCount > 0 && i < nCount)
303 : {
304 82962 : if (pResults->Name == aPropIter->GetApiName())
305 : {
306 4228 : aNewProperty.mnIndex = -1;
307 4228 : aNewProperty.maValue = pResults->Value;
308 :
309 27429 : for( std::list<sal_uInt32>::iterator aIndexItr(aPropIter->GetIndexes().begin());
310 18286 : aIndexItr != aPropIter->GetIndexes().end();
311 : ++aIndexItr )
312 : {
313 4915 : aNewProperty.mnIndex = *aIndexItr;
314 4915 : aPropStates.AddPropertyState( aNewProperty );
315 : }
316 4228 : ++pResults;
317 4228 : --nResultCount;
318 : }
319 82962 : ++aPropIter;
320 82962 : ++i;
321 1148 : }
322 4078 : }
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 13116 : Sequence < PropertyState > aStates;
357 13116 : const PropertyState *pStates = 0;
358 26232 : Reference< XPropertyState > xPropState( rPropSet, UNO_QUERY );
359 13116 : if( xPropState.is() )
360 : {
361 13082 : aStates = xPropState->getPropertyStates( rApiNames );
362 13082 : pStates = aStates.getConstArray();
363 : }
364 :
365 26232 : Reference < XMultiPropertySet > xMultiPropSet( rPropSet, UNO_QUERY );
366 13116 : if( xMultiPropSet.is() && !bDefault )
367 : {
368 11910 : Sequence < Any > aValues;
369 11910 : if( pStates )
370 : {
371 : // step 1: get value count
372 11876 : sal_uInt32 nValueCount = 0;
373 : sal_uInt32 i;
374 :
375 833427 : for( i = 0; i < nCount; ++i, ++pStates )
376 : {
377 821551 : if( (*pStates == PropertyState_DIRECT_VALUE)/* || (bDefault && (*pStates == PropertyState_DEFAULT_VALUE))*/ )
378 97981 : nValueCount++;
379 : }
380 :
381 11876 : if( nValueCount )
382 : {
383 : // step 2: collect property names
384 9141 : Sequence < OUString > aAPINames( nValueCount );
385 9141 : OUString *pAPINames = aAPINames.getArray();
386 :
387 18282 : ::std::vector< FilterPropertyInfoList_Impl::iterator > aPropIters;
388 9141 : aPropIters.reserve( nValueCount );
389 :
390 9141 : FilterPropertyInfoList_Impl::iterator aItr = aPropInfos.begin();
391 : OSL_ENSURE(aItr != aPropInfos.end(),"Invalid iterator!");
392 :
393 9141 : pStates = aStates.getConstArray();
394 9141 : i = 0;
395 607418 : while( i < nValueCount )
396 : {
397 589136 : if( (*pStates == PropertyState_DIRECT_VALUE)/* || (bDefault && (*pStates == PropertyState_DEFAULT_VALUE))*/ )
398 : {
399 97981 : *pAPINames++ = aItr->GetApiName();
400 97981 : aPropIters.push_back( aItr );
401 97981 : ++i;
402 : }
403 589136 : ++aItr;
404 589136 : ++pStates;
405 : }
406 :
407 9141 : aValues = xMultiPropSet->getPropertyValues( aAPINames );
408 9141 : const Any *pValues = aValues.getConstArray();
409 :
410 : ::std::vector< FilterPropertyInfoList_Impl::iterator >::const_iterator
411 9141 : pPropIter = aPropIters.begin();
412 :
413 18282 : XMLPropertyState aNewProperty( -1 );
414 107122 : for( i = 0; i < nValueCount; ++i )
415 : {
416 97981 : aNewProperty.mnIndex = -1;
417 97981 : aNewProperty.maValue = *pValues;
418 :
419 97981 : const ::std::list< sal_uInt32 >& rIndexes( (*pPropIter)->GetIndexes() );
420 625584 : for ( std::list<sal_uInt32>::const_iterator aIndexItr = rIndexes.begin();
421 417056 : aIndexItr != rIndexes.end();
422 : ++aIndexItr
423 : )
424 : {
425 110547 : aNewProperty.mnIndex = *aIndexItr;
426 110547 : aPropStates.AddPropertyState( aNewProperty );
427 : }
428 :
429 97981 : ++pPropIter;
430 97981 : ++pValues;
431 9141 : }
432 : }
433 : }
434 : else
435 : {
436 34 : aValues = xMultiPropSet->getPropertyValues( rApiNames );
437 34 : const Any *pValues = aValues.getConstArray();
438 :
439 34 : FilterPropertyInfoList_Impl::iterator aItr = aPropInfos.begin();
440 252 : for(sal_uInt32 i = 0; i < nCount; ++i)
441 : {
442 : // The value is stored in the PropertySet itself, add to list.
443 218 : XMLPropertyState aNewProperty( -1 );
444 218 : aNewProperty.maValue = *pValues;
445 218 : ++pValues;
446 1308 : for( std::list<sal_uInt32>::iterator aIndexItr =
447 218 : aItr->GetIndexes().begin();
448 872 : aIndexItr != aItr->GetIndexes().end();
449 : ++aIndexItr )
450 : {
451 218 : aNewProperty.mnIndex = *aIndexItr;
452 218 : aPropStates.AddPropertyState( aNewProperty );
453 : }
454 218 : ++aItr;
455 218 : }
456 11910 : }
457 : }
458 : else
459 : {
460 1206 : FilterPropertyInfoList_Impl::iterator aItr = aPropInfos.begin();
461 103547 : for(sal_uInt32 i = 0; i < nCount; ++i)
462 : {
463 : bool bDirectValue =
464 102341 : !pStates || *pStates == PropertyState_DIRECT_VALUE;
465 102341 : if( bDirectValue || bDefault )
466 : {
467 : // The value is stored in the PropertySet itself, add to list.
468 30981 : bool bGotValue = false;
469 30981 : XMLPropertyState aNewProperty( -1 );
470 212982 : for( std::list<sal_uInt32>::const_iterator aIndexItr =
471 30981 : aItr->GetIndexes().begin();
472 141988 : aIndexItr != aItr->GetIndexes().end();
473 : ++aIndexItr )
474 : {
475 62027 : if( bDirectValue ||
476 22014 : (rPropMapper->GetEntryFlags( *aIndexItr ) &
477 : MID_FLAG_DEFAULT_ITEM_EXPORT) != 0 )
478 : {
479 : try
480 : {
481 18621 : if( !bGotValue )
482 : {
483 27514 : aNewProperty.maValue =
484 27514 : rPropSet->getPropertyValue( aItr->GetApiName() );
485 13757 : bGotValue = true;
486 : }
487 18621 : aNewProperty.mnIndex = *aIndexItr;
488 18621 : 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 30981 : }
498 : }
499 :
500 102341 : ++aItr;
501 102341 : if( pStates )
502 102341 : ++pStates;
503 : }
504 13116 : }
505 : }
506 34388 : aPropStates.FillPropertyStateVector(rPropStates);
507 17194 : }
508 :
509 : }
510 :
511 13734 : 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 13719 : ~Impl()
522 13719 : {
523 13719 : CacheType::iterator it = maCache.begin(), itEnd = maCache.end();
524 19742 : for (; it != itEnd; ++it)
525 6023 : delete it->second;
526 13719 : }
527 : };
528 :
529 : // ctor/dtor , class SvXMLExportPropertyMapper
530 :
531 13734 : SvXMLExportPropertyMapper::SvXMLExportPropertyMapper(
532 : const rtl::Reference< XMLPropertySetMapper >& rMapper ) :
533 13734 : mpImpl(new Impl)
534 : {
535 13734 : mpImpl->mxPropMapper = rMapper;
536 13734 : }
537 :
538 29738 : SvXMLExportPropertyMapper::~SvXMLExportPropertyMapper()
539 : {
540 13719 : delete mpImpl;
541 16019 : }
542 :
543 2646 : void SvXMLExportPropertyMapper::ChainExportMapper(
544 : const rtl::Reference< SvXMLExportPropertyMapper>& rMapper )
545 : {
546 : // add map entries from rMapper to current map
547 2646 : mpImpl->mxPropMapper->AddMapperEntry( rMapper->getPropertySetMapper() );
548 : // rMapper uses the same map as 'this'
549 2646 : rMapper->mpImpl->mxPropMapper = mpImpl->mxPropMapper;
550 :
551 : // set rMapper as last mapper in current chain
552 2646 : rtl::Reference< SvXMLExportPropertyMapper > xNext = mpImpl->mxNextMapper;
553 2646 : if( xNext.is())
554 : {
555 1824 : while (xNext->mpImpl->mxNextMapper.is())
556 0 : xNext = xNext->mpImpl->mxNextMapper;
557 912 : xNext->mpImpl->mxNextMapper = rMapper;
558 : }
559 : else
560 1734 : mpImpl->mxNextMapper = rMapper;
561 :
562 : // if rMapper was already chained, correct
563 : // map pointer of successors
564 2646 : xNext = rMapper;
565 :
566 5292 : while (xNext->mpImpl->mxNextMapper.is())
567 : {
568 0 : xNext = xNext->mpImpl->mxNextMapper;
569 0 : xNext->mpImpl->mxPropMapper = mpImpl->mxPropMapper;
570 2646 : }
571 2646 : }
572 :
573 16824 : std::vector<XMLPropertyState> SvXMLExportPropertyMapper::Filter(
574 : const uno::Reference<beans::XPropertySet>& rPropSet, bool bEnableFoFontFamily ) const
575 : {
576 16824 : return _Filter(rPropSet, false, bEnableFoFontFamily);
577 : }
578 :
579 420 : std::vector<XMLPropertyState> SvXMLExportPropertyMapper::FilterDefaults(
580 : const uno::Reference<beans::XPropertySet>& rPropSet, bool bEnableFoFontFamily ) const
581 : {
582 420 : return _Filter(rPropSet, true, bEnableFoFontFamily);
583 : }
584 :
585 17244 : vector<XMLPropertyState> SvXMLExportPropertyMapper::_Filter(
586 : const Reference<XPropertySet>& xPropSet, bool bDefault, bool bEnableFoFontFamily ) const
587 : {
588 17244 : vector< XMLPropertyState > aPropStateArray;
589 :
590 : // Retrieve XPropertySetInfo and XPropertyState
591 34488 : Reference< XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo() );
592 17244 : if( !xInfo.is() )
593 0 : return aPropStateArray;
594 :
595 17244 : sal_Int32 nProps = mpImpl->mxPropMapper->GetEntryCount();
596 :
597 17244 : FilterPropertiesInfo_Impl *pFilterInfo = 0;
598 :
599 17244 : Impl::CacheType::iterator aIter = mpImpl->maCache.find(xInfo);
600 17244 : if (aIter != mpImpl->maCache.end())
601 11140 : pFilterInfo = (*aIter).second;
602 :
603 17244 : bool bDelInfo = false;
604 17244 : if( !pFilterInfo )
605 : {
606 6104 : const SvtSaveOptions::ODFDefaultVersion nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() );
607 6104 : pFilterInfo = new FilterPropertiesInfo_Impl;
608 2225045 : 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 2218941 : const OUString& rAPIName = mpImpl->mxPropMapper->GetEntryAPIName( i );
613 2218941 : const sal_Int32 nFlags = mpImpl->mxPropMapper->GetEntryFlags( i );
614 4980037 : if( (0 == (nFlags & MID_FLAG_NO_PROPERTY_EXPORT)) &&
615 4388382 : ( (0 != (nFlags & MID_FLAG_MUST_EXIST)) ||
616 2194191 : xInfo->hasPropertyByName( rAPIName ) ) )
617 : {
618 : const SvtSaveOptions::ODFDefaultVersion nEarliestODFVersionForExport(
619 566905 : mpImpl->mxPropMapper->GetEarliestODFVersionForExport(i));
620 566905 : if( nCurrentVersion >= nEarliestODFVersionForExport
621 0 : || nCurrentVersion == SvtSaveOptions::ODFVER_UNKNOWN
622 0 : || nEarliestODFVersionForExport == SvtSaveOptions::ODFVER_UNKNOWN )
623 566905 : 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 6104 : WeakReference < XPropertySetInfo > xWeakInfo( xInfo );
632 6104 : xInfo = 0;
633 6104 : xInfo = xWeakInfo;
634 6104 : if( xInfo.is() )
635 : {
636 6026 : mpImpl->maCache.insert(Impl::CacheType::value_type(xInfo, pFilterInfo));
637 : }
638 : else
639 78 : bDelInfo = true;
640 : }
641 :
642 17244 : if( pFilterInfo->GetPropertyCount() )
643 : {
644 : try
645 : {
646 : pFilterInfo->FillPropertyStateArray(
647 17194 : 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 17244 : if( !aPropStateArray.empty() )
658 11266 : ContextFilter(bEnableFoFontFamily, aPropStateArray, xPropSet);
659 :
660 : // Have to do if we change from a vector to a list or something like that
661 :
662 17244 : if( bDelInfo )
663 78 : delete pFilterInfo;
664 :
665 17244 : return aPropStateArray;
666 : }
667 :
668 26465 : void SvXMLExportPropertyMapper::ContextFilter(
669 : bool bEnableFoFontFamily,
670 : vector< XMLPropertyState >& rProperties,
671 : Reference< XPropertySet > rPropSet ) const
672 : {
673 : // Derived class could implement this.
674 26465 : if (mpImpl->mxNextMapper.is())
675 15261 : mpImpl->mxNextMapper->ContextFilter(bEnableFoFontFamily, rProperties, rPropSet);
676 26465 : }
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 5569 : bool SvXMLExportPropertyMapper::Equals(
683 : const vector< XMLPropertyState >& aProperties1,
684 : const vector< XMLPropertyState >& aProperties2 ) const
685 : {
686 5569 : bool bRet = true;
687 5569 : sal_uInt32 nCount = aProperties1.size();
688 :
689 5569 : if( nCount == aProperties2.size() )
690 : {
691 5569 : sal_uInt32 nIndex = 0;
692 33501 : while( bRet && nIndex < nCount )
693 : {
694 22363 : const XMLPropertyState& rProp1 = aProperties1[ nIndex ];
695 22363 : const XMLPropertyState& rProp2 = aProperties2[ nIndex ];
696 :
697 : // Compare index. If equal, compare value
698 22363 : if( rProp1.mnIndex == rProp2.mnIndex )
699 : {
700 20666 : if( rProp1.mnIndex != -1 )
701 : {
702 : // Now compare values
703 17448 : if ( (mpImpl->mxPropMapper->GetEntryType( rProp1.mnIndex ) &
704 : XML_TYPE_BUILDIN_CMP ) != 0 )
705 : // simple type ( binary compare )
706 8514 : bRet = ( rProp1.maValue == rProp2.maValue );
707 : else
708 : // complex type ( ask for compare-function )
709 : bRet = mpImpl->mxPropMapper->GetPropertyHandler(
710 8934 : rProp1.mnIndex )->equals( rProp1.maValue,
711 8934 : rProp2.maValue );
712 : }
713 : }
714 : else
715 1697 : bRet = false;
716 :
717 22363 : nIndex++;
718 : }
719 : }
720 : else
721 0 : bRet = false;
722 :
723 5569 : 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 1858 : void SvXMLExportPropertyMapper::exportXML(
750 : SvXMLExport& rExport,
751 : const ::std::vector< XMLPropertyState >& rProperties,
752 : SvXmlExportFlags nFlags ) const
753 : {
754 1858 : exportXML( rExport, rProperties, -1, -1, nFlags );
755 1858 : }
756 :
757 6241 : void SvXMLExportPropertyMapper::exportXML(
758 : SvXMLExport& rExport,
759 : const ::std::vector< XMLPropertyState >& rProperties,
760 : sal_Int32 nPropMapStartIdx, sal_Int32 nPropMapEndIdx,
761 : SvXmlExportFlags nFlags, bool bExtensionNamespace ) const
762 : {
763 6241 : sal_uInt16 nPropTypeFlags = 0;
764 93615 : for( sal_uInt16 i=0; i<MAX_PROP_TYPES; ++i )
765 : {
766 87374 : sal_uInt16 nPropType = aPropTokens[i].nType;
767 87374 : if( 0==i || (nPropTypeFlags & (1 << nPropType)) != 0 )
768 : {
769 14696 : std::vector<sal_uInt16> aIndexArray;
770 :
771 : _exportXML( nPropType, nPropTypeFlags,
772 14696 : rExport.GetAttrList(), rProperties,
773 14696 : rExport.GetMM100UnitConverter(),
774 14696 : rExport.GetNamespaceMap(),
775 : nFlags, &aIndexArray,
776 14696 : nPropMapStartIdx, nPropMapEndIdx );
777 :
778 62958 : if( rExport.GetAttrList().getLength() > 0L ||
779 56610 : (nFlags & SvXmlExportFlags::EMPTY) ||
780 4174 : !aIndexArray.empty() )
781 : {
782 10538 : sal_uInt16 nNamespace = XML_NAMESPACE_STYLE;
783 10538 : if(bExtensionNamespace && aPropTokens[i].eToken ==
784 : xmloff::token::XML_GRAPHIC_PROPERTIES)
785 48 : nNamespace = XML_NAMESPACE_LO_EXT;
786 : SvXMLElementExport aElem( rExport, nNamespace,
787 : aPropTokens[i].eToken,
788 21076 : bool(nFlags & SvXmlExportFlags::IGN_WS),
789 10538 : false );
790 :
791 10538 : exportElementItems( rExport, rProperties, nFlags, aIndexArray );
792 14696 : }
793 : }
794 : }
795 6241 : }
796 :
797 : /** this method is called for every item that has the
798 : MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
799 27 : 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 27 : if (mpImpl->mxNextMapper.is())
809 21 : mpImpl->mxNextMapper->handleSpecialItem(
810 21 : rAttrList, rProperty, rUnitConverter, rNamespaceMap, pProperties, nIdx);
811 27 : }
812 :
813 : /** this method is called for every item that has the
814 : MID_FLAG_ELEMENT_EXPORT flag set */
815 99 : void SvXMLExportPropertyMapper::handleElementItem(
816 : SvXMLExport& rExport,
817 : const XMLPropertyState& rProperty,
818 : SvXmlExportFlags 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 99 : if (mpImpl->mxNextMapper.is())
824 99 : mpImpl->mxNextMapper->handleElementItem(rExport, rProperty, nFlags, pProperties, nIdx);
825 99 : }
826 :
827 : // protected methods
828 :
829 : /** fills the given attribute list with the items in the given set */
830 14696 : 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 : SvXmlExportFlags nFlags,
837 : std::vector<sal_uInt16>* pIndexArray,
838 : sal_Int32 nPropMapStartIdx, sal_Int32 nPropMapEndIdx ) const
839 : {
840 14696 : const sal_uInt32 nCount = rProperties.size();
841 14696 : sal_uInt32 nIndex = 0;
842 :
843 14696 : if( -1 == nPropMapStartIdx )
844 13969 : nPropMapStartIdx = 0;
845 14696 : if( -1 == nPropMapEndIdx )
846 13969 : nPropMapEndIdx = mpImpl->mxPropMapper->GetEntryCount();
847 :
848 266029 : while( nIndex < nCount )
849 : {
850 236637 : sal_Int32 nPropMapIdx = rProperties[nIndex].mnIndex;
851 236637 : if( nPropMapIdx >= nPropMapStartIdx &&
852 : nPropMapIdx < nPropMapEndIdx )// valid entry?
853 : {
854 177759 : sal_uInt32 nEFlags = mpImpl->mxPropMapper->GetEntryFlags(nPropMapIdx);
855 177759 : 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 177759 : rPropTypeFlags |= (1 << nEPType);
859 177759 : if( nEPType == nPropType )
860 : {
861 : // we have a valid map entry here, so lets use it...
862 63602 : if( ( nEFlags & MID_FLAG_ELEMENT_ITEM_EXPORT ) != 0 )
863 : {
864 : // element items do not add any properties,
865 : // we export it later
866 928 : if( pIndexArray )
867 : {
868 928 : pIndexArray->push_back( (sal_uInt16)nIndex );
869 : }
870 : }
871 : else
872 : {
873 62674 : _exportXML( rAttrList, rProperties[nIndex], rUnitConverter,
874 62674 : rNamespaceMap, nFlags, &rProperties, nIndex );
875 : }
876 : }
877 : }
878 :
879 236637 : nIndex++;
880 : }
881 14696 : }
882 :
883 62674 : void SvXMLExportPropertyMapper::_exportXML(
884 : SvXMLAttributeList& rAttrList,
885 : const XMLPropertyState& rProperty,
886 : const SvXMLUnitConverter& rUnitConverter,
887 : const SvXMLNamespaceMap& rNamespaceMap,
888 : SvXmlExportFlags /*nFlags*/,
889 : const ::std::vector< XMLPropertyState > *pProperties,
890 : sal_uInt32 nIdx ) const
891 : {
892 62674 : if ((mpImpl->mxPropMapper->GetEntryFlags(rProperty.mnIndex) & MID_FLAG_SPECIAL_ITEM_EXPORT) != 0)
893 : {
894 4146 : uno::Reference< container::XNameContainer > xAttrContainer;
895 4146 : if( (rProperty.maValue >>= xAttrContainer) && xAttrContainer.is() )
896 : {
897 39 : SvXMLNamespaceMap *pNewNamespaceMap = 0;
898 39 : const SvXMLNamespaceMap *pNamespaceMap = &rNamespaceMap;
899 :
900 39 : uno::Sequence< OUString > aAttribNames( xAttrContainer->getElementNames() );
901 39 : const OUString* pAttribName = aAttribNames.getConstArray();
902 :
903 39 : const sal_Int32 nCount = aAttribNames.getLength();
904 :
905 78 : OUStringBuffer sNameBuffer;
906 78 : xml::AttributeData aData;
907 39 : 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 78 : delete pNewNamespaceMap;
990 : }
991 : else
992 : {
993 : handleSpecialItem( rAttrList, rProperty, rUnitConverter,
994 4107 : rNamespaceMap, pProperties, nIdx );
995 4146 : }
996 : }
997 58528 : else if ((mpImpl->mxPropMapper->GetEntryFlags(rProperty.mnIndex) & MID_FLAG_ELEMENT_ITEM_EXPORT ) == 0)
998 : {
999 58528 : OUString aValue;
1000 : const OUString sName = rNamespaceMap.GetQNameByKey(
1001 58528 : mpImpl->mxPropMapper->GetEntryNameSpace(rProperty.mnIndex),
1002 175584 : mpImpl->mxPropMapper->GetEntryXMLName(rProperty.mnIndex));
1003 :
1004 58528 : bool bRemove = false;
1005 58528 : if ((mpImpl->mxPropMapper->GetEntryFlags( rProperty.mnIndex ) & MID_FLAG_MERGE_ATTRIBUTE) != 0)
1006 : {
1007 4441 : aValue = rAttrList.getValueByName( sName );
1008 4441 : bRemove = true;
1009 : }
1010 :
1011 58528 : if (mpImpl->mxPropMapper->exportXML(aValue, rProperty, rUnitConverter))
1012 : {
1013 47899 : if( bRemove )
1014 3784 : rAttrList.RemoveAttribute( sName );
1015 47899 : rAttrList.AddAttribute( sName, aValue );
1016 58528 : }
1017 : }
1018 62674 : }
1019 :
1020 10538 : void SvXMLExportPropertyMapper::exportElementItems(
1021 : SvXMLExport& rExport,
1022 : const ::std::vector< XMLPropertyState >& rProperties,
1023 : SvXmlExportFlags nFlags,
1024 : const std::vector<sal_uInt16>& rIndexArray ) const
1025 : {
1026 10538 : const sal_uInt16 nCount = rIndexArray.size();
1027 :
1028 10538 : bool bItemsExported = false;
1029 11466 : for( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
1030 : {
1031 928 : 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 928 : rExport.IgnorableWhitespace();
1038 928 : handleElementItem( rExport, rProperties[nElement],
1039 1856 : nFlags, &rProperties, nElement );
1040 928 : bItemsExported = true;
1041 : }
1042 :
1043 10538 : if( bItemsExported )
1044 837 : rExport.IgnorableWhitespace();
1045 10538 : }
1046 :
1047 329167 : const rtl::Reference<XMLPropertySetMapper>& SvXMLExportPropertyMapper::getPropertySetMapper() const
1048 : {
1049 329167 : return mpImpl->mxPropMapper;
1050 : }
1051 :
1052 2996 : void SvXMLExportPropertyMapper::SetStyleName( const OUString& rStyleName )
1053 : {
1054 2996 : mpImpl->maStyleName = rStyleName;
1055 2996 : }
1056 :
1057 36 : const OUString& SvXMLExportPropertyMapper::GetStyleName() const
1058 : {
1059 36 : return mpImpl->maStyleName;
1060 : }
1061 :
1062 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|