1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26 #include "propertyimport.hxx"
27 #include <xmloff/xmlimp.hxx>
28 #include <xmloff/xmluconv.hxx>
29 #include <xmloff/nmspmap.hxx>
30 #include <osl/diagnose.h>
31 #include <comphelper/extract.hxx>
32 #include "callbacks.hxx"
33 #include "xmloff/xmlnmspe.hxx"
34 #include <tools/date.hxx>
35 #include <tools/time.hxx>
36 #include <tools/datetime.hxx>
37 #include <com/sun/star/util/Date.hpp>
38 #include <com/sun/star/util/Time.hpp>
39 #include <com/sun/star/util/DateTime.hpp>
40 #include <unotools/datetime.hxx>
41 #include <rtl/logfile.hxx>
42
43 #if OSL_DEBUG_LEVEL > 0
44 #ifndef _OSL_THREAD_H_
45 #include <osl/thread.h>
46 #endif
47 #endif
48
49 //.........................................................................
50 namespace xmloff
51 {
52 //.........................................................................
53
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::beans;
56 using namespace ::com::sun::star::xml;
57
58 // NO using namespace ...util !!!
59 // need a tools Date/Time/DateTime below, which would conflict with the uno types then
60
61 #define TYPE_DATE 1
62 #define TYPE_TIME 2
63 #define TYPE_DATETIME 3
64
65 //=====================================================================
66 //= PropertyConversion
67 //=====================================================================
68 namespace
69 {
70 //---------------------------------------------------------------------
lcl_getTime(double _nValue)71 ::com::sun::star::util::Time lcl_getTime(double _nValue)
72 {
73 ::com::sun::star::util::Time aTime;
74 sal_uInt32 nIntValue = sal_Int32(_nValue * 8640000);
75 nIntValue *= 8640000;
76 aTime.HundredthSeconds = (sal_uInt16)( nIntValue % 100 );
77 nIntValue /= 100;
78 aTime.Seconds = (sal_uInt16)( nIntValue % 60 );
79 nIntValue /= 60;
80 aTime.Minutes = (sal_uInt16)( nIntValue % 60 );
81 nIntValue /= 60;
82 OSL_ENSURE(nIntValue < 24, "lcl_getTime: more than a day?");
83 aTime.Hours = static_cast< sal_uInt16 >( nIntValue );
84
85 return aTime;
86 }
87
88 //---------------------------------------------------------------------
lcl_getDate(double _nValue)89 static ::com::sun::star::util::Date lcl_getDate( double _nValue )
90 {
91 Date aToolsDate((sal_uInt32)_nValue);
92 ::com::sun::star::util::Date aDate;
93 ::utl::typeConvert(aToolsDate, aDate);
94 return aDate;
95 }
96 }
97
98 //---------------------------------------------------------------------
convertString(SvXMLImport & _rImporter,const::com::sun::star::uno::Type & _rExpectedType,const::rtl::OUString & _rReadCharacters,const SvXMLEnumMapEntry * _pEnumMap,const sal_Bool _bInvertBoolean)99 Any PropertyConversion::convertString( SvXMLImport& _rImporter, const ::com::sun::star::uno::Type& _rExpectedType,
100 const ::rtl::OUString& _rReadCharacters, const SvXMLEnumMapEntry* _pEnumMap, const sal_Bool _bInvertBoolean )
101 {
102 Any aReturn;
103 sal_Bool bEnumAsInt = sal_False;
104 switch (_rExpectedType.getTypeClass())
105 {
106 case TypeClass_BOOLEAN: // sal_Bool
107 {
108 sal_Bool bValue;
109 #if OSL_DEBUG_LEVEL > 0
110 sal_Bool bSuccess =
111 #endif
112 _rImporter.GetMM100UnitConverter().convertBool(bValue, _rReadCharacters);
113 OSL_ENSURE(bSuccess,
114 ::rtl::OString("PropertyConversion::convertString: could not convert \"")
115 += ::rtl::OString(_rReadCharacters.getStr(), _rReadCharacters.getLength(), RTL_TEXTENCODING_ASCII_US)
116 += ::rtl::OString("\" into a boolean!"));
117 aReturn = ::cppu::bool2any(_bInvertBoolean ? !bValue : bValue);
118 }
119 break;
120 case TypeClass_SHORT: // sal_Int16
121 case TypeClass_LONG: // sal_Int32
122 if (!_pEnumMap)
123 { // it's a real int32/16 property
124 sal_Int32 nValue(0);
125 #if OSL_DEBUG_LEVEL > 0
126 sal_Bool bSuccess =
127 #endif
128 _rImporter.GetMM100UnitConverter().convertNumber(nValue, _rReadCharacters);
129 OSL_ENSURE(bSuccess,
130 ::rtl::OString("PropertyConversion::convertString: could not convert \"")
131 += ::rtl::OString(_rReadCharacters.getStr(), _rReadCharacters.getLength(), RTL_TEXTENCODING_ASCII_US)
132 += ::rtl::OString("\" into an integer!"));
133 if (TypeClass_SHORT == _rExpectedType.getTypeClass())
134 aReturn <<= (sal_Int16)nValue;
135 else
136 aReturn <<= (sal_Int32)nValue;
137 break;
138 }
139 bEnumAsInt = sal_True;
140 // NO BREAK! handle it as enum
141 case TypeClass_ENUM:
142 {
143 sal_uInt16 nEnumValue(0);
144 #if OSL_DEBUG_LEVEL > 0
145 sal_Bool bSuccess =
146 #endif
147 _rImporter.GetMM100UnitConverter().convertEnum(nEnumValue, _rReadCharacters, _pEnumMap);
148 OSL_ENSURE(bSuccess, "PropertyConversion::convertString: could not convert to an enum value!");
149 if (bEnumAsInt)
150 if (TypeClass_SHORT == _rExpectedType.getTypeClass())
151 aReturn <<= (sal_Int16)nEnumValue;
152 else
153 aReturn <<= (sal_Int32)nEnumValue;
154 else
155 aReturn = ::cppu::int2enum((sal_Int32)nEnumValue, _rExpectedType);
156 }
157 break;
158 case TypeClass_HYPER:
159 {
160 OSL_ENSURE(sal_False, "PropertyConversion::convertString: 64-bit integers not implemented yet!");
161 }
162 break;
163 case TypeClass_DOUBLE:
164 {
165 double nValue;
166 #if OSL_DEBUG_LEVEL > 0
167 sal_Bool bSuccess =
168 #endif
169 _rImporter.GetMM100UnitConverter().convertDouble(nValue, _rReadCharacters);
170 OSL_ENSURE(bSuccess,
171 ::rtl::OString("PropertyConversion::convertString: could not convert \"")
172 += ::rtl::OString(_rReadCharacters.getStr(), _rReadCharacters.getLength(), RTL_TEXTENCODING_ASCII_US)
173 += ::rtl::OString("\" into a double!"));
174 aReturn <<= (double)nValue;
175 }
176 break;
177 case TypeClass_STRING:
178 aReturn <<= _rReadCharacters;
179 break;
180 case TypeClass_STRUCT:
181 {
182 sal_Int32 nType = 0;
183 if ( _rExpectedType.equals( ::cppu::UnoType< ::com::sun::star::util::Date >::get() ) )
184 nType = TYPE_DATE;
185 else if ( _rExpectedType.equals( ::cppu::UnoType< ::com::sun::star::util::Time >::get() ) )
186 nType = TYPE_TIME;
187 else if ( _rExpectedType.equals( ::cppu::UnoType< ::com::sun::star::util::DateTime >::get() ) )
188 nType = TYPE_DATETIME;
189
190 if ( nType )
191 {
192 // first extract the double
193 double nValue = 0;
194 #if OSL_DEBUG_LEVEL > 0
195 sal_Bool bSuccess =
196 #endif
197 _rImporter.GetMM100UnitConverter().convertDouble(nValue, _rReadCharacters);
198 OSL_ENSURE(bSuccess,
199 ::rtl::OString("PropertyConversion::convertString: could not convert \"")
200 += ::rtl::OString(_rReadCharacters.getStr(), _rReadCharacters.getLength(), RTL_TEXTENCODING_ASCII_US)
201 += ::rtl::OString("\" into a double!"));
202
203 // then convert it into the target type
204 switch (nType)
205 {
206 case TYPE_DATE:
207 {
208 OSL_ENSURE(((sal_uInt32)nValue) - nValue == 0,
209 "PropertyConversion::convertString: a Date value with a fractional part?");
210 aReturn <<= lcl_getDate(nValue);
211 }
212 break;
213 case TYPE_TIME:
214 {
215 OSL_ENSURE(((sal_uInt32)nValue) == 0,
216 "PropertyConversion::convertString: a Time value with more than a fractional part?");
217 aReturn <<= lcl_getTime(nValue);
218 }
219 break;
220 case TYPE_DATETIME:
221 {
222 ::com::sun::star::util::Time aTime = lcl_getTime(nValue);
223 ::com::sun::star::util::Date aDate = lcl_getDate(nValue);
224
225 ::com::sun::star::util::DateTime aDateTime;
226 aDateTime.HundredthSeconds = aTime.HundredthSeconds;
227 aDateTime.Seconds = aTime.Seconds;
228 aDateTime.Minutes = aTime.Minutes;
229 aDateTime.Hours = aTime.Hours;
230 aDateTime.Day = aDate.Day;
231 aDateTime.Month = aDate.Month;
232 aDateTime.Year = aDate.Year;
233 aReturn <<= aDateTime;
234 }
235 break;
236 }
237 }
238 else
239 OSL_ENSURE(sal_False, "PropertyConversion::convertString: unsupported property type!");
240 }
241 break;
242 default:
243 OSL_ENSURE(sal_False, "PropertyConversion::convertString: invalid type class!");
244 }
245
246 return aReturn;
247 }
248
249 //---------------------------------------------------------------------
xmlTypeToUnoType(const::rtl::OUString & _rType)250 Type PropertyConversion::xmlTypeToUnoType( const ::rtl::OUString& _rType )
251 {
252 Type aUnoType( ::getVoidCppuType() );
253
254 DECLARE_STL_USTRINGACCESS_MAP( ::com::sun::star::uno::Type, MapString2Type );
255 static MapString2Type s_aTypeNameMap;
256 if ( s_aTypeNameMap.empty() )
257 {
258 s_aTypeNameMap[ token::GetXMLToken( token::XML_BOOLEAN ) ] = ::getBooleanCppuType();
259 s_aTypeNameMap[ token::GetXMLToken( token::XML_FLOAT ) ] = ::getCppuType( static_cast< double* >(NULL) );
260 s_aTypeNameMap[ token::GetXMLToken( token::XML_STRING ) ] = ::getCppuType( static_cast< ::rtl::OUString* >(NULL) );
261 s_aTypeNameMap[ token::GetXMLToken( token::XML_VOID ) ] = ::getVoidCppuType();
262 }
263
264 const ConstMapString2TypeIterator aTypePos = s_aTypeNameMap.find( _rType );
265 OSL_ENSURE( s_aTypeNameMap.end() != aTypePos, "PropertyConversion::xmlTypeToUnoType: invalid property name!" );
266 if ( s_aTypeNameMap.end() != aTypePos )
267 aUnoType = aTypePos->second;
268
269 return aUnoType;
270 }
271
272 //=====================================================================
273 //= OPropertyImport
274 //=====================================================================
275 //---------------------------------------------------------------------
OPropertyImport(OFormLayerXMLImport_Impl & _rImport,sal_uInt16 _nPrefix,const::rtl::OUString & _rName)276 OPropertyImport::OPropertyImport(OFormLayerXMLImport_Impl& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName)
277 :SvXMLImportContext(_rImport.getGlobalContext(), _nPrefix, _rName)
278 ,m_rContext(_rImport)
279 ,m_bTrackAttributes(sal_False)
280 {
281 }
282
283 //---------------------------------------------------------------------
CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<sax::XAttributeList> & _rxAttrList)284 SvXMLImportContext* OPropertyImport::CreateChildContext(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName,
285 const Reference< sax::XAttributeList >& _rxAttrList)
286 {
287 if( token::IsXMLToken( _rLocalName, token::XML_PROPERTIES) )
288 {
289 return new OPropertyElementsContext( m_rContext.getGlobalContext(),
290 _nPrefix, _rLocalName, this);
291 }
292 else
293 {
294 OSL_ENSURE(sal_False,
295 ::rtl::OString("OPropertyImport::CreateChildContext: unknown sub element (only \"properties\" is recognized, but it is ")
296 += ::rtl::OString(_rLocalName.getStr(), _rLocalName.getLength(), RTL_TEXTENCODING_ASCII_US)
297 += ::rtl::OString(")!"));
298 return SvXMLImportContext::CreateChildContext(_nPrefix, _rLocalName, _rxAttrList);
299 }
300 }
301
302 //---------------------------------------------------------------------
StartElement(const Reference<sax::XAttributeList> & _rxAttrList)303 void OPropertyImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList)
304 {
305 OSL_ENSURE(_rxAttrList.is(), "OPropertyImport::StartElement: invalid attribute list!");
306 const sal_Int32 nAttributeCount = _rxAttrList->getLength();
307
308 // assume the 'worst' case: all attributes describe properties. This should save our property array
309 // some reallocs
310 m_aValues.reserve(nAttributeCount);
311
312 const SvXMLNamespaceMap& rMap = m_rContext.getGlobalContext().GetNamespaceMap();
313 sal_uInt16 nNamespace;
314 ::rtl::OUString sLocalName;
315 for (sal_Int16 i=0; i<nAttributeCount; ++i)
316 {
317 nNamespace = rMap.GetKeyByAttrName(_rxAttrList->getNameByIndex(i), &sLocalName);
318 handleAttribute(nNamespace, sLocalName, _rxAttrList->getValueByIndex(i));
319
320 if (m_bTrackAttributes)
321 m_aEncounteredAttributes.insert(sLocalName);
322 }
323
324 // TODO: create PropertyValues for all the attributes which were not present, because they were implied
325 // this is necessary as soon as we have properties where the XML default is different from the property
326 // default
327 }
328
329 //---------------------------------------------------------------------
encounteredAttribute(const::rtl::OUString & _rAttributeName) const330 sal_Bool OPropertyImport::encounteredAttribute(const ::rtl::OUString& _rAttributeName) const
331 {
332 OSL_ENSURE(m_bTrackAttributes, "OPropertyImport::encounteredAttribute: attribute tracking not enabled!");
333 return m_aEncounteredAttributes.end() != m_aEncounteredAttributes.find(_rAttributeName);
334 }
335
336 //---------------------------------------------------------------------
Characters(const::rtl::OUString & _rChars)337 void OPropertyImport::Characters(const ::rtl::OUString&
338 #if OSL_DEBUG_LEVEL > 0
339 _rChars
340 #endif
341 )
342 {
343 // ignore them (should be whitespaces only)
344 OSL_ENSURE(0 == _rChars.trim().getLength(), "OPropertyImport::Characters: non-whitespace characters!");
345 }
346
347 //---------------------------------------------------------------------
handleAttribute(sal_uInt16,const::rtl::OUString & _rLocalName,const::rtl::OUString & _rValue)348 bool OPropertyImport::handleAttribute(sal_uInt16 /*_nNamespaceKey*/, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue)
349 {
350 const OAttribute2Property::AttributeAssignment* pProperty = m_rContext.getAttributeMap().getAttributeTranslation(_rLocalName);
351 if (pProperty)
352 {
353 // create and store a new PropertyValue
354 PropertyValue aNewValue;
355 aNewValue.Name = pProperty->sPropertyName;
356
357 // convert the value string into the target type
358 aNewValue.Value = PropertyConversion::convertString(m_rContext.getGlobalContext(), pProperty->aPropertyType, _rValue, pProperty->pEnumMap, pProperty->bInverseSemantics);
359 implPushBackPropertyValue( aNewValue );
360 return true;
361 }
362 if (!token::IsXMLToken(_rLocalName, token::XML_TYPE)) // xlink:type is valid but ignored for <form:form>
363 {
364 #if OSL_DEBUG_LEVEL > 0
365 ::rtl::OString sMessage( "OPropertyImport::handleAttribute: Can't handle the following:\n" );
366 sMessage += ::rtl::OString( " Attribute name: " );
367 sMessage += ::rtl::OString( _rLocalName.getStr(), _rLocalName.getLength(), osl_getThreadTextEncoding() );
368 sMessage += ::rtl::OString( "\n value: " );
369 sMessage += ::rtl::OString( _rValue.getStr(), _rValue.getLength(), osl_getThreadTextEncoding() );
370 OSL_ENSURE( sal_False, sMessage.getStr() );
371 #endif
372 return false;
373 }
374 return true;
375 }
376
377 //=====================================================================
378 //= OPropertyElementsContext
379 //=====================================================================
380 //---------------------------------------------------------------------
OPropertyElementsContext(SvXMLImport & _rImport,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const OPropertyImportRef & _rPropertyImporter)381 OPropertyElementsContext::OPropertyElementsContext(SvXMLImport& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName,
382 const OPropertyImportRef& _rPropertyImporter)
383 :SvXMLImportContext(_rImport, _nPrefix, _rName)
384 ,m_xPropertyImporter(_rPropertyImporter)
385 {
386 }
387
388 //---------------------------------------------------------------------
CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<sax::XAttributeList> &)389 SvXMLImportContext* OPropertyElementsContext::CreateChildContext(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName,
390 const Reference< sax::XAttributeList >&)
391 {
392 if( token::IsXMLToken( _rLocalName, token::XML_PROPERTY ) )
393 {
394 return new OSinglePropertyContext(GetImport(), _nPrefix, _rLocalName, m_xPropertyImporter);
395 }
396 else if( token::IsXMLToken( _rLocalName, token::XML_LIST_PROPERTY ) )
397 {
398 return new OListPropertyContext( GetImport(), _nPrefix, _rLocalName, m_xPropertyImporter );
399 }
400 else
401 {
402 OSL_ENSURE(sal_False,
403 ::rtl::OString("OPropertyElementsContext::CreateChildContext: unknown child element (\"")
404 += ::rtl::OString(_rLocalName.getStr(), _rLocalName.getLength(), RTL_TEXTENCODING_ASCII_US)
405 += ::rtl::OString("\")!"));
406 return new SvXMLImportContext(GetImport(), _nPrefix, _rLocalName);
407 }
408 }
409
410 #if OSL_DEBUG_LEVEL > 0
411 //---------------------------------------------------------------------
StartElement(const Reference<sax::XAttributeList> & _rxAttrList)412 void OPropertyElementsContext::StartElement(const Reference< sax::XAttributeList >& _rxAttrList)
413 {
414 OSL_ENSURE(0 == _rxAttrList->getLength(), "OPropertyElementsContext::StartElement: the form:properties element should not have attributes!");
415 SvXMLImportContext::StartElement(_rxAttrList);
416 }
417
418 //---------------------------------------------------------------------
Characters(const::rtl::OUString & _rChars)419 void OPropertyElementsContext::Characters(const ::rtl::OUString& _rChars)
420 {
421 OSL_ENSURE(0 == _rChars.trim(), "OPropertyElementsContext::Characters: non-whitespace characters detected!");
422 SvXMLImportContext::Characters(_rChars);
423 }
424
425 #endif
426
427 //=====================================================================
428 //= OSinglePropertyContext
429 //=====================================================================
430 //---------------------------------------------------------------------
OSinglePropertyContext(SvXMLImport & _rImport,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const OPropertyImportRef & _rPropertyImporter)431 OSinglePropertyContext::OSinglePropertyContext(SvXMLImport& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName,
432 const OPropertyImportRef& _rPropertyImporter)
433 :SvXMLImportContext(_rImport, _nPrefix, _rName)
434 ,m_xPropertyImporter(_rPropertyImporter)
435 {
436 }
437
438 //---------------------------------------------------------------------
CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<sax::XAttributeList> &)439 SvXMLImportContext* OSinglePropertyContext::CreateChildContext(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName,
440 const Reference< sax::XAttributeList >&)
441 {
442 OSL_ENSURE(sal_False,
443 ::rtl::OString("OSinglePropertyContext::CreateChildContext: unknown child element (\"")
444 += ::rtl::OString(_rLocalName.getStr(), _rLocalName.getLength(), RTL_TEXTENCODING_ASCII_US)
445 += ::rtl::OString("\")!"));
446 return new SvXMLImportContext(GetImport(), _nPrefix, _rLocalName);
447 }
448
449 //---------------------------------------------------------------------
StartElement(const Reference<sax::XAttributeList> & _rxAttrList)450 void OSinglePropertyContext::StartElement(const Reference< sax::XAttributeList >& _rxAttrList)
451 {
452 ::com::sun::star::beans::PropertyValue aPropValue; // the property the instance imports currently
453 ::com::sun::star::uno::Type aPropType; // the type of the property the instance imports currently
454
455 ::rtl::OUString sType, sValue;
456 const SvXMLNamespaceMap& rMap = GetImport().GetNamespaceMap();
457 const sal_Int16 nAttrCount = _rxAttrList.is() ? _rxAttrList->getLength() : 0;
458 for( sal_Int16 i=0; i < nAttrCount; i++ )
459 {
460 const ::rtl::OUString& rAttrName = _rxAttrList->getNameByIndex( i );
461 //const ::rtl::OUString& rValue = _rxAttrList->getValueByIndex( i );
462
463 ::rtl::OUString aLocalName;
464 sal_uInt16 nPrefix =
465 rMap.GetKeyByAttrName( rAttrName,
466 &aLocalName );
467 if( XML_NAMESPACE_FORM == nPrefix )
468 {
469 if( token::IsXMLToken( aLocalName, token::XML_PROPERTY_NAME ) )
470 aPropValue.Name = _rxAttrList->getValueByIndex( i );
471
472 }
473 else if( XML_NAMESPACE_OFFICE == nPrefix )
474 {
475 if( token::IsXMLToken( aLocalName, token::XML_VALUE_TYPE ) )
476 sType = _rxAttrList->getValueByIndex( i );
477 else if( token::IsXMLToken( aLocalName,
478 token::XML_VALUE ) ||
479 token::IsXMLToken( aLocalName,
480 token::XML_BOOLEAN_VALUE ) ||
481 token::IsXMLToken( aLocalName,
482 token::XML_STRING_VALUE ) )
483 sValue = _rxAttrList->getValueByIndex( i );
484 }
485 }
486
487 // the name of the property
488 OSL_ENSURE(aPropValue.Name.getLength(), "OSinglePropertyContext::StartElement: invalid property name!");
489
490 // needs to be translated into a ::com::sun::star::uno::Type
491 aPropType = PropertyConversion::xmlTypeToUnoType( sType );
492 if( TypeClass_VOID == aPropType.getTypeClass() )
493 {
494 aPropValue.Value = Any();
495 }
496 else
497 {
498 aPropValue.Value =
499 PropertyConversion::convertString(GetImport(), aPropType,
500 sValue);
501 }
502
503 // now that we finally have our property value, add it to our parent object
504 if( aPropValue.Name.getLength() )
505 m_xPropertyImporter->implPushBackGenericPropertyValue(aPropValue);
506 }
507
508 //=====================================================================
509 //= OListPropertyContext
510 //=====================================================================
511 //---------------------------------------------------------------------
OListPropertyContext(SvXMLImport & _rImport,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const OPropertyImportRef & _rPropertyImporter)512 OListPropertyContext::OListPropertyContext( SvXMLImport& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName,
513 const OPropertyImportRef& _rPropertyImporter )
514 :SvXMLImportContext( _rImport, _nPrefix, _rName )
515 ,m_xPropertyImporter( _rPropertyImporter )
516 {
517 }
518
519 //---------------------------------------------------------------------
StartElement(const Reference<sax::XAttributeList> & _rxAttrList)520 void OListPropertyContext::StartElement( const Reference< sax::XAttributeList >& _rxAttrList )
521 {
522 sal_Int32 nAttributeCount = _rxAttrList->getLength();
523
524 sal_uInt16 nNamespace;
525 ::rtl::OUString sAttributeName;
526 const SvXMLNamespaceMap& rMap = GetImport().GetNamespaceMap();
527 for ( sal_Int16 i = 0; i < nAttributeCount; ++i )
528 {
529 nNamespace = rMap.GetKeyByAttrName( _rxAttrList->getNameByIndex( i ), &sAttributeName );
530 if ( ( XML_NAMESPACE_FORM == nNamespace )
531 && ( token::IsXMLToken( sAttributeName, token::XML_PROPERTY_NAME ) )
532 )
533 {
534 m_sPropertyName = _rxAttrList->getValueByIndex( i );
535 }
536 else if ( ( XML_NAMESPACE_OFFICE == nNamespace )
537 && ( token::IsXMLToken( sAttributeName, token::XML_VALUE_TYPE ) )
538 )
539 {
540 m_sPropertyType = _rxAttrList->getValueByIndex( i );
541 }
542 else
543 {
544 OSL_ENSURE( false,
545 ::rtl::OString( "OListPropertyContext::StartElement: unknown child element (\"")
546 += ::rtl::OString( sAttributeName.getStr(), sAttributeName.getLength(), RTL_TEXTENCODING_ASCII_US )
547 += ::rtl::OString( "\")!" ) );
548 }
549 }
550 }
551
552 //---------------------------------------------------------------------
EndElement()553 void OListPropertyContext::EndElement()
554 {
555 OSL_ENSURE( m_sPropertyName.getLength() && m_sPropertyType.getLength(),
556 "OListPropertyContext::EndElement: no property name or type!" );
557
558 if ( !m_sPropertyName.getLength() || !m_sPropertyType.getLength() )
559 return;
560
561 Sequence< Any > aListElements( m_aListValues.size() );
562 Any* pListElement = aListElements.getArray();
563 com::sun::star::uno::Type aType = PropertyConversion::xmlTypeToUnoType( m_sPropertyType );
564 for ( ::std::vector< ::rtl::OUString >::const_iterator values = m_aListValues.begin();
565 values != m_aListValues.end();
566 ++values, ++pListElement
567 )
568 {
569 *pListElement = PropertyConversion::convertString( GetImport(), aType, *values );
570 }
571
572 PropertyValue aSequenceValue;
573 aSequenceValue.Name = m_sPropertyName;
574 aSequenceValue.Value <<= aListElements;
575
576 m_xPropertyImporter->implPushBackGenericPropertyValue( aSequenceValue );
577 }
578
579 //---------------------------------------------------------------------
CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<sax::XAttributeList> &)580 SvXMLImportContext* OListPropertyContext::CreateChildContext( sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, const Reference< sax::XAttributeList >& /*_rxAttrList*/ )
581 {
582 if ( token::IsXMLToken( _rLocalName, token::XML_LIST_VALUE ) )
583 {
584 m_aListValues.resize( m_aListValues.size() + 1 );
585 return new OListValueContext( GetImport(), _nPrefix, _rLocalName, *m_aListValues.rbegin() );
586 }
587 else
588 {
589 OSL_ENSURE( sal_False,
590 ::rtl::OString("OListPropertyContext::CreateChildContext: unknown child element (\"")
591 += ::rtl::OString(_rLocalName.getStr(), _rLocalName.getLength(), RTL_TEXTENCODING_ASCII_US)
592 += ::rtl::OString("\")!"));
593 return new SvXMLImportContext( GetImport(), _nPrefix, _rLocalName );
594 }
595 }
596
597 //=====================================================================
598 //= OListValueContext
599 //=====================================================================
600 //---------------------------------------------------------------------
OListValueContext(SvXMLImport & _rImport,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,::rtl::OUString & _rListValueHolder)601 OListValueContext::OListValueContext( SvXMLImport& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, ::rtl::OUString& _rListValueHolder )
602 :SvXMLImportContext( _rImport, _nPrefix, _rName )
603 ,m_rListValueHolder( _rListValueHolder )
604 {
605 }
606
607 //---------------------------------------------------------------------
StartElement(const Reference<sax::XAttributeList> & _rxAttrList)608 void OListValueContext::StartElement( const Reference< sax::XAttributeList >& _rxAttrList )
609 {
610 const sal_Int32 nAttributeCount = _rxAttrList->getLength();
611
612 sal_uInt16 nNamespace;
613 ::rtl::OUString sAttributeName;
614 const SvXMLNamespaceMap& rMap = GetImport().GetNamespaceMap();
615 for ( sal_Int16 i = 0; i < nAttributeCount; ++i )
616 {
617 nNamespace = rMap.GetKeyByAttrName( _rxAttrList->getNameByIndex( i ), &sAttributeName );
618 if ( XML_NAMESPACE_OFFICE == nNamespace )
619 {
620 if ( token::IsXMLToken( sAttributeName, token::XML_VALUE )
621 || token::IsXMLToken( sAttributeName, token::XML_STRING_VALUE )
622 || token::IsXMLToken( sAttributeName, token::XML_BOOLEAN_VALUE )
623 )
624 {
625 m_rListValueHolder = _rxAttrList->getValueByIndex( i );
626 continue;
627 }
628 }
629
630 OSL_ENSURE( false,
631 ::rtl::OString( "OListValueContext::StartElement: unknown child element (\"")
632 += ::rtl::OString( sAttributeName.getStr(), sAttributeName.getLength(), RTL_TEXTENCODING_ASCII_US )
633 += ::rtl::OString( "\")!" ) );
634 }
635 }
636
637 //.........................................................................
638 } // namespace xmloff
639 //.........................................................................
640
641