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 "res_ErrorBar.hxx" 32 #include "res_ErrorBar_IDs.hrc" 33 #include "ResId.hxx" 34 #include "Strings.hrc" 35 #include "Bitmaps.hrc" 36 #include "Bitmaps_HC.hrc" 37 #include "RangeSelectionHelper.hxx" 38 // for RANGE_SELECTION_INVALID_RANGE_BACKGROUND_COLOR 39 #include "TabPageNotifiable.hxx" 40 #include "macros.hxx" 41 42 #include <rtl/math.hxx> 43 #include <vcl/dialog.hxx> 44 #include <svl/stritem.hxx> 45 46 using namespace ::com::sun::star; 47 48 namespace 49 { 50 void lcl_enableRangeChoosing( bool bEnable, Dialog * pDialog ) 51 { 52 if( pDialog ) 53 { 54 pDialog->Show( bEnable ? sal_False : sal_True ); 55 pDialog->SetModalInputMode( bEnable ? sal_False : sal_True ); 56 } 57 } 58 59 sal_uInt16 lcl_getLbEntryPosByErrorKind( SvxChartKindError eErrorKind ) 60 { 61 sal_uInt16 nResult = 0; 62 switch( eErrorKind ) 63 { 64 // for these cases select the default in the list box 65 case CHERROR_NONE: 66 case CHERROR_PERCENT: 67 case CHERROR_CONST: 68 case CHERROR_RANGE: 69 nResult = CHART_LB_FUNCTION_STD_DEV; 70 break; 71 case CHERROR_VARIANT: 72 nResult = CHART_LB_FUNCTION_VARIANCE; 73 break; 74 case CHERROR_SIGMA: 75 nResult = CHART_LB_FUNCTION_STD_DEV; 76 break; 77 case CHERROR_BIGERROR: 78 nResult = CHART_LB_FUNCTION_ERROR_MARGIN; 79 break; 80 case CHERROR_STDERROR: 81 nResult = CHART_LB_FUNCTION_STD_ERROR; 82 break; 83 } 84 return nResult; 85 } 86 } // anonymous namespace 87 88 89 //............................................................................. 90 namespace chart 91 { 92 //............................................................................. 93 94 // macro for selecting a normal or high contrast bitmap the stack variable 95 // bIsHighContrast must exist and reflect the correct state 96 #define SELECT_IMAGE(name) Image( SchResId( bIsHighContrast ? name ## _HC : name )) 97 98 enum StatIndicator 99 { 100 INDICATE_BOTH, 101 INDICATE_UP, 102 INDICATE_DOWN 103 }; 104 105 ErrorBarResources::ErrorBarResources( Window* pParent, Dialog * pParentDialog, 106 const SfxItemSet& rInAttrs, bool bNoneAvailable, 107 tErrorBarType eType /* = ERROR_BAR_Y */ ) : 108 109 m_aFlErrorCategory( pParent, SchResId( FL_ERROR )), 110 m_aRbNone( pParent, SchResId( RB_NONE )), 111 m_aRbConst( pParent, SchResId( RB_CONST )), 112 m_aRbPercent( pParent, SchResId( RB_PERCENT )), 113 m_aRbFunction( pParent, SchResId( RB_FUNCTION )), 114 m_aRbRange( pParent, SchResId( RB_RANGE )), 115 m_aLbFunction( pParent, SchResId( LB_FUNCTION )), 116 117 m_aFlParameters( pParent, SchResId( FL_PARAMETERS )), 118 m_aFtPositive( pParent, SchResId( FT_POSITIVE )), 119 m_aMfPositive( pParent, SchResId( MF_POSITIVE )), 120 m_aEdRangePositive( pParent, SchResId( ED_RANGE_POSITIVE )), 121 m_aIbRangePositive( pParent, SchResId( IB_RANGE_POSITIVE )), 122 m_aFtNegative( pParent, SchResId( FT_NEGATIVE )), 123 m_aMfNegative( pParent, SchResId( MF_NEGATIVE )), 124 m_aEdRangeNegative( pParent, SchResId( ED_RANGE_NEGATIVE )), 125 m_aIbRangeNegative( pParent, SchResId( IB_RANGE_NEGATIVE )), 126 m_aCbSyncPosNeg( pParent, SchResId( CB_SYN_POS_NEG )), 127 128 m_aFlIndicate( pParent, SchResId( FL_INDICATE )), 129 m_aRbBoth( pParent, SchResId( RB_BOTH )), 130 m_aRbPositive( pParent, SchResId( RB_POSITIVE )), 131 m_aRbNegative( pParent, SchResId( RB_NEGATIVE )), 132 m_aFiBoth( pParent, SchResId( FI_BOTH )), 133 m_aFiPositive( pParent, SchResId( FI_POSITIVE )), 134 m_aFiNegative( pParent, SchResId( FI_NEGATIVE )), 135 136 m_eErrorKind( CHERROR_NONE ), 137 m_eIndicate( CHINDICATE_BOTH ), 138 m_bErrorKindUnique( true ), 139 m_bIndicatorUnique( true ), 140 m_bPlusUnique( true ), 141 m_bMinusUnique( true ), 142 m_bRangePosUnique( true ), 143 m_bRangeNegUnique( true ), 144 m_bNoneAvailable( bNoneAvailable ), 145 m_eErrorBarType( eType ), 146 m_nConstDecimalDigits( 1 ), 147 m_nConstSpinSize( 1 ), 148 m_pParentWindow( pParent ), 149 m_pParentDialog( pParentDialog ), 150 m_pCurrentRangeChoosingField( 0 ), 151 m_bHasInternalDataProvider( true ), 152 m_bDisableDataTableDialog( false ) 153 { 154 if( m_bNoneAvailable ) 155 m_aRbNone.SetClickHdl( LINK( this, ErrorBarResources, CategoryChosen )); 156 else 157 m_aRbNone.Hide(); 158 159 m_aRbConst.SetClickHdl( LINK( this, ErrorBarResources, CategoryChosen )); 160 m_aRbPercent.SetClickHdl( LINK( this, ErrorBarResources, CategoryChosen )); 161 m_aRbFunction.SetClickHdl( LINK( this, ErrorBarResources, CategoryChosen )); 162 m_aRbRange.SetClickHdl( LINK( this, ErrorBarResources, CategoryChosen )); 163 m_aLbFunction.SetSelectHdl( LINK( this, ErrorBarResources, CategoryChosen )); 164 165 m_aCbSyncPosNeg.Check( sal_False ); 166 m_aCbSyncPosNeg.SetToggleHdl( LINK( this, ErrorBarResources, SynchronizePosAndNeg )); 167 168 m_aMfPositive.SetModifyHdl( LINK( this, ErrorBarResources, PosValueChanged )); 169 m_aEdRangePositive.SetModifyHdl( LINK( this, ErrorBarResources, RangeChanged )); 170 m_aEdRangeNegative.SetModifyHdl( LINK( this, ErrorBarResources, RangeChanged )); 171 172 m_aRbPositive.SetClickHdl( LINK( this, ErrorBarResources, IndicatorChanged )); 173 m_aRbNegative.SetClickHdl( LINK( this, ErrorBarResources, IndicatorChanged )); 174 m_aRbBoth.SetClickHdl( LINK( this, ErrorBarResources, IndicatorChanged )); 175 176 m_aIbRangePositive.SetClickHdl( LINK( this, ErrorBarResources, ChooseRange )); 177 m_aIbRangeNegative.SetClickHdl( LINK( this, ErrorBarResources, ChooseRange )); 178 m_aIbRangePositive.SetQuickHelpText( String( SchResId( STR_TIP_SELECT_RANGE ))); 179 m_aIbRangeNegative.SetQuickHelpText( String( SchResId( STR_TIP_SELECT_RANGE ))); 180 181 FillValueSets(); 182 Reset( rInAttrs ); 183 } 184 185 ErrorBarResources::~ErrorBarResources() 186 { 187 } 188 189 void ErrorBarResources::SetErrorBarType( tErrorBarType eNewType ) 190 { 191 if( m_eErrorBarType != eNewType ) 192 { 193 m_eErrorBarType = eNewType; 194 FillValueSets(); 195 } 196 } 197 198 void ErrorBarResources::SetChartDocumentForRangeChoosing( 199 const uno::Reference< chart2::XChartDocument > & xChartDocument ) 200 { 201 if( xChartDocument.is()) 202 { 203 m_bHasInternalDataProvider = xChartDocument->hasInternalDataProvider(); 204 uno::Reference< beans::XPropertySet > xProps( xChartDocument, uno::UNO_QUERY ); 205 if ( xProps.is() ) 206 { 207 try 208 { 209 xProps->getPropertyValue( C2U( "DisableDataTableDialog" ) ) >>= m_bDisableDataTableDialog; 210 } 211 catch( uno::Exception& e ) 212 { 213 ASSERT_EXCEPTION( e ); 214 } 215 } 216 } 217 m_apRangeSelectionHelper.reset( new RangeSelectionHelper( xChartDocument )); 218 219 // has internal data provider => rename "cell range" to "from data" 220 OSL_ASSERT( m_apRangeSelectionHelper.get()); 221 if( m_bHasInternalDataProvider ) 222 { 223 m_aRbRange.SetText( String( SchResId( STR_CONTROLTEXT_ERROR_BARS_FROM_DATA ))); 224 } 225 226 if( m_aRbRange.IsChecked()) 227 { 228 isRangeFieldContentValid( m_aEdRangePositive ); 229 isRangeFieldContentValid( m_aEdRangeNegative ); 230 } 231 } 232 233 void ErrorBarResources::SetAxisMinorStepWidthForErrorBarDecimals( double fMinorStepWidth ) 234 { 235 if( fMinorStepWidth < 0 ) 236 fMinorStepWidth = -fMinorStepWidth; 237 238 sal_Int32 nExponent = static_cast< sal_Int32 >( ::rtl::math::approxFloor( log10( fMinorStepWidth ))); 239 if( nExponent <= 0 ) 240 { 241 // one digit precision more 242 m_nConstDecimalDigits = static_cast< sal_uInt16 >( (-nExponent) + 1 ); 243 m_nConstSpinSize = 10; 244 } 245 else 246 { 247 m_nConstDecimalDigits = 0; 248 m_nConstSpinSize = static_cast< sal_Int64 >( pow( 10.0, (int)nExponent )); 249 } 250 } 251 252 void ErrorBarResources::UpdateControlStates() 253 { 254 // function 255 bool bIsFunction = m_aRbFunction.IsChecked(); 256 m_aLbFunction.Enable( bIsFunction ); 257 258 // range buttons 259 m_aRbRange.Enable( !m_bHasInternalDataProvider || !m_bDisableDataTableDialog ); 260 bool bShowRange = ( m_aRbRange.IsChecked()); 261 bool bCanChooseRange = 262 ( bShowRange && 263 m_apRangeSelectionHelper.get() && 264 m_apRangeSelectionHelper->hasRangeSelection()); 265 266 m_aMfPositive.Show( ! bShowRange ); 267 m_aMfNegative.Show( ! bShowRange ); 268 269 // use range but without range chooser => hide controls 270 m_aEdRangePositive.Show( bShowRange && ! m_bHasInternalDataProvider ); 271 m_aIbRangePositive.Show( bCanChooseRange ); 272 m_aEdRangeNegative.Show( bShowRange && ! m_bHasInternalDataProvider ); 273 m_aIbRangeNegative.Show( bCanChooseRange ); 274 275 bool bShowPosNegAndSync = ! (bShowRange && m_bHasInternalDataProvider); 276 m_aFtPositive.Show( bShowPosNegAndSync ); 277 m_aFtNegative.Show( bShowPosNegAndSync ); 278 m_aCbSyncPosNeg.Show( bShowPosNegAndSync ); 279 m_aFlParameters.Show( bShowPosNegAndSync ); 280 281 // unit for metric fields 282 bool bIsErrorMargin( 283 ( m_aRbFunction.IsChecked()) && 284 ( m_aLbFunction.GetSelectEntryPos() == CHART_LB_FUNCTION_ERROR_MARGIN )); 285 bool bIsPercentage( m_aRbPercent.IsChecked() || bIsErrorMargin ); 286 String aCustomUnit; 287 288 if( bIsPercentage ) 289 { 290 aCustomUnit = String( RTL_CONSTASCII_USTRINGPARAM( " %" )); 291 m_aMfPositive.SetDecimalDigits( 1 ); 292 m_aMfPositive.SetSpinSize( 10 ); 293 m_aMfNegative.SetDecimalDigits( 1 ); 294 m_aMfNegative.SetSpinSize( 10 ); 295 } 296 else 297 { 298 m_aMfPositive.SetDecimalDigits( m_nConstDecimalDigits ); 299 m_aMfPositive.SetSpinSize( m_nConstSpinSize ); 300 m_aMfNegative.SetDecimalDigits( m_nConstDecimalDigits ); 301 m_aMfNegative.SetSpinSize( m_nConstSpinSize ); 302 } 303 m_aMfPositive.SetCustomUnitText( aCustomUnit ); 304 m_aMfNegative.SetCustomUnitText( aCustomUnit ); 305 306 // positive and negative value fields 307 bool bPosEnabled = ( m_aRbPositive.IsChecked() || m_aRbBoth.IsChecked()); 308 bool bNegEnabled = ( m_aRbNegative.IsChecked() || m_aRbBoth.IsChecked()); 309 if( !( bPosEnabled || bNegEnabled )) 310 { 311 // all three controls are not checked -> ambiguous state 312 bPosEnabled = true; 313 bNegEnabled = true; 314 } 315 316 // functions with only one parameter 317 bool bOneParameterCategory = 318 bIsErrorMargin || m_aRbPercent.IsChecked(); 319 if( bOneParameterCategory ) 320 { 321 m_aCbSyncPosNeg.Check(); 322 } 323 324 if( m_aCbSyncPosNeg.IsChecked()) 325 { 326 bPosEnabled = true; 327 bNegEnabled = false; 328 } 329 330 // all functions except error margin take no arguments 331 if( m_aRbFunction.IsChecked() && 332 ( m_aLbFunction.GetSelectEntryPos() != CHART_LB_FUNCTION_ERROR_MARGIN )) 333 { 334 bPosEnabled = false; 335 bNegEnabled = false; 336 } 337 338 // enable/disable pos/neg fields 339 m_aFtPositive.Enable( bPosEnabled ); 340 m_aFtNegative.Enable( bNegEnabled ); 341 if( bShowRange ) 342 { 343 m_aEdRangePositive.Enable( bPosEnabled ); 344 m_aIbRangePositive.Enable( bPosEnabled ); 345 m_aEdRangeNegative.Enable( bNegEnabled ); 346 m_aIbRangeNegative.Enable( bNegEnabled ); 347 } 348 else 349 { 350 m_aMfPositive.Enable( bPosEnabled ); 351 m_aMfNegative.Enable( bNegEnabled ); 352 } 353 354 m_aCbSyncPosNeg.Enable( 355 !bOneParameterCategory && 356 ( bPosEnabled || bNegEnabled )); 357 358 // mark invalid entries in the range fields 359 if( bShowRange && ! m_bHasInternalDataProvider ) 360 { 361 isRangeFieldContentValid( m_aEdRangePositive ); 362 isRangeFieldContentValid( m_aEdRangeNegative ); 363 } 364 } 365 366 IMPL_LINK( ErrorBarResources, CategoryChosen, void *, ) 367 { 368 m_bErrorKindUnique = true; 369 SvxChartKindError eOldError = m_eErrorKind; 370 371 if( m_aRbNone.IsChecked()) 372 m_eErrorKind = CHERROR_NONE; 373 else if( m_aRbConst.IsChecked()) 374 m_eErrorKind = CHERROR_CONST; 375 else if( m_aRbPercent.IsChecked()) 376 m_eErrorKind = CHERROR_PERCENT; 377 else if( m_aRbRange.IsChecked()) 378 m_eErrorKind = CHERROR_RANGE; 379 else if( m_aRbFunction.IsChecked()) 380 { 381 if( m_aLbFunction.GetSelectEntryCount() == 1 ) 382 { 383 switch( m_aLbFunction.GetSelectEntryPos()) 384 { 385 case CHART_LB_FUNCTION_STD_ERROR: 386 m_eErrorKind = CHERROR_STDERROR; break; 387 case CHART_LB_FUNCTION_STD_DEV: 388 m_eErrorKind = CHERROR_SIGMA; break; 389 case CHART_LB_FUNCTION_VARIANCE: 390 m_eErrorKind = CHERROR_VARIANT; break; 391 case CHART_LB_FUNCTION_ERROR_MARGIN: 392 m_eErrorKind = CHERROR_BIGERROR; break; 393 default: 394 m_bErrorKindUnique = false; 395 } 396 } 397 else 398 m_bErrorKindUnique = false; 399 } 400 else 401 { 402 OSL_ENSURE( false, "Unknown category chosen" ); 403 m_bErrorKindUnique = false; 404 } 405 406 // changed to range 407 if( m_eErrorKind == CHERROR_RANGE && 408 eOldError != CHERROR_RANGE ) 409 { 410 m_aCbSyncPosNeg.Check( 411 (m_aEdRangePositive.GetText().Len() > 0) && 412 m_aEdRangePositive.GetText().Equals( 413 m_aEdRangeNegative.GetText())); 414 } 415 // changed from range 416 else if( m_eErrorKind != CHERROR_RANGE && 417 eOldError == CHERROR_RANGE ) 418 { 419 m_aCbSyncPosNeg.Check( 420 m_aMfPositive.GetValue() == m_aMfNegative.GetValue()); 421 } 422 423 UpdateControlStates(); 424 return 0; 425 } 426 427 IMPL_LINK( ErrorBarResources, SynchronizePosAndNeg, void *, EMPTYARG ) 428 { 429 UpdateControlStates(); 430 PosValueChanged( 0 ); 431 return 0; 432 } 433 434 IMPL_LINK( ErrorBarResources, PosValueChanged, void *, EMPTYARG ) 435 { 436 if( m_aCbSyncPosNeg.IsChecked()) 437 { 438 if( m_aRbRange.IsChecked()) 439 { 440 m_aEdRangeNegative.SetText( m_aEdRangePositive.GetText()); 441 m_bRangeNegUnique = m_bRangePosUnique; 442 } 443 else 444 m_aMfNegative.SetValue( m_aMfPositive.GetValue()); 445 } 446 447 return 0; 448 } 449 450 IMPL_LINK( ErrorBarResources, IndicatorChanged, void *, EMPTYARG ) 451 { 452 m_bIndicatorUnique = true; 453 if( m_aRbBoth.IsChecked()) 454 m_eIndicate = CHINDICATE_BOTH; 455 else if( m_aRbPositive.IsChecked()) 456 m_eIndicate = CHINDICATE_UP; 457 else if( m_aRbNegative.IsChecked()) 458 m_eIndicate = CHINDICATE_DOWN; 459 else 460 m_bIndicatorUnique = false; 461 462 UpdateControlStates(); 463 return 0; 464 } 465 466 IMPL_LINK( ErrorBarResources, ChooseRange, RangeSelectionButton *, pButton ) 467 { 468 OSL_ASSERT( m_apRangeSelectionHelper.get()); 469 if( ! m_apRangeSelectionHelper.get()) 470 return 0; 471 OSL_ASSERT( m_pCurrentRangeChoosingField == 0 ); 472 473 ::rtl::OUString aUIString; 474 if( pButton == &m_aIbRangePositive ) 475 { 476 m_pCurrentRangeChoosingField = &m_aEdRangePositive; 477 aUIString = String( SchResId( STR_DATA_SELECT_RANGE_FOR_POSITIVE_ERRORBARS )); 478 } 479 else 480 { 481 m_pCurrentRangeChoosingField = &m_aEdRangeNegative; 482 aUIString = String( SchResId( STR_DATA_SELECT_RANGE_FOR_NEGATIVE_ERRORBARS )); 483 } 484 485 OSL_ASSERT( m_pParentDialog ); 486 if( m_pParentDialog ) 487 { 488 lcl_enableRangeChoosing( true, m_pParentDialog ); 489 m_apRangeSelectionHelper->chooseRange( 490 m_pCurrentRangeChoosingField->GetText(), 491 aUIString, *this ); 492 } 493 else 494 m_pCurrentRangeChoosingField = 0; 495 496 return 0; 497 } 498 499 IMPL_LINK( ErrorBarResources, RangeChanged, Edit *, pEdit ) 500 { 501 if( pEdit == & m_aEdRangePositive ) 502 { 503 m_bRangePosUnique = true; 504 PosValueChanged( 0 ); 505 } 506 else 507 { 508 m_bRangeNegUnique = true; 509 } 510 511 isRangeFieldContentValid( *pEdit ); 512 513 return 0; 514 } 515 516 void ErrorBarResources::Reset(const SfxItemSet& rInAttrs) 517 { 518 const SfxPoolItem *pPoolItem = NULL; 519 SfxItemState aState = SFX_ITEM_UNKNOWN; 520 521 // category 522 m_eErrorKind = CHERROR_NONE; 523 aState = rInAttrs.GetItemState( SCHATTR_STAT_KIND_ERROR, sal_True, &pPoolItem ); 524 m_bErrorKindUnique = ( aState != SFX_ITEM_DONTCARE ); 525 526 if( aState == SFX_ITEM_SET ) 527 m_eErrorKind = ((const SvxChartKindErrorItem*) pPoolItem)->GetValue(); 528 529 m_aLbFunction.SelectEntryPos( lcl_getLbEntryPosByErrorKind( m_eErrorKind )); 530 531 if( m_bErrorKindUnique ) 532 { 533 switch( m_eErrorKind ) 534 { 535 case CHERROR_NONE: 536 m_aRbNone.Check(); 537 break; 538 case CHERROR_PERCENT: 539 m_aRbPercent.Check(); 540 break; 541 case CHERROR_CONST: 542 m_aRbConst.Check(); 543 break; 544 case CHERROR_STDERROR: 545 case CHERROR_VARIANT: 546 case CHERROR_SIGMA: 547 case CHERROR_BIGERROR: 548 m_aRbFunction.Check(); 549 break; 550 case CHERROR_RANGE: 551 m_aRbRange.Check(); 552 break; 553 } 554 } 555 else 556 { 557 m_aRbNone.Check( sal_False ); 558 m_aRbConst.Check( sal_False ); 559 m_aRbPercent.Check( sal_False ); 560 m_aRbFunction.Check( sal_False ); 561 } 562 563 // parameters 564 aState = rInAttrs.GetItemState( SCHATTR_STAT_CONSTPLUS, sal_True, &pPoolItem ); 565 m_bPlusUnique = ( aState != SFX_ITEM_DONTCARE ); 566 double fPlusValue = 0.0; 567 if( aState == SFX_ITEM_SET ) 568 { 569 fPlusValue = ((const SvxDoubleItem*) pPoolItem)->GetValue(); 570 sal_Int32 nPlusValue = static_cast< sal_Int32 >( fPlusValue * pow(10.0,m_aMfPositive.GetDecimalDigits()) ); 571 m_aMfPositive.SetValue( nPlusValue ); 572 } 573 574 aState = rInAttrs.GetItemState( SCHATTR_STAT_CONSTMINUS, sal_True, &pPoolItem ); 575 m_bMinusUnique = ( aState != SFX_ITEM_DONTCARE ); 576 double fMinusValue = 0.0; 577 if( aState == SFX_ITEM_SET ) 578 { 579 fMinusValue = ((const SvxDoubleItem*) pPoolItem)->GetValue(); 580 sal_Int32 nMinusValue = static_cast< sal_Int32 >( fMinusValue * pow(10.0,m_aMfNegative.GetDecimalDigits()) ); 581 m_aMfNegative.SetValue( nMinusValue ); 582 583 if( m_eErrorKind != CHERROR_RANGE && 584 fPlusValue == fMinusValue ) 585 m_aCbSyncPosNeg.Check(); 586 } 587 588 // indicator 589 aState = rInAttrs.GetItemState( SCHATTR_STAT_INDICATE, sal_True, &pPoolItem ); 590 m_bIndicatorUnique = ( aState != SFX_ITEM_DONTCARE ); 591 if( aState == SFX_ITEM_SET) 592 m_eIndicate = ((const SvxChartIndicateItem * ) pPoolItem)->GetValue(); 593 594 if( m_bIndicatorUnique ) 595 { 596 switch( m_eIndicate ) 597 { 598 case CHINDICATE_NONE : 599 // no longer used, use both as default 600 m_eIndicate = CHINDICATE_BOTH; 601 // fall-through intended to BOTH 602 case CHINDICATE_BOTH : 603 m_aRbBoth.Check(); break; 604 case CHINDICATE_UP : 605 m_aRbPositive.Check(); break; 606 case CHINDICATE_DOWN : 607 m_aRbNegative.Check(); break; 608 } 609 } 610 else 611 { 612 m_aRbBoth.Check( sal_False ); 613 m_aRbPositive.Check( sal_False ); 614 m_aRbNegative.Check( sal_False ); 615 } 616 617 // ranges 618 aState = rInAttrs.GetItemState( SCHATTR_STAT_RANGE_POS, sal_True, &pPoolItem ); 619 m_bRangePosUnique = ( aState != SFX_ITEM_DONTCARE ); 620 if( aState == SFX_ITEM_SET ) 621 { 622 String sRangePositive = (static_cast< const SfxStringItem * >( pPoolItem ))->GetValue(); 623 m_aEdRangePositive.SetText( sRangePositive ); 624 } 625 626 aState = rInAttrs.GetItemState( SCHATTR_STAT_RANGE_NEG, sal_True, &pPoolItem ); 627 m_bRangeNegUnique = ( aState != SFX_ITEM_DONTCARE ); 628 if( aState == SFX_ITEM_SET ) 629 { 630 String sRangeNegative = (static_cast< const SfxStringItem * >( pPoolItem ))->GetValue(); 631 m_aEdRangeNegative.SetText( sRangeNegative ); 632 if( m_eErrorKind == CHERROR_RANGE && 633 sRangeNegative.Len() > 0 && 634 sRangeNegative.Equals( m_aEdRangePositive.GetText())) 635 m_aCbSyncPosNeg.Check(); 636 } 637 638 UpdateControlStates(); 639 } 640 641 sal_Bool ErrorBarResources::FillItemSet(SfxItemSet& rOutAttrs) const 642 { 643 if( m_bErrorKindUnique ) 644 rOutAttrs.Put( SvxChartKindErrorItem( m_eErrorKind, SCHATTR_STAT_KIND_ERROR )); 645 if( m_bIndicatorUnique ) 646 rOutAttrs.Put( SvxChartIndicateItem( m_eIndicate, SCHATTR_STAT_INDICATE )); 647 648 if( m_bErrorKindUnique ) 649 { 650 if( m_eErrorKind == CHERROR_RANGE ) 651 { 652 String aPosRange; 653 String aNegRange; 654 if( m_bHasInternalDataProvider ) 655 { 656 // the strings aPosRange/aNegRange have to be set to a non-empty 657 // arbitrary string to generate error-bar sequences 658 aPosRange.Assign( sal_Unicode('x')); 659 aNegRange = aPosRange; 660 } 661 else 662 { 663 aPosRange = m_aEdRangePositive.GetText(); 664 if( m_aCbSyncPosNeg.IsChecked()) 665 aNegRange = aPosRange; 666 else 667 aNegRange = m_aEdRangeNegative.GetText(); 668 } 669 670 if( m_bRangePosUnique ) 671 rOutAttrs.Put( SfxStringItem( SCHATTR_STAT_RANGE_POS, aPosRange )); 672 if( m_bRangeNegUnique ) 673 rOutAttrs.Put( SfxStringItem( SCHATTR_STAT_RANGE_NEG, aNegRange )); 674 } 675 else if( m_eErrorKind == CHERROR_CONST || 676 m_eErrorKind == CHERROR_PERCENT || 677 m_eErrorKind == CHERROR_BIGERROR ) 678 { 679 double fPosValue = static_cast< double >( m_aMfPositive.GetValue()) / 680 pow( 10.0, m_aMfPositive.GetDecimalDigits()); 681 double fNegValue = 0.0; 682 683 if( m_aCbSyncPosNeg.IsChecked()) 684 fNegValue = fPosValue; 685 else 686 fNegValue = static_cast< double >( m_aMfNegative.GetValue()) / 687 pow( 10.0, m_aMfNegative.GetDecimalDigits()); 688 689 rOutAttrs.Put( SvxDoubleItem( fPosValue, SCHATTR_STAT_CONSTPLUS )); 690 rOutAttrs.Put( SvxDoubleItem( fNegValue, SCHATTR_STAT_CONSTMINUS )); 691 } 692 } 693 694 return sal_True; 695 } 696 697 void ErrorBarResources::FillValueSets() 698 { 699 bool bIsHighContrast = ( true && m_aRbConst.GetSettings().GetStyleSettings().GetHighContrastMode() ); 700 701 // do not scale images, show then centered 702 // m_aFiPositive.SetStyle( (m_aFiPositive.GetStyle() & (~WB_SCALE)) | WB_CENTER ); 703 // m_aFiNegative.SetStyle( (m_aFiNegative.GetStyle() & (~WB_SCALE)) | WB_CENTER ); 704 // m_aFiBoth.SetStyle( (m_aFiBoth.GetStyle() & (~WB_SCALE)) | WB_CENTER ); 705 706 if( m_eErrorBarType == ERROR_BAR_Y ) 707 { 708 m_aFiNegative.SetImage( SELECT_IMAGE( BMP_INDICATE_DOWN )); 709 m_aFiPositive.SetImage( SELECT_IMAGE( BMP_INDICATE_UP )); 710 m_aFiBoth.SetImage( SELECT_IMAGE( BMP_INDICATE_BOTH_VERTI )); 711 } 712 else if( m_eErrorBarType == ERROR_BAR_X ) 713 { 714 m_aFiNegative.SetImage( SELECT_IMAGE( BMP_INDICATE_LEFT )); 715 m_aFiPositive.SetImage( SELECT_IMAGE( BMP_INDICATE_RIGHT )); 716 m_aFiBoth.SetImage( SELECT_IMAGE( BMP_INDICATE_BOTH_HORI )); 717 } 718 } 719 720 void ErrorBarResources::listeningFinished( 721 const ::rtl::OUString & rNewRange ) 722 { 723 OSL_ASSERT( m_apRangeSelectionHelper.get()); 724 if( ! m_apRangeSelectionHelper.get()) 725 return; 726 727 // rNewRange becomes invalid after removing the listener 728 ::rtl::OUString aRange( rNewRange ); 729 730 // m_rDialogModel.startControllerLockTimer(); 731 732 // stop listening 733 m_apRangeSelectionHelper->stopRangeListening(); 734 735 // change edit field 736 if( m_pParentWindow ) 737 { 738 m_pParentWindow->ToTop(); 739 m_pParentWindow->GrabFocus(); 740 } 741 742 if( m_pCurrentRangeChoosingField ) 743 { 744 m_pCurrentRangeChoosingField->SetText( String( aRange )); 745 m_pCurrentRangeChoosingField->GrabFocus(); 746 PosValueChanged( 0 ); 747 } 748 749 m_pCurrentRangeChoosingField = 0; 750 751 UpdateControlStates(); 752 OSL_ASSERT( m_pParentDialog ); 753 if( m_pParentDialog ) 754 lcl_enableRangeChoosing( false, m_pParentDialog ); 755 } 756 757 void ErrorBarResources::disposingRangeSelection() 758 { 759 OSL_ASSERT( m_apRangeSelectionHelper.get()); 760 if( m_apRangeSelectionHelper.get()) 761 m_apRangeSelectionHelper->stopRangeListening( false ); 762 } 763 764 bool ErrorBarResources::isRangeFieldContentValid( Edit & rEdit ) 765 { 766 ::rtl::OUString aRange( rEdit.GetText()); 767 bool bIsValid = ( aRange.getLength() == 0 ) || 768 ( m_apRangeSelectionHelper.get() && 769 m_apRangeSelectionHelper->verifyCellRange( aRange )); 770 771 if( bIsValid || !rEdit.IsEnabled()) 772 { 773 rEdit.SetControlForeground(); 774 rEdit.SetControlBackground(); 775 } 776 else 777 { 778 rEdit.SetControlBackground( RANGE_SELECTION_INVALID_RANGE_BACKGROUND_COLOR ); 779 rEdit.SetControlForeground( RANGE_SELECTION_INVALID_RANGE_FOREGROUND_COLOR ); 780 } 781 782 return bIsValid; 783 } 784 785 //............................................................................. 786 } //namespace chart 787 //............................................................................. 788