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