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