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