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_chart2.hxx" 26 #include "LegendWrapper.hxx" 27 #include "macros.hxx" 28 #include "Chart2ModelContact.hxx" 29 #include "LegendHelper.hxx" 30 #include "ContainerHelper.hxx" 31 #include <comphelper/InlineContainer.hxx> 32 #include <com/sun/star/beans/PropertyAttribute.hpp> 33 #include <com/sun/star/chart2/XTitled.hpp> 34 #include <com/sun/star/chart/ChartLegendPosition.hpp> 35 #include <com/sun/star/chart2/LegendPosition.hpp> 36 #include <com/sun/star/chart/ChartLegendExpansion.hpp> 37 #include <com/sun/star/chart2/RelativePosition.hpp> 38 #include <com/sun/star/drawing/FillStyle.hpp> 39 40 #include "CharacterProperties.hxx" 41 #include "LineProperties.hxx" 42 #include "FillProperties.hxx" 43 #include "UserDefinedProperties.hxx" 44 #include "WrappedCharacterHeightProperty.hxx" 45 #include "PositionAndSizeHelper.hxx" 46 #include "WrappedDirectStateProperty.hxx" 47 #include "WrappedAutomaticPositionProperties.hxx" 48 #include "WrappedScaleTextProperties.hxx" 49 50 #include <algorithm> 51 #include <rtl/ustrbuf.hxx> 52 53 using namespace ::com::sun::star; 54 using ::com::sun::star::beans::Property; 55 using ::osl::MutexGuard; 56 using ::com::sun::star::uno::Any; 57 using ::com::sun::star::uno::Reference; 58 using ::com::sun::star::uno::Sequence; 59 60 //----------------------------------------------------------------------------- 61 //----------------------------------------------------------------------------- 62 63 namespace chart 64 { 65 class WrappedLegendAlignmentProperty : public WrappedProperty 66 { 67 public: 68 WrappedLegendAlignmentProperty(); 69 virtual ~WrappedLegendAlignmentProperty(); 70 71 virtual void setPropertyValue( const Any& rOuterValue, const Reference< beans::XPropertySet >& xInnerPropertySet ) const 72 throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException); 73 virtual Any getPropertyValue( const Reference< beans::XPropertySet >& xInnerPropertySet ) const 74 throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException); 75 76 protected: 77 virtual Any convertInnerToOuterValue( const Any& rInnerValue ) const; 78 virtual Any convertOuterToInnerValue( const Any& rOuterValue ) const; 79 }; 80 81 WrappedLegendAlignmentProperty::WrappedLegendAlignmentProperty() 82 : ::chart::WrappedProperty( C2U( "Alignment" ), C2U( "AnchorPosition" ) ) 83 { 84 } 85 WrappedLegendAlignmentProperty::~WrappedLegendAlignmentProperty() 86 { 87 } 88 89 Any WrappedLegendAlignmentProperty::getPropertyValue( const Reference< beans::XPropertySet >& xInnerPropertySet ) const 90 throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) 91 { 92 Any aRet; 93 if( xInnerPropertySet.is() ) 94 { 95 sal_Bool bShowLegend = sal_True; 96 xInnerPropertySet->getPropertyValue( C2U( "Show" ) ) >>= bShowLegend; 97 if(!bShowLegend) 98 { 99 aRet = uno::makeAny( ::com::sun::star::chart::ChartLegendPosition_NONE ); 100 } 101 else 102 { 103 aRet = xInnerPropertySet->getPropertyValue( m_aInnerName ); 104 aRet = this->convertInnerToOuterValue( aRet ); 105 } 106 } 107 return aRet; 108 } 109 110 void WrappedLegendAlignmentProperty::setPropertyValue( const Any& rOuterValue, const Reference< beans::XPropertySet >& xInnerPropertySet ) const 111 throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) 112 { 113 if(xInnerPropertySet.is()) 114 { 115 sal_Bool bNewShowLegend = sal_True; 116 sal_Bool bOldShowLegend = sal_True; 117 { 118 ::com::sun::star::chart::ChartLegendPosition eOuterPos(::com::sun::star::chart::ChartLegendPosition_NONE); 119 if( (rOuterValue >>= eOuterPos) && eOuterPos == ::com::sun::star::chart::ChartLegendPosition_NONE ) 120 bNewShowLegend = sal_False; 121 xInnerPropertySet->getPropertyValue( C2U( "Show" ) ) >>= bOldShowLegend; 122 } 123 if(bNewShowLegend!=bOldShowLegend) 124 { 125 xInnerPropertySet->setPropertyValue( C2U( "Show" ), uno::makeAny(bNewShowLegend) ); 126 } 127 if(!bNewShowLegend) 128 return; 129 130 //set corresponding LegendPosition 131 Any aInnerValue = this->convertOuterToInnerValue( rOuterValue ); 132 xInnerPropertySet->setPropertyValue( m_aInnerName, aInnerValue ); 133 134 //correct LegendExpansion 135 chart2::LegendPosition eNewInnerPos(chart2::LegendPosition_LINE_END); 136 if( aInnerValue >>= eNewInnerPos ) 137 { 138 ::com::sun::star::chart::ChartLegendExpansion eNewExpansion = 139 ( eNewInnerPos == chart2::LegendPosition_LINE_END || 140 eNewInnerPos == chart2::LegendPosition_LINE_START ) 141 ? ::com::sun::star::chart::ChartLegendExpansion_HIGH 142 : ::com::sun::star::chart::ChartLegendExpansion_WIDE; 143 144 ::com::sun::star::chart::ChartLegendExpansion eOldExpansion( ::com::sun::star::chart::ChartLegendExpansion_HIGH ); 145 bool bExpansionWasSet( 146 xInnerPropertySet->getPropertyValue( C2U( "Expansion" ) ) >>= eOldExpansion ); 147 148 if( !bExpansionWasSet || (eOldExpansion != eNewExpansion)) 149 xInnerPropertySet->setPropertyValue( C2U( "Expansion" ), uno::makeAny( eNewExpansion )); 150 } 151 152 //correct RelativePosition 153 Any aRelativePosition( xInnerPropertySet->getPropertyValue( C2U( "RelativePosition" ) ) ); 154 if(aRelativePosition.hasValue()) 155 { 156 xInnerPropertySet->setPropertyValue( C2U( "RelativePosition" ), Any() ); 157 } 158 } 159 } 160 161 Any WrappedLegendAlignmentProperty::convertInnerToOuterValue( const Any& rInnerValue ) const 162 { 163 ::com::sun::star::chart::ChartLegendPosition ePos = ::com::sun::star::chart::ChartLegendPosition_NONE; 164 165 chart2::LegendPosition eNewPos; 166 if( rInnerValue >>= eNewPos ) 167 { 168 switch( eNewPos ) 169 { 170 case chart2::LegendPosition_LINE_START: 171 ePos = ::com::sun::star::chart::ChartLegendPosition_LEFT; 172 break; 173 case chart2::LegendPosition_LINE_END: 174 ePos = ::com::sun::star::chart::ChartLegendPosition_RIGHT; 175 break; 176 case chart2::LegendPosition_PAGE_START: 177 ePos = ::com::sun::star::chart::ChartLegendPosition_TOP; 178 break; 179 case chart2::LegendPosition_PAGE_END: 180 ePos = ::com::sun::star::chart::ChartLegendPosition_BOTTOM; 181 break; 182 183 default: 184 ePos = ::com::sun::star::chart::ChartLegendPosition_NONE; 185 break; 186 } 187 } 188 return uno::makeAny( ePos ); 189 } 190 Any WrappedLegendAlignmentProperty::convertOuterToInnerValue( const Any& rOuterValue ) const 191 { 192 chart2::LegendPosition eNewPos = chart2::LegendPosition_LINE_END; 193 194 ::com::sun::star::chart::ChartLegendPosition ePos; 195 if( rOuterValue >>= ePos ) 196 { 197 switch( ePos ) 198 { 199 case ::com::sun::star::chart::ChartLegendPosition_LEFT: 200 eNewPos = chart2::LegendPosition_LINE_START; 201 break; 202 case ::com::sun::star::chart::ChartLegendPosition_RIGHT: 203 eNewPos = chart2::LegendPosition_LINE_END; 204 break; 205 case ::com::sun::star::chart::ChartLegendPosition_TOP: 206 eNewPos = chart2::LegendPosition_PAGE_START; 207 break; 208 case ::com::sun::star::chart::ChartLegendPosition_BOTTOM: 209 eNewPos = chart2::LegendPosition_PAGE_END; 210 break; 211 default: // NONE 212 break; 213 } 214 } 215 216 return uno::makeAny( eNewPos ); 217 } 218 } 219 //----------------------------------------------------------------------------- 220 //----------------------------------------------------------------------------- 221 //----------------------------------------------------------------------------- 222 //----------------------------------------------------------------------------- 223 224 namespace 225 { 226 static const ::rtl::OUString lcl_aServiceName( 227 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.Legend" )); 228 229 enum 230 { 231 PROP_LEGEND_ALIGNMENT, 232 PROP_LEGEND_EXPANSION 233 }; 234 235 void lcl_AddPropertiesToVector( 236 ::std::vector< Property > & rOutProperties ) 237 { 238 rOutProperties.push_back( 239 Property( C2U( "Alignment" ), 240 PROP_LEGEND_ALIGNMENT, 241 ::getCppuType( reinterpret_cast< const ::com::sun::star::chart::ChartLegendPosition * >(0)), 242 //#i111967# no PropertyChangeEvent is fired on change so far 243 beans::PropertyAttribute::MAYBEDEFAULT )); 244 245 rOutProperties.push_back( 246 Property( C2U( "Expansion" ), 247 PROP_LEGEND_EXPANSION, 248 ::getCppuType( reinterpret_cast< const ::com::sun::star::chart::ChartLegendExpansion * >(0)), 249 //#i111967# no PropertyChangeEvent is fired on change so far 250 beans::PropertyAttribute::MAYBEDEFAULT )); 251 } 252 253 struct StaticLegendWrapperPropertyArray_Initializer 254 { 255 Sequence< Property >* operator()() 256 { 257 static Sequence< Property > aPropSeq( lcl_GetPropertySequence() ); 258 return &aPropSeq; 259 } 260 261 private: 262 Sequence< Property > lcl_GetPropertySequence() 263 { 264 ::std::vector< ::com::sun::star::beans::Property > aProperties; 265 lcl_AddPropertiesToVector( aProperties ); 266 ::chart::CharacterProperties::AddPropertiesToVector( aProperties ); 267 ::chart::LineProperties::AddPropertiesToVector( aProperties ); 268 ::chart::FillProperties::AddPropertiesToVector( aProperties ); 269 //::chart::NamedProperties::AddPropertiesToVector( aProperties ); 270 ::chart::UserDefinedProperties::AddPropertiesToVector( aProperties ); 271 ::chart::wrapper::WrappedAutomaticPositionProperties::addProperties( aProperties ); 272 ::chart::wrapper::WrappedScaleTextProperties::addProperties( aProperties ); 273 274 ::std::sort( aProperties.begin(), aProperties.end(), 275 ::chart::PropertyNameLess() ); 276 277 return ::chart::ContainerHelper::ContainerToSequence( aProperties ); 278 } 279 }; 280 281 struct StaticLegendWrapperPropertyArray : public rtl::StaticAggregate< Sequence< Property >, StaticLegendWrapperPropertyArray_Initializer > 282 { 283 }; 284 285 } // anonymous namespace 286 287 // -------------------------------------------------------------------------------- 288 // -------------------------------------------------------------------------------- 289 290 namespace chart 291 { 292 namespace wrapper 293 { 294 295 LegendWrapper::LegendWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact ) : 296 m_spChart2ModelContact( spChart2ModelContact ), 297 m_aEventListenerContainer( m_aMutex ) 298 { 299 } 300 301 LegendWrapper::~LegendWrapper() 302 { 303 } 304 305 // ____ XShape ____ 306 awt::Point SAL_CALL LegendWrapper::getPosition() 307 throw (uno::RuntimeException) 308 { 309 return m_spChart2ModelContact->GetLegendPosition(); 310 } 311 312 void SAL_CALL LegendWrapper::setPosition( const awt::Point& aPosition ) 313 throw (uno::RuntimeException) 314 { 315 Reference< beans::XPropertySet > xProp( this->getInnerPropertySet() ); 316 if( xProp.is() ) 317 { 318 awt::Size aPageSize( m_spChart2ModelContact->GetPageSize() ); 319 320 chart2::RelativePosition aRelativePosition; 321 aRelativePosition.Anchor = drawing::Alignment_TOP_LEFT; 322 aRelativePosition.Primary = double(aPosition.X)/double(aPageSize.Width); 323 aRelativePosition.Secondary = double(aPosition.Y)/double(aPageSize.Height); 324 xProp->setPropertyValue( C2U( "RelativePosition" ), uno::makeAny(aRelativePosition) ); 325 } 326 } 327 328 awt::Size SAL_CALL LegendWrapper::getSize() 329 throw (uno::RuntimeException) 330 { 331 return m_spChart2ModelContact->GetLegendSize(); 332 } 333 334 void SAL_CALL LegendWrapper::setSize( const awt::Size& aSize ) 335 throw (beans::PropertyVetoException, 336 uno::RuntimeException) 337 { 338 Reference< beans::XPropertySet > xProp( this->getInnerPropertySet() ); 339 if( xProp.is() ) 340 { 341 awt::Size aPageSize( m_spChart2ModelContact->GetPageSize() ); 342 awt::Rectangle aPageRectangle( 0,0,aPageSize.Width,aPageSize.Height); 343 344 awt::Point aPos( this->getPosition() ); 345 awt::Rectangle aNewPositionAndSize(aPos.X,aPos.Y,aSize.Width,aSize.Height); 346 347 PositionAndSizeHelper::moveObject( OBJECTTYPE_LEGEND 348 , xProp, aNewPositionAndSize, aPageRectangle ); 349 } 350 } 351 352 // ____ XShapeDescriptor (base of XShape) ____ 353 ::rtl::OUString SAL_CALL LegendWrapper::getShapeType() 354 throw (uno::RuntimeException) 355 { 356 return C2U( "com.sun.star.chart.ChartLegend" ); 357 } 358 359 // ____ XComponent ____ 360 void SAL_CALL LegendWrapper::dispose() 361 throw (uno::RuntimeException) 362 { 363 Reference< uno::XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); 364 m_aEventListenerContainer.disposeAndClear( lang::EventObject( xSource ) ); 365 366 // /-- 367 MutexGuard aGuard( GetMutex()); 368 clearWrappedPropertySet(); 369 // \-- 370 } 371 372 void SAL_CALL LegendWrapper::addEventListener( 373 const Reference< lang::XEventListener >& xListener ) 374 throw (uno::RuntimeException) 375 { 376 m_aEventListenerContainer.addInterface( xListener ); 377 } 378 379 void SAL_CALL LegendWrapper::removeEventListener( 380 const Reference< lang::XEventListener >& aListener ) 381 throw (uno::RuntimeException) 382 { 383 m_aEventListenerContainer.removeInterface( aListener ); 384 } 385 386 // ================================================================================ 387 388 //ReferenceSizePropertyProvider 389 void LegendWrapper::updateReferenceSize() 390 { 391 Reference< beans::XPropertySet > xProp( this->getInnerPropertySet(), uno::UNO_QUERY ); 392 if( xProp.is() ) 393 { 394 if( xProp->getPropertyValue( C2U("ReferencePageSize") ).hasValue() ) 395 xProp->setPropertyValue( C2U("ReferencePageSize"), uno::makeAny( 396 m_spChart2ModelContact->GetPageSize() )); 397 } 398 } 399 Any LegendWrapper::getReferenceSize() 400 { 401 Any aRet; 402 Reference< beans::XPropertySet > xProp( this->getInnerPropertySet(), uno::UNO_QUERY ); 403 if( xProp.is() ) 404 aRet = xProp->getPropertyValue( C2U("ReferencePageSize") ); 405 406 return aRet; 407 } 408 awt::Size LegendWrapper::getCurrentSizeForReference() 409 { 410 return m_spChart2ModelContact->GetPageSize(); 411 } 412 413 // ================================================================================ 414 415 // WrappedPropertySet 416 Reference< beans::XPropertySet > LegendWrapper::getInnerPropertySet() 417 { 418 Reference< beans::XPropertySet > xRet; 419 Reference< chart2::XDiagram > xDiagram( m_spChart2ModelContact->getChart2Diagram() ); 420 if( xDiagram.is() ) 421 xRet.set( xDiagram->getLegend(), uno::UNO_QUERY ); 422 OSL_ENSURE(xRet.is(),"LegendWrapper::getInnerPropertySet() is NULL"); 423 return xRet; 424 } 425 426 const Sequence< beans::Property >& LegendWrapper::getPropertySequence() 427 { 428 return *StaticLegendWrapperPropertyArray::get(); 429 } 430 431 const std::vector< WrappedProperty* > LegendWrapper::createWrappedProperties() 432 { 433 ::std::vector< ::chart::WrappedProperty* > aWrappedProperties; 434 435 aWrappedProperties.push_back( new WrappedLegendAlignmentProperty() ); 436 aWrappedProperties.push_back( new WrappedProperty( C2U("Expansion"), C2U("Expansion") )); 437 WrappedCharacterHeightProperty::addWrappedProperties( aWrappedProperties, this ); 438 //same problem as for wall: thje defaults ion the old chart are different for different charttypes, so we need to export explicitly 439 aWrappedProperties.push_back( new WrappedDirectStateProperty( C2U("FillStyle"), C2U("FillStyle") ) ); 440 aWrappedProperties.push_back( new WrappedDirectStateProperty( C2U("FillColor"), C2U("FillColor") )); 441 WrappedAutomaticPositionProperties::addWrappedProperties( aWrappedProperties ); 442 WrappedScaleTextProperties::addWrappedProperties( aWrappedProperties, m_spChart2ModelContact ); 443 444 return aWrappedProperties; 445 } 446 447 // ================================================================================ 448 449 Sequence< ::rtl::OUString > LegendWrapper::getSupportedServiceNames_Static() 450 { 451 Sequence< ::rtl::OUString > aServices( 4 ); 452 aServices[ 0 ] = C2U( "com.sun.star.chart.ChartLegend" ); 453 aServices[ 1 ] = C2U( "com.sun.star.drawing.Shape" ); 454 aServices[ 2 ] = C2U( "com.sun.star.xml.UserDefinedAttributeSupplier" ); 455 aServices[ 3 ] = C2U( "com.sun.star.style.CharacterProperties" ); 456 // aServices[ 4 ] = C2U( "com.sun.star.beans.PropertySet" ); 457 // aServices[ 5 ] = C2U( "com.sun.star.drawing.FillProperties" ); 458 // aServices[ 6 ] = C2U( "com.sun.star.drawing.LineProperties" ); 459 460 return aServices; 461 } 462 463 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static 464 APPHELPER_XSERVICEINFO_IMPL( LegendWrapper, lcl_aServiceName ); 465 466 } // namespace wrapper 467 } // namespace chart 468