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_sc.hxx" 30 31 #include "xlchart.hxx" 32 33 #include <com/sun/star/container/XNameContainer.hpp> 34 #include <com/sun/star/awt/Size.hpp> 35 #include <com/sun/star/awt/Gradient.hpp> 36 #include <com/sun/star/drawing/Hatch.hpp> 37 #include <com/sun/star/drawing/LineDash.hpp> 38 #include <com/sun/star/drawing/LineStyle.hpp> 39 #include <com/sun/star/drawing/FillStyle.hpp> 40 #include <com/sun/star/drawing/BitmapMode.hpp> 41 #include <com/sun/star/chart/DataLabelPlacement.hpp> 42 #include <com/sun/star/chart/XAxisXSupplier.hpp> 43 #include <com/sun/star/chart/XAxisYSupplier.hpp> 44 #include <com/sun/star/chart/XAxisZSupplier.hpp> 45 #include <com/sun/star/chart/XChartDocument.hpp> 46 #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp> 47 #include <com/sun/star/chart2/Symbol.hpp> 48 49 #include <rtl/math.hxx> 50 #include <svl/itemset.hxx> 51 #include <svx/xfillit0.hxx> 52 #include <svx/xflclit.hxx> 53 #include <svx/xfltrit.hxx> 54 #include <svx/xflgrit.hxx> 55 #include <svx/xbtmpit.hxx> 56 #include <svx/unomid.hxx> 57 #include <filter/msfilter/escherex.hxx> 58 #include <editeng/memberids.hrc> 59 #include "global.hxx" 60 #include "xlroot.hxx" 61 #include "xlstyle.hxx" 62 63 using ::rtl::OUString; 64 using ::com::sun::star::uno::Any; 65 using ::com::sun::star::uno::Reference; 66 using ::com::sun::star::uno::UNO_QUERY; 67 using ::com::sun::star::uno::Exception; 68 using ::com::sun::star::lang::XMultiServiceFactory; 69 using ::com::sun::star::chart2::XChartDocument; 70 using ::com::sun::star::drawing::XShape; 71 72 namespace cssc = ::com::sun::star::chart; 73 74 // Common ===================================================================== 75 76 XclChRectangle::XclChRectangle() : 77 mnX( 0 ), 78 mnY( 0 ), 79 mnWidth( 0 ), 80 mnHeight( 0 ) 81 { 82 } 83 84 // ---------------------------------------------------------------------------- 85 86 XclChDataPointPos::XclChDataPointPos( sal_uInt16 nSeriesIdx, sal_uInt16 nPointIdx ) : 87 mnSeriesIdx( nSeriesIdx ), 88 mnPointIdx( nPointIdx ) 89 { 90 } 91 92 bool operator<( const XclChDataPointPos& rL, const XclChDataPointPos& rR ) 93 { 94 return (rL.mnSeriesIdx < rR.mnSeriesIdx) || 95 ((rL.mnSeriesIdx == rR.mnSeriesIdx) && (rL.mnPointIdx < rR.mnPointIdx)); 96 } 97 98 // ---------------------------------------------------------------------------- 99 100 XclChFrBlock::XclChFrBlock( sal_uInt16 nType ) : 101 mnType( nType ), 102 mnContext( 0 ), 103 mnValue1( 0 ), 104 mnValue2( 0 ) 105 { 106 } 107 108 // Frame formatting =========================================================== 109 110 XclChFramePos::XclChFramePos() : 111 mnTLMode( EXC_CHFRAMEPOS_PARENT ), 112 mnBRMode( EXC_CHFRAMEPOS_PARENT ) 113 { 114 } 115 116 // ---------------------------------------------------------------------------- 117 118 XclChLineFormat::XclChLineFormat() : 119 maColor( COL_BLACK ), 120 mnPattern( EXC_CHLINEFORMAT_SOLID ), 121 mnWeight( EXC_CHLINEFORMAT_SINGLE ), 122 mnFlags( EXC_CHLINEFORMAT_AUTO ) 123 { 124 } 125 126 // ---------------------------------------------------------------------------- 127 128 XclChAreaFormat::XclChAreaFormat() : 129 maPattColor( COL_WHITE ), 130 maBackColor( COL_BLACK ), 131 mnPattern( EXC_PATT_SOLID ), 132 mnFlags( EXC_CHAREAFORMAT_AUTO ) 133 { 134 } 135 136 // ---------------------------------------------------------------------------- 137 138 XclChEscherFormat::XclChEscherFormat() 139 { 140 } 141 142 XclChEscherFormat::~XclChEscherFormat() 143 { 144 } 145 146 // ---------------------------------------------------------------------------- 147 148 XclChPicFormat::XclChPicFormat() : 149 mnBmpMode( EXC_CHPICFORMAT_NONE ), 150 mnFlags( EXC_CHPICFORMAT_TOPBOTTOM | EXC_CHPICFORMAT_FRONTBACK | EXC_CHPICFORMAT_LEFTRIGHT ), 151 mfScale( 0.5 ) 152 { 153 } 154 155 // ---------------------------------------------------------------------------- 156 157 XclChFrame::XclChFrame() : 158 mnFormat( EXC_CHFRAME_STANDARD ), 159 mnFlags( EXC_CHFRAME_AUTOSIZE | EXC_CHFRAME_AUTOPOS ) 160 { 161 } 162 163 // Source links =============================================================== 164 165 XclChSourceLink::XclChSourceLink() : 166 mnDestType( EXC_CHSRCLINK_TITLE ), 167 mnLinkType( EXC_CHSRCLINK_DEFAULT ), 168 mnFlags( 0 ), 169 mnNumFmtIdx( 0 ) 170 { 171 } 172 173 // Text ======================================================================= 174 175 XclChObjectLink::XclChObjectLink() : 176 mnTarget( EXC_CHOBJLINK_NONE ) 177 { 178 } 179 180 // ---------------------------------------------------------------------------- 181 182 XclChFrLabelProps::XclChFrLabelProps() : 183 mnFlags( 0 ) 184 { 185 } 186 187 // ---------------------------------------------------------------------------- 188 189 XclChText::XclChText() : 190 maTextColor( COL_BLACK ), 191 mnHAlign( EXC_CHTEXT_ALIGN_CENTER ), 192 mnVAlign( EXC_CHTEXT_ALIGN_CENTER ), 193 mnBackMode( EXC_CHTEXT_TRANSPARENT ), 194 mnFlags( EXC_CHTEXT_AUTOCOLOR | EXC_CHTEXT_AUTOFILL ), 195 mnFlags2( EXC_CHTEXT_POS_DEFAULT ), 196 mnRotation( EXC_ROT_NONE ) 197 { 198 } 199 200 // Data series ================================================================ 201 202 XclChMarkerFormat::XclChMarkerFormat() : 203 maLineColor( COL_BLACK ), 204 maFillColor( COL_WHITE ), 205 mnMarkerSize( EXC_CHMARKERFORMAT_SINGLESIZE ), 206 mnMarkerType( EXC_CHMARKERFORMAT_NOSYMBOL ), 207 mnFlags( EXC_CHMARKERFORMAT_AUTO ) 208 { 209 }; 210 211 // ---------------------------------------------------------------------------- 212 213 XclCh3dDataFormat::XclCh3dDataFormat() : 214 mnBase( EXC_CH3DDATAFORMAT_RECT ), 215 mnTop( EXC_CH3DDATAFORMAT_STRAIGHT ) 216 { 217 } 218 219 // ---------------------------------------------------------------------------- 220 221 XclChDataFormat::XclChDataFormat() : 222 mnFormatIdx( EXC_CHDATAFORMAT_DEFAULT ), 223 mnFlags( 0 ) 224 { 225 } 226 227 // ---------------------------------------------------------------------------- 228 229 XclChSerTrendLine::XclChSerTrendLine() : 230 mfForecastFor( 0.0 ), 231 mfForecastBack( 0.0 ), 232 mnLineType( EXC_CHSERTREND_POLYNOMIAL ), 233 mnOrder( 1 ), 234 mnShowEquation( 0 ), 235 mnShowRSquared( 0 ) 236 { 237 /* Set all bits in mfIntercept to 1 (that is -1.#NAN) to indicate that 238 there is no interception point. Cannot use ::rtl::math::setNan() here 239 cause it misses the sign bit. */ 240 sal_math_Double* pDouble = reinterpret_cast< sal_math_Double* >( &mfIntercept ); 241 pDouble->w32_parts.msw = pDouble->w32_parts.lsw = 0xFFFFFFFF; 242 } 243 244 // ---------------------------------------------------------------------------- 245 246 XclChSerErrorBar::XclChSerErrorBar() : 247 mfValue( 0.0 ), 248 mnValueCount( 1 ), 249 mnBarType( EXC_CHSERERR_NONE ), 250 mnSourceType( EXC_CHSERERR_FIXED ), 251 mnLineEnd( EXC_CHSERERR_END_TSHAPE ) 252 { 253 } 254 255 // ---------------------------------------------------------------------------- 256 257 XclChSeries::XclChSeries() : 258 mnCategType( EXC_CHSERIES_NUMERIC ), 259 mnValueType( EXC_CHSERIES_NUMERIC ), 260 mnBubbleType( EXC_CHSERIES_NUMERIC ), 261 mnCategCount( 0 ), 262 mnValueCount( 0 ), 263 mnBubbleCount( 0 ) 264 { 265 } 266 267 // Chart type groups ========================================================== 268 269 XclChType::XclChType() : 270 mnOverlap( 0 ), 271 mnGap( 150 ), 272 mnRotation( 0 ), 273 mnPieHole( 0 ), 274 mnBubbleSize( 100 ), 275 mnBubbleType( EXC_CHSCATTER_AREA ), 276 mnFlags( 0 ) 277 { 278 } 279 280 // ---------------------------------------------------------------------------- 281 282 XclChChart3d::XclChChart3d() : 283 mnRotation( 20 ), 284 mnElevation( 15 ), 285 mnEyeDist( 30 ), 286 mnRelHeight( 100 ), 287 mnRelDepth( 100 ), 288 mnDepthGap( 150 ), 289 mnFlags( EXC_CHCHART3D_AUTOHEIGHT ) 290 { 291 } 292 293 // ---------------------------------------------------------------------------- 294 295 XclChLegend::XclChLegend() : 296 mnDockMode( EXC_CHLEGEND_RIGHT ), 297 mnSpacing( EXC_CHLEGEND_MEDIUM ), 298 mnFlags( EXC_CHLEGEND_DOCKED | EXC_CHLEGEND_AUTOSERIES | 299 EXC_CHLEGEND_AUTOPOSX | EXC_CHLEGEND_AUTOPOSY | EXC_CHLEGEND_STACKED ) 300 { 301 } 302 303 // ---------------------------------------------------------------------------- 304 305 XclChTypeGroup::XclChTypeGroup() : 306 mnFlags( 0 ), 307 mnGroupIdx( EXC_CHSERGROUP_NONE ) 308 { 309 } 310 311 // ---------------------------------------------------------------------------- 312 313 XclChProperties::XclChProperties() : 314 mnFlags( 0 ), 315 mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP ) 316 { 317 } 318 319 // Axes ======================================================================= 320 321 XclChLabelRange::XclChLabelRange() : 322 mnCross( 1 ), 323 mnLabelFreq( 1 ), 324 mnTickFreq( 1 ), 325 mnFlags( 0 ) 326 { 327 } 328 329 // ---------------------------------------------------------------------------- 330 331 XclChDateRange::XclChDateRange() : 332 mnMinDate( 0 ), 333 mnMaxDate( 0 ), 334 mnMajorStep( 0 ), 335 mnMajorUnit( EXC_CHDATERANGE_DAYS ), 336 mnMinorStep( 0 ), 337 mnMinorUnit( EXC_CHDATERANGE_DAYS ), 338 mnBaseUnit( EXC_CHDATERANGE_DAYS ), 339 mnCross( 0 ), 340 mnFlags( EXC_CHDATERANGE_AUTOMIN | EXC_CHDATERANGE_AUTOMAX | 341 EXC_CHDATERANGE_AUTOMAJOR | EXC_CHDATERANGE_AUTOMINOR | 342 EXC_CHDATERANGE_AUTOBASE | EXC_CHDATERANGE_AUTOCROSS | 343 EXC_CHDATERANGE_AUTODATE ) 344 { 345 } 346 347 // ---------------------------------------------------------------------------- 348 349 XclChValueRange::XclChValueRange() : 350 mfMin( 0.0 ), 351 mfMax( 0.0 ), 352 mfMajorStep( 0.0 ), 353 mfMinorStep( 0.0 ), 354 mfCross( 0.0 ), 355 mnFlags( EXC_CHVALUERANGE_AUTOMIN | EXC_CHVALUERANGE_AUTOMAX | 356 EXC_CHVALUERANGE_AUTOMAJOR | EXC_CHVALUERANGE_AUTOMINOR | 357 EXC_CHVALUERANGE_AUTOCROSS | EXC_CHVALUERANGE_BIT8 ) 358 { 359 } 360 361 // ---------------------------------------------------------------------------- 362 363 XclChTick::XclChTick() : 364 maTextColor( COL_BLACK ), 365 mnMajor( EXC_CHTICK_INSIDE | EXC_CHTICK_OUTSIDE ), 366 mnMinor( 0 ), 367 mnLabelPos( EXC_CHTICK_NEXT ), 368 mnBackMode( EXC_CHTICK_TRANSPARENT ), 369 mnFlags( EXC_CHTICK_AUTOCOLOR | EXC_CHTICK_AUTOROT ), 370 mnRotation( EXC_ROT_NONE ) 371 { 372 } 373 374 // ---------------------------------------------------------------------------- 375 376 XclChAxis::XclChAxis() : 377 mnType( EXC_CHAXIS_NONE ) 378 { 379 } 380 381 sal_Int32 XclChAxis::GetApiAxisDimension() const 382 { 383 sal_Int32 nApiAxisDim = EXC_CHART_AXIS_NONE; 384 switch( mnType ) 385 { 386 case EXC_CHAXIS_X: nApiAxisDim = EXC_CHART_AXIS_X; break; 387 case EXC_CHAXIS_Y: nApiAxisDim = EXC_CHART_AXIS_Y; break; 388 case EXC_CHAXIS_Z: nApiAxisDim = EXC_CHART_AXIS_Z; break; 389 } 390 return nApiAxisDim; 391 } 392 393 // ---------------------------------------------------------------------------- 394 395 XclChAxesSet::XclChAxesSet() : 396 mnAxesSetId( EXC_CHAXESSET_PRIMARY ) 397 { 398 } 399 400 sal_Int32 XclChAxesSet::GetApiAxesSetIndex() const 401 { 402 sal_Int32 nApiAxesSetIdx = EXC_CHART_AXESSET_NONE; 403 switch( mnAxesSetId ) 404 { 405 case EXC_CHAXESSET_PRIMARY: nApiAxesSetIdx = EXC_CHART_AXESSET_PRIMARY; break; 406 case EXC_CHAXESSET_SECONDARY: nApiAxesSetIdx = EXC_CHART_AXESSET_SECONDARY; break; 407 } 408 return nApiAxesSetIdx; 409 } 410 411 // Static helper functions ==================================================== 412 413 sal_uInt16 XclChartHelper::GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx ) 414 { 415 static const sal_uInt16 spnLineColors[] = 416 { 417 32, 33, 34, 35, 36, 37, 38, 39, 418 40, 41, 42, 43, 44, 45, 46, 47, 419 48, 49, 50, 51, 52, 53, 54, 55, 420 56, 57, 58, 59, 60, 61, 62, 8, 421 9, 10, 11, 12, 13, 14, 15, 16, 422 17, 18, 19, 20, 21, 22, 23, 24, 423 25, 26, 27, 28, 29, 30, 31, 63 424 }; 425 return spnLineColors[ nFormatIdx % STATIC_ARRAY_SIZE( spnLineColors ) ]; 426 } 427 428 sal_uInt16 XclChartHelper::GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx ) 429 { 430 static const sal_uInt16 spnFillColors[] = 431 { 432 24, 25, 26, 27, 28, 29, 30, 31, 433 32, 33, 34, 35, 36, 37, 38, 39, 434 40, 41, 42, 43, 44, 45, 46, 47, 435 48, 49, 50, 51, 52, 53, 54, 55, 436 56, 57, 58, 59, 60, 61, 62, 63, 437 8, 9, 10, 11, 12, 13, 14, 15, 438 16, 17, 18, 19, 20, 21, 22, 23 439 }; 440 return spnFillColors[ nFormatIdx % STATIC_ARRAY_SIZE( spnFillColors ) ]; 441 } 442 443 sal_uInt8 XclChartHelper::GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx ) 444 { 445 static const sal_uInt8 spnTrans[] = { 0x00, 0x40, 0x20, 0x60, 0x70 }; 446 return spnTrans[ (nFormatIdx / 56) % STATIC_ARRAY_SIZE( spnTrans ) ]; 447 } 448 449 sal_uInt16 XclChartHelper::GetAutoMarkerType( sal_uInt16 nFormatIdx ) 450 { 451 static const sal_uInt16 spnSymbols[] = { 452 EXC_CHMARKERFORMAT_DIAMOND, EXC_CHMARKERFORMAT_SQUARE, EXC_CHMARKERFORMAT_TRIANGLE, 453 EXC_CHMARKERFORMAT_CROSS, EXC_CHMARKERFORMAT_STAR, EXC_CHMARKERFORMAT_CIRCLE, 454 EXC_CHMARKERFORMAT_PLUS, EXC_CHMARKERFORMAT_DOWJ, EXC_CHMARKERFORMAT_STDDEV }; 455 return spnSymbols[ nFormatIdx % STATIC_ARRAY_SIZE( spnSymbols ) ]; 456 } 457 458 bool XclChartHelper::HasMarkerFillColor( sal_uInt16 nMarkerType ) 459 { 460 static const bool spbFilled[] = { 461 false, true, true, true, false, false, false, false, true, false }; 462 return (nMarkerType < STATIC_ARRAY_SIZE( spbFilled )) && spbFilled[ nMarkerType ]; 463 } 464 465 OUString XclChartHelper::GetErrorBarValuesRole( sal_uInt8 nBarType ) 466 { 467 switch( nBarType ) 468 { 469 case EXC_CHSERERR_XPLUS: return EXC_CHPROP_ROLE_ERRORBARS_POSX; 470 case EXC_CHSERERR_XMINUS: return EXC_CHPROP_ROLE_ERRORBARS_NEGX; 471 case EXC_CHSERERR_YPLUS: return EXC_CHPROP_ROLE_ERRORBARS_POSY; 472 case EXC_CHSERERR_YMINUS: return EXC_CHPROP_ROLE_ERRORBARS_NEGY; 473 default: DBG_ERRORFILE( "XclChartHelper::GetErrorBarValuesRole - unknown bar type" ); 474 } 475 return OUString(); 476 } 477 478 // Chart formatting info provider ============================================= 479 480 namespace { 481 482 static const XclChFormatInfo spFmtInfos[] = 483 { 484 // object type property mode auto line color auto line weight auto pattern color missing frame type create delete isframe 485 { EXC_CHOBJTYPE_BACKGROUND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true }, 486 { EXC_CHOBJTYPE_PLOTFRAME, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, true, true, true }, 487 { EXC_CHOBJTYPE_WALL3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, false, true }, 488 { EXC_CHOBJTYPE_FLOOR3D, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, 23, EXC_CHFRAMETYPE_AUTO, true, false, true }, 489 { EXC_CHOBJTYPE_TEXT, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, true }, 490 { EXC_CHOBJTYPE_LEGEND, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, true, true, true }, 491 { EXC_CHOBJTYPE_LINEARSERIES, EXC_CHPROPMODE_LINEARSERIES, 0xFFFF, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false }, 492 { EXC_CHOBJTYPE_FILLEDSERIES, EXC_CHPROPMODE_FILLEDSERIES, EXC_COLOR_CHBORDERAUTO, EXC_CHLINEFORMAT_SINGLE, 0xFFFF, EXC_CHFRAMETYPE_AUTO, false, false, true }, 493 { EXC_CHOBJTYPE_AXISLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_AUTO, false, false, false }, 494 { EXC_CHOBJTYPE_GRIDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, true, false }, 495 { EXC_CHOBJTYPE_TRENDLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_DOUBLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false }, 496 { EXC_CHOBJTYPE_ERRORBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_SINGLE, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false }, 497 { EXC_CHOBJTYPE_CONNECTLINE, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false }, 498 { EXC_CHOBJTYPE_HILOLINE, EXC_CHPROPMODE_LINEARSERIES, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, false }, 499 { EXC_CHOBJTYPE_WHITEDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWBACK, EXC_CHFRAMETYPE_INVISIBLE, false, false, true }, 500 { EXC_CHOBJTYPE_BLACKDROPBAR, EXC_CHPROPMODE_COMMON, EXC_COLOR_CHWINDOWTEXT, EXC_CHLINEFORMAT_HAIR, EXC_COLOR_CHWINDOWTEXT, EXC_CHFRAMETYPE_INVISIBLE, false, false, true } 501 }; 502 503 } 504 505 // ---------------------------------------------------------------------------- 506 507 XclChFormatInfoProvider::XclChFormatInfoProvider() 508 { 509 const XclChFormatInfo* pEnd = STATIC_ARRAY_END( spFmtInfos ); 510 for( const XclChFormatInfo* pIt = spFmtInfos; pIt != pEnd; ++pIt ) 511 maInfoMap[ pIt->meObjType ] = pIt; 512 } 513 514 const XclChFormatInfo& XclChFormatInfoProvider::GetFormatInfo( XclChObjectType eObjType ) const 515 { 516 XclFmtInfoMap::const_iterator aIt = maInfoMap.find( eObjType ); 517 DBG_ASSERT( aIt != maInfoMap.end(), "XclChFormatInfoProvider::GetFormatInfo - unknown object type" ); 518 return (aIt == maInfoMap.end()) ? *spFmtInfos : *aIt->second; 519 } 520 521 // Chart type info provider =================================================== 522 523 namespace { 524 525 // chart type service names 526 const sal_Char SERVICE_CHART2_AREA[] = "com.sun.star.chart2.AreaChartType"; 527 const sal_Char SERVICE_CHART2_CANDLE[] = "com.sun.star.chart2.CandleStickChartType"; 528 const sal_Char SERVICE_CHART2_COLUMN[] = "com.sun.star.chart2.ColumnChartType"; 529 const sal_Char SERVICE_CHART2_LINE[] = "com.sun.star.chart2.LineChartType"; 530 const sal_Char SERVICE_CHART2_NET[] = "com.sun.star.chart2.NetChartType"; 531 const sal_Char SERVICE_CHART2_FILLEDNET[] = "com.sun.star.chart2.FilledNetChartType"; 532 const sal_Char SERVICE_CHART2_PIE[] = "com.sun.star.chart2.PieChartType"; 533 const sal_Char SERVICE_CHART2_SCATTER[] = "com.sun.star.chart2.ScatterChartType"; 534 const sal_Char SERVICE_CHART2_BUBBLE[] = "com.sun.star.chart2.BubbleChartType"; 535 const sal_Char SERVICE_CHART2_SURFACE[] = "com.sun.star.chart2.ColumnChartType"; // Todo 536 537 namespace csscd = cssc::DataLabelPlacement; 538 539 static const XclChTypeInfo spTypeInfos[] = 540 { 541 // chart type chart type category record id service varied point color def label pos comb2d 3d polar area2d area3d 1stvis xcateg swap stack revers betw 542 { EXC_CHTYPEID_BAR, EXC_CHTYPECATEG_BAR, EXC_ID_CHBAR, SERVICE_CHART2_COLUMN, EXC_CHVARPOINT_SINGLE, csscd::OUTSIDE, true, true, false, true, true, false, true, false, true, false, true }, 543 { EXC_CHTYPEID_HORBAR, EXC_CHTYPECATEG_BAR, EXC_ID_CHBAR, SERVICE_CHART2_COLUMN, EXC_CHVARPOINT_SINGLE, csscd::OUTSIDE, false, true, false, true, true, false, true, true, true, false, true }, 544 { EXC_CHTYPEID_LINE, EXC_CHTYPECATEG_LINE, EXC_ID_CHLINE, SERVICE_CHART2_LINE, EXC_CHVARPOINT_SINGLE, csscd::RIGHT, true, true, false, false, true, false, true, false, true, false, false }, 545 { EXC_CHTYPEID_AREA, EXC_CHTYPECATEG_LINE, EXC_ID_CHAREA, SERVICE_CHART2_AREA, EXC_CHVARPOINT_NONE, csscd::CENTER, true, true, false, true, true, false, true, false, true, true, false }, 546 { EXC_CHTYPEID_STOCK, EXC_CHTYPECATEG_LINE, EXC_ID_CHLINE, SERVICE_CHART2_CANDLE, EXC_CHVARPOINT_NONE, csscd::RIGHT, true, false, false, false, false, false, true, false, true, false, false }, 547 { EXC_CHTYPEID_RADARLINE, EXC_CHTYPECATEG_RADAR, EXC_ID_CHRADARLINE, SERVICE_CHART2_NET, EXC_CHVARPOINT_SINGLE, csscd::TOP, false, false, true, false, true, false, true, false, false, false, false }, 548 { EXC_CHTYPEID_RADARAREA, EXC_CHTYPECATEG_RADAR, EXC_ID_CHRADARAREA, SERVICE_CHART2_FILLEDNET, EXC_CHVARPOINT_NONE, csscd::TOP, false, false, true, true, true, false, true, false, false, true, false }, 549 { EXC_CHTYPEID_PIE, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIE, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, true, true, true, true, true, true, false, false, false, false }, 550 { EXC_CHTYPEID_DONUT, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIE, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, true, true, true, true, false, true, false, false, false, false }, 551 { EXC_CHTYPEID_PIEEXT, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIEEXT, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, false, true, true, true, true, true, false, false, false, false }, 552 { EXC_CHTYPEID_SCATTER, EXC_CHTYPECATEG_SCATTER, EXC_ID_CHSCATTER, SERVICE_CHART2_SCATTER, EXC_CHVARPOINT_SINGLE, csscd::RIGHT, true, false, false, false, true, false, false, false, false, false, false }, 553 { EXC_CHTYPEID_BUBBLES, EXC_CHTYPECATEG_SCATTER, EXC_ID_CHSCATTER, SERVICE_CHART2_BUBBLE, EXC_CHVARPOINT_SINGLE, csscd::RIGHT, false, false, false, true, true, false, false, false, false, false, false }, 554 { EXC_CHTYPEID_SURFACE, EXC_CHTYPECATEG_SURFACE, EXC_ID_CHSURFACE, SERVICE_CHART2_SURFACE, EXC_CHVARPOINT_NONE, csscd::RIGHT, false, true, false, true, true, false, true, false, false, false, false }, 555 { EXC_CHTYPEID_UNKNOWN, EXC_CHTYPECATEG_BAR, EXC_ID_CHBAR, SERVICE_CHART2_COLUMN, EXC_CHVARPOINT_SINGLE, csscd::OUTSIDE, true, true, false, true, true, false, true, false, true, false, true } 556 }; 557 558 } // namespace 559 560 XclChExtTypeInfo::XclChExtTypeInfo( const XclChTypeInfo& rTypeInfo ) : 561 XclChTypeInfo( rTypeInfo ), 562 mb3dChart( false ), 563 mbSpline( false ) 564 { 565 } 566 567 void XclChExtTypeInfo::Set( const XclChTypeInfo& rTypeInfo, bool b3dChart, bool bSpline ) 568 { 569 static_cast< XclChTypeInfo& >( *this ) = rTypeInfo; 570 mb3dChart = mbSupports3d && b3dChart; 571 mbSpline = bSpline; 572 } 573 574 // ---------------------------------------------------------------------------- 575 576 XclChTypeInfoProvider::XclChTypeInfoProvider() 577 { 578 const XclChTypeInfo* pEnd = STATIC_ARRAY_END( spTypeInfos ); 579 for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt ) 580 maInfoMap[ pIt->meTypeId ] = pIt; 581 } 582 583 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfo( XclChTypeId eTypeId ) const 584 { 585 XclChTypeInfoMap::const_iterator aIt = maInfoMap.find( eTypeId ); 586 DBG_ASSERT( aIt != maInfoMap.end(), "XclChTypeInfoProvider::GetTypeInfo - unknown chart type" ); 587 return (aIt == maInfoMap.end()) ? *maInfoMap.rbegin()->second : *aIt->second; 588 } 589 590 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRecId ) const 591 { 592 const XclChTypeInfo* pEnd = STATIC_ARRAY_END( spTypeInfos ); 593 for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt ) 594 if( pIt->mnRecId == nRecId ) 595 return *pIt; 596 DBG_ERRORFILE( "XclChTypeInfoProvider::GetTypeInfoFromRecId - unknown record id" ); 597 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN ); 598 } 599 600 const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromService( const OUString& rServiceName ) const 601 { 602 const XclChTypeInfo* pEnd = STATIC_ARRAY_END( spTypeInfos ); 603 for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt ) 604 if( rServiceName.equalsAscii( pIt->mpcServiceName ) ) 605 return *pIt; 606 DBG_ERRORFILE( "XclChTypeInfoProvider::GetTypeInfoFromService - unknown service name" ); 607 return GetTypeInfo( EXC_CHTYPEID_UNKNOWN ); 608 } 609 610 // Property helpers =========================================================== 611 612 XclChObjectTable::XclChObjectTable( Reference< XMultiServiceFactory > xFactory, 613 const OUString& rServiceName, const OUString& rObjNameBase ) : 614 mxFactory( xFactory ), 615 maServiceName( rServiceName ), 616 maObjNameBase( rObjNameBase ), 617 mnIndex( 0 ) 618 { 619 } 620 621 Any XclChObjectTable::GetObject( const OUString& rObjName ) 622 { 623 // get object table 624 if( !mxContainer.is() ) 625 mxContainer.set( ScfApiHelper::CreateInstance( mxFactory, maServiceName ), UNO_QUERY ); 626 DBG_ASSERT( mxContainer.is(), "XclChObjectTable::GetObject - container not found" ); 627 628 Any aObj; 629 if( mxContainer.is() ) 630 { 631 // get object from container 632 try 633 { 634 aObj = mxContainer->getByName( rObjName ); 635 } 636 catch( Exception& ) 637 { 638 DBG_ERRORFILE( "XclChObjectTable::GetObject - object not found" ); 639 } 640 } 641 return aObj; 642 } 643 644 OUString XclChObjectTable::InsertObject( const Any& rObj ) 645 { 646 647 // create object table 648 if( !mxContainer.is() ) 649 mxContainer.set( ScfApiHelper::CreateInstance( mxFactory, maServiceName ), UNO_QUERY ); 650 DBG_ASSERT( mxContainer.is(), "XclChObjectTable::InsertObject - container not found" ); 651 652 OUString aObjName; 653 if( mxContainer.is() ) 654 { 655 // create new unused identifier 656 do 657 { 658 aObjName = maObjNameBase + OUString::valueOf( ++mnIndex ); 659 } 660 while( mxContainer->hasByName( aObjName ) ); 661 662 // insert object 663 try 664 { 665 mxContainer->insertByName( aObjName, rObj ); 666 } 667 catch( Exception& ) 668 { 669 DBG_ERRORFILE( "XclChObjectTable::InsertObject - cannot insert object" ); 670 aObjName = OUString(); 671 } 672 } 673 return aObjName; 674 } 675 676 // Property names ------------------------------------------------------------- 677 678 namespace { 679 680 /** Property names for line style in common objects. */ 681 const sal_Char* const sppcLineNamesCommon[] = 682 { "LineStyle", "LineWidth", "LineColor", "LineTransparence", "LineDashName", 0 }; 683 /** Property names for line style in linear series objects. */ 684 const sal_Char* const sppcLineNamesLinear[] = 685 { "LineStyle", "LineWidth", "Color", "Transparency", "LineDashName", 0 }; 686 /** Property names for line style in filled series objects. */ 687 const sal_Char* const sppcLineNamesFilled[] = 688 { "BorderStyle", "BorderWidth", "BorderColor", "BorderTransparency", "BorderDashName", 0 }; 689 690 /** Property names for solid area style in common objects. */ 691 const sal_Char* const sppcAreaNamesCommon[] = { "FillStyle", "FillColor", "FillTransparence", 0 }; 692 /** Property names for solid area style in filled series objects. */ 693 const sal_Char* const sppcAreaNamesFilled[] = { "FillStyle", "Color", "Transparency", 0 }; 694 /** Property names for gradient area style in common objects. */ 695 const sal_Char* const sppcGradNamesCommon[] = { "FillStyle", "FillGradientName", 0 }; 696 /** Property names for gradient area style in filled series objects. */ 697 const sal_Char* const sppcGradNamesFilled[] = { "FillStyle", "GradientName", 0 }; 698 /** Property names for hatch area style in common objects. */ 699 const sal_Char* const sppcHatchNamesCommon[] = { "FillStyle", "FillHatchName", "FillColor", "FillBackground", 0 }; 700 /** Property names for hatch area style in filled series objects. */ 701 const sal_Char* const sppcHatchNamesFilled[] = { "FillStyle", "HatchName", "Color", "FillBackground", 0 }; 702 /** Property names for bitmap area style. */ 703 const sal_Char* const sppcBitmapNames[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", 0 }; 704 705 } // namespace 706 707 // ---------------------------------------------------------------------------- 708 709 XclChPropSetHelper::XclChPropSetHelper() : 710 maLineHlpCommon( sppcLineNamesCommon ), 711 maLineHlpLinear( sppcLineNamesLinear ), 712 maLineHlpFilled( sppcLineNamesFilled ), 713 maAreaHlpCommon( sppcAreaNamesCommon ), 714 maAreaHlpFilled( sppcAreaNamesFilled ), 715 maGradHlpCommon( sppcGradNamesCommon ), 716 maGradHlpFilled( sppcGradNamesFilled ), 717 maHatchHlpCommon( sppcHatchNamesCommon ), 718 maHatchHlpFilled( sppcHatchNamesFilled ), 719 maBitmapHlp( sppcBitmapNames ) 720 { 721 } 722 723 // read properties ------------------------------------------------------------ 724 725 void XclChPropSetHelper::ReadLineProperties( 726 XclChLineFormat& rLineFmt, XclChObjectTable& rDashTable, 727 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) 728 { 729 namespace cssd = ::com::sun::star::drawing; 730 731 // read properties from property set 732 cssd::LineStyle eApiStyle = cssd::LineStyle_NONE; 733 sal_Int32 nApiWidth = 0; 734 sal_Int16 nApiTrans = 0; 735 Any aDashNameAny; 736 737 ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode ); 738 rLineHlp.ReadFromPropertySet( rPropSet ); 739 rLineHlp >> eApiStyle >> nApiWidth >> rLineFmt.maColor >> nApiTrans >> aDashNameAny; 740 741 // clear automatic flag 742 ::set_flag( rLineFmt.mnFlags, EXC_CHLINEFORMAT_AUTO, false ); 743 744 // line width 745 if( nApiWidth <= 0 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_HAIR; 746 else if( nApiWidth <= 35 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_SINGLE; 747 else if( nApiWidth <= 70 ) rLineFmt.mnWeight = EXC_CHLINEFORMAT_DOUBLE; 748 else rLineFmt.mnWeight = EXC_CHLINEFORMAT_TRIPLE; 749 750 // line style 751 switch( eApiStyle ) 752 { 753 case cssd::LineStyle_NONE: 754 rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE; 755 break; 756 case cssd::LineStyle_SOLID: 757 { 758 if( nApiTrans < 13 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID; 759 else if( nApiTrans < 38 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_DARKTRANS; 760 else if( nApiTrans < 63 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_MEDTRANS; 761 else if( nApiTrans < 100 ) rLineFmt.mnPattern = EXC_CHLINEFORMAT_LIGHTTRANS; 762 else rLineFmt.mnPattern = EXC_CHLINEFORMAT_NONE; 763 } 764 break; 765 case cssd::LineStyle_DASH: 766 { 767 rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID; 768 OUString aDashName; 769 cssd::LineDash aApiDash; 770 if( (aDashNameAny >>= aDashName) && (rDashTable.GetObject( aDashName ) >>= aApiDash) ) 771 { 772 // reorder dashes that are shorter than dots 773 if( (aApiDash.Dashes == 0) || (aApiDash.DashLen < aApiDash.DotLen) ) 774 { 775 ::std::swap( aApiDash.Dashes, aApiDash.Dots ); 776 ::std::swap( aApiDash.DashLen, aApiDash.DotLen ); 777 } 778 // ignore dots that are nearly equal to dashes 779 if( aApiDash.DotLen * 3 > aApiDash.DashLen * 2 ) 780 aApiDash.Dots = 0; 781 782 // convert line dash to predefined Excel dash types 783 if( (aApiDash.Dashes == 1) && (aApiDash.Dots >= 1) ) 784 // one dash and one or more dots 785 rLineFmt.mnPattern = (aApiDash.Dots == 1) ? 786 EXC_CHLINEFORMAT_DASHDOT : EXC_CHLINEFORMAT_DASHDOTDOT; 787 else if( aApiDash.Dashes >= 1 ) 788 // one or more dashes and no dots (also: dash-dash-dot) 789 rLineFmt.mnPattern = (aApiDash.DashLen < 250) ? 790 EXC_CHLINEFORMAT_DOT : EXC_CHLINEFORMAT_DASH; 791 } 792 } 793 break; 794 default: 795 DBG_ERRORFILE( "XclChPropSetHelper::ReadLineProperties - unknown line style" ); 796 rLineFmt.mnPattern = EXC_CHLINEFORMAT_SOLID; 797 } 798 } 799 800 bool XclChPropSetHelper::ReadAreaProperties( XclChAreaFormat& rAreaFmt, 801 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) 802 { 803 namespace cssd = ::com::sun::star::drawing; 804 805 // read properties from property set 806 cssd::FillStyle eApiStyle = cssd::FillStyle_NONE; 807 sal_Int16 nTransparency = 0; 808 809 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode ); 810 rAreaHlp.ReadFromPropertySet( rPropSet ); 811 rAreaHlp >> eApiStyle >> rAreaFmt.maPattColor >> nTransparency; 812 813 // clear automatic flag 814 ::set_flag( rAreaFmt.mnFlags, EXC_CHAREAFORMAT_AUTO, false ); 815 816 // set fill style transparent or solid (set solid for anything but transparent) 817 rAreaFmt.mnPattern = (eApiStyle == cssd::FillStyle_NONE) ? EXC_PATT_NONE : EXC_PATT_SOLID; 818 819 // return true to indicate complex fill (gradient, bitmap, solid transparency) 820 return (eApiStyle != cssd::FillStyle_NONE) && ((eApiStyle != cssd::FillStyle_SOLID) || (nTransparency > 0)); 821 } 822 823 void XclChPropSetHelper::ReadEscherProperties( 824 XclChEscherFormat& rEscherFmt, XclChPicFormat& rPicFmt, 825 XclChObjectTable& rGradientTable, XclChObjectTable& rHatchTable, XclChObjectTable& rBitmapTable, 826 const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) 827 { 828 namespace cssd = ::com::sun::star::drawing; 829 namespace cssa = ::com::sun::star::awt; 830 831 // read style and transparency properties from property set 832 cssd::FillStyle eApiStyle = cssd::FillStyle_NONE; 833 Color aColor; 834 sal_Int16 nTransparency = 0; 835 836 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode ); 837 rAreaHlp.ReadFromPropertySet( rPropSet ); 838 rAreaHlp >> eApiStyle >> aColor >> nTransparency; 839 840 switch( eApiStyle ) 841 { 842 case cssd::FillStyle_SOLID: 843 { 844 DBG_ASSERT( nTransparency > 0, "XclChPropSetHelper::ReadEscherProperties - unexpected solid area without transparency" ); 845 if( (0 < nTransparency) && (nTransparency <= 100) ) 846 { 847 // convert to Escher properties 848 sal_uInt32 nEscherColor = 0x02000000; 849 ::insert_value( nEscherColor, aColor.GetBlue(), 16, 8 ); 850 ::insert_value( nEscherColor, aColor.GetGreen(), 8, 8 ); 851 ::insert_value( nEscherColor, aColor.GetRed(), 0, 8 ); 852 sal_uInt32 nEscherOpacity = static_cast< sal_uInt32 >( (100 - nTransparency) * 655.36 ); 853 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer ); 854 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillType, ESCHER_FillSolid ); 855 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillColor, nEscherColor ); 856 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillOpacity, nEscherOpacity ); 857 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackColor, 0x02FFFFFF ); 858 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fillBackOpacity, 0x00010000 ); 859 rEscherFmt.mxEscherSet->AddOpt( ESCHER_Prop_fNoFillHitTest, 0x001F001C ); 860 } 861 } 862 break; 863 case cssd::FillStyle_GRADIENT: 864 { 865 // extract gradient from global gradient table 866 OUString aGradientName; 867 ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode ); 868 rGradHlp.ReadFromPropertySet( rPropSet ); 869 rGradHlp >> eApiStyle >> aGradientName; 870 cssa::Gradient aGradient; 871 if( rGradientTable.GetObject( aGradientName ) >>= aGradient ) 872 { 873 // convert to Escher properties 874 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer ); 875 rEscherFmt.mxEscherSet->CreateGradientProperties( aGradient ); 876 } 877 } 878 break; 879 case cssd::FillStyle_HATCH: 880 { 881 // extract hatch from global hatch table 882 OUString aHatchName; 883 bool bFillBackground; 884 ScfPropSetHelper& rHatchHlp = GetHatchHelper( ePropMode ); 885 rHatchHlp.ReadFromPropertySet( rPropSet ); 886 rHatchHlp >> eApiStyle >> aHatchName >> aColor >> bFillBackground; 887 cssd::Hatch aHatch; 888 if( rHatchTable.GetObject( aHatchName ) >>= aHatch ) 889 { 890 // convert to Escher properties 891 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer ); 892 rEscherFmt.mxEscherSet->CreateEmbeddedHatchProperties( aHatch, aColor, bFillBackground ); 893 rPicFmt.mnBmpMode = EXC_CHPICFORMAT_STACK; 894 } 895 } 896 break; 897 case cssd::FillStyle_BITMAP: 898 { 899 // extract bitmap URL from global bitmap table 900 OUString aBitmapName; 901 cssd::BitmapMode eApiBmpMode; 902 maBitmapHlp.ReadFromPropertySet( rPropSet ); 903 maBitmapHlp >> eApiStyle >> aBitmapName >> eApiBmpMode; 904 OUString aBitmapUrl; 905 if( rBitmapTable.GetObject( aBitmapName ) >>= aBitmapUrl ) 906 { 907 // convert to Escher properties 908 rEscherFmt.mxEscherSet.reset( new EscherPropertyContainer ); 909 rEscherFmt.mxEscherSet->CreateEmbeddedBitmapProperties( aBitmapUrl, eApiBmpMode ); 910 rPicFmt.mnBmpMode = (eApiBmpMode == cssd::BitmapMode_REPEAT) ? 911 EXC_CHPICFORMAT_STACK : EXC_CHPICFORMAT_STRETCH; 912 } 913 } 914 break; 915 default: 916 DBG_ERRORFILE( "XclChPropSetHelper::ReadEscherProperties - unknown fill style" ); 917 } 918 } 919 920 void XclChPropSetHelper::ReadMarkerProperties( 921 XclChMarkerFormat& rMarkerFmt, const ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) 922 { 923 namespace cssc = ::com::sun::star::chart2; 924 namespace cssa = ::com::sun::star::awt; 925 cssc::Symbol aApiSymbol; 926 if( rPropSet.GetProperty( aApiSymbol, EXC_CHPROP_SYMBOL ) ) 927 { 928 // clear automatic flag 929 ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_AUTO, false ); 930 931 // symbol style 932 switch( aApiSymbol.Style ) 933 { 934 case cssc::SymbolStyle_NONE: 935 rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_NOSYMBOL; 936 break; 937 case cssc::SymbolStyle_STANDARD: 938 switch( aApiSymbol.StandardSymbol ) 939 { 940 case 0: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_SQUARE; break; // square 941 case 1: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_DIAMOND; break; // diamond 942 case 2: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STDDEV; break; // arrow down 943 case 3: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_TRIANGLE; break; // arrow up 944 case 4: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CIRCLE; break; // arrow right 945 case 5: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_PLUS; break; // arrow left 946 case 6: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_CROSS; break; // bow tie 947 case 7: rMarkerFmt.mnMarkerType = EXC_CHMARKERFORMAT_STAR; break; // sand glass 948 default: rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx ); 949 } 950 break; 951 default: 952 rMarkerFmt.mnMarkerType = XclChartHelper::GetAutoMarkerType( nFormatIdx ); 953 } 954 bool bHasFillColor = XclChartHelper::HasMarkerFillColor( rMarkerFmt.mnMarkerType ); 955 ::set_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOFILL, !bHasFillColor ); 956 957 // symbol size 958 sal_Int32 nApiSize = (aApiSymbol.Size.Width + aApiSymbol.Size.Height + 1) / 2; 959 rMarkerFmt.mnMarkerSize = XclTools::GetTwipsFromHmm( nApiSize ); 960 961 // symbol colors 962 rMarkerFmt.maLineColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.BorderColor ); 963 rMarkerFmt.maFillColor = ScfApiHelper::ConvertFromApiColor( aApiSymbol.FillColor ); 964 } 965 } 966 967 sal_uInt16 XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet& rPropSet, bool bSupportsStacked ) 968 { 969 // chart2 handles rotation as double in the range [0,360) 970 double fAngle = 0.0; 971 rPropSet.GetProperty( fAngle, EXC_CHPROP_TEXTROTATION ); 972 bool bStacked = bSupportsStacked && rPropSet.GetBoolProperty( EXC_CHPROP_STACKCHARACTERS ); 973 return bStacked ? EXC_ROT_STACKED : 974 XclTools::GetXclRotation( static_cast< sal_Int32 >( fAngle * 100.0 + 0.5 ) ); 975 } 976 977 // write properties ----------------------------------------------------------- 978 979 void XclChPropSetHelper::WriteLineProperties( 980 ScfPropertySet& rPropSet, XclChObjectTable& rDashTable, 981 const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode ) 982 { 983 namespace cssd = ::com::sun::star::drawing; 984 985 // line width 986 sal_Int32 nApiWidth = 0; // 0 is the width of a hair line 987 switch( rLineFmt.mnWeight ) 988 { 989 case EXC_CHLINEFORMAT_SINGLE: nApiWidth = 35; break; 990 case EXC_CHLINEFORMAT_DOUBLE: nApiWidth = 70; break; 991 case EXC_CHLINEFORMAT_TRIPLE: nApiWidth = 105; break; 992 } 993 994 // line style 995 cssd::LineStyle eApiStyle = cssd::LineStyle_NONE; 996 sal_Int16 nApiTrans = 0; 997 sal_Int32 nDotLen = ::std::min< sal_Int32 >( rLineFmt.mnWeight + 105, 210 ); 998 cssd::LineDash aApiDash( cssd::DashStyle_RECT, 0, nDotLen, 0, 4 * nDotLen, nDotLen ); 999 1000 switch( rLineFmt.mnPattern ) 1001 { 1002 case EXC_CHLINEFORMAT_SOLID: 1003 eApiStyle = cssd::LineStyle_SOLID; 1004 break; 1005 case EXC_CHLINEFORMAT_DARKTRANS: 1006 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 25; 1007 break; 1008 case EXC_CHLINEFORMAT_MEDTRANS: 1009 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 50; 1010 break; 1011 case EXC_CHLINEFORMAT_LIGHTTRANS: 1012 eApiStyle = cssd::LineStyle_SOLID; nApiTrans = 75; 1013 break; 1014 case EXC_CHLINEFORMAT_DASH: 1015 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1; 1016 break; 1017 case EXC_CHLINEFORMAT_DOT: 1018 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dots = 1; 1019 break; 1020 case EXC_CHLINEFORMAT_DASHDOT: 1021 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = aApiDash.Dots = 1; 1022 break; 1023 case EXC_CHLINEFORMAT_DASHDOTDOT: 1024 eApiStyle = cssd::LineStyle_DASH; aApiDash.Dashes = 1; aApiDash.Dots = 2; 1025 break; 1026 } 1027 1028 // line color 1029 sal_Int32 nApiColor = ScfApiHelper::ConvertToApiColor( rLineFmt.maColor ); 1030 1031 // try to insert the dash style and receive its name 1032 Any aDashNameAny; 1033 if( eApiStyle == cssd::LineStyle_DASH ) 1034 { 1035 OUString aDashName = rDashTable.InsertObject( ::com::sun::star::uno::makeAny( aApiDash ) ); 1036 if( aDashName.getLength() ) 1037 aDashNameAny <<= aDashName; 1038 } 1039 1040 // write the properties 1041 ScfPropSetHelper& rLineHlp = GetLineHelper( ePropMode ); 1042 rLineHlp.InitializeWrite(); 1043 rLineHlp << eApiStyle << nApiWidth << nApiColor << nApiTrans << aDashNameAny; 1044 rLineHlp.WriteToPropertySet( rPropSet ); 1045 } 1046 1047 void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet& rPropSet, 1048 const XclChAreaFormat& rAreaFmt, XclChPropertyMode ePropMode ) 1049 { 1050 namespace cssd = ::com::sun::star::drawing; 1051 cssd::FillStyle eFillStyle = cssd::FillStyle_NONE; 1052 Color aColor; 1053 sal_Int16 nTransparency = 0; 1054 1055 // fill color 1056 if( rAreaFmt.mnPattern != EXC_PATT_NONE ) 1057 { 1058 eFillStyle = cssd::FillStyle_SOLID; 1059 aColor = XclTools::GetPatternColor( rAreaFmt.maPattColor, rAreaFmt.maBackColor, rAreaFmt.mnPattern ); 1060 } 1061 1062 // write the properties 1063 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode ); 1064 rAreaHlp.InitializeWrite(); 1065 rAreaHlp << eFillStyle << aColor << nTransparency; 1066 rAreaHlp.WriteToPropertySet( rPropSet ); 1067 } 1068 1069 void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet& rPropSet, 1070 XclChObjectTable& rGradientTable, XclChObjectTable& /*rHatchTable*/, XclChObjectTable& rBitmapTable, 1071 const XclChEscherFormat& rEscherFmt, const XclChPicFormat* pPicFmt, 1072 sal_uInt32 nDffFillType, XclChPropertyMode ePropMode ) 1073 { 1074 if( rEscherFmt.mxItemSet.is() ) 1075 { 1076 if( const XFillStyleItem* pStyleItem = static_cast< const XFillStyleItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLSTYLE, sal_False ) ) ) 1077 { 1078 switch( pStyleItem->GetValue() ) 1079 { 1080 case XFILL_SOLID: 1081 // #i84812# Excel 2007 writes Escher properties for solid fill 1082 if( const XFillColorItem* pColorItem = static_cast< const XFillColorItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLCOLOR, sal_False ) ) ) 1083 { 1084 namespace cssd = ::com::sun::star::drawing; 1085 // get solid transparence too 1086 const XFillTransparenceItem* pTranspItem = static_cast< const XFillTransparenceItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLTRANSPARENCE, sal_False ) ); 1087 sal_uInt16 nTransp = pTranspItem ? pTranspItem->GetValue() : 0; 1088 ScfPropSetHelper& rAreaHlp = GetAreaHelper( ePropMode ); 1089 rAreaHlp.InitializeWrite(); 1090 rAreaHlp << cssd::FillStyle_SOLID << pColorItem->GetColorValue() << static_cast< sal_Int16 >( nTransp ); 1091 rAreaHlp.WriteToPropertySet( rPropSet ); 1092 } 1093 break; 1094 case XFILL_GRADIENT: 1095 if( const XFillGradientItem* pGradItem = static_cast< const XFillGradientItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLGRADIENT, sal_False ) ) ) 1096 { 1097 Any aGradientAny; 1098 if( pGradItem->QueryValue( aGradientAny, MID_FILLGRADIENT ) ) 1099 { 1100 OUString aGradName = rGradientTable.InsertObject( aGradientAny ); 1101 if( aGradName.getLength() ) 1102 { 1103 namespace cssd = ::com::sun::star::drawing; 1104 ScfPropSetHelper& rGradHlp = GetGradientHelper( ePropMode ); 1105 rGradHlp.InitializeWrite(); 1106 rGradHlp << cssd::FillStyle_GRADIENT << aGradName; 1107 rGradHlp.WriteToPropertySet( rPropSet ); 1108 } 1109 } 1110 } 1111 break; 1112 case XFILL_BITMAP: 1113 if( const XFillBitmapItem* pBmpItem = static_cast< const XFillBitmapItem* >( rEscherFmt.mxItemSet->GetItem( XATTR_FILLBITMAP, sal_False ) ) ) 1114 { 1115 Any aBitmapAny; 1116 if( pBmpItem->QueryValue( aBitmapAny, MID_GRAFURL ) ) 1117 { 1118 OUString aBmpName = rBitmapTable.InsertObject( aBitmapAny ); 1119 if( aBmpName.getLength() ) 1120 { 1121 namespace cssd = ::com::sun::star::drawing; 1122 /* #i71810# Caller decides whether to use a CHPICFORMAT record for bitmap mode. 1123 If not passed, detect fill mode from the DFF property 'fill-type'. */ 1124 bool bStretch = pPicFmt ? (pPicFmt->mnBmpMode == EXC_CHPICFORMAT_STRETCH) : (nDffFillType == mso_fillPicture); 1125 cssd::BitmapMode eApiBmpMode = bStretch ? cssd::BitmapMode_STRETCH : cssd::BitmapMode_REPEAT; 1126 maBitmapHlp.InitializeWrite(); 1127 maBitmapHlp << cssd::FillStyle_BITMAP << aBmpName << eApiBmpMode; 1128 maBitmapHlp.WriteToPropertySet( rPropSet ); 1129 } 1130 } 1131 } 1132 break; 1133 default: 1134 DBG_ERRORFILE( "XclChPropSetHelper::WriteEscherProperties - unknown fill mode" ); 1135 } 1136 } 1137 } 1138 } 1139 1140 void XclChPropSetHelper::WriteMarkerProperties( 1141 ScfPropertySet& rPropSet, const XclChMarkerFormat& rMarkerFmt ) 1142 { 1143 namespace cssc = ::com::sun::star::chart2; 1144 namespace cssa = ::com::sun::star::awt; 1145 1146 // symbol style 1147 cssc::Symbol aApiSymbol; 1148 aApiSymbol.Style = cssc::SymbolStyle_STANDARD; 1149 switch( rMarkerFmt.mnMarkerType ) 1150 { 1151 case EXC_CHMARKERFORMAT_NOSYMBOL: aApiSymbol.Style = cssc::SymbolStyle_NONE; break; 1152 case EXC_CHMARKERFORMAT_SQUARE: aApiSymbol.StandardSymbol = 0; break; // square 1153 case EXC_CHMARKERFORMAT_DIAMOND: aApiSymbol.StandardSymbol = 1; break; // diamond 1154 case EXC_CHMARKERFORMAT_TRIANGLE: aApiSymbol.StandardSymbol = 3; break; // arrow up 1155 case EXC_CHMARKERFORMAT_CROSS: aApiSymbol.StandardSymbol = 6; break; // bow tie 1156 case EXC_CHMARKERFORMAT_STAR: aApiSymbol.StandardSymbol = 7; break; // sand glass 1157 case EXC_CHMARKERFORMAT_DOWJ: aApiSymbol.StandardSymbol = 4; break; // arrow right 1158 case EXC_CHMARKERFORMAT_STDDEV: aApiSymbol.StandardSymbol = 2; break; // arrow down 1159 case EXC_CHMARKERFORMAT_CIRCLE: aApiSymbol.StandardSymbol = 4; break; // arrow right 1160 case EXC_CHMARKERFORMAT_PLUS: aApiSymbol.StandardSymbol = 5; break; // arrow left 1161 } 1162 1163 // symbol size 1164 sal_Int32 nApiSize = XclTools::GetHmmFromTwips( rMarkerFmt.mnMarkerSize ); 1165 aApiSymbol.Size = cssa::Size( nApiSize, nApiSize ); 1166 1167 // symbol colors 1168 aApiSymbol.FillColor = ScfApiHelper::ConvertToApiColor( rMarkerFmt.maFillColor ); 1169 aApiSymbol.BorderColor = ::get_flag( rMarkerFmt.mnFlags, EXC_CHMARKERFORMAT_NOLINE ) ? 1170 aApiSymbol.FillColor : ScfApiHelper::ConvertToApiColor( rMarkerFmt.maLineColor ); 1171 1172 // set the property 1173 rPropSet.SetProperty( EXC_CHPROP_SYMBOL, aApiSymbol ); 1174 } 1175 1176 void XclChPropSetHelper::WriteRotationProperties( 1177 ScfPropertySet& rPropSet, sal_uInt16 nRotation, bool bSupportsStacked ) 1178 { 1179 if( nRotation != EXC_CHART_AUTOROTATION ) 1180 { 1181 // chart2 handles rotation as double in the range [0,360) 1182 double fAngle = XclTools::GetScRotation( nRotation, 0 ) / 100.0; 1183 rPropSet.SetProperty( EXC_CHPROP_TEXTROTATION, fAngle ); 1184 if( bSupportsStacked ) 1185 rPropSet.SetProperty( EXC_CHPROP_STACKCHARACTERS, nRotation == EXC_ROT_STACKED ); 1186 } 1187 } 1188 1189 // private -------------------------------------------------------------------- 1190 1191 ScfPropSetHelper& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode ) 1192 { 1193 switch( ePropMode ) 1194 { 1195 case EXC_CHPROPMODE_COMMON: return maLineHlpCommon; 1196 case EXC_CHPROPMODE_LINEARSERIES: return maLineHlpLinear; 1197 case EXC_CHPROPMODE_FILLEDSERIES: return maLineHlpFilled; 1198 default: DBG_ERRORFILE( "XclChPropSetHelper::GetLineHelper - unknown property mode" ); 1199 } 1200 return maLineHlpCommon; 1201 } 1202 1203 ScfPropSetHelper& XclChPropSetHelper::GetAreaHelper( XclChPropertyMode ePropMode ) 1204 { 1205 switch( ePropMode ) 1206 { 1207 case EXC_CHPROPMODE_COMMON: return maAreaHlpCommon; 1208 case EXC_CHPROPMODE_FILLEDSERIES: return maAreaHlpFilled; 1209 default: DBG_ERRORFILE( "XclChPropSetHelper::GetAreaHelper - unknown property mode" ); 1210 } 1211 return maAreaHlpCommon; 1212 } 1213 1214 ScfPropSetHelper& XclChPropSetHelper::GetGradientHelper( XclChPropertyMode ePropMode ) 1215 { 1216 switch( ePropMode ) 1217 { 1218 case EXC_CHPROPMODE_COMMON: return maGradHlpCommon; 1219 case EXC_CHPROPMODE_FILLEDSERIES: return maGradHlpFilled; 1220 default: DBG_ERRORFILE( "XclChPropSetHelper::GetGradientHelper - unknown property mode" ); 1221 } 1222 return maGradHlpCommon; 1223 } 1224 1225 ScfPropSetHelper& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMode ) 1226 { 1227 switch( ePropMode ) 1228 { 1229 case EXC_CHPROPMODE_COMMON: return maHatchHlpCommon; 1230 case EXC_CHPROPMODE_FILLEDSERIES: return maHatchHlpFilled; 1231 default: DBG_ERRORFILE( "XclChPropSetHelper::GetHatchHelper - unknown property mode" ); 1232 } 1233 return maHatchHlpCommon; 1234 } 1235 1236 // ============================================================================ 1237 1238 namespace { 1239 1240 /* The following local functions implement getting the XShape interface of all 1241 supported title objects (chart and axes). This needs some effort due to the 1242 design of the old Chart1 API used to access these objects. */ 1243 1244 /** A code fragment that returns a shape object from the passed shape supplier 1245 using the specified interface function. Checks a boolean property first. */ 1246 #define EXC_FRAGMENT_GETTITLESHAPE( shape_supplier, supplier_func, property_name ) \ 1247 ScfPropertySet aPropSet( shape_supplier ); \ 1248 if( shape_supplier.is() && aPropSet.GetBoolProperty( CREATE_OUSTRING( #property_name ) ) ) \ 1249 return shape_supplier->supplier_func(); \ 1250 return Reference< XShape >(); \ 1251 1252 /** Implements a function returning the drawing shape of an axis title, if 1253 existing, using the specified API interface and its function. */ 1254 #define EXC_DEFINEFUNC_GETAXISTITLESHAPE( func_name, interface_type, supplier_func, property_name ) \ 1255 Reference< XShape > func_name( const Reference< cssc::XChartDocument >& rxChart1Doc ) \ 1256 { \ 1257 Reference< cssc::interface_type > xAxisSupp( rxChart1Doc->getDiagram(), UNO_QUERY ); \ 1258 EXC_FRAGMENT_GETTITLESHAPE( xAxisSupp, supplier_func, property_name ) \ 1259 } 1260 1261 /** Returns the drawing shape of the main title, if existing. */ 1262 Reference< XShape > lclGetMainTitleShape( const Reference< cssc::XChartDocument >& rxChart1Doc ) 1263 { 1264 EXC_FRAGMENT_GETTITLESHAPE( rxChart1Doc, getTitle, HasMainTitle ) 1265 } 1266 1267 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetXAxisTitleShape, XAxisXSupplier, getXAxisTitle, HasXAxisTitle ) 1268 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetYAxisTitleShape, XAxisYSupplier, getYAxisTitle, HasYAxisTitle ) 1269 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetZAxisTitleShape, XAxisZSupplier, getZAxisTitle, HasZAxisTitle ) 1270 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecXAxisTitleShape, XSecondAxisTitleSupplier, getSecondXAxisTitle, HasSecondaryXAxisTitle ) 1271 EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecYAxisTitleShape, XSecondAxisTitleSupplier, getSecondYAxisTitle, HasSecondaryYAxisTitle ) 1272 1273 #undef EXC_DEFINEFUNC_GETAXISTITLESHAPE 1274 #undef EXC_IMPLEMENT_GETTITLESHAPE 1275 1276 } // namespace 1277 1278 // ---------------------------------------------------------------------------- 1279 1280 XclChRootData::XclChRootData() : 1281 mxTypeInfoProv( new XclChTypeInfoProvider ), 1282 mxFmtInfoProv( new XclChFormatInfoProvider ), 1283 mnBorderGapX( 0 ), 1284 mnBorderGapY( 0 ) 1285 { 1286 // remember some title shape getter functions 1287 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_TITLE ) ] = lclGetMainTitleShape; 1288 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_X ) ] = lclGetXAxisTitleShape; 1289 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Y ) ] = lclGetYAxisTitleShape; 1290 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Z ) ] = lclGetZAxisTitleShape; 1291 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_X ) ] = lclGetSecXAxisTitleShape; 1292 maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_Y ) ] = lclGetSecYAxisTitleShape; 1293 } 1294 1295 XclChRootData::~XclChRootData() 1296 { 1297 } 1298 1299 void XclChRootData::InitConversion( const XclRoot& rRoot, const Reference< XChartDocument >& rxChartDoc, const Rectangle& rChartRect ) 1300 { 1301 // remember chart document reference and chart shape position/size 1302 DBG_ASSERT( rxChartDoc.is(), "XclChRootData::InitConversion - missing chart document" ); 1303 mxChartDoc = rxChartDoc; 1304 maChartRect = rChartRect; 1305 1306 // Excel excludes a border of 5 pixels in each direction from chart area 1307 mnBorderGapX = rRoot.GetHmmFromPixelX( 5.0 ); 1308 mnBorderGapY = rRoot.GetHmmFromPixelY( 5.0 ); 1309 1310 // size of a chart unit in 1/100 mm 1311 mfUnitSizeX = ::std::max< double >( maChartRect.GetWidth() - 2 * mnBorderGapX, mnBorderGapX ) / EXC_CHART_TOTALUNITS; 1312 mfUnitSizeY = ::std::max< double >( maChartRect.GetHeight() - 2 * mnBorderGapY, mnBorderGapY ) / EXC_CHART_TOTALUNITS; 1313 1314 // create object tables 1315 Reference< XMultiServiceFactory > xFactory( mxChartDoc, UNO_QUERY ); 1316 mxLineDashTable.reset( new XclChObjectTable( 1317 xFactory, SERVICE_DRAWING_DASHTABLE, CREATE_OUSTRING( "Excel line dash " ) ) ); 1318 mxGradientTable.reset( new XclChObjectTable( 1319 xFactory, SERVICE_DRAWING_GRADIENTTABLE, CREATE_OUSTRING( "Excel gradient " ) ) ); 1320 mxHatchTable.reset( new XclChObjectTable( 1321 xFactory, SERVICE_DRAWING_HATCHTABLE, CREATE_OUSTRING( "Excel hatch " ) ) ); 1322 mxBitmapTable.reset( new XclChObjectTable( 1323 xFactory, SERVICE_DRAWING_BITMAPTABLE, CREATE_OUSTRING( "Excel bitmap " ) ) ); 1324 } 1325 1326 void XclChRootData::FinishConversion() 1327 { 1328 // forget formatting object tables 1329 mxBitmapTable.reset(); 1330 mxHatchTable.reset(); 1331 mxGradientTable.reset(); 1332 mxLineDashTable.reset(); 1333 // forget chart document reference 1334 mxChartDoc.clear(); 1335 } 1336 1337 Reference< XShape > XclChRootData::GetTitleShape( const XclChTextKey& rTitleKey ) const 1338 { 1339 XclChGetShapeFuncMap::const_iterator aIt = maGetShapeFuncs.find( rTitleKey ); 1340 OSL_ENSURE( aIt != maGetShapeFuncs.end(), "XclChRootData::GetTitleShape - invalid title key" ); 1341 Reference< cssc::XChartDocument > xChart1Doc( mxChartDoc, UNO_QUERY ); 1342 Reference< XShape > xTitleShape; 1343 if( xChart1Doc.is() && (aIt != maGetShapeFuncs.end()) ) 1344 xTitleShape = (aIt->second)( xChart1Doc ); 1345 return xTitleShape; 1346 } 1347 1348 // ============================================================================ 1349