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 31 #include "SeriesOptionsItemConverter.hxx" 32 #include "SchWhichPairs.hxx" 33 34 #include "macros.hxx" 35 #include "ItemPropertyMap.hxx" 36 #include "GraphicPropertyItemConverter.hxx" 37 #include "MultipleItemConverter.hxx" 38 #include "ChartModelHelper.hxx" 39 #include "AxisHelper.hxx" 40 #include "DiagramHelper.hxx" 41 #include "ChartTypeHelper.hxx" 42 #include "DataSeriesHelper.hxx" 43 44 #include <com/sun/star/chart/MissingValueTreatment.hpp> 45 #include <com/sun/star/chart2/XDataSeries.hpp> 46 47 // for SfxBoolItem 48 #include <svl/eitem.hxx> 49 #include <svl/intitem.hxx> 50 51 //SfxIntegerListItem 52 #include <svl/ilstitem.hxx> 53 #define _SVSTDARR_ULONGS 54 #include <svl/svstdarr.hxx> 55 56 #include <rtl/math.hxx> 57 #include <functional> 58 #include <algorithm> 59 60 using namespace ::com::sun::star; 61 using namespace ::com::sun::star::chart2; 62 63 namespace chart 64 { 65 namespace wrapper 66 { 67 68 // ======================================== 69 70 SeriesOptionsItemConverter::SeriesOptionsItemConverter( 71 const uno::Reference< frame::XModel >& xChartModel 72 , const uno::Reference< uno::XComponentContext > & xContext 73 , const uno::Reference< beans::XPropertySet >& xPropertySet 74 , SfxItemPool& rItemPool ) 75 : ItemConverter( xPropertySet, rItemPool ) 76 , m_xChartModel(xChartModel) 77 , m_xCC(xContext) 78 , m_bAttachToMainAxis(true) 79 , m_bSupportingOverlapAndGapWidthProperties(false) 80 , m_bSupportingBarConnectors(false) 81 , m_nBarOverlap(0) 82 , m_nGapWidth(100) 83 , m_bConnectBars(false) 84 , m_bSupportingAxisSideBySide(false) 85 , m_bGroupBarsPerAxis(true) 86 , m_bAllSeriesAttachedToSameAxis(true) 87 , m_nAllSeriesAxisIndex(-1) 88 , m_bSupportingStartingAngle(false) 89 , m_nStartingAngle(90) 90 , m_bClockwise(false) 91 , m_aSupportedMissingValueTreatments() 92 , m_nMissingValueTreatment(0) 93 , m_bSupportingPlottingOfHiddenCells(false) 94 , m_bIncludeHiddenCells(true) 95 { 96 try 97 { 98 uno::Reference< XDataSeries > xDataSeries( xPropertySet, uno::UNO_QUERY ); 99 100 m_bAttachToMainAxis = DiagramHelper::isSeriesAttachedToMainAxis( xDataSeries ); 101 102 uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram(xChartModel) ); 103 uno::Reference< beans::XPropertySet > xDiagramProperties( xDiagram, uno::UNO_QUERY ); 104 uno::Reference< XChartType > xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram , xDataSeries ) ); 105 106 m_xCooSys = DataSeriesHelper::getCoordinateSystemOfSeries( xDataSeries, xDiagram ); 107 if( m_xCooSys.is() ) 108 { 109 uno::Reference< chart2::XAxis > xAxis( AxisHelper::getAxis( 1, 0, m_xCooSys ) ); 110 chart2::ScaleData aScale( xAxis->getScaleData() ); 111 m_bClockwise = (aScale.Orientation == chart2::AxisOrientation_REVERSE); 112 } 113 114 sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram ); 115 m_bSupportingOverlapAndGapWidthProperties = ChartTypeHelper::isSupportingOverlapAndGapWidthProperties( xChartType, nDimensionCount ); 116 117 if( m_bSupportingOverlapAndGapWidthProperties ) 118 { 119 120 sal_Int32 nAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries); 121 122 uno::Sequence< sal_Int32 > m_aBarPositionSequence; 123 uno::Reference< beans::XPropertySet > xChartTypeProps( xChartType, uno::UNO_QUERY ); 124 if( xChartTypeProps.is() ) 125 { 126 if( xChartTypeProps->getPropertyValue( C2U( "OverlapSequence" ) ) >>= m_aBarPositionSequence ) 127 { 128 if( nAxisIndex >= 0 && nAxisIndex < m_aBarPositionSequence.getLength() ) 129 m_nBarOverlap = m_aBarPositionSequence[nAxisIndex]; 130 } 131 if( xChartTypeProps->getPropertyValue( C2U( "GapwidthSequence" ) ) >>= m_aBarPositionSequence ) 132 { 133 if( nAxisIndex >= 0 && nAxisIndex < m_aBarPositionSequence.getLength() ) 134 m_nGapWidth = m_aBarPositionSequence[nAxisIndex]; 135 } 136 } 137 } 138 139 m_bSupportingBarConnectors = ChartTypeHelper::isSupportingBarConnectors( xChartType, nDimensionCount ); 140 if( m_bSupportingBarConnectors && xDiagramProperties.is() ) 141 { 142 xDiagramProperties->getPropertyValue( C2U("ConnectBars")) >>= m_bConnectBars; 143 } 144 145 m_bSupportingAxisSideBySide = ChartTypeHelper::isSupportingAxisSideBySide( xChartType, nDimensionCount ); 146 if( m_bSupportingAxisSideBySide && xDiagramProperties.is() ) 147 { 148 xDiagramProperties->getPropertyValue( C2U("GroupBarsPerAxis")) >>= m_bGroupBarsPerAxis; 149 m_bAllSeriesAttachedToSameAxis = DataSeriesHelper::areAllSeriesAttachedToSameAxis( xChartType, m_nAllSeriesAxisIndex ); 150 } 151 152 m_bSupportingStartingAngle = ChartTypeHelper::isSupportingStartingAngle( xChartType ); 153 if( m_bSupportingStartingAngle ) 154 { 155 xDiagramProperties->getPropertyValue( C2U( "StartingAngle" ) ) >>= m_nStartingAngle; 156 } 157 158 m_aSupportedMissingValueTreatments = ChartTypeHelper::getSupportedMissingValueTreatments( xChartType ); 159 m_nMissingValueTreatment = DiagramHelper::getCorrectedMissingValueTreatment( 160 ChartModelHelper::findDiagram(m_xChartModel), xChartType ); 161 162 uno::Reference< XChartDocument > xChartDoc( m_xChartModel, uno::UNO_QUERY ); 163 uno::Reference< beans::XPropertySet > xProp( xChartDoc->getDataProvider(), uno::UNO_QUERY ); 164 if( xProp.is() ) 165 { 166 try 167 { 168 //test whether the data provider offers this property 169 xProp->getPropertyValue(C2U("IncludeHiddenCells")); 170 //if not exception is thrown the property is offered 171 m_bSupportingPlottingOfHiddenCells = true; 172 xDiagramProperties->getPropertyValue( C2U("IncludeHiddenCells") ) >>= m_bIncludeHiddenCells; 173 } 174 catch( const beans::UnknownPropertyException& ) 175 { 176 } 177 } 178 } 179 catch( uno::Exception ex ) 180 { 181 ASSERT_EXCEPTION( ex ); 182 } 183 } 184 185 SeriesOptionsItemConverter::~SeriesOptionsItemConverter() 186 { 187 } 188 189 const sal_uInt16 * SeriesOptionsItemConverter::GetWhichPairs() const 190 { 191 // must span all used items! 192 return nSeriesOptionsWhichPairs; 193 } 194 195 bool SeriesOptionsItemConverter::GetItemProperty( tWhichIdType /*nWhichId*/, tPropertyNameWithMemberId & /*rOutProperty*/ ) const 196 { 197 return false; 198 } 199 200 bool SeriesOptionsItemConverter::ApplySpecialItem( sal_uInt16 nWhichId, const SfxItemSet & rItemSet ) 201 throw( uno::Exception ) 202 { 203 bool bChanged = false; 204 switch( nWhichId ) 205 { 206 case SCHATTR_AXIS: 207 { 208 sal_Int32 nItemValue = static_cast< const SfxInt32Item & >( 209 rItemSet.Get( nWhichId )).GetValue(); 210 bool bAttachToMainAxis = nItemValue == CHART_AXIS_PRIMARY_Y; 211 if( bAttachToMainAxis != m_bAttachToMainAxis ) 212 { 213 //change model: 214 bChanged = DiagramHelper::attachSeriesToAxis( bAttachToMainAxis, uno::Reference< XDataSeries >::query( GetPropertySet() ) 215 , ChartModelHelper::findDiagram(m_xChartModel), m_xCC ); 216 217 if( bChanged ) 218 m_bAttachToMainAxis = bAttachToMainAxis; 219 } 220 } 221 break; 222 223 case SCHATTR_BAR_OVERLAP: 224 case SCHATTR_BAR_GAPWIDTH: 225 { 226 if( m_bSupportingOverlapAndGapWidthProperties ) 227 { 228 sal_Int32& rBarPosition = ( SCHATTR_BAR_OVERLAP == nWhichId ) ? m_nBarOverlap : m_nGapWidth; 229 rBarPosition = static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue(); 230 231 rtl::OUString aPropName( C2U( "GapwidthSequence" ) ); 232 if( SCHATTR_BAR_OVERLAP == nWhichId ) 233 aPropName = C2U( "OverlapSequence" ); 234 235 uno::Reference< XDataSeries > xDataSeries( GetPropertySet(), uno::UNO_QUERY ); 236 uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram(m_xChartModel) ); 237 uno::Reference< beans::XPropertySet > xChartTypeProps( DiagramHelper::getChartTypeOfSeries( xDiagram , xDataSeries ), uno::UNO_QUERY ); 238 if( xChartTypeProps.is() ) 239 { 240 sal_Int32 nAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries); 241 uno::Sequence< sal_Int32 > m_aBarPositionSequence; 242 if( xChartTypeProps.is() ) 243 { 244 if( xChartTypeProps->getPropertyValue( aPropName ) >>= m_aBarPositionSequence ) 245 { 246 bool bGroupBarsPerAxis = static_cast< const SfxBoolItem & >(rItemSet.Get( SCHATTR_GROUP_BARS_PER_AXIS )).GetValue(); 247 if(!bGroupBarsPerAxis) 248 { 249 //set the same value for all axes 250 for( sal_Int32 nN = 0; nN < m_aBarPositionSequence.getLength(); nN++ ) 251 m_aBarPositionSequence[nN] = rBarPosition; 252 } 253 else if( nAxisIndex >= 0 && nAxisIndex < m_aBarPositionSequence.getLength() ) 254 m_aBarPositionSequence[nAxisIndex] = rBarPosition; 255 256 xChartTypeProps->setPropertyValue( aPropName, uno::makeAny(m_aBarPositionSequence) ); 257 bChanged = true; 258 } 259 } 260 } 261 } 262 } 263 break; 264 265 case SCHATTR_BAR_CONNECT: 266 { 267 sal_Bool bOldConnectBars = sal_False; 268 m_bConnectBars = static_cast< const SfxBoolItem & >( 269 rItemSet.Get( nWhichId )).GetValue(); 270 if( m_bSupportingBarConnectors ) 271 { 272 uno::Reference< beans::XPropertySet > xDiagramProperties( ChartModelHelper::findDiagram(m_xChartModel), uno::UNO_QUERY ); 273 if( xDiagramProperties.is() && 274 (xDiagramProperties->getPropertyValue( C2U("ConnectBars")) >>= bOldConnectBars) && 275 bOldConnectBars != m_bConnectBars ) 276 { 277 xDiagramProperties->setPropertyValue( C2U("ConnectBars"), uno::makeAny(m_bConnectBars) ); 278 bChanged = true; 279 } 280 } 281 } 282 break; 283 284 case SCHATTR_GROUP_BARS_PER_AXIS: 285 { 286 bool bOldGroupBarsPerAxis = true; 287 m_bGroupBarsPerAxis = static_cast< const SfxBoolItem & >( 288 rItemSet.Get( nWhichId )).GetValue(); 289 if( m_bSupportingAxisSideBySide ) 290 { 291 uno::Reference< beans::XPropertySet > xDiagramProperties( ChartModelHelper::findDiagram(m_xChartModel), uno::UNO_QUERY ); 292 if( xDiagramProperties.is() && 293 (xDiagramProperties->getPropertyValue( C2U("GroupBarsPerAxis")) >>= bOldGroupBarsPerAxis) && 294 bOldGroupBarsPerAxis != m_bGroupBarsPerAxis ) 295 { 296 xDiagramProperties->setPropertyValue( C2U("GroupBarsPerAxis"), uno::makeAny(m_bGroupBarsPerAxis) ); 297 bChanged = true; 298 } 299 } 300 } 301 break; 302 303 case SCHATTR_STARTING_ANGLE: 304 { 305 if( m_bSupportingStartingAngle ) 306 { 307 m_nStartingAngle = static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue(); 308 uno::Reference< beans::XPropertySet > xDiagramProperties( ChartModelHelper::findDiagram(m_xChartModel), uno::UNO_QUERY ); 309 if( xDiagramProperties.is() ) 310 { 311 xDiagramProperties->setPropertyValue( C2U("StartingAngle"), uno::makeAny(m_nStartingAngle) ); 312 bChanged = true; 313 } 314 } 315 } 316 break; 317 318 case SCHATTR_CLOCKWISE: 319 { 320 bool bClockwise = (static_cast< const SfxBoolItem & >( 321 rItemSet.Get( nWhichId )).GetValue() ); 322 if( m_xCooSys.is() ) 323 { 324 uno::Reference< chart2::XAxis > xAxis( AxisHelper::getAxis( 1, 0, m_xCooSys ) ); 325 if( xAxis.is() ) 326 { 327 chart2::ScaleData aScaleData( xAxis->getScaleData() ); 328 aScaleData.Orientation = bClockwise ? chart2::AxisOrientation_REVERSE : chart2::AxisOrientation_MATHEMATICAL; 329 xAxis->setScaleData( aScaleData ); 330 bChanged = true; 331 } 332 } 333 } 334 break; 335 336 case SCHATTR_MISSING_VALUE_TREATMENT: 337 { 338 if( m_aSupportedMissingValueTreatments.getLength() ) 339 { 340 sal_Int32 nNew = static_cast< const SfxInt32Item & >( rItemSet.Get( nWhichId )).GetValue(); 341 if( m_nMissingValueTreatment != nNew ) 342 { 343 try 344 { 345 uno::Reference< beans::XPropertySet > xDiagramProperties( ChartModelHelper::findDiagram(m_xChartModel), uno::UNO_QUERY ); 346 if( xDiagramProperties.is() ) 347 { 348 xDiagramProperties->setPropertyValue( C2U( "MissingValueTreatment" ), uno::makeAny( nNew )); 349 bChanged = true; 350 } 351 } 352 catch( uno::Exception& e ) 353 { 354 ASSERT_EXCEPTION( e ); 355 } 356 } 357 } 358 } 359 break; 360 case SCHATTR_INCLUDE_HIDDEN_CELLS: 361 { 362 if( m_bSupportingPlottingOfHiddenCells ) 363 { 364 bool bIncludeHiddenCells = static_cast<const SfxBoolItem &>(rItemSet.Get(nWhichId)).GetValue(); 365 if (bIncludeHiddenCells != m_bIncludeHiddenCells) 366 bChanged = ChartModelHelper::setIncludeHiddenCells( bIncludeHiddenCells, m_xChartModel ); 367 } 368 } 369 break; 370 } 371 return bChanged; 372 } 373 374 void SeriesOptionsItemConverter::FillSpecialItem( 375 sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const 376 throw( uno::Exception ) 377 { 378 switch( nWhichId ) 379 { 380 case SCHATTR_AXIS: 381 { 382 sal_Int32 nItemValue = m_bAttachToMainAxis ? CHART_AXIS_PRIMARY_Y : CHART_AXIS_SECONDARY_Y; 383 rOutItemSet.Put( SfxInt32Item(nWhichId,nItemValue ) ); 384 break; 385 } 386 case SCHATTR_BAR_OVERLAP: 387 { 388 if( m_bSupportingOverlapAndGapWidthProperties ) 389 rOutItemSet.Put( SfxInt32Item(nWhichId,m_nBarOverlap) ); 390 break; 391 } 392 case SCHATTR_BAR_GAPWIDTH: 393 { 394 if( m_bSupportingOverlapAndGapWidthProperties ) 395 rOutItemSet.Put( SfxInt32Item(nWhichId,m_nGapWidth) ); 396 break; 397 } 398 case SCHATTR_BAR_CONNECT: 399 { 400 if( m_bSupportingBarConnectors ) 401 rOutItemSet.Put( SfxBoolItem(nWhichId,m_bConnectBars)); 402 break; 403 } 404 case SCHATTR_GROUP_BARS_PER_AXIS: 405 { 406 if( m_bSupportingAxisSideBySide ) 407 rOutItemSet.Put( SfxBoolItem(nWhichId,m_bGroupBarsPerAxis) ); 408 break; 409 } 410 case SCHATTR_AXIS_FOR_ALL_SERIES: 411 { 412 if( m_nAllSeriesAxisIndex != - 1) 413 rOutItemSet.Put( SfxInt32Item(nWhichId, m_nAllSeriesAxisIndex)); 414 break; 415 } 416 case SCHATTR_STARTING_ANGLE: 417 { 418 if( m_bSupportingStartingAngle ) 419 rOutItemSet.Put( SfxInt32Item(nWhichId,m_nStartingAngle)); 420 break; 421 } 422 case SCHATTR_CLOCKWISE: 423 { 424 rOutItemSet.Put( SfxBoolItem(nWhichId,m_bClockwise) ); 425 break; 426 } 427 case SCHATTR_MISSING_VALUE_TREATMENT: 428 { 429 if( m_aSupportedMissingValueTreatments.getLength() ) 430 rOutItemSet.Put( SfxInt32Item( nWhichId, m_nMissingValueTreatment )); 431 break; 432 } 433 case SCHATTR_AVAILABLE_MISSING_VALUE_TREATMENTS: 434 { 435 SvULongs aList; 436 for ( sal_Int32 nN=0; nN<m_aSupportedMissingValueTreatments.getLength(); nN++ ) 437 aList.Insert( m_aSupportedMissingValueTreatments[nN], sal::static_int_cast< sal_uInt16 >(nN) ); 438 rOutItemSet.Put( SfxIntegerListItem( nWhichId, aList ) ); 439 break; 440 } 441 case SCHATTR_INCLUDE_HIDDEN_CELLS: 442 { 443 if( m_bSupportingPlottingOfHiddenCells ) 444 rOutItemSet.Put( SfxBoolItem(nWhichId, m_bIncludeHiddenCells) ); 445 break; 446 } 447 default: 448 break; 449 } 450 } 451 452 } // namespace wrapper 453 } // namespace chart 454