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