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