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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 330 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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 //--------------------------------------------------------------------- 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