diff options
author | RĂ¼diger Timm <rt@openoffice.org> | 2008-01-17 07:06:10 +0000 |
---|---|---|
committer | RĂ¼diger Timm <rt@openoffice.org> | 2008-01-17 07:06:10 +0000 |
commit | 3381981e76873304b171f7df900561dac681d2af (patch) | |
tree | f496d5a2006e8719b5783d5a8966a05858ed3014 /oox/inc/oox/helper/containerhelper.hxx | |
parent | 90e7bde2a1f3dd8c81e947578f14f40059961740 (diff) |
#i10000# Bring module to HEAD.
Diffstat (limited to 'oox/inc/oox/helper/containerhelper.hxx')
-rw-r--r-- | oox/inc/oox/helper/containerhelper.hxx | 424 |
1 files changed, 424 insertions, 0 deletions
diff --git a/oox/inc/oox/helper/containerhelper.hxx b/oox/inc/oox/helper/containerhelper.hxx new file mode 100644 index 000000000000..95155358fb59 --- /dev/null +++ b/oox/inc/oox/helper/containerhelper.hxx @@ -0,0 +1,424 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: containerhelper.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2008-01-17 08:05:47 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef OOX_HELPER_CONTAINERHELPER_HXX +#define OOX_HELPER_CONTAINERHELPER_HXX + +#include <vector> +#include <map> +#include <boost/shared_ptr.hpp> +#include <boost/bind.hpp> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/uno/Sequence.h> + +namespace rtl { class OUString; } + +namespace com { namespace sun { namespace star { + namespace container { class XIndexContainer; } + namespace container { class XNameAccess; } + namespace container { class XNameContainer; } +} } } + +namespace oox { + +// ============================================================================ + +/** Template for a vector of ref-counted objects with additional accessor functions. + + An instance of the class RefVector< Type > stores elements of the type + ::boost::shared_ptr< Type >. The new accessor functions has() and get() + work correctly for indexes out of the current range, there is no need to + check the passed index before. + */ +template< typename ObjType > +class RefVector : public ::std::vector< ::boost::shared_ptr< ObjType > > +{ +public: + typedef ::std::vector< ::boost::shared_ptr< ObjType > > container_type; + typedef typename container_type::value_type value_type; + typedef typename container_type::size_type size_type; + +public: + /** Returns true, if the object with the passed index exists. Returns + false, if the vector element exists but is an empty reference. */ + inline bool has( sal_Int32 nIndex ) const + { + const value_type* pxRef = getRef( nIndex ); + return pxRef && pxRef->get(); + } + + /** Returns a reference to the object with the passed index, or 0 on error. */ + inline value_type get( sal_Int32 nIndex ) const + { + if( const value_type* pxRef = getRef( nIndex ) ) return *pxRef; + return value_type(); + } + + /** Returns the index of the last element, or -1, if the vector is empty. + Does *not* check whether the last element is an empty reference. */ + inline sal_Int32 getLastIndex() const { return static_cast< sal_Int32 >( this->size() ) - 1; } + + /** Calls the passed member function of ObjType on every contained object. */ + template< typename FunctorType > + inline void forEach( const FunctorType& rFunctor ) const + { + ::std::for_each( this->begin(), this->end(), Functor< FunctorType >( rFunctor ) ); + } + + /** Calls the passed member function of ObjType on every contained object. */ + template< typename FuncType > + inline void forEachMem( FuncType pFunc ) const + { + forEach( ::boost::bind( pFunc, _1 ) ); + } + + /** Calls the passed member function of ObjType on every contained object. */ + template< typename FuncType, typename ParamType > + inline void forEachMem( FuncType pFunc, ParamType aParam ) const + { + forEach( ::boost::bind( pFunc, _1, aParam ) ); + } + +private: + template< typename FunctorType > + struct Functor + { + const FunctorType& mrFunctor; + inline explicit Functor( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {} + inline void operator()( const value_type& rValue ) const { mrFunctor( *rValue ); } + }; + + inline const value_type* getRef( sal_Int32 nIndex ) const + { + return ((0 <= nIndex) && (static_cast< size_type >( nIndex ) < this->size())) ? + &(*this)[ static_cast< size_type >( nIndex ) ] : 0; + } +}; + +// ============================================================================ + +/** Template for a map of ref-counted objects with additional accessor functions. + + An instance of the class RefMap< Type > stores elements of the type + ::boost::shared_ptr< Type >. The new accessor functions has() and get() + work correctly for nonexisting keys, there is no need to check the passed + key before. + */ +template< typename KeyType, typename ObjType > +class RefMap : public ::std::map< KeyType, ::boost::shared_ptr< ObjType > > +{ +public: + typedef ::std::map< KeyType, ::boost::shared_ptr< ObjType > > container_type; + typedef typename container_type::key_type key_type; + typedef typename container_type::mapped_type mapped_type; + typedef typename container_type::value_type value_type; + +public: + /** Returns true, if the object accossiated to the passed key exists. + Returns false, if the key exists but points to an empty reference. */ + inline bool has( key_type nKey ) const + { + const mapped_type* pxRef = getRef( nKey ); + return pxRef && pxRef->get(); + } + + /** Returns a reference to the object accossiated to the passed key, or 0 on error. */ + inline mapped_type get( key_type nKey ) const + { + if( const mapped_type* pxRef = getRef( nKey ) ) return *pxRef; + return mapped_type(); + } + + /** Calls the passed functor for every contained object. */ + template< typename FunctorType > + inline void forEach( const FunctorType& rFunctor ) const + { + ::std::for_each( this->begin(), this->end(), Functor< FunctorType >( rFunctor ) ); + } + + /** Calls the passed member function of ObjType on every contained object. */ + template< typename FuncType > + inline void forEachMem( FuncType pFunc ) const + { + forEach( ::boost::bind( pFunc, _1 ) ); + } + + /** Calls the passed member function of ObjType on every contained object. */ + template< typename FuncType, typename ParamType > + inline void forEachMem( FuncType pFunc, ParamType aParam ) const + { + forEach( ::boost::bind( pFunc, _1, aParam ) ); + } + +private: + template< typename FunctorType > + struct Functor + { + const FunctorType& mrFunctor; + inline explicit Functor( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {} + inline void operator()( const value_type& rValue ) const { mrFunctor( *rValue.second ); } + }; + + inline const mapped_type* getRef( key_type nKey ) const + { + typename container_type::const_iterator aIt = find( nKey ); + return (aIt == this->end()) ? 0 : &aIt->second; + } +}; + +// ============================================================================ + +/** Template for a 2-dimensional array of objects. + + This class template provides a similar interface to the ::std::vector + template. + */ +template< typename Type > +class Matrix +{ +public: + typedef ::std::vector< Type > container_type; + typedef typename container_type::value_type value_type; + typedef typename container_type::pointer pointer; + typedef typename container_type::reference reference; + typedef typename container_type::const_reference const_reference; + typedef typename container_type::size_type size_type; + typedef typename container_type::iterator iterator; + typedef typename container_type::const_iterator const_iterator; + + inline explicit Matrix() : mnWidth( 0 ) {}; + inline explicit Matrix( size_type nWidth, size_type nHeight ) { this->resize( nWidth, nHeight ); } + inline explicit Matrix( size_type nWidth, size_type nHeight, const_reference rData ) { this->resize( nWidth, nHeight, rData ); } + + inline size_type capacity() const { return maData.capacity(); } + inline bool empty() const { return maData.empty(); } + inline size_type size() const { return maData.size(); } + inline size_type width() const { return mnWidth; } + inline size_type height() const { return this->empty() ? 0 : (this->size() / this->width()); } + inline bool has( size_type nX, size_type nY ) const { return (nX < this->width()) && (nY < this->height()); } + + inline void reserve( size_type nWidth, size_type nHeight ) { maData.reserve( nWidth * nHeight ); } + inline void clear() { this->resize( 0, 0 ); } + inline void resize( size_type nWidth, size_type nHeight ) { mnWidth = nWidth; maData.resize( nWidth * nHeight ); } + inline void resize( size_type nWidth, size_type nHeight, const_reference rData ) { mnWidth = nWidth; maData.resize( nWidth * nHeight, rData ); } + + inline iterator at( size_type nX, size_type nY ) { return maData.begin() + mnWidth * nY + nX; } + inline const_iterator at( size_type nX, size_type nY ) const { return maData.begin() + mnWidth * nY + nX; } + + inline reference operator()( size_type nX, size_type nY ) { return *this->at( nX, nY ); } + inline const_reference operator()( size_type nX, size_type nY ) const { return *this->at( nX, nY ); } + + inline iterator begin() { return maData.begin(); } + inline const_iterator begin() const { return maData.begin(); } + inline iterator end() { return maData.end(); } + inline const_iterator end() const { return maData.end(); } + + inline reference front() { return maData.front(); } + inline const_reference front() const { return maData.front(); } + inline reference back() { return maData.back(); } + inline const_reference back() const { return maData.back(); } + + inline iterator row_begin( size_type nY ) { return this->at( 0, nY ); } + inline const_iterator row_begin( size_type nY ) const { return this->at( 0, nY ); } + inline iterator row_end( size_type nY ) { return this->at( mnWidth, nY ); } + inline const_iterator row_end( size_type nY ) const { return this->at( mnWidth, nY ); } + + inline reference row_front( size_type nY ) { return (*this)( 0, nY ); } + inline const_reference row_front( size_type nY ) const { return (*this)( 0, nY ); } + inline reference row_back( size_type nY ) { return (*this)( mnWidth - 1, nY ); } + inline const_reference row_back( size_type nY ) const { return (*this)( mnWidth - 1, nY ); } + + inline void swap( Matrix& rMatrix ) { maData.swap( rMatrix.maData ); } + +private: + container_type maData; + size_type mnWidth; +}; + +// ============================================================================ + +/** Static helper functions for improved API container handling. */ +class ContainerHelper +{ +public: + // com.sun.star.container.XIndexContainer --------------------------------- + + /** Creates a new index container object from scratch. */ + static ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > + createIndexContainer(); + + /** Inserts an object into an indexed container. + + @param rxIndexContainer com.sun.star.container.XIndexContainer + interface of the indexed container. + + @param nIndex Insertion index for the object. + + @param rObject The object to be inserted. + + @return True = object successfully inserted. + */ + static bool insertByIndex( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >& rxIndexContainer, + sal_Int32 nIndex, + const ::com::sun::star::uno::Any& rObject ); + + // com.sun.star.container.XNameContainer ---------------------------------- + + /** Creates a new name container object from scratch. */ + static ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > + createNameContainer(); + + /** Returns a name that is not used in the passed name container. + + @param rxNameAccess com.sun.star.container.XNameAccess interface of + the name container. + + @param rSuggestedName Suggested name for the object. + + @return An unused name. Will be equal to the suggested name, if not + contained, otherwise a numerical index will be appended. + */ + static ::rtl::OUString getUnusedName( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& rxNameAccess, + const ::rtl::OUString& rSuggestedName, + sal_Unicode cSeparator, + sal_Int32 nFirstIndexToAppend = 1 ); + + /** Inserts an object into a name container. + + @param rxNameContainer com.sun.star.container.XNameContainer interface + of the name container. + + @param rName Exact name for the object. + + @param rObject The object to be inserted. + + @return True = object successfully inserted. + */ + static bool insertByName( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxNameContainer, + const ::rtl::OUString& rName, + const ::com::sun::star::uno::Any& rObject ); + + /** Inserts an object into a name container. + + The function will use an unused name to insert the object, based on the + suggested object name. It is possible to specify whether the existing + object or the new inserted object will be renamed, if the container + already has an object with the name suggested for the new object. + + @param rxNameContainer com.sun.star.container.XNameContainer interface + of the name container. + + @param rObject The object to be inserted. + + @param rSuggestedName Suggested name for the object. + + @param bRenameOldExisting Specifies behaviour if an object with the + suggested name already exists. If false (default), the new object + will be inserted with a name not yet extant in the container (this + is done by appending a numerical index to the suggested name). If + true, the existing object will be removed and inserted with an + unused name, and the new object will be inserted with the suggested + name. + + @return The final name the object is inserted with. Will always be + equal to the suggested name, if parameter bRenameOldExisting is + true. + */ + static ::rtl::OUString insertByUnusedName( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxNameContainer, + const ::com::sun::star::uno::Any& rObject, + const ::rtl::OUString& rSuggestedName, + sal_Unicode cSeparator, + bool bRenameOldExisting = false ); + + // vector and matrix ------------------------------------------------------ + + /** Creates a UNO sequence from a std::vector with copies of all elements. + + @param rVector The vector to be converted to a sequence. + + @return A com.sun.star.uno.Sequence object with copies of all objects + contained in the passed vector. + */ + template< typename Type > + static ::com::sun::star::uno::Sequence< Type > + vectorToSequence( const ::std::vector< Type >& rVector ); + + /** Creates a UNO sequence of sequences from a matrix with copies of all elements. + + @param rMatrix The matrix to be converted to a sequence of sequences. + + @return A com.sun.star.uno.Sequence object containing + com.sun.star.uno.Sequence objects with copies of all objects + contained in the passed matrix. + */ + template< typename Type > + static ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< Type > > + matrixToSequenceSequence( const Matrix< Type >& rMatrix ); +}; + +// ---------------------------------------------------------------------------- + +template< typename Type > +::com::sun::star::uno::Sequence< Type > ContainerHelper::vectorToSequence( const ::std::vector< Type >& rVector ) +{ + if( rVector.empty() ) + return ::com::sun::star::uno::Sequence< Type >(); + return ::com::sun::star::uno::Sequence< Type >( &rVector.front(), static_cast< sal_Int32 >( rVector.size() ) ); +} + +template< typename Type > +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< Type > > ContainerHelper::matrixToSequenceSequence( const Matrix< Type >& rMatrix ) +{ + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< Type > > aSeq; + if( !rMatrix.empty() ) + { + aSeq.realloc( static_cast< sal_Int32 >( rMatrix.height() ) ); + for( size_t nRow = 0, nHeight = rMatrix.height(); nRow < nHeight; ++nRow ) + aSeq[ static_cast< sal_Int32 >( nRow ) ] = + ::com::sun::star::uno::Sequence< Type >( &rMatrix.row_front( nRow ), static_cast< sal_Int32 >( rMatrix.width() ) ); + } + return aSeq; +} + +// ============================================================================ + +} // namespace oox + +#endif + |