|  | /************************************************************** | 
|  | * | 
|  | * Licensed to the Apache Software Foundation (ASF) under one | 
|  | * or more contributor license agreements.  See the NOTICE file | 
|  | * distributed with this work for additional information | 
|  | * regarding copyright ownership.  The ASF licenses this file | 
|  | * to you under the Apache License, Version 2.0 (the | 
|  | * "License"); you may not use this file except in compliance | 
|  | * with the License.  You may obtain a copy of the License at | 
|  | * | 
|  | *   http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, | 
|  | * software distributed under the License is distributed on an | 
|  | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
|  | * KIND, either express or implied.  See the License for the | 
|  | * specific language governing permissions and limitations | 
|  | * under the License. | 
|  | * | 
|  | *************************************************************/ | 
|  |  | 
|  |  | 
|  |  | 
|  | // MARKER(update_precomp.py): autogen include statement, do not remove | 
|  | #include "precompiled_xmloff.hxx" | 
|  |  | 
|  | #include <stdio.h> | 
|  | #include "propertyexport.hxx" | 
|  | #include <xmloff/xmlexp.hxx> | 
|  | #include "strings.hxx" | 
|  | #include "xmloff/xmlnmspe.hxx" | 
|  | #include <xmloff/xmluconv.hxx> | 
|  | #include <xmloff/families.hxx> | 
|  | #include <osl/diagnose.h> | 
|  | #include <com/sun/star/beans/PropertyAttribute.hpp> | 
|  | #include <com/sun/star/util/Date.hpp> | 
|  | #include <com/sun/star/util/Time.hpp> | 
|  | #include <com/sun/star/util/DateTime.hpp> | 
|  | #include <osl/diagnose.h> | 
|  | #include <comphelper/extract.hxx> | 
|  | #include <comphelper/sequence.hxx> | 
|  | #include <comphelper/types.hxx> | 
|  | #include "callbacks.hxx" | 
|  | #include <unotools/datetime.hxx> | 
|  | #include <tools/date.hxx> | 
|  | #include <tools/time.hxx> | 
|  | #include <tools/datetime.hxx> | 
|  |  | 
|  | //......................................................................... | 
|  | namespace xmloff | 
|  | { | 
|  | //......................................................................... | 
|  |  | 
|  | using namespace ::com::sun::star::uno; | 
|  | using namespace ::com::sun::star::lang; | 
|  | using namespace ::com::sun::star::beans; | 
|  |  | 
|  | // NO using namespace ...util !!! | 
|  | // need a tools Date/Time/DateTime below, which would conflict with the uno types then | 
|  |  | 
|  | using namespace ::comphelper; | 
|  |  | 
|  | //===================================================================== | 
|  | //= OPropertyExport | 
|  | //===================================================================== | 
|  | //--------------------------------------------------------------------- | 
|  | OPropertyExport::OPropertyExport(IFormsExportContext& _rContext, const Reference< XPropertySet >& _rxProps) | 
|  | :m_rContext(_rContext) | 
|  | ,m_xProps(_rxProps) | 
|  | ,m_xPropertyInfo( m_xProps->getPropertySetInfo() ) | 
|  | ,m_xPropertyState( _rxProps, UNO_QUERY ) | 
|  | { | 
|  | // caching | 
|  | ::rtl::OUStringBuffer aBuffer; | 
|  | m_rContext.getGlobalContext().GetMM100UnitConverter().convertBool(aBuffer, sal_True); | 
|  | m_sValueTrue = aBuffer.makeStringAndClear(); | 
|  | m_rContext.getGlobalContext().GetMM100UnitConverter().convertBool(aBuffer, sal_False); | 
|  | m_sValueFalse = aBuffer.makeStringAndClear(); | 
|  |  | 
|  | OSL_ENSURE(m_xPropertyInfo.is(), "OPropertyExport::OPropertyExport: need an XPropertySetInfo!"); | 
|  |  | 
|  | // collect the properties which need to be exported | 
|  | examinePersistence(); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | bool OPropertyExport::shouldExportProperty( const ::rtl::OUString& i_propertyName ) const | 
|  | { | 
|  | // if the property state is DEFAULT, it does not need to be written - at least | 
|  | // if it's a built-in property, and not a dynamically-added one. | 
|  | bool bIsDefaultValue =    m_xPropertyState.is() | 
|  | &&  ( PropertyState_DEFAULT_VALUE == m_xPropertyState->getPropertyState( i_propertyName ) ); | 
|  | bool bIsDynamicProperty =  m_xPropertyInfo.is() | 
|  | && ( ( m_xPropertyInfo->getPropertyByName( i_propertyName ).Attributes & PropertyAttribute::REMOVEABLE ) != 0 ); | 
|  | return ( !bIsDefaultValue || bIsDynamicProperty ); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::exportRemainingProperties() | 
|  | { | 
|  | // the properties tag (will be created if we have at least one no-default property) | 
|  | SvXMLElementExport* pPropertiesTag = NULL; | 
|  |  | 
|  | try | 
|  | { | 
|  | Any aValue; | 
|  | ::rtl::OUString sValue; | 
|  |  | 
|  | // loop through all the properties which are yet to be exported | 
|  | for	(	ConstStringSetIterator	aProperty = m_aRemainingProps.begin(); | 
|  | aProperty != m_aRemainingProps.end(); | 
|  | ++aProperty | 
|  | ) | 
|  | { | 
|  | DBG_CHECK_PROPERTY_NO_TYPE(*aProperty); | 
|  |  | 
|  | #if OSL_DEBUG_LEVEL > 0 | 
|  | const ::rtl::OUString sPropertyName = *aProperty; (void)sPropertyName; | 
|  | #endif | 
|  | if ( !shouldExportProperty( *aProperty ) ) | 
|  | continue; | 
|  |  | 
|  | // now that we have the first sub-tag we need the form:properties element | 
|  | if (!pPropertiesTag) | 
|  | pPropertiesTag = new SvXMLElementExport(m_rContext.getGlobalContext(), XML_NAMESPACE_FORM, token::XML_PROPERTIES, sal_True, sal_True); | 
|  |  | 
|  | // add the name attribute | 
|  | AddAttribute(XML_NAMESPACE_FORM, token::XML_PROPERTY_NAME, *aProperty); | 
|  |  | 
|  | // get the value | 
|  | aValue = m_xProps->getPropertyValue(*aProperty); | 
|  |  | 
|  | // the type to export | 
|  | Type aExportType; | 
|  |  | 
|  | // is it a sequence | 
|  | sal_Bool bIsSequence = TypeClass_SEQUENCE == aValue.getValueTypeClass(); | 
|  | // the type of the property, maybe reduced to the element type of a sequence | 
|  | if (bIsSequence) | 
|  | aExportType = getSequenceElementType( aValue.getValueType() ); | 
|  | else | 
|  | aExportType = aValue.getValueType(); | 
|  |  | 
|  | // the type attribute | 
|  | // modified by BerryJia for Bug102407 | 
|  | bool bIsEmptyValue = TypeClass_VOID == aValue.getValueType().getTypeClass(); | 
|  | if ( bIsEmptyValue ) | 
|  | { | 
|  | com::sun::star::beans::Property aPropDesc; | 
|  | aPropDesc = m_xPropertyInfo->getPropertyByName( *aProperty ); | 
|  | aExportType = aPropDesc.Type; | 
|  | } | 
|  | token::XMLTokenEnum eValueType = implGetPropertyXMLType( aExportType ); | 
|  |  | 
|  | if ( bIsEmptyValue ) | 
|  | AddAttribute( XML_NAMESPACE_OFFICE, token::XML_VALUE_TYPE, token::XML_VOID ); | 
|  | else | 
|  | AddAttribute( XML_NAMESPACE_OFFICE, token::XML_VALUE_TYPE, eValueType ); | 
|  |  | 
|  | token::XMLTokenEnum eValueAttName( token::XML_VALUE ); | 
|  | switch ( eValueType ) | 
|  | { | 
|  | case token::XML_BOOLEAN:    eValueAttName = token::XML_BOOLEAN_VALUE; break; | 
|  | case token::XML_STRING:     eValueAttName = token::XML_STRING_VALUE;  break; | 
|  | default:    break; | 
|  | } | 
|  |  | 
|  | if( !bIsSequence && !bIsEmptyValue ) | 
|  | {	// the simple case | 
|  | //add by BerryJia for Bug102407 | 
|  | sValue = implConvertAny(aValue); | 
|  | AddAttribute(XML_NAMESPACE_OFFICE, eValueAttName, sValue ); | 
|  | } | 
|  |  | 
|  |  | 
|  | // start the property tag | 
|  | SvXMLElementExport aValueTag1(m_rContext.getGlobalContext(), | 
|  | XML_NAMESPACE_FORM, | 
|  | bIsSequence ? token::XML_LIST_PROPERTY | 
|  | : token::XML_PROPERTY, sal_True, sal_True); | 
|  |  | 
|  | if (!bIsSequence) | 
|  | continue; | 
|  |  | 
|  | // the not-that-simple case, we need to iterate through the sequence elements | 
|  | IIterator* pSequenceIterator = NULL; | 
|  |  | 
|  | switch ( aExportType.getTypeClass() ) | 
|  | { | 
|  | case TypeClass_STRING: | 
|  | pSequenceIterator = new OSequenceIterator< ::rtl::OUString >(aValue); | 
|  | break; | 
|  | case TypeClass_DOUBLE: | 
|  | pSequenceIterator = new OSequenceIterator< double >(aValue); | 
|  | break; | 
|  | case TypeClass_BOOLEAN: | 
|  | pSequenceIterator = new OSequenceIterator< sal_Bool >(aValue); | 
|  | break; | 
|  | case TypeClass_BYTE: | 
|  | pSequenceIterator = new OSequenceIterator< sal_Int8 >(aValue); | 
|  | break; | 
|  | case TypeClass_SHORT: | 
|  | pSequenceIterator = new OSequenceIterator< sal_Int16 >(aValue); | 
|  | break; | 
|  | case TypeClass_LONG: | 
|  | pSequenceIterator = new OSequenceIterator< sal_Int32 >(aValue); | 
|  | break; | 
|  | case TypeClass_HYPER: | 
|  | pSequenceIterator = new OSequenceIterator< sal_Int64 >(aValue); | 
|  | break; | 
|  | default: | 
|  | OSL_ENSURE(sal_False, "OPropertyExport::exportRemainingProperties: unsupported sequence tyoe !"); | 
|  | break; | 
|  | } | 
|  | if (pSequenceIterator) | 
|  | { | 
|  | while (pSequenceIterator->hasMoreElements()) | 
|  | { | 
|  | sValue = | 
|  | implConvertAny(pSequenceIterator->nextElement()); | 
|  | AddAttribute(XML_NAMESPACE_OFFICE, eValueAttName, sValue ); | 
|  | SvXMLElementExport aValueTag( | 
|  | m_rContext.getGlobalContext(), | 
|  | XML_NAMESPACE_FORM, token::XML_LIST_VALUE, | 
|  | sal_True, sal_False); | 
|  | } | 
|  | } | 
|  | delete pSequenceIterator; | 
|  | } | 
|  | } | 
|  | catch(...) | 
|  | { | 
|  | delete pPropertiesTag; | 
|  | throw; | 
|  | } | 
|  | delete pPropertiesTag; | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::examinePersistence() | 
|  | { | 
|  | m_aRemainingProps.clear(); | 
|  | Sequence< Property > aProperties = m_xPropertyInfo->getProperties(); | 
|  | const Property* pProperties = aProperties.getConstArray(); | 
|  | for (sal_Int32 i=0; i<aProperties.getLength(); ++i, ++pProperties) | 
|  | { | 
|  | // no transient props | 
|  | if ( pProperties->Attributes & PropertyAttribute::TRANSIENT ) | 
|  | continue; | 
|  | // no read-only props | 
|  | if ( ( pProperties->Attributes & PropertyAttribute::READONLY ) != 0 ) | 
|  | // except they're dynamically added | 
|  | if ( ( pProperties->Attributes & PropertyAttribute::REMOVEABLE ) == 0 ) | 
|  | continue; | 
|  | m_aRemainingProps.insert(pProperties->Name); | 
|  | } | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::exportStringPropertyAttribute( const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName, | 
|  | const ::rtl::OUString& _rPropertyName ) | 
|  | { | 
|  | DBG_CHECK_PROPERTY( _rPropertyName, ::rtl::OUString ); | 
|  |  | 
|  | // no try-catch here, this would be to expensive. The outer scope has to handle exceptions (which should not | 
|  | // happen if we're used correctly :) | 
|  |  | 
|  | // this is way simple, as we don't need to convert anything (the property already is a string) | 
|  |  | 
|  | // get the string | 
|  | ::rtl::OUString sPropValue; | 
|  | m_xProps->getPropertyValue( _rPropertyName ) >>= sPropValue; | 
|  |  | 
|  | // add the attribute | 
|  | if ( sPropValue.getLength() ) | 
|  | AddAttribute( _nNamespaceKey, _pAttributeName, sPropValue ); | 
|  |  | 
|  | // the property does not need to be handled anymore | 
|  | exportedProperty( _rPropertyName ); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::exportBooleanPropertyAttribute(const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName, | 
|  | const ::rtl::OUString& _rPropertyName, const sal_Int8 _nBooleanAttributeFlags) | 
|  | { | 
|  | DBG_CHECK_PROPERTY_NO_TYPE( _rPropertyName ); | 
|  | // no check of the property value type: this method is allowed to be called with any integer properties | 
|  | // (e.g. sal_Int32, sal_uInt16 etc) | 
|  |  | 
|  | sal_Bool bDefault = (BOOLATTR_DEFAULT_TRUE == (BOOLATTR_DEFAULT_MASK & _nBooleanAttributeFlags)); | 
|  | sal_Bool bDefaultVoid = (BOOLATTR_DEFAULT_VOID == (BOOLATTR_DEFAULT_MASK & _nBooleanAttributeFlags)); | 
|  |  | 
|  | // get the value | 
|  | sal_Bool bCurrentValue = bDefault; | 
|  | Any aCurrentValue = m_xProps->getPropertyValue( _rPropertyName ); | 
|  | if (aCurrentValue.hasValue()) | 
|  | { | 
|  | bCurrentValue = ::cppu::any2bool(aCurrentValue); | 
|  | // this will extract a boolean value even if the Any contains a int or short or something like that ... | 
|  |  | 
|  | if (_nBooleanAttributeFlags & BOOLATTR_INVERSE_SEMANTICS) | 
|  | bCurrentValue = !bCurrentValue; | 
|  |  | 
|  | // we have a non-void current value | 
|  | if (bDefaultVoid || (bDefault != bCurrentValue)) | 
|  | // and (the default is void, or the non-void default does not equal the current value) | 
|  | // -> write the attribute | 
|  | AddAttribute(_nNamespaceKey, _pAttributeName, bCurrentValue ? m_sValueTrue : m_sValueFalse); | 
|  | } | 
|  | else | 
|  | // we have a void current value | 
|  | if (!bDefaultVoid) | 
|  | // and we have a non-void default | 
|  | // -> write the attribute | 
|  | AddAttribute(_nNamespaceKey, _pAttributeName, bCurrentValue ? m_sValueTrue : m_sValueFalse); | 
|  |  | 
|  | // the property does not need to be handled anymore | 
|  | exportedProperty( _rPropertyName ); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::exportInt16PropertyAttribute(const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName, | 
|  | const ::rtl::OUString& _rPropertyName, const sal_Int16 _nDefault) | 
|  | { | 
|  | DBG_CHECK_PROPERTY( _rPropertyName, sal_Int16 ); | 
|  |  | 
|  | // get the value | 
|  | sal_Int16 nCurrentValue(_nDefault); | 
|  | m_xProps->getPropertyValue( _rPropertyName ) >>= nCurrentValue; | 
|  |  | 
|  | // add the attribute | 
|  | if (_nDefault != nCurrentValue) | 
|  | { | 
|  | // let the formatter of the export context build a string | 
|  | ::rtl::OUStringBuffer sBuffer; | 
|  | m_rContext.getGlobalContext().GetMM100UnitConverter().convertNumber(sBuffer, (sal_Int32)nCurrentValue); | 
|  |  | 
|  | AddAttribute(_nNamespaceKey, _pAttributeName, sBuffer.makeStringAndClear()); | 
|  | } | 
|  |  | 
|  | // the property does not need to be handled anymore | 
|  | exportedProperty( _rPropertyName ); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::exportInt32PropertyAttribute( const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName, | 
|  | const ::rtl::OUString& _rPropertyName, const sal_Int32 _nDefault ) | 
|  | { | 
|  | DBG_CHECK_PROPERTY( _rPropertyName, sal_Int32 ); | 
|  |  | 
|  | // get the value | 
|  | sal_Int32 nCurrentValue( _nDefault ); | 
|  | m_xProps->getPropertyValue( _rPropertyName ) >>= nCurrentValue; | 
|  |  | 
|  | // add the attribute | 
|  | if ( _nDefault != nCurrentValue ) | 
|  | { | 
|  | // let the formatter of the export context build a string | 
|  | ::rtl::OUStringBuffer sBuffer; | 
|  | m_rContext.getGlobalContext().GetMM100UnitConverter().convertNumber( sBuffer, nCurrentValue ); | 
|  |  | 
|  | AddAttribute( _nNamespaceKey, _pAttributeName, sBuffer.makeStringAndClear() ); | 
|  | } | 
|  |  | 
|  | // the property does not need to be handled anymore | 
|  | exportedProperty( _rPropertyName ); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::exportEnumPropertyAttribute( | 
|  | const sal_uInt16 _nNamespaceKey, const sal_Char* _pAttributeName, | 
|  | const sal_Char* _pPropertyName, const SvXMLEnumMapEntry* _pValueMap, | 
|  | const sal_Int32 _nDefault, const sal_Bool _bVoidDefault) | 
|  | { | 
|  | // get the value | 
|  | sal_Int32 nCurrentValue(_nDefault); | 
|  | ::rtl::OUString sPropertyName(::rtl::OUString::createFromAscii(_pPropertyName)); | 
|  | Any aValue = m_xProps->getPropertyValue(sPropertyName); | 
|  |  | 
|  | if (aValue.hasValue()) | 
|  | {	// we have a non-void current value | 
|  | ::cppu::enum2int(nCurrentValue, aValue); | 
|  |  | 
|  | // add the attribute | 
|  | if ((_nDefault != nCurrentValue) || _bVoidDefault) | 
|  | {	// the default does not equal the value, or the default is void and the value isn't | 
|  |  | 
|  | // let the formatter of the export context build a string | 
|  | ::rtl::OUStringBuffer sBuffer; | 
|  | m_rContext.getGlobalContext().GetMM100UnitConverter().convertEnum(sBuffer, (sal_uInt16)nCurrentValue, _pValueMap); | 
|  |  | 
|  | AddAttribute(_nNamespaceKey, _pAttributeName, sBuffer.makeStringAndClear()); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if (!_bVoidDefault) | 
|  | AddAttributeASCII(_nNamespaceKey, _pAttributeName, ""); | 
|  | } | 
|  |  | 
|  | // the property does not need to be handled anymore | 
|  | exportedProperty(sPropertyName); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::exportTargetFrameAttribute() | 
|  | { | 
|  | DBG_CHECK_PROPERTY( PROPERTY_TARGETFRAME, ::rtl::OUString ); | 
|  |  | 
|  | ::rtl::OUString sTargetFrame = comphelper::getString(m_xProps->getPropertyValue(PROPERTY_TARGETFRAME)); | 
|  | if (0 != sTargetFrame.compareToAscii("_blank")) | 
|  | {	// an empty string and "_blank" have the same meaning and don't have to be written | 
|  | AddAttribute(OAttributeMetaData::getCommonControlAttributeNamespace(CCA_TARGET_FRAME) | 
|  | ,OAttributeMetaData::getCommonControlAttributeName(CCA_TARGET_FRAME) | 
|  | ,sTargetFrame); | 
|  | } | 
|  |  | 
|  | exportedProperty(PROPERTY_TARGETFRAME); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::exportRelativeTargetLocation(const ConstAsciiString& _sPropertyName,sal_Int32 _nProperty,bool _bAddType) | 
|  | { | 
|  | DBG_CHECK_PROPERTY( _sPropertyName, ::rtl::OUString ); | 
|  |  | 
|  | ::rtl::OUString sTargetLocation = comphelper::getString(m_xProps->getPropertyValue(_sPropertyName)); | 
|  | if ( sTargetLocation.getLength() ) | 
|  | // If this isn't a GraphicObject then GetRelativeReference | 
|  | // will be called anyway ( in AddEmbeddedGraphic ) | 
|  | sTargetLocation = m_rContext.getGlobalContext().AddEmbeddedGraphicObject(sTargetLocation); | 
|  | AddAttribute(OAttributeMetaData::getCommonControlAttributeNamespace(_nProperty) | 
|  | ,OAttributeMetaData::getCommonControlAttributeName(_nProperty) | 
|  | , sTargetLocation); | 
|  |  | 
|  | // #i110911# add xlink:type="simple" if required | 
|  | if (_bAddType) | 
|  | AddAttribute(XML_NAMESPACE_XLINK, token::XML_TYPE, token::XML_SIMPLE); | 
|  |  | 
|  | exportedProperty(_sPropertyName); | 
|  | } | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::flagStyleProperties() | 
|  | { | 
|  | // flag all the properties which are part of the style as "handled" | 
|  | UniReference< XMLPropertySetMapper > xStylePropertiesSupplier = m_rContext.getStylePropertyMapper()->getPropertySetMapper(); | 
|  | for (sal_Int32 i=0; i<xStylePropertiesSupplier->GetEntryCount(); ++i) | 
|  | exportedProperty(xStylePropertiesSupplier->GetEntryAPIName(i)); | 
|  |  | 
|  | // the font properties are exported as single properties, but there is a FontDescriptor property which | 
|  | // collects them all-in-one, this has been exported implicitly | 
|  | exportedProperty(PROPERTY_FONT); | 
|  |  | 
|  | // for the DateFormat and TimeFormat, there exist wrapper properties which has been exported as | 
|  | // style, too | 
|  | exportedProperty(PROPERTY_DATEFORMAT); | 
|  | exportedProperty(PROPERTY_TIMEFORMAT); | 
|  |  | 
|  | // the following properties should have been exported at the shape already: | 
|  | exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VerticalAlign" ) ) ); | 
|  | exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WritingMode" ) ) ); | 
|  | exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScaleMode" ) ) ); | 
|  | // ditto the TextWritingMode | 
|  | exportedProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WritingMode" ) ) ); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::exportGenericPropertyAttribute( | 
|  | const sal_uInt16 _nAttributeNamespaceKey, const sal_Char* _pAttributeName, const sal_Char* _pPropertyName) | 
|  | { | 
|  | DBG_CHECK_PROPERTY_ASCII_NO_TYPE( _pPropertyName ); | 
|  |  | 
|  | ::rtl::OUString sPropertyName = ::rtl::OUString::createFromAscii(_pPropertyName); | 
|  | exportedProperty(sPropertyName); | 
|  |  | 
|  | Any aCurrentValue = m_xProps->getPropertyValue(sPropertyName); | 
|  | if (!aCurrentValue.hasValue()) | 
|  | // nothing to do without a concrete value | 
|  | return; | 
|  |  | 
|  | ::rtl::OUString sValue = implConvertAny(aCurrentValue); | 
|  | if (!sValue.getLength() && (TypeClass_STRING == aCurrentValue.getValueTypeClass())) | 
|  | { | 
|  | // check whether or not the property is allowed to be VOID | 
|  | Property aProperty = m_xPropertyInfo->getPropertyByName(sPropertyName); | 
|  | if ((aProperty.Attributes & PropertyAttribute::MAYBEVOID) == 0) | 
|  | // the string is empty, and the property is not allowed to be void | 
|  | // -> don't need to write the attibute, 'cause missing it is unambiguous | 
|  | return; | 
|  | } | 
|  |  | 
|  | // finally add the attribuite to the context | 
|  | AddAttribute(_nAttributeNamespaceKey, _pAttributeName, sValue); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::exportStringSequenceAttribute(const sal_uInt16 _nAttributeNamespaceKey, const sal_Char* _pAttributeName, | 
|  | const ::rtl::OUString& _rPropertyName, | 
|  | const sal_Unicode _aQuoteCharacter, const sal_Unicode _aListSeparator) | 
|  | { | 
|  | DBG_CHECK_PROPERTY( _rPropertyName, Sequence< ::rtl::OUString > ); | 
|  | OSL_ENSURE(_aListSeparator != 0, "OPropertyExport::exportStringSequenceAttribute: invalid separator character!"); | 
|  |  | 
|  | Sequence< ::rtl::OUString > aItems; | 
|  | m_xProps->getPropertyValue( _rPropertyName ) >>= aItems; | 
|  |  | 
|  | ::rtl::OUString sFinalList; | 
|  |  | 
|  | // unfortunately the OUString can't append single sal_Unicode characters ... | 
|  | const ::rtl::OUString sQuote(&_aQuoteCharacter, 1); | 
|  | const ::rtl::OUString sSeparator(&_aListSeparator, 1); | 
|  | const sal_Bool bQuote = 0 != sQuote.getLength(); | 
|  |  | 
|  | // concatenate the string items | 
|  | const ::rtl::OUString* pItems = aItems.getConstArray(); | 
|  | const ::rtl::OUString* pEnd = pItems + aItems.getLength(); | 
|  | const ::rtl::OUString* pLastElement = pEnd - 1; | 
|  | for	(	; | 
|  | pItems != pEnd; | 
|  | ++pItems | 
|  | ) | 
|  | { | 
|  | OSL_ENSURE(!_aQuoteCharacter || (-1 == pItems->indexOf(_aQuoteCharacter)), | 
|  | "OPropertyExport::exportStringSequenceAttribute: there is an item which contains the quote character!"); | 
|  | OSL_ENSURE(_aQuoteCharacter || (-1 == pItems->indexOf(_aListSeparator)), | 
|  | "OPropertyExport::exportStringSequenceAttribute: no quote character, but there is an item containing the separator character!"); | 
|  |  | 
|  | if (bQuote) | 
|  | sFinalList += sQuote; | 
|  | sFinalList += *pItems; | 
|  | if (bQuote) | 
|  | sFinalList += sQuote; | 
|  |  | 
|  | if (pItems != pLastElement) | 
|  | sFinalList += sSeparator; | 
|  | } | 
|  |  | 
|  | if (sFinalList.getLength()) | 
|  | AddAttribute(_nAttributeNamespaceKey, _pAttributeName, sFinalList); | 
|  |  | 
|  | exportedProperty( _rPropertyName ); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | ::rtl::OUString OPropertyExport::implConvertAny(const Any& _rValue) | 
|  | { | 
|  | ::rtl::OUStringBuffer aBuffer; | 
|  | switch (_rValue.getValueTypeClass()) | 
|  | { | 
|  | case TypeClass_STRING: | 
|  | {	// extract the string | 
|  | ::rtl::OUString sCurrentValue; | 
|  | _rValue >>= sCurrentValue; | 
|  | aBuffer.append(sCurrentValue); | 
|  | } | 
|  | break; | 
|  | case TypeClass_DOUBLE: | 
|  | // let the unit converter format is as string | 
|  | m_rContext.getGlobalContext().GetMM100UnitConverter().convertDouble(aBuffer, getDouble(_rValue)); | 
|  | break; | 
|  | case TypeClass_BOOLEAN: | 
|  | aBuffer = getBOOL(_rValue) ? m_sValueTrue : m_sValueFalse; | 
|  | break; | 
|  | case TypeClass_BYTE: | 
|  | case TypeClass_SHORT: | 
|  | case TypeClass_LONG: | 
|  | // let the unit converter format is as string | 
|  | m_rContext.getGlobalContext().GetMM100UnitConverter().convertNumber(aBuffer, getINT32(_rValue)); | 
|  | break; | 
|  | case TypeClass_HYPER: | 
|  | // TODO | 
|  | OSL_ENSURE(sal_False, "OPropertyExport::implConvertAny: missing implementation for sal_Int64!"); | 
|  | break; | 
|  | case TypeClass_ENUM: | 
|  | { | 
|  | // convert it into an int32 | 
|  | sal_Int32 nValue = 0; | 
|  | ::cppu::enum2int(nValue, _rValue); | 
|  | m_rContext.getGlobalContext().GetMM100UnitConverter().convertNumber(aBuffer, nValue); | 
|  | } | 
|  | break; | 
|  | default: | 
|  | {	// hmmm .... what else do we know? | 
|  | double fValue = 0; | 
|  | ::com::sun::star::util::Date aDate; | 
|  | ::com::sun::star::util::Time aTime; | 
|  | ::com::sun::star::util::DateTime aDateTime; | 
|  | if (_rValue >>= aDate) | 
|  | { | 
|  | Date aToolsDate; | 
|  | ::utl::typeConvert(aDate, aToolsDate); | 
|  | fValue = aToolsDate.GetDate(); | 
|  | } | 
|  | else if (_rValue >>= aTime) | 
|  | { | 
|  | fValue = ((aTime.Hours * 60 + aTime.Minutes) * 60 + aTime.Seconds) * 100 + aTime.HundredthSeconds; | 
|  | fValue = fValue / 8640000.0; | 
|  | } | 
|  | else if (_rValue >>= aDateTime) | 
|  | { | 
|  | DateTime aToolsDateTime; | 
|  | ::utl::typeConvert(aDateTime, aToolsDateTime); | 
|  | // the time part (the digits behind the comma) | 
|  | fValue = ((aDateTime.Hours * 60 + aDateTime.Minutes) * 60 + aDateTime.Seconds) * 100 + aDateTime.HundredthSeconds; | 
|  | fValue = fValue / 8640000.0; | 
|  | // plus the data part (the digits in front of the comma) | 
|  | fValue += aToolsDateTime.GetDate(); | 
|  | } | 
|  | else | 
|  | { | 
|  | // if any other types are added here, please remember to adjust implGetPropertyXMLType accordingly | 
|  |  | 
|  | // no more options ... | 
|  | OSL_ENSURE(sal_False, "OPropertyExport::implConvertAny: unsupported value type!"); | 
|  | break; | 
|  | } | 
|  | // let the unit converter format is as string | 
|  | m_rContext.getGlobalContext().GetMM100UnitConverter().convertDouble(aBuffer, fValue); | 
|  | } | 
|  | break; | 
|  | } | 
|  |  | 
|  | return aBuffer.makeStringAndClear(); | 
|  | } | 
|  |  | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | token::XMLTokenEnum OPropertyExport::implGetPropertyXMLType(const ::com::sun::star::uno::Type& _rType) | 
|  | { | 
|  | // handle the type description | 
|  | switch (_rType.getTypeClass()) | 
|  | { | 
|  | case TypeClass_STRING: | 
|  | return token::XML_STRING; | 
|  | case TypeClass_DOUBLE: | 
|  | case TypeClass_BYTE: | 
|  | case TypeClass_SHORT: | 
|  | case TypeClass_LONG: | 
|  | case TypeClass_HYPER: | 
|  | case TypeClass_ENUM: | 
|  | return token::XML_FLOAT; | 
|  | case TypeClass_BOOLEAN: | 
|  | return token::XML_BOOLEAN; | 
|  |  | 
|  | default: | 
|  | return token::XML_FLOAT; | 
|  | } | 
|  | } | 
|  |  | 
|  | #ifdef DBG_UTIL | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::AddAttribute(sal_uInt16 _nPrefix, const sal_Char* _pName, const ::rtl::OUString& _rValue) | 
|  | { | 
|  | OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::rtl::OUString::createFromAscii(_pName)).getLength(), | 
|  | "OPropertyExport::AddAttribute: already have such an attribute"); | 
|  |  | 
|  | m_rContext.getGlobalContext().AddAttribute(_nPrefix, _pName, _rValue); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::AddAttribute( sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, const ::rtl::OUString& _rValue ) | 
|  | { | 
|  | OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName( _rName ).getLength(), | 
|  | "OPropertyExport::AddAttribute: already have such an attribute"); | 
|  |  | 
|  | m_rContext.getGlobalContext().AddAttribute( _nPrefix, _rName, _rValue ); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::AddAttributeASCII(sal_uInt16 _nPrefix, const sal_Char* _pName, const sal_Char *pValue) | 
|  | { | 
|  | OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::rtl::OUString::createFromAscii(_pName)).getLength(), | 
|  | "OPropertyExport::AddAttributeASCII: already have such an attribute"); | 
|  |  | 
|  | m_rContext.getGlobalContext().AddAttributeASCII(_nPrefix, _pName, pValue); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::AddAttribute(sal_uInt16 _nPrefix, ::xmloff::token::XMLTokenEnum _eName, const ::rtl::OUString& _rValue) | 
|  | { | 
|  | OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::xmloff::token::GetXMLToken(_eName)).getLength(), | 
|  | "OPropertyExport::AddAttribute: already have such an attribute"); | 
|  |  | 
|  | m_rContext.getGlobalContext().AddAttribute(_nPrefix, _eName, _rValue); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::AddAttribute(sal_uInt16 _nPrefix, ::xmloff::token::XMLTokenEnum _eName, ::xmloff::token::XMLTokenEnum _eValue ) | 
|  | { | 
|  | OSL_ENSURE(0 == m_rContext.getGlobalContext().GetXAttrList()->getValueByName(::xmloff::token::GetXMLToken(_eName)).getLength(), | 
|  | "OPropertyExport::AddAttribute: already have such an attribute"); | 
|  |  | 
|  | m_rContext.getGlobalContext().AddAttribute(_nPrefix, _eName, _eValue); | 
|  | } | 
|  |  | 
|  | //--------------------------------------------------------------------- | 
|  | void OPropertyExport::dbg_implCheckProperty(const ::rtl::OUString& _rPropertyName, const Type* _pType) | 
|  | { | 
|  | try | 
|  | { | 
|  | // the property must exist | 
|  | if (!m_xPropertyInfo->hasPropertyByName(_rPropertyName)) | 
|  | { | 
|  | OSL_ENSURE(sal_False, | 
|  | ::rtl::OString("OPropertyExport::dbg_implCheckProperty: no property with the name ") += | 
|  | ::rtl::OString(_rPropertyName.getStr(), _rPropertyName.getLength(), RTL_TEXTENCODING_ASCII_US) += | 
|  | ::rtl::OString("!")); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (_pType) | 
|  | { | 
|  | // and it must have the correct type | 
|  | Property aPropertyDescription = m_xPropertyInfo->getPropertyByName(_rPropertyName); | 
|  | OSL_ENSURE(aPropertyDescription.Type.equals(*_pType), "OPropertyExport::dbg_implCheckProperty: invalid property type!"); | 
|  | } | 
|  | } | 
|  | catch(Exception&) | 
|  | { | 
|  | OSL_ENSURE(sal_False, "OPropertyExport::dbg_implCheckProperty: caught an exception, could not check the property!"); | 
|  | } | 
|  | } | 
|  | #endif // DBG_UTIL - dbg_implCheckProperty | 
|  |  | 
|  | //......................................................................... | 
|  | }	// namespace xmloff | 
|  | //......................................................................... | 
|  |  | 
|  |  |