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 #ifndef _XMLOFF_MULTIPROPERTYSETHELPER_HXX 32 #include "MultiPropertySetHelper.hxx" 33 #endif 34 #include <com/sun/star/beans/XPropertySetInfo.hpp> 35 #include <com/sun/star/beans/XPropertySet.hpp> 36 #include <com/sun/star/beans/XMultiPropertySet.hpp> 37 #include <com/sun/star/lang/XServiceInfo.hpp> 38 #include <comphelper/stl_types.hxx> 39 40 // STL includes 41 #include <algorithm> 42 43 44 using ::com::sun::star::beans::XMultiPropertySet; 45 using ::com::sun::star::beans::XPropertySet; 46 using ::com::sun::star::beans::XPropertySetInfo; 47 using ::com::sun::star::lang::XServiceInfo; 48 using ::com::sun::star::uno::Any; 49 using ::com::sun::star::uno::Reference; 50 using ::com::sun::star::uno::Sequence; 51 using ::com::sun::star::uno::UNO_QUERY; 52 using ::comphelper::UStringLess; 53 using ::rtl::OUString; 54 using ::std::sort; 55 56 57 MultiPropertySetHelper::MultiPropertySetHelper( 58 const sal_Char** pNames ) : 59 pPropertyNames( NULL ), 60 nLength( 0 ), 61 aPropertySequence(), 62 pSequenceIndex( NULL ), 63 aValues(), 64 pValues( NULL ) 65 { 66 // first count the elements 67 for( const sal_Char** pPtr = pNames; *pPtr != NULL; pPtr++ ) 68 nLength++; 69 70 // allocate array and create strings 71 pPropertyNames = new OUString[nLength]; 72 for( sal_Int16 i = 0; i < nLength; i++ ) 73 pPropertyNames[i] = OUString::createFromAscii( pNames[i] ); 74 } 75 76 MultiPropertySetHelper::MultiPropertySetHelper( 77 const OUString* pNames ) : 78 pPropertyNames( NULL ), 79 nLength( 0 ), 80 aPropertySequence(), 81 pSequenceIndex( NULL ), 82 aValues(), 83 pValues( NULL ) 84 { 85 // count elements 86 for( const OUString* pPtr = pNames; pPtr != NULL; pPtr++ ) 87 nLength++; 88 89 // allocate array and assign strings 90 pPropertyNames = new OUString[nLength]; 91 for( sal_Int16 i = 0; i < nLength; i++ ) 92 pPropertyNames[i] = pNames[i]; 93 } 94 95 96 MultiPropertySetHelper::~MultiPropertySetHelper() 97 { 98 pValues = NULL; // memory 'owned' by aValues 99 100 delete[] pSequenceIndex; 101 delete[] pPropertyNames; 102 } 103 104 105 106 void MultiPropertySetHelper::hasProperties( 107 const Reference<XPropertySetInfo> & rInfo ) 108 { 109 DBG_ASSERT( rInfo.is(), "I'd really like an XPropertySetInfo here." ); 110 111 // allocate sequence index 112 if ( NULL == pSequenceIndex ) 113 pSequenceIndex = new sal_Int16[nLength] ; 114 115 // construct pSequenceIndex 116 sal_Int16 nNumberOfProperties = 0; 117 sal_Int16 i; 118 119 for( i = 0; i < nLength; i++ ) 120 { 121 // ask for property 122 sal_Bool bHasProperty = 123 rInfo->hasPropertyByName( pPropertyNames[i] ); 124 125 // set index and increment (if appropriate) 126 pSequenceIndex[i]= bHasProperty ? nNumberOfProperties : -1; 127 if ( bHasProperty ) 128 nNumberOfProperties++; 129 } 130 131 // construct property sequence from index array 132 if ( aPropertySequence.getLength() != nNumberOfProperties ) 133 aPropertySequence.realloc( nNumberOfProperties ); 134 OUString* pPropertySequence = aPropertySequence.getArray(); 135 for( i = 0; i < nLength; i ++ ) 136 { 137 sal_Int16 nIndex = pSequenceIndex[i]; 138 if ( nIndex != -1 ) 139 pPropertySequence[nIndex] = pPropertyNames[i]; 140 } 141 } 142 143 sal_Bool MultiPropertySetHelper::checkedProperties() 144 { 145 return (NULL != pSequenceIndex); 146 } 147 148 149 150 void MultiPropertySetHelper::getValues( 151 const Reference<XMultiPropertySet> & rMultiPropertySet ) 152 { 153 DBG_ASSERT( rMultiPropertySet.is(), "We need an XMultiPropertySet." ); 154 155 aValues = rMultiPropertySet->getPropertyValues( aPropertySequence ); 156 pValues = aValues.getConstArray(); 157 } 158 159 void MultiPropertySetHelper::getValues( 160 const Reference<XPropertySet> & rPropertySet ) 161 { 162 DBG_ASSERT( rPropertySet.is(), "We need an XPropertySet." ); 163 164 // re-alloc aValues (if necessary) and fill with values from XPropertySet 165 sal_Int16 nSupportedPropertiesCount = 166 (sal_Int16)aPropertySequence.getLength(); 167 if ( aValues.getLength() != nSupportedPropertiesCount ) 168 aValues.realloc( nSupportedPropertiesCount ); 169 Any* pMutableArray = aValues.getArray(); 170 for( sal_Int16 i = 0; i < nSupportedPropertiesCount; i++ ) 171 { 172 pMutableArray[i] = rPropertySet->getPropertyValue( 173 pPropertyNames[ pSequenceIndex[ i ] ] ); 174 } 175 176 // re-establish pValues pointer 177 pValues = aValues.getConstArray(); 178 } 179 180 181 const Any& MultiPropertySetHelper::getValue( sal_Int16 nIndex, 182 const Reference< XPropertySet> & rPropSet, 183 sal_Bool bTryMulti ) 184 { 185 if( !pValues ) 186 { 187 if( bTryMulti ) 188 { 189 Reference < XMultiPropertySet > xMultiPropSet( rPropSet, 190 UNO_QUERY ); 191 if( xMultiPropSet.is() ) 192 getValues( xMultiPropSet ); 193 else 194 getValues( rPropSet ); 195 } 196 else 197 { 198 getValues( rPropSet ); 199 } 200 } 201 202 return getValue( nIndex ); 203 } 204 205 const Any& MultiPropertySetHelper::getValue( sal_Int16 nIndex, 206 const Reference< XMultiPropertySet> & rMultiPropSet ) 207 { 208 if( !pValues ) 209 getValues( rMultiPropSet ); 210 211 return getValue( nIndex ); 212 } 213 214 // inline methods defined in header: 215 // inline Any& MultiPropertySetHelper::getValue( sal_Int16 nIndex ) 216 // inline sal_Bool MultiPropertySetHelper::hasProperty( sal_Int16 nValueNo ) 217