diff options
Diffstat (limited to 'oox/source/helper/propertymap.cxx')
-rw-r--r-- | oox/source/helper/propertymap.cxx | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/oox/source/helper/propertymap.cxx b/oox/source/helper/propertymap.cxx new file mode 100644 index 000000000000..31072fe449e5 --- /dev/null +++ b/oox/source/helper/propertymap.cxx @@ -0,0 +1,307 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/helper/propertymap.hxx" +#include <osl/mutex.hxx> +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include "properties.hxx" +#include "oox/token/propertylist.hxx" + +using ::rtl::OUString; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::lang::IllegalArgumentException; +using ::com::sun::star::lang::WrappedTargetException; +using ::com::sun::star::beans::Property; +using ::com::sun::star::beans::PropertyValue; +using ::com::sun::star::beans::PropertyVetoException; +using ::com::sun::star::beans::UnknownPropertyException; +using ::com::sun::star::beans::XPropertyChangeListener; +using ::com::sun::star::beans::XPropertySet; +using ::com::sun::star::beans::XPropertySetInfo; +using ::com::sun::star::beans::XVetoableChangeListener; + +#if OSL_DEBUG_LEVEL > 0 +#include <cstdio> +#include <com/sun/star/style/LineSpacing.hpp> +#include <com/sun/star/style/LineSpacingMode.hpp> +#include <com/sun/star/text/WritingMode.hpp> +#define USS(x) OUStringToOString( x, RTL_TEXTENCODING_UTF8 ).getStr() +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using ::rtl::OString; +using ::com::sun::star::style::LineSpacing; +using ::com::sun::star::text::WritingMode; +#endif + +namespace oox { + +// ============================================================================ + +namespace { + +/** Thread-save singleton of a vector of all supported property names. */ +struct StaticPropertyList : public ::rtl::Static< PropertyList, StaticPropertyList > {}; + +// ---------------------------------------------------------------------------- + +typedef ::cppu::WeakImplHelper2< XPropertySet, XPropertySetInfo > GenericPropertySetImplBase; + +/** This class implements a generic XPropertySet. + + Properties of all names and types can be set and later retrieved. + TODO: move this to comphelper or better find an existing implementation + */ +class GenericPropertySet : public GenericPropertySetImplBase, private ::osl::Mutex +{ +public: + explicit GenericPropertySet(); + explicit GenericPropertySet( const PropertyMap& rPropMap ); + + // XPropertySet + virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo() throw (RuntimeException); + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException); + virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException); + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException); + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException); + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException); + + // XPropertySetInfo + virtual Sequence< Property > SAL_CALL getProperties() throw (RuntimeException); + virtual Property SAL_CALL getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException); + virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) throw (RuntimeException); + +private: + typedef ::std::map< OUString, Any > PropertyNameMap; + PropertyNameMap maPropMap; +}; + +// ---------------------------------------------------------------------------- + +GenericPropertySet::GenericPropertySet() +{ +} + +GenericPropertySet::GenericPropertySet( const PropertyMap& rPropMap ) +{ + const PropertyList& rPropNames = StaticPropertyList::get(); + for( PropertyMap::const_iterator aIt = rPropMap.begin(), aEnd = rPropMap.end(); aIt != aEnd; ++aIt ) + maPropMap[ rPropNames[ aIt->first ] ] = aIt->second; +} + +Reference< XPropertySetInfo > SAL_CALL GenericPropertySet::getPropertySetInfo() throw (RuntimeException) +{ + return this; +} + +void SAL_CALL GenericPropertySet::setPropertyValue( const OUString& rPropertyName, const Any& rValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + ::osl::MutexGuard aGuard( *this ); + maPropMap[ rPropertyName ] = rValue; +} + +Any SAL_CALL GenericPropertySet::getPropertyValue( const OUString& rPropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + PropertyNameMap::iterator aIt = maPropMap.find( rPropertyName ); + if( aIt == maPropMap.end() ) + throw UnknownPropertyException(); + return aIt->second; +} + +// listeners are not supported by this implementation +void SAL_CALL GenericPropertySet::addPropertyChangeListener( const OUString& , const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {} +void SAL_CALL GenericPropertySet::removePropertyChangeListener( const OUString& , const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {} +void SAL_CALL GenericPropertySet::addVetoableChangeListener( const OUString& , const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {} +void SAL_CALL GenericPropertySet::removeVetoableChangeListener( const OUString& , const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {} + +// XPropertySetInfo +Sequence< Property > SAL_CALL GenericPropertySet::getProperties() throw (RuntimeException) +{ + Sequence< Property > aSeq( static_cast< sal_Int32 >( maPropMap.size() ) ); + Property* pProperty = aSeq.getArray(); + for( PropertyNameMap::iterator aIt = maPropMap.begin(), aEnd = maPropMap.end(); aIt != aEnd; ++aIt, ++pProperty ) + { + pProperty->Name = aIt->first; + pProperty->Handle = 0; + pProperty->Type = aIt->second.getValueType(); + pProperty->Attributes = 0; + } + return aSeq; +} + +Property SAL_CALL GenericPropertySet::getPropertyByName( const OUString& rPropertyName ) throw (UnknownPropertyException, RuntimeException) +{ + PropertyNameMap::iterator aIt = maPropMap.find( rPropertyName ); + if( aIt == maPropMap.end() ) + throw UnknownPropertyException(); + Property aProperty; + aProperty.Name = aIt->first; + aProperty.Handle = 0; + aProperty.Type = aIt->second.getValueType(); + aProperty.Attributes = 0; + return aProperty; +} + +sal_Bool SAL_CALL GenericPropertySet::hasPropertyByName( const OUString& rPropertyName ) throw (RuntimeException) +{ + return maPropMap.find( rPropertyName ) != maPropMap.end(); +} + +} // namespace + +// ============================================================================ + +PropertyMap::PropertyMap() : + mpPropNames( &StaticPropertyList::get() ) +{ +} + +PropertyMap::~PropertyMap() +{ +} + +/*static*/ const OUString& PropertyMap::getPropertyName( sal_Int32 nPropId ) +{ + OSL_ENSURE( (0 <= nPropId) && (nPropId < PROP_COUNT), "PropertyMap::getPropertyName - invalid property identifier" ); + return StaticPropertyList::get()[ nPropId ]; +} + +const Any* PropertyMap::getProperty( sal_Int32 nPropId ) const +{ + const_iterator aIt = find( nPropId ); + return (aIt == end()) ? 0 : &aIt->second; +} + +Sequence< PropertyValue > PropertyMap::makePropertyValueSequence() const +{ + Sequence< PropertyValue > aSeq( static_cast< sal_Int32 >( size() ) ); + if( !empty() ) + { + PropertyValue* pValues = aSeq.getArray(); + for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt, ++pValues ) + { + OSL_ENSURE( (0 <= aIt->first) && (aIt->first < PROP_COUNT), "PropertyMap::makePropertyValueSequence - invalid property identifier" ); + pValues->Name = (*mpPropNames)[ aIt->first ]; + pValues->Value = aIt->second; + pValues->State = ::com::sun::star::beans::PropertyState_DIRECT_VALUE; + } + } + return aSeq; +} + +void PropertyMap::fillSequences( Sequence< OUString >& rNames, Sequence< Any >& rValues ) const +{ + rNames.realloc( static_cast< sal_Int32 >( size() ) ); + rValues.realloc( static_cast< sal_Int32 >( size() ) ); + if( !empty() ) + { + OUString* pNames = rNames.getArray(); + Any* pValues = rValues.getArray(); + for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt, ++pNames, ++pValues ) + { + OSL_ENSURE( (0 <= aIt->first) && (aIt->first < PROP_COUNT), "PropertyMap::fillSequences - invalid property identifier" ); + *pNames = (*mpPropNames)[ aIt->first ]; + *pValues = aIt->second; + } + } +} + +Reference< XPropertySet > PropertyMap::makePropertySet() const +{ + return new GenericPropertySet( *this ); +} + +#if OSL_DEBUG_LEVEL > 0 +void PropertyMap::dump( Reference< XPropertySet > rXPropSet ) +{ + Reference< XPropertySetInfo > info = rXPropSet->getPropertySetInfo (); + Sequence< beans::Property > props = info->getProperties (); + + OSL_TRACE("dump props, len: %d", props.getLength ()); + + for (int i=0; i < props.getLength (); i++) { + OString name = OUStringToOString( props [i].Name, RTL_TEXTENCODING_UTF8); + fprintf (stderr,"%30s = ", name.getStr() ); + + try { + Any value = rXPropSet->getPropertyValue( props [i].Name ); + + OUString strValue; + sal_Int32 intValue = 0; + sal_uInt32 uintValue = 0; + sal_Int16 int16Value = 0; + sal_uInt16 uint16Value = 0; + bool boolValue = false; + LineSpacing spacing; +// RectanglePoint pointValue; + WritingMode aWritingMode; + + if( value >>= strValue ) + fprintf (stderr,"\"%s\"\n", USS( strValue ) ); + else if( value >>= intValue ) + fprintf (stderr,"%"SAL_PRIdINT32" (hex: %"SAL_PRIxUINT32")\n", intValue, intValue); + else if( value >>= uintValue ) + fprintf (stderr,"%"SAL_PRIdINT32" (hex: %"SAL_PRIxUINT32")\n", uintValue, uintValue); + else if( value >>= int16Value ) + fprintf (stderr,"%d (hex: %x)\n", int16Value, int16Value); + else if( value >>= uint16Value ) + fprintf (stderr,"%d (hex: %x)\n", uint16Value, uint16Value); + else if( value >>= boolValue ) + fprintf (stderr,"%d (bool)\n", boolValue); + else if( value >>= aWritingMode ) + fprintf (stderr, "%d writing mode\n", aWritingMode); + else if( value >>= spacing ) { + fprintf (stderr, "mode: %d value: %d\n", spacing.Mode, spacing.Height); + } else if( value.isExtractableTo(::getCppuType((const sal_Int32*)0))) { + fprintf (stderr,"is extractable to int32\n"); + } +// else if( value >>= pointValue ) +// fprintf (stderr,"%d (RectanglePoint)\n", pointValue); + else + fprintf (stderr,"??? <unhandled type %s>\n", USS(value.getValueTypeName())); + } catch(Exception e) { + fprintf (stderr,"unable to get '%s' value\n", USS(props [i].Name)); + } + } +} + +void PropertyMap::dump() +{ + dump( Reference< XPropertySet >( makePropertySet(), UNO_QUERY ) ); +} +#endif + +// ============================================================================ + +} // namespace oox + |