1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_charttools.hxx" 26 27 #include "UncachedDataSequence.hxx" 28 #include "macros.hxx" 29 #include "PropertyHelper.hxx" 30 #include "CommonFunctors.hxx" 31 #include "ModifyListenerHelper.hxx" 32 33 #include <algorithm> 34 #include <com/sun/star/beans/PropertyAttribute.hpp> 35 #include <rtl/math.hxx> 36 37 using namespace ::com::sun::star; 38 39 using ::com::sun::star::uno::Sequence; 40 using ::com::sun::star::uno::Reference; 41 using ::com::sun::star::uno::Any; 42 using ::rtl::OUString; 43 using ::osl::MutexGuard; 44 45 // necessary for MS compiler 46 using ::comphelper::OPropertyContainer; 47 using ::chart::impl::UncachedDataSequence_Base; 48 49 namespace 50 { 51 static const OUString lcl_aServiceName( 52 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.UncachedDataSequence" )); 53 54 enum 55 { 56 // PROP_SOURCE_IDENTIFIER, 57 PROP_NUMBERFORMAT_KEY, 58 PROP_PROPOSED_ROLE, 59 PROP_XML_RANGE 60 }; 61 } // anonymous namespace 62 63 64 // ____________________ 65 namespace chart 66 { 67 68 UncachedDataSequence::UncachedDataSequence( 69 const Reference< chart2::XInternalDataProvider > & xIntDataProv, 70 const OUString & rRangeRepresentation ) 71 : OPropertyContainer( GetBroadcastHelper()), 72 UncachedDataSequence_Base( GetMutex()), 73 m_nNumberFormatKey(0), 74 m_xDataProvider( xIntDataProv ), 75 m_aSourceRepresentation( rRangeRepresentation ), 76 m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()) 77 { 78 registerProperties(); 79 } 80 81 UncachedDataSequence::UncachedDataSequence( 82 const Reference< chart2::XInternalDataProvider > & xIntDataProv, 83 const OUString & rRangeRepresentation, 84 const OUString & rRole ) 85 : OPropertyContainer( GetBroadcastHelper()), 86 UncachedDataSequence_Base( GetMutex()), 87 m_nNumberFormatKey(0), 88 m_xDataProvider( xIntDataProv ), 89 m_aSourceRepresentation( rRangeRepresentation ), 90 m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()) 91 { 92 registerProperties(); 93 setFastPropertyValue_NoBroadcast( PROP_PROPOSED_ROLE, uno::makeAny( rRole )); 94 } 95 96 UncachedDataSequence::UncachedDataSequence( const UncachedDataSequence & rSource ) 97 : ::comphelper::OMutexAndBroadcastHelper(), 98 OPropertyContainer( GetBroadcastHelper()), 99 ::comphelper::OPropertyArrayUsageHelper< UncachedDataSequence >(), 100 UncachedDataSequence_Base( GetMutex()), 101 m_nNumberFormatKey( rSource.m_nNumberFormatKey ), 102 m_sRole( rSource.m_sRole ), 103 m_xDataProvider( rSource.m_xDataProvider ), 104 m_aSourceRepresentation( rSource.m_aSourceRepresentation ), 105 m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()) 106 { 107 registerProperties(); 108 } 109 110 UncachedDataSequence::~UncachedDataSequence() 111 {} 112 113 void UncachedDataSequence::registerProperties() 114 { 115 registerProperty( C2U( "NumberFormatKey" ), 116 PROP_NUMBERFORMAT_KEY, 117 0, // PropertyAttributes 118 & m_nNumberFormatKey, 119 ::getCppuType( & m_nNumberFormatKey ) ); 120 121 registerProperty( C2U( "Role" ), 122 PROP_PROPOSED_ROLE, 123 0, // PropertyAttributes 124 & m_sRole, 125 ::getCppuType( & m_sRole ) ); 126 127 registerProperty( C2U( "CachedXMLRange" ), 128 PROP_XML_RANGE, 129 0, // PropertyAttributes 130 & m_aXMLRange, 131 ::getCppuType( & m_aXMLRange ) ); 132 } 133 134 // ================================================================================ 135 136 Sequence< OUString > UncachedDataSequence::getSupportedServiceNames_Static() 137 { 138 Sequence< OUString > aServices( 4 ); 139 aServices[ 0 ] = lcl_aServiceName; 140 aServices[ 1 ] = C2U( "com.sun.star.chart2.data.DataSequence" ); 141 aServices[ 2 ] = C2U( "com.sun.star.chart2.data.NumericalDataSequence" ); 142 aServices[ 3 ] = C2U( "com.sun.star.chart2.data.TextualDataSequence" ); 143 return aServices; 144 } 145 146 IMPLEMENT_FORWARD_XINTERFACE2( UncachedDataSequence, UncachedDataSequence_Base, OPropertyContainer ) 147 IMPLEMENT_FORWARD_XTYPEPROVIDER2( UncachedDataSequence, UncachedDataSequence_Base, OPropertyContainer ) 148 149 // ____ XPropertySet ____ 150 Reference< beans::XPropertySetInfo > SAL_CALL UncachedDataSequence::getPropertySetInfo() 151 { 152 return Reference< beans::XPropertySetInfo >( createPropertySetInfo( getInfoHelper() ) ); 153 } 154 155 // ____ ::comphelper::OPropertySetHelper ____ 156 // __________________________________________ 157 ::cppu::IPropertyArrayHelper& UncachedDataSequence::getInfoHelper() 158 { 159 return *getArrayHelper(); 160 } 161 162 // ____ ::comphelper::OPropertyArrayHelper ____ 163 // ____________________________________________ 164 ::cppu::IPropertyArrayHelper* UncachedDataSequence::createArrayHelper() const 165 { 166 Sequence< beans::Property > aProps; 167 // describes all properties which have been registered in the ctor 168 describeProperties( aProps ); 169 170 return new ::cppu::OPropertyArrayHelper( aProps ); 171 } 172 173 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static 174 APPHELPER_XSERVICEINFO_IMPL( UncachedDataSequence, lcl_aServiceName ) 175 176 // ================================================================================ 177 178 // ________ XNumericalDataSequence ________ 179 Sequence< double > SAL_CALL UncachedDataSequence::getNumericalData() 180 { 181 Sequence< double > aResult; 182 // /-- 183 MutexGuard aGuard( GetMutex() ); 184 if( m_xDataProvider.is()) 185 { 186 Sequence< uno::Any > aValues( m_xDataProvider->getDataByRangeRepresentation( m_aSourceRepresentation )); 187 aResult.realloc( aValues.getLength()); 188 ::std::transform( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(), 189 aResult.getArray(), CommonFunctors::AnyToDouble()); 190 } 191 return aResult; 192 // \-- 193 } 194 195 // ________ XTextualDataSequence ________ 196 Sequence< OUString > SAL_CALL UncachedDataSequence::getTextualData() 197 { 198 Sequence< OUString > aResult; 199 // /-- 200 MutexGuard aGuard( GetMutex() ); 201 if( m_xDataProvider.is()) 202 { 203 Sequence< uno::Any > aValues( m_xDataProvider->getDataByRangeRepresentation( m_aSourceRepresentation )); 204 aResult.realloc( aValues.getLength()); 205 ::std::transform( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(), 206 aResult.getArray(), CommonFunctors::AnyToString()); 207 } 208 return aResult; 209 // \-- 210 } 211 212 // ________ XDataSequence ________ 213 Sequence< Any > SAL_CALL UncachedDataSequence::getData() 214 { 215 // /-- 216 MutexGuard aGuard( GetMutex() ); 217 if( m_xDataProvider.is()) 218 return m_xDataProvider->getDataByRangeRepresentation( m_aSourceRepresentation ); 219 return Sequence< Any >(); 220 // \-- 221 } 222 223 OUString SAL_CALL UncachedDataSequence::getSourceRangeRepresentation() 224 { 225 return getName(); 226 } 227 228 229 Sequence< OUString > SAL_CALL UncachedDataSequence::generateLabel( chart2::data::LabelOrigin ) 230 { 231 // auto-generated label is an empty string 232 static const Sequence< OUString > aOneEmptyString( 1 ); 233 return aOneEmptyString; 234 } 235 236 ::sal_Int32 SAL_CALL UncachedDataSequence::getNumberFormatKeyByIndex( ::sal_Int32 ) 237 { 238 return m_nNumberFormatKey; 239 } 240 241 // ____ XIndexReplace ____ 242 void SAL_CALL UncachedDataSequence::replaceByIndex( ::sal_Int32 Index, const uno::Any& Element ) 243 { 244 // /-- 245 MutexGuard aGuard( GetMutex() ); 246 Sequence< Any > aData( getData()); 247 if( Index < aData.getLength() && 248 m_xDataProvider.is() ) 249 { 250 aData[Index] = Element; 251 m_xDataProvider->setDataByRangeRepresentation( m_aSourceRepresentation, aData ); 252 fireModifyEvent(); 253 } 254 } 255 256 // ____ XIndexAccess (base of XIndexReplace) ____ 257 ::sal_Int32 SAL_CALL UncachedDataSequence::getCount() 258 { 259 OSL_ENSURE( false, "Implement!" ); 260 return 0; 261 } 262 263 uno::Any SAL_CALL UncachedDataSequence::getByIndex( ::sal_Int32 ) 264 { 265 OSL_ENSURE( false, "Implement!" ); 266 return uno::Any(); 267 } 268 269 // ____ XElementAccess (base of XIndexAccess) ____ 270 uno::Type SAL_CALL UncachedDataSequence::getElementType() 271 { 272 return ::getCppuType( reinterpret_cast< uno::Any * >(0)); 273 } 274 275 ::sal_Bool SAL_CALL UncachedDataSequence::hasElements() 276 { 277 if( ! m_xDataProvider.is()) 278 return sal_False; 279 return m_xDataProvider->hasDataByRangeRepresentation( m_aSourceRepresentation ); 280 } 281 282 // ____ XNamed ____ 283 ::rtl::OUString SAL_CALL UncachedDataSequence::getName() 284 { 285 return m_aSourceRepresentation; 286 } 287 288 void SAL_CALL UncachedDataSequence::setName( const OUString& aName ) 289 { 290 m_aSourceRepresentation = aName; 291 fireModifyEvent(); 292 } 293 294 295 296 Reference< util::XCloneable > SAL_CALL UncachedDataSequence::createClone() 297 { 298 UncachedDataSequence * pNewSeq = new UncachedDataSequence( *this ); 299 return Reference< util::XCloneable >( pNewSeq ); 300 } 301 302 303 // ____ XModifiable ____ 304 ::sal_Bool SAL_CALL UncachedDataSequence::isModified() 305 { 306 return sal_False; 307 } 308 309 void SAL_CALL UncachedDataSequence::setModified( ::sal_Bool bModified ) 310 { 311 if( bModified ) 312 fireModifyEvent(); 313 } 314 315 // ____ XModifyBroadcaster (base of XModifiable) ____ 316 void SAL_CALL UncachedDataSequence::addModifyListener( const Reference< util::XModifyListener >& aListener ) 317 { 318 try 319 { 320 Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW ); 321 xBroadcaster->addModifyListener( aListener ); 322 } 323 catch( const uno::Exception & ex ) 324 { 325 ASSERT_EXCEPTION( ex ); 326 } 327 } 328 329 void SAL_CALL UncachedDataSequence::removeModifyListener( const Reference< util::XModifyListener >& aListener ) 330 { 331 try 332 { 333 Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW ); 334 xBroadcaster->removeModifyListener( aListener ); 335 } 336 catch( const uno::Exception & ex ) 337 { 338 ASSERT_EXCEPTION( ex ); 339 } 340 } 341 342 void UncachedDataSequence::fireModifyEvent() 343 { 344 // @todo: currently never called, as data changes are not yet reported by 345 // the data provider 346 m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this ))); 347 } 348 349 } // namespace chart 350