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 31 #include <stdio.h> 32 #include "propertyexport.hxx" 33 #include <xmloff/xmlexp.hxx> 34 #include "strings.hxx" 35 #include "xmloff/xmlnmspe.hxx" 36 #include <xmloff/xmluconv.hxx> 37 #include <xmloff/families.hxx> 38 #include <osl/diagnose.h> 39 #include <com/sun/star/beans/PropertyAttribute.hpp> 40 #include <com/sun/star/util/Date.hpp> 41 #include <com/sun/star/util/Time.hpp> 42 #include <com/sun/star/util/DateTime.hpp> 43 #include <osl/diagnose.h> 44 #include <comphelper/extract.hxx> 45 #include <comphelper/sequence.hxx> 46 #include <comphelper/types.hxx> 47 #include "callbacks.hxx" 48 #include <unotools/datetime.hxx> 49 #include <tools/date.hxx> 50 #include <tools/time.hxx> 51 #include <tools/datetime.hxx> 52 53 //......................................................................... 54 namespace xmloff 55 { 56 //......................................................................... 57 58 using namespace ::com::sun::star::uno; 59 using namespace ::com::sun::star::lang; 60 using namespace ::com::sun::star::beans; 61 62 // NO using namespace ...util !!! 63 // need a tools Date/Time/DateTime below, which would conflict with the uno types then 64 65 using namespace ::comphelper; 66 67 //===================================================================== 68 //= OPropertyExport 69 //===================================================================== 70 //--------------------------------------------------------------------- 71 OPropertyExport::OPropertyExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxProps) 72 :m_rContext(_rContext) 73 ,m_xProps(_rxProps) 74 ,m_xPropertyInfo( m_xProps->getPropertySetInfo() ) 75 ,m_xPropertyState( _rxProps, UNO_QUERY ) 76 { 77 // caching 78 ::rtl::OUStringBuffer aBuffer; 79 m_rContext.getGlobalContext().GetMM100UnitConverter().convertBool(aBuffer, sal_True); 80 m_sValueTrue = aBuffer.makeStringAndClear(); 81 m_rContext.getGlobalContext().GetMM100UnitConverter().convertBool(aBuffer, sal_False); 82 m_sValueFalse = aBuffer.makeStringAndClear(); 83 84 OSL_ENSURE(m_xPropertyInfo.is(), "OPropertyExport::OPropertyExport: need an XPropertySetInfo!"); 85 86 // collect the properties which need to be exported 87 examinePersistence(); 88 } 89 90 //--------------------------------------------------------------------- 91 bool OPropertyExport::shouldExportProperty( const ::rtl::OUString& i_propertyName ) const 92 { 93 // if the property state is DEFAULT, it does not need to be written - at least 94 // if it's a built-in property, and not a dynamically-added one. 95 bool bIsDefaultValue = m_xPropertyState.is() 96 && ( PropertyState_DEFAULT_VALUE == m_xPropertyState->getPropertyState( i_propertyName ) ); 97 bool bIsDynamicProperty = m_xPropertyInfo.is() 98 && ( ( m_xPropertyInfo->getPropertyByName( i_propertyName ).Attributes & PropertyAttribute::REMOVEABLE ) != 0 ); 99 return ( !bIsDefaultValue || bIsDynamicProperty ); 100 } 101 102 //--------------------------------------------------------------------- 103 void OPropertyExport::exportRemainingProperties() 104 { 105 // the properties tag (will be created if we have at least one no-default property) 106 SvXMLElementExport* pPropertiesTag = NULL; 107 108 try 109 { 110 Any aValue; 111 ::rtl::OUString sValue; 112 113 // loop through all the properties which are yet to be exported 114 for ( ConstStringSetIterator aProperty = m_aRemainingProps.begin(); 115 aProperty != m_aRemainingProps.end(); 116 ++aProperty 117 ) 118 { 119 DBG_CHECK_PROPERTY_NO_TYPE(*aProperty); 120 121 #if OSL_DEBUG_LEVEL > 0 122 const ::rtl::OUString sPropertyName = *aProperty; (void)sPropertyName; 123 #endif 124 if ( !shouldExportProperty( *aProperty ) ) 125 continue; 126 127 // now that we have the first sub-tag we need the form:properties element 128 if (!pPropertiesTag) 129 pPropertiesTag = new SvXMLElementExport(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, token::XML_PROPERTIES, sal_True, sal_True); 130 131 // add the name attribute 132 AddAttribute(XML_NAMESPACE_FORM, token::XML_PROPERTY_NAME, *aProperty); 133 134 // get the value 135 aValue = m_xProps->getPropertyValue(*aProperty); 136 137 // the type to export 138 Type aExportType; 139 140 // is it a sequence 141 sal_Bool bIsSequence = TypeClass_SEQUENCE == aValue.getValueTypeClass(); 142 // the type of the property, maybe reduced to the element type of a sequence 143 if (bIsSequence) 144 aExportType = getSequenceElementType( aValue.getValueType() ); 145 else 146 aExportType = aValue.getValueType(); 147 148 // the type attribute 149 // modified by BerryJia for Bug102407 150 bool bIsEmptyValue = TypeClass_VOID == aValue.getValueType().getTypeClass(); 151 if ( bIsEmptyValue ) 152 { 153 com::sun::star::beans::Property aPropDesc; 154 aPropDesc = m_xPropertyInfo->getPropertyByName( *aProperty ); 155 aExportType = aPropDesc.Type; 156 } 157 token::XMLTokenEnum eValueType = implGetPropertyXMLType( aExportType ); 158 159 if ( bIsEmptyValue ) 160 AddAttribute( XML_NAMESPACE_OFFICE, token::XML_VALUE_TYPE, token::XML_VOID ); 161 else 162 AddAttribute( XML_NAMESPACE_OFFICE, token::XML_VALUE_TYPE, eValueType ); 163 164 token::XMLTokenEnum eValueAttName( token::XML_VALUE ); 165 switch ( eValueType ) 166 { 167 case token::XML_BOOLEAN: eValueAttName = token::XML_BOOLEAN_VALUE; break; 168 case token::XML_STRING: eValueAttName = token::XML_STRING_VALUE; break; 169 default: break; 170 } 171 172 if( !bIsSequence && !bIsEmptyValue ) 173 { // the simple case 174 //add by BerryJia for Bug102407 175 sValue = implConvertAny(aValue); 176 AddAttribute(XML_NAMESPACE_OFFICE, eValueAttName, sValue ); 177 } 178 179 180 // start the property tag 181 SvXMLElementExport aValueTag1(m_rContext.getGlobalContext(), 182 XML_NAMESPACE_FORM, 183 bIsSequence ? token::XML_LIST_PROPERTY 184 : token::XML_PROPERTY, sal_True, sal_True); 185 186 if (!bIsSequence) 187 continue; 188 189 // the not-that-simple case, we need to iterate through the sequence elements 190 IIterator* pSequenceIterator = NULL; 191 192 switch ( aExportType.getTypeClass() ) 193 { 194 case TypeClass_STRING: 195 pSequenceIterator = new OSequenceIterator< ::rtl::OUString >(aValue); 196 break; 197 case TypeClass_DOUBLE: 198 pSequenceIterator = new OSequenceIterator< double >(aValue); 199 break; 200 case TypeClass_BOOLEAN: 201 pSequenceIterator = new OSequenceIterator< sal_Bool >(aValue); 202 break; 203 case TypeClass_BYTE: 204 pSequenceIterator = new OSequenceIterator< sal_Int8 >(aValue); 205 break; 206 case TypeClass_SHORT: 207 pSequenceIterator = new OSequenceIterator< sal_Int16 >(aValue); 208 break; 209 case TypeClass_LONG: 210 pSequenceIterator = new OSequenceIterator< sal_Int32 >(aValue); 211 break; 212 case TypeClass_HYPER: 213 pSequenceIterator = new OSequenceIterator< sal_Int64 >(aValue); 214 break; 215 default: 216 OSL_ENSURE(sal_False, "OPropertyExport::exportRemainingProperties: unsupported sequence tyoe !"); 217 break; 218 } 219 if (pSequenceIterator) 220 { 221 while (pSequenceIterator->hasMoreElements()) 222 { 223 sValue = 224 implConvertAny(pSequenceIterator->nextElement()); 225 AddAttribute(XML_NAMESPACE_OFFICE, eValueAttName, sValue ); 226 SvXMLElementExport aValueTag( 227 m_rContext.getGlobalContext(), 228 XML_NAMESPACE_FORM, token::XML_LIST_VALUE, 229 sal_True, sal_False); 230 } 231 } 232 delete pSequenceIterator; 233 } 234 } 235 catch(...) 236 { 237 delete pPropertiesTag; 238 throw; 239 } 240 delete pPropertiesTag; 241 } 242 243 //--------------------------------------------------------------------- 244 void OPropertyExport::examinePersistence() 245 { 246 m_aRemainingProps.clear(); 247 Sequence< Property > aProperties = m_xPropertyInfo->getProperties(); 248 const Property* pProperties = aProperties.getConstArray(); 249 for (sal_Int32 i=0; i<aProperties.getLength(); ++i, ++pProperties) 250 { 251 // no transient props 252 if ( pProperties->Attributes & PropertyAttribute::TRANSIENT ) 253 continue; 254 // no read-only props 255 if ( ( pProperties->Attributes & PropertyAttribute::READONLY ) != 0 ) 256 // except they're dynamically added 257 if ( ( pProperties->Attributes & PropertyAttribute::REMOVEABLE ) == 0 ) 258 continue; 259 m_aRemainingProps.insert(pProperties->Name); 260 } 261 } 262 263 //--------------------------------------------------------------------- 264 void OPropertyExport::exportStringPropertyAttribute( const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName, 265 const ::rtl::OUString& _rPropertyName ) 266 { 267 DBG_CHECK_PROPERTY( _rPropertyName, ::rtl::OUString ); 268 269 // no try-catch here, this would be to expensive. The outer scope has to handle exceptions (which should not 270 // happen if we're used correctly :) 271 272 // this is way simple, as we don't need to convert anything (the property already is a string) 273 274 // get the string 275 ::rtl::OUString sPropValue; 276 m_xProps->getPropertyValue( _rPropertyName ) >>= sPropValue; 277 278 // add the attribute 279 if ( sPropValue.getLength() ) 280 AddAttribute( _nNamespaceKey, _pAttributeName, sPropValue ); 281 282 // the property does not need to be handled anymore 283 exportedProperty( _rPropertyName ); 284 } 285 286 //--------------------------------------------------------------------- 287 void OPropertyExport::exportBooleanPropertyAttribute(const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName, 288 const ::rtl::OUString& _rPropertyName, const sal_Int8 _nBooleanAttributeFlags) 289 { 290 DBG_CHECK_PROPERTY_NO_TYPE( _rPropertyName ); 291 // no check of the property value type: this method is allowed to be called with any interger properties 292 // (e.g. sal_Int32, sal_uInt16 etc) 293 294 sal_Bool bDefault = (BOOLATTR_DEFAULT_TRUE == (BOOLATTR_DEFAULT_MASK & _nBooleanAttributeFlags)); 295 sal_Bool bDefaultVoid = (BOOLATTR_DEFAULT_VOID == (BOOLATTR_DEFAULT_MASK & _nBooleanAttributeFlags)); 296 297 // get the value 298 sal_Bool bCurrentValue = bDefault; 299 Any aCurrentValue = m_xProps->getPropertyValue( _rPropertyName ); 300 if (aCurrentValue.hasValue()) 301 { 302 bCurrentValue = ::cppu::any2bool(aCurrentValue); 303 // this will extract a boolean value even if the Any contains a int or short or something like that ... 304 305 if (_nBooleanAttributeFlags & BOOLATTR_INVERSE_SEMANTICS) 306 bCurrentValue = !bCurrentValue; 307 308 // we have a non-void current value 309 if (bDefaultVoid || (bDefault != bCurrentValue)) 310 // and (the default is void, or the non-void default does not equal the current value) 311 // -> write the attribute 312 AddAttribute(_nNamespaceKey, _pAttributeName, bCurrentValue ? m_sValueTrue : m_sValueFalse); 313 } 314 else 315 // we have a void current value 316 if (!bDefaultVoid) 317 // and we have a non-void default 318 // -> write the attribute 319 AddAttribute(_nNamespaceKey, _pAttributeName, bCurrentValue ? m_sValueTrue : m_sValueFalse); 320 321 // the property does not need to be handled anymore 322 exportedProperty( _rPropertyName ); 323 } 324 325 //--------------------------------------------------------------------- 326 void OPropertyExport::exportInt16PropertyAttribute(const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName, 327 const ::rtl::OUString& _rPropertyName, const sal_Int16 _nDefault) 328 { 329 DBG_CHECK_PROPERTY( _rPropertyName, sal_Int16 ); 330 331 // get the value 332 sal_Int16 nCurrentValue(_nDefault); 333 m_xProps->getPropertyValue( _rPropertyName ) >>= nCurrentValue; 334 335 // add the attribute 336 if (_nDefault != nCurrentValue) 337 { 338 // let the formatter of the export context build a string 339 ::rtl::OUStringBuffer sBuffer; 340 m_rContext.getGlobalContext().GetMM100UnitConverter().convertNumber(sBuffer, (sal_Int32)nCurrentValue); 341 342 AddAttribute(_nNamespaceKey, _pAttributeName, sBuffer.makeStringAndClear()); 343 } 344 345 // the property does not need to be handled anymore 346 exportedProperty( _rPropertyName ); 347 } 348 349 //--------------------------------------------------------------------- 350 void OPropertyExport::exportInt32PropertyAttribute( const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName, 351 const ::rtl::OUString& _rPropertyName, const sal_Int32 _nDefault ) 352 { 353 DBG_CHECK_PROPERTY( _rPropertyName, sal_Int32 ); 354 355 // get the value 356 sal_Int32 nCurrentValue( _nDefault ); 357 m_xProps->getPropertyValue( _rPropertyName ) >>= nCurrentValue; 358 359 // add the attribute 360 if ( _nDefault != nCurrentValue ) 361 { 362 // let the formatter of the export context build a string 363 ::rtl::OUStringBuffer sBuffer; 364 m_rContext.getGlobalContext().GetMM100UnitConverter().convertNumber( sBuffer, nCurrentValue ); 365 366 AddAttribute( _nNamespaceKey, _pAttributeName, sBuffer.makeStringAndClear() ); 367 } 368 369 // the property does not need to be handled anymore 370 exportedProperty( _rPropertyName ); 371 } 372 373 //--------------------------------------------------------------------- 374 void OPropertyExport::exportEnumPropertyAttribute( 375 const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName, 376 const sal_Char* _pPropertyName, const SvXMLEnumMapEntry* _pValueMap, 377 const sal_Int32 _nDefault, const sal_Bool _bVoidDefault) 378 { 379 // get the value 380 sal_Int32 nCurrentValue(_nDefault); 381 ::rtl::OUString sPropertyName(::rtl::OUString::createFromAscii(_pPropertyName)); 382 Any aValue = m_xProps->getPropertyValue(sPropertyName); 383 384 if (aValue.hasValue()) 385 { // we have a non-void current value 386 ::cppu::enum2int(nCurrentValue, aValue); 387 388 // add the attribute 389 if ((_nDefault != nCurrentValue) || _bVoidDefault) 390 { // the default does not equal the value, or the default is void and the value isn't 391 392 // let the formatter of the export context build a string 393 ::rtl::OUStringBuffer sBuffer; 394 m_rContext.getGlobalContext().GetMM100UnitConverter().convertEnum(sBuffer, (sal_uInt16)nCurrentValue, _pValueMap); 395 396 AddAttribute(_nNamespaceKey, _pAttributeName, sBuffer.makeStringAndClear()); 397 } 398 } 399 else 400 { 401 if (!_bVoidDefault) 402 AddAttributeASCII(_nNamespaceKey, _pAttributeName, ""); 403 } 404 405 // the property does not need to be handled anymore 406 exportedProperty(sPropertyName); 407 } 408 409 //--------------------------------------------------------------------- 410 void OPropertyExport::exportTargetFrameAttribute() 411 { 412 DBG_CHECK_PROPERTY( PROPERTY_TARGETFRAME, ::rtl::OUString ); 413 414 ::rtl::OUString sTargetFrame = comphelper::getString(m_xProps->getPropertyValue(PROPERTY_TARGETFRAME)); 415 if (0 != sTargetFrame.compareToAscii("_blank")) 416 { // an empty string and "_blank" have the same meaning and don't have to be written 417 AddAttribute(OAttributeMetaData::getCommonControlAttributeNamespace(CCA_TARGET_FRAME) 418 ,OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_FRAME) 419 ,sTargetFrame); 420 } 421 422 exportedProperty(PROPERTY_TARGETFRAME); 423 } 424 425 //--------------------------------------------------------------------- 426 void OPropertyExport::exportRelativeTargetLocation(const ConstAsciiString& _sPropertyName,sal_Int32 _nProperty,bool _bAddType) 427 { 428 DBG_CHECK_PROPERTY( _sPropertyName, ::rtl::OUString ); 429 430 ::rtl::OUString sTargetLocation = comphelper::getString(m_xProps->getPropertyValue(_sPropertyName)); 431 if ( sTargetLocation.getLength() ) 432 // If this isn't a GraphicObject then GetRelativeReference 433 // will be called anyway ( in AddEmbeddedGraphic ) 434 sTargetLocation = m_rContext.getGlobalContext().AddEmbeddedGraphicObject(sTargetLocation); 435 AddAttribute(OAttributeMetaData::getCommonControlAttributeNamespace(_nProperty) 436 ,OAttributeMetaData::getCommonControlAttributeName(_nProperty) 437 , sTargetLocation); 438 439 // #i110911# add xlink:type="simple" if required 440 if (_bAddType) 441 AddAttribute(XML_NAMESPACE_XLINK, token::XML_TYPE, token::XML_SIMPLE); 442 443 exportedProperty(_sPropertyName); 444 } 445 //--------------------------------------------------------------------- 446 void OPropertyExport::flagStyleProperties() 447 { 448 // flag all the properties which are part of the style as "handled" 449 UniReference< XMLPropertySetMapper > xStylePropertiesSupplier = m_rContext.getStylePropertyMapper()->getPropertySetMapper(); 450 for (sal_Int32 i=0; i<xStylePropertiesSupplier->GetEntryCount(); ++i) 451 exportedProperty(xStylePropertiesSupplier->GetEntryAPIName(i)); 452 453 // the font properties are exported as single properties, but there is a FontDescriptor property which 454 // collects them all-in-one, this has been exported implicitly 455 exportedProperty(PROPERTY_FONT); 456 457 // for the DateFormat and TimeFormat, there exist wrapper properties which has been exported as 458 // style, too 459 exportedProperty(PROPERTY_DATEFORMAT); 460 exportedProperty(PROPERTY_TIMEFORMAT); 461 462 // the following properties should have been exported at the shape already: 463 exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VerticalAlign" ) ) ); 464 exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WritingMode" ) ) ); 465 exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScaleMode" ) ) ); 466 // ditto the TextWritingMode 467 exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WritingMode" ) ) ); 468 } 469 470 //--------------------------------------------------------------------- 471 void OPropertyExport::exportGenericPropertyAttribute( 472 const sal_uInt16 _nAttributeNamespaceKey, const sal_Char* _pAttributeName, const sal_Char* _pPropertyName) 473 { 474 DBG_CHECK_PROPERTY_ASCII_NO_TYPE( _pPropertyName ); 475 476 ::rtl::OUString sPropertyName = ::rtl::OUString::createFromAscii(_pPropertyName); 477 exportedProperty(sPropertyName); 478 479 Any aCurrentValue = m_xProps->getPropertyValue(sPropertyName); 480 if (!aCurrentValue.hasValue()) 481 // nothing to do without a concrete value 482 return; 483 484 ::rtl::OUString sValue = implConvertAny(aCurrentValue); 485 if (!sValue.getLength() && (TypeClass_STRING == aCurrentValue.getValueTypeClass())) 486 { 487 // check whether or not the property is allowed to be VOID 488 Property aProperty = m_xPropertyInfo->getPropertyByName(sPropertyName); 489 if ((aProperty.Attributes & PropertyAttribute::MAYBEVOID) == 0) 490 // the string is empty, and the property is not allowed to be void 491 // -> don't need to write the attibute, 'cause missing it is unambiguous 492 return; 493 } 494 495 // finally add the attribuite to the context 496 AddAttribute(_nAttributeNamespaceKey, _pAttributeName, sValue); 497 } 498 499 //--------------------------------------------------------------------- 500 void OPropertyExport::exportStringSequenceAttribute(const sal_uInt16 _nAttributeNamespaceKey, const sal_Char* _pAttributeName, 501 const ::rtl::OUString& _rPropertyName, 502 const sal_Unicode _aQuoteCharacter, const sal_Unicode _aListSeparator) 503 { 504 DBG_CHECK_PROPERTY( _rPropertyName, Sequence< ::rtl::OUString > ); 505 OSL_ENSURE(_aListSeparator != 0, "OPropertyExport::exportStringSequenceAttribute: invalid separator character!"); 506 507 Sequence< ::rtl::OUString > aItems; 508 m_xProps->getPropertyValue( _rPropertyName ) >>= aItems; 509 510 ::rtl::OUString sFinalList; 511 512 // unfortunately the OUString can't append single sal_Unicode characters ... 513 const ::rtl::OUString sQuote(&_aQuoteCharacter, 1); 514 const ::rtl::OUString sSeparator(&_aListSeparator, 1); 515 const sal_Bool bQuote = 0 != sQuote.getLength(); 516 517 // concatenate the string items 518 const ::rtl::OUString* pItems = aItems.getConstArray(); 519 const ::rtl::OUString* pEnd = pItems + aItems.getLength(); 520 const ::rtl::OUString* pLastElement = pEnd - 1; 521 for ( ; 522 pItems != pEnd; 523 ++pItems 524 ) 525 { 526 OSL_ENSURE(!_aQuoteCharacter || (-1 == pItems->indexOf(_aQuoteCharacter)), 527 "OPropertyExport::exportStringSequenceAttribute: there is an item which contains the quote character!"); 528 OSL_ENSURE(_aQuoteCharacter || (-1 == pItems->indexOf(_aListSeparator)), 529 "OPropertyExport::exportStringSequenceAttribute: no quote character, but there is an item containing the separator character!"); 530 531 if (bQuote) 532 sFinalList += sQuote; 533 sFinalList += *pItems; 534 if (bQuote) 535 sFinalList += sQuote; 536 537 if (pItems != pLastElement) 538 sFinalList += sSeparator; 539 } 540 541 if (sFinalList.getLength()) 542 AddAttribute(_nAttributeNamespaceKey, _pAttributeName, sFinalList); 543 544 exportedProperty( _rPropertyName ); 545 } 546 547 //--------------------------------------------------------------------- 548 ::rtl::OUString OPropertyExport::implConvertAny(const Any& _rValue) 549 { 550 ::rtl::OUStringBuffer aBuffer; 551 switch (_rValue.getValueTypeClass()) 552 { 553 case TypeClass_STRING: 554 { // extract the string 555 ::rtl::OUString sCurrentValue; 556 _rValue >>= sCurrentValue; 557 aBuffer.append(sCurrentValue); 558 } 559 break; 560 case TypeClass_DOUBLE: 561 // let the unit converter format is as string 562 m_rContext.getGlobalContext().GetMM100UnitConverter().convertDouble(aBuffer, getDouble(_rValue)); 563 break; 564 case TypeClass_BOOLEAN: 565 aBuffer = getBOOL(_rValue) ? m_sValueTrue : m_sValueFalse; 566 break; 567 case TypeClass_BYTE: 568 case TypeClass_SHORT: 569 case TypeClass_LONG: 570 // let the unit converter format is as string 571 m_rContext.getGlobalContext().GetMM100UnitConverter().convertNumber(aBuffer, getINT32(_rValue)); 572 break; 573 case TypeClass_HYPER: 574 // TODO 575 OSL_ENSURE(sal_False, "OPropertyExport::implConvertAny: missing implementation for sal_Int64!"); 576 break; 577 case TypeClass_ENUM: 578 { 579 // convert it into an int32 580 sal_Int32 nValue = 0; 581 ::cppu::enum2int(nValue, _rValue); 582 m_rContext.getGlobalContext().GetMM100UnitConverter().convertNumber(aBuffer, nValue); 583 } 584 break; 585 default: 586 { // hmmm .... what else do we know? 587 double fValue = 0; 588 ::com::sun::star::util::Date aDate; 589 ::com::sun::star::util::Time aTime; 590 ::com::sun::star::util::DateTime aDateTime; 591 if (_rValue >>= aDate) 592 { 593 Date aToolsDate; 594 ::utl::typeConvert(aDate, aToolsDate); 595 fValue = aToolsDate.GetDate(); 596 } 597 else if (_rValue >>= aTime) 598 { 599 fValue = ((aTime.Hours * 60 + aTime.Minutes) * 60 + aTime.Seconds) * 100 + aTime.HundredthSeconds; 600 fValue = fValue / 8640000.0; 601 } 602 else if (_rValue >>= aDateTime) 603 { 604 DateTime aToolsDateTime; 605 ::utl::typeConvert(aDateTime, aToolsDateTime); 606 // the time part (the digits behind the comma) 607 fValue = ((aDateTime.Hours * 60 + aDateTime.Minutes) * 60 + aDateTime.Seconds) * 100 + aDateTime.HundredthSeconds; 608 fValue = fValue / 8640000.0; 609 // plus the data part (the digits in front of the comma) 610 fValue += aToolsDateTime.GetDate(); 611 } 612 else 613 { 614 // if any other types are added here, please remember to adjust implGetPropertyXMLType accordingly 615 616 // no more options ... 617 OSL_ENSURE(sal_False, "OPropertyExport::implConvertAny: unsupported value type!"); 618 break; 619 } 620 // let the unit converter format is as string 621 m_rContext.getGlobalContext().GetMM100UnitConverter().convertDouble(aBuffer, fValue); 622 } 623 break; 624 } 625 626 return aBuffer.makeStringAndClear(); 627 } 628 629 630 //--------------------------------------------------------------------- 631 token::XMLTokenEnum OPropertyExport::implGetPropertyXMLType(const ::com::sun::star::uno::Type& _rType) 632 { 633 // handle the type description 634 switch (_rType.getTypeClass()) 635 { 636 case TypeClass_STRING: 637 return token::XML_STRING; 638 case TypeClass_DOUBLE: 639 case TypeClass_BYTE: 640 case TypeClass_SHORT: 641 case TypeClass_LONG: 642 case TypeClass_HYPER: 643 case TypeClass_ENUM: 644 return token::XML_FLOAT; 645 case TypeClass_BOOLEAN: 646 return token::XML_BOOLEAN; 647 648 default: 649 return token::XML_FLOAT; 650 } 651 } 652 653 #ifdef DBG_UTIL 654 //--------------------------------------------------------------------- 655 void OPropertyExport::AddAttribute(sal_uInt16 _nPrefix, const sal_Char* _pName, const ::rtl::OUString& _rValue) 656 { 657 OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::rtl::OUString::createFromAscii(_pName)).getLength(), 658 "OPropertyExport::AddAttribute: already have such an attribute"); 659 660 m_rContext.getGlobalContext().AddAttribute(_nPrefix, _pName, _rValue); 661 } 662 663 //--------------------------------------------------------------------- 664 void OPropertyExport::AddAttribute( sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, const ::rtl::OUString& _rValue ) 665 { 666 OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName( _rName ).getLength(), 667 "OPropertyExport::AddAttribute: already have such an attribute"); 668 669 m_rContext.getGlobalContext().AddAttribute( _nPrefix, _rName, _rValue ); 670 } 671 672 //--------------------------------------------------------------------- 673 void OPropertyExport::AddAttributeASCII(sal_uInt16 _nPrefix, const sal_Char* _pName, const sal_Char *pValue) 674 { 675 OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::rtl::OUString::createFromAscii(_pName)).getLength(), 676 "OPropertyExport::AddAttributeASCII: already have such an attribute"); 677 678 m_rContext.getGlobalContext().AddAttributeASCII(_nPrefix, _pName, pValue); 679 } 680 681 //--------------------------------------------------------------------- 682 void OPropertyExport::AddAttribute(sal_uInt16 _nPrefix, ::xmloff::token::XMLTokenEnum _eName, const ::rtl::OUString& _rValue) 683 { 684 OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::xmloff::token::GetXMLToken(_eName)).getLength(), 685 "OPropertyExport::AddAttribute: already have such an attribute"); 686 687 m_rContext.getGlobalContext().AddAttribute(_nPrefix, _eName, _rValue); 688 } 689 690 //--------------------------------------------------------------------- 691 void OPropertyExport::AddAttribute(sal_uInt16 _nPrefix, ::xmloff::token::XMLTokenEnum _eName, ::xmloff::token::XMLTokenEnum _eValue ) 692 { 693 OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::xmloff::token::GetXMLToken(_eName)).getLength(), 694 "OPropertyExport::AddAttribute: already have such an attribute"); 695 696 m_rContext.getGlobalContext().AddAttribute(_nPrefix, _eName, _eValue); 697 } 698 699 //--------------------------------------------------------------------- 700 void OPropertyExport::dbg_implCheckProperty(const ::rtl::OUString& _rPropertyName, const Type* _pType) 701 { 702 try 703 { 704 // the property must exist 705 if (!m_xPropertyInfo->hasPropertyByName(_rPropertyName)) 706 { 707 OSL_ENSURE(sal_False, 708 ::rtl::OString("OPropertyExport::dbg_implCheckProperty: no property with the name ") += 709 ::rtl::OString(_rPropertyName.getStr(), _rPropertyName.getLength(), RTL_TEXTENCODING_ASCII_US) += 710 ::rtl::OString("!")); 711 return; 712 } 713 714 if (_pType) 715 { 716 // and it must have the correct type 717 Property aPropertyDescription = m_xPropertyInfo->getPropertyByName(_rPropertyName); 718 OSL_ENSURE(aPropertyDescription.Type.equals(*_pType), "OPropertyExport::dbg_implCheckProperty: invalid property type!"); 719 } 720 } 721 catch(Exception&) 722 { 723 OSL_ENSURE(sal_False, "OPropertyExport::dbg_implCheckProperty: caught an exception, could not check the property!"); 724 } 725 } 726 #endif // DBG_UTIL - dbg_implCheckProperty 727 728 //......................................................................... 729 } // namespace xmloff 730 //......................................................................... 731 732 733