fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / vcl / source / control / field.cxx
blob87043dd86f1aab6b9968cfdfcf4e4bca8763ce5e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "sal/config.h"
22 #include <comphelper/processfactory.hxx>
23 #include <comphelper/string.hxx>
25 #include "tools/debug.hxx"
27 #include "tools/rc.h"
29 #include "vcl/dialog.hxx"
30 #include "vcl/field.hxx"
31 #include "vcl/event.hxx"
32 #include "vcl/svapp.hxx"
34 #include "svids.hrc"
35 #include "svdata.hxx"
37 #include "i18nutil/unicode.hxx"
39 #include "rtl/math.hxx"
41 #include <unotools/localedatawrapper.hxx>
43 using namespace ::com::sun::star;
44 using namespace ::comphelper;
46 // -----------------------------------------------------------------------
48 #define FORMAT_NUMERIC 1
49 #define FORMAT_METRIC 2
50 #define FORMAT_CURRENCY 3
52 // -----------------------------------------------------------------------
54 static sal_Int64 ImplPower10( sal_uInt16 n )
56 sal_uInt16 i;
57 sal_Int64 nValue = 1;
59 for ( i=0; i < n; i++ )
60 nValue *= 10;
62 return nValue;
65 // -----------------------------------------------------------------------
67 static bool ImplNumericProcessKeyInput( Edit*, const KeyEvent& rKEvt,
68 bool bStrictFormat, bool bThousandSep,
69 const LocaleDataWrapper& rLocaleDataWrappper )
71 if ( !bStrictFormat )
72 return false;
73 else
75 sal_Unicode cChar = rKEvt.GetCharCode();
76 sal_uInt16 nGroup = rKEvt.GetKeyCode().GetGroup();
78 if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) ||
79 (nGroup == KEYGROUP_MISC) ||
80 ((cChar >= '0') && (cChar <= '9')) ||
81 string::equals(rLocaleDataWrappper.getNumDecimalSep(), cChar) ||
82 (bThousandSep && string::equals(rLocaleDataWrappper.getNumThousandSep(), cChar)) ||
83 (cChar == '-') )
84 return false;
85 else
86 return true;
90 // -----------------------------------------------------------------------
92 static bool ImplNumericGetValue( const OUString& rStr, sal_Int64& rValue,
93 sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrappper,
94 bool bCurrency = false )
96 OUString aStr = rStr;
97 OUStringBuffer aStr1, aStr2;
98 bool bNegative = false;
99 sal_Int32 nDecPos;
101 // react on empty string
102 if ( rStr.isEmpty() )
103 return false;
105 // remove leading and trailing spaces
106 aStr = aStr.trim();
108 // find position of decimal point
109 nDecPos = aStr.indexOf( rLocaleDataWrappper.getNumDecimalSep() );
110 if ( nDecPos >= 0)
112 aStr1.append(aStr.getStr(), nDecPos);
113 aStr2.append(aStr.getStr()+nDecPos+1);
115 else
116 aStr1 = aStr;
118 // negative?
119 if ( bCurrency )
121 if ( aStr[0] == '(' && aStr[aStr.getLength()-1] == ')' )
122 bNegative = true;
123 if ( !bNegative )
125 for (sal_Int32 i=0; i < aStr.getLength(); i++ )
127 if ( (aStr[i] >= '0') && (aStr[i] <= '9') )
128 break;
129 else if ( aStr[i] == '-' )
131 bNegative = true;
132 break;
136 if ( !bNegative && bCurrency && !aStr.isEmpty() )
138 sal_uInt16 nFormat = rLocaleDataWrappper.getCurrNegativeFormat();
139 if ( (nFormat == 3) || (nFormat == 6) || // $1- || 1-$
140 (nFormat == 7) || (nFormat == 10) ) // 1$- || 1 $-
142 for (sal_Int32 i = aStr.getLength()-1; i > 0; --i )
144 if ( (aStr[i] >= '0') && (aStr[i] <= '9') )
145 break;
146 else if ( aStr[i] == '-' )
148 bNegative = true;
149 break;
155 else
157 if ( !aStr1.isEmpty() && aStr1[0] == '-')
158 bNegative = true;
161 // remove all unwanted charaters
162 for (sal_Int32 i=0; i < aStr1.getLength(); )
164 if ( (aStr1[i] >= '0') && (aStr1[i] <= '9') )
165 i++;
166 else
167 aStr1.remove( i, 1 );
169 for (sal_Int32 i=0; i < aStr2.getLength(); )
171 if ((aStr2[i] >= '0') && (aStr2[i] <= '9'))
172 ++i;
173 else
174 aStr2.remove(i, 1);
177 if ( aStr1.isEmpty() && aStr2.isEmpty() )
178 return false;
180 if ( aStr1.isEmpty() )
181 aStr1 = "0";
182 if ( bNegative )
183 aStr1 = "-" + aStr1;
185 // prune and round fraction
186 bool bRound = false;
187 if (aStr2.getLength() > nDecDigits)
189 if (aStr2[nDecDigits] >= '5')
190 bRound = true;
191 string::truncateToLength(aStr2, nDecDigits);
193 if (aStr2.getLength() < nDecDigits)
194 string::padToLength(aStr2, nDecDigits, '0');
196 aStr = aStr1.makeStringAndClear() + aStr2.makeStringAndClear();
198 // check range
199 sal_Int64 nValue = aStr.toInt64();
200 if( nValue == 0 )
202 // check if string is equivalent to zero
203 sal_Int16 nIndex = bNegative ? 1 : 0;
204 while (nIndex < aStr.getLength() && aStr[nIndex] == '0')
205 ++nIndex;
206 if( nIndex < aStr.getLength() )
208 rValue = bNegative ? SAL_MIN_INT64 : SAL_MAX_INT64;
209 return true;
212 if (bRound)
214 if ( !bNegative )
215 nValue++;
216 else
217 nValue--;
220 rValue = nValue;
222 return true;
225 static void ImplUpdateSeparatorString( String& io_rText,
226 const String& rOldDecSep, const String& rNewDecSep,
227 const String& rOldThSep, const String& rNewThSep )
229 OUStringBuffer aBuf( io_rText.Len() );
230 xub_StrLen nIndexDec = 0, nIndexTh = 0, nIndex = 0;
232 const sal_Unicode* pBuffer = io_rText.GetBuffer();
233 while( nIndex != STRING_NOTFOUND )
235 nIndexDec = io_rText.Search( rOldDecSep, nIndex );
236 nIndexTh = io_rText.Search( rOldThSep, nIndex );
237 if( (nIndexTh != STRING_NOTFOUND && nIndexDec != STRING_NOTFOUND && nIndexTh < nIndexDec )
238 || (nIndexTh != STRING_NOTFOUND && nIndexDec == STRING_NOTFOUND)
241 aBuf.append( pBuffer + nIndex, nIndexTh - nIndex );
242 aBuf.append( rNewThSep );
243 nIndex = nIndexTh + rOldThSep.Len();
245 else if( nIndexDec != STRING_NOTFOUND )
247 aBuf.append( pBuffer + nIndex, nIndexDec - nIndex );
248 aBuf.append( rNewDecSep );
249 nIndex = nIndexDec + rOldDecSep.Len();
251 else
253 aBuf.append( pBuffer + nIndex );
254 nIndex = STRING_NOTFOUND;
258 io_rText = aBuf.makeStringAndClear();
261 static void ImplUpdateSeparators( const String& rOldDecSep, const String& rNewDecSep,
262 const String& rOldThSep, const String& rNewThSep,
263 Edit* pEdit )
265 bool bChangeDec = (rOldDecSep != rNewDecSep);
266 bool bChangeTh = (rOldThSep != rNewThSep );
268 if( bChangeDec || bChangeTh )
270 sal_Bool bUpdateMode = pEdit->IsUpdateMode();
271 pEdit->SetUpdateMode( sal_False );
272 String aText = pEdit->GetText();
273 ImplUpdateSeparatorString( aText, rOldDecSep, rNewDecSep, rOldThSep, rNewThSep );
274 pEdit->SetText( aText );
276 ComboBox* pCombo = dynamic_cast<ComboBox*>(pEdit);
277 if( pCombo )
279 // update box entries
280 sal_uInt16 nEntryCount = pCombo->GetEntryCount();
281 for ( sal_uInt16 i=0; i < nEntryCount; i++ )
283 aText = pCombo->GetEntry( i );
284 void* pEntryData = pCombo->GetEntryData( i );
285 ImplUpdateSeparatorString( aText, rOldDecSep, rNewDecSep, rOldThSep, rNewThSep );
286 pCombo->RemoveEntry( i );
287 pCombo->InsertEntry( aText, i );
288 pCombo->SetEntryData( i, pEntryData );
291 if( bUpdateMode )
292 pEdit->SetUpdateMode( bUpdateMode );
296 // -----------------------------------------------------------------------
298 FormatterBase::FormatterBase( Edit* pField )
300 mpField = pField;
301 mpLocaleDataWrapper = NULL;
302 mbReformat = sal_False;
303 mbStrictFormat = sal_False;
304 mbEmptyFieldValue = sal_False;
305 mbEmptyFieldValueEnabled = sal_False;
306 mbDefaultLocale = sal_True;
309 // -----------------------------------------------------------------------
311 FormatterBase::~FormatterBase()
313 delete mpLocaleDataWrapper;
316 // -----------------------------------------------------------------------
318 LocaleDataWrapper& FormatterBase::ImplGetLocaleDataWrapper() const
320 if ( !mpLocaleDataWrapper )
322 ((FormatterBase*)this)->mpLocaleDataWrapper = new LocaleDataWrapper( GetLanguageTag() );
324 return *mpLocaleDataWrapper;
327 const LocaleDataWrapper& FormatterBase::GetLocaleDataWrapper() const
329 return ImplGetLocaleDataWrapper();
332 // -----------------------------------------------------------------------
334 void FormatterBase::Reformat()
338 // -----------------------------------------------------------------------
340 void FormatterBase::ReformatAll()
342 Reformat();
345 // -----------------------------------------------------------------------
347 void FormatterBase::SetStrictFormat( sal_Bool bStrict )
349 if ( bStrict != mbStrictFormat )
351 mbStrictFormat = bStrict;
352 if ( mbStrictFormat )
353 ReformatAll();
357 // -----------------------------------------------------------------------
359 void FormatterBase::SetLocale( const lang::Locale& rLocale )
361 ImplGetLocaleDataWrapper().setLanguageTag( LanguageTag( rLocale) );
362 mbDefaultLocale = sal_False;
363 ReformatAll();
366 // -----------------------------------------------------------------------
368 const lang::Locale& FormatterBase::GetLocale() const
370 if ( !mpLocaleDataWrapper || mbDefaultLocale )
372 if ( mpField )
373 return mpField->GetSettings().GetLanguageTag().getLocale();
374 else
375 return Application::GetSettings().GetLanguageTag().getLocale();
378 return mpLocaleDataWrapper->getLanguageTag().getLocale();
381 // -----------------------------------------------------------------------
383 const LanguageTag& FormatterBase::GetLanguageTag() const
385 if ( !mpLocaleDataWrapper || mbDefaultLocale )
387 if ( mpField )
388 return mpField->GetSettings().GetLanguageTag();
389 else
390 return Application::GetSettings().GetLanguageTag();
393 return mpLocaleDataWrapper->getLanguageTag();
396 // -----------------------------------------------------------------------
398 const AllSettings& FormatterBase::GetFieldSettings() const
400 if ( mpField )
401 return mpField->GetSettings();
402 else
403 return Application::GetSettings();
406 // -----------------------------------------------------------------------
408 void FormatterBase::ImplSetText( const OUString& rText, Selection* pNewSelection )
410 if ( mpField )
412 if ( pNewSelection )
413 mpField->SetText( rText, *pNewSelection );
414 else
416 Selection aSel = mpField->GetSelection();
417 aSel.Min() = aSel.Max();
418 mpField->SetText( rText, aSel );
421 MarkToBeReformatted( sal_False );
425 // -----------------------------------------------------------------------
427 void FormatterBase::SetEmptyFieldValue()
429 if ( mpField )
430 mpField->SetText( ImplGetSVEmptyStr() );
431 mbEmptyFieldValue = sal_True;
434 // -----------------------------------------------------------------------
436 sal_Bool FormatterBase::IsEmptyFieldValue() const
438 return (!mpField || mpField->GetText().isEmpty());
441 // -----------------------------------------------------------------------
443 sal_Bool NumericFormatter::ImplNumericReformat( const OUString& rStr, sal_Int64& rValue,
444 OUString& rOutStr )
446 if ( !ImplNumericGetValue( rStr, rValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
447 return sal_True;
448 else
450 sal_Int64 nTempVal = rValue;
451 if ( nTempVal > mnMax )
452 nTempVal = mnMax;
453 else if ( nTempVal < mnMin )
454 nTempVal = mnMin;
456 if ( GetErrorHdl().IsSet() && (rValue != nTempVal) )
458 mnCorrectedValue = nTempVal;
459 if ( !GetErrorHdl().Call( this ) )
461 mnCorrectedValue = 0;
462 return sal_False;
464 else
465 mnCorrectedValue = 0;
468 rOutStr = CreateFieldText( nTempVal );
469 return sal_True;
473 // -----------------------------------------------------------------------
475 void NumericFormatter::ImplInit()
477 mnFieldValue = 0;
478 mnLastValue = 0;
479 mnMin = 0;
480 mnMax = 0x7FFFFFFFFFFFFFFFLL;
481 mnCorrectedValue = 0;
482 mnDecimalDigits = 2;
483 mnType = FORMAT_NUMERIC;
484 mbThousandSep = sal_True;
485 mbShowTrailingZeros = sal_True;
487 // for fields
488 mnSpinSize = 1;
489 mnFirst = mnMin;
490 mnLast = mnMax;
492 SetDecimalDigits( 0 );
495 // -----------------------------------------------------------------------
497 NumericFormatter::NumericFormatter()
499 ImplInit();
502 // -----------------------------------------------------------------------
504 void NumericFormatter::ImplLoadRes( const ResId& rResId )
506 ResMgr* pMgr = rResId.GetResMgr();
508 if( pMgr )
510 sal_uLong nMask = pMgr->ReadLong();
512 if ( NUMERICFORMATTER_MIN & nMask )
513 mnMin = pMgr->ReadLong();
515 if ( NUMERICFORMATTER_MAX & nMask )
516 mnMax = pMgr->ReadLong();
518 if ( NUMERICFORMATTER_STRICTFORMAT & nMask )
519 SetStrictFormat( (sal_Bool)pMgr->ReadShort() );
521 if ( NUMERICFORMATTER_DECIMALDIGITS & nMask )
522 SetDecimalDigits( pMgr->ReadShort() );
524 if ( NUMERICFORMATTER_VALUE & nMask )
526 mnFieldValue = pMgr->ReadLong();
527 if ( mnFieldValue > mnMax )
528 mnFieldValue = mnMax;
529 else if ( mnFieldValue < mnMin )
530 mnFieldValue = mnMin;
531 mnLastValue = mnFieldValue;
534 if ( NUMERICFORMATTER_NOTHOUSANDSEP & nMask )
535 SetUseThousandSep( !(sal_Bool)pMgr->ReadShort() );
539 // -----------------------------------------------------------------------
541 NumericFormatter::~NumericFormatter()
545 // -----------------------------------------------------------------------
547 void NumericFormatter::SetMin( sal_Int64 nNewMin )
549 mnMin = nNewMin;
550 if ( !IsEmptyFieldValue() )
551 ReformatAll();
554 // -----------------------------------------------------------------------
556 void NumericFormatter::SetMax( sal_Int64 nNewMax )
558 mnMax = nNewMax;
559 if ( !IsEmptyFieldValue() )
560 ReformatAll();
563 // -----------------------------------------------------------------------
565 void NumericFormatter::SetUseThousandSep( sal_Bool b )
567 mbThousandSep = b;
568 ReformatAll();
571 // -----------------------------------------------------------------------
573 void NumericFormatter::SetDecimalDigits( sal_uInt16 nDigits )
575 mnDecimalDigits = nDigits;
576 ReformatAll();
579 // -----------------------------------------------------------------------
581 void NumericFormatter::SetShowTrailingZeros( sal_Bool bShowTrailingZeros )
583 if ( mbShowTrailingZeros != bShowTrailingZeros )
585 mbShowTrailingZeros = bShowTrailingZeros;
586 ReformatAll();
590 // -----------------------------------------------------------------------
592 sal_uInt16 NumericFormatter::GetDecimalDigits() const
594 return mnDecimalDigits;
597 // -----------------------------------------------------------------------
599 void NumericFormatter::SetValue( sal_Int64 nNewValue )
601 SetUserValue( nNewValue );
602 mnFieldValue = mnLastValue;
603 SetEmptyFieldValueData( sal_False );
606 // -----------------------------------------------------------------------
608 OUString NumericFormatter::CreateFieldText( sal_Int64 nValue ) const
610 return OUString(ImplGetLocaleDataWrapper().getNum( nValue, GetDecimalDigits(), IsUseThousandSep(), IsShowTrailingZeros() ));
613 // -----------------------------------------------------------------------
615 void NumericFormatter::ImplSetUserValue( sal_Int64 nNewValue, Selection* pNewSelection )
617 if ( nNewValue > mnMax )
618 nNewValue = mnMax;
619 else if ( nNewValue < mnMin )
620 nNewValue = mnMin;
621 mnLastValue = nNewValue;
623 if ( GetField() )
624 ImplSetText( CreateFieldText( nNewValue ), pNewSelection );
627 // -----------------------------------------------------------------------
629 void NumericFormatter::SetUserValue( sal_Int64 nNewValue )
631 ImplSetUserValue( nNewValue );
634 // -----------------------------------------------------------------------
636 sal_Int64 NumericFormatter::GetValue() const
638 if ( !GetField() )
639 return 0;
641 sal_Int64 nTempValue;
643 if ( ImplNumericGetValue( GetField()->GetText(), nTempValue,
644 GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
646 if ( nTempValue > mnMax )
647 nTempValue = mnMax;
648 else if ( nTempValue < mnMin )
649 nTempValue = mnMin;
650 return nTempValue;
652 else
653 return mnLastValue;
656 // -----------------------------------------------------------------------
658 sal_Bool NumericFormatter::IsValueModified() const
660 if ( ImplGetEmptyFieldValue() )
661 return !IsEmptyFieldValue();
662 else if ( GetValue() != mnFieldValue )
663 return sal_True;
664 else
665 return sal_False;
668 // -----------------------------------------------------------------------
670 sal_Int64 NumericFormatter::Normalize( sal_Int64 nValue ) const
672 return (nValue * ImplPower10( GetDecimalDigits() ) );
675 // -----------------------------------------------------------------------
677 sal_Int64 NumericFormatter::Denormalize( sal_Int64 nValue ) const
679 sal_Int64 nFactor = ImplPower10( GetDecimalDigits() );
680 if( nValue < 0 )
682 sal_Int64 nHalf = nValue < ( SAL_MIN_INT64 + nFactor )? 0 : nFactor/2;
683 return ((nValue-nHalf) / nFactor );
685 else
687 sal_Int64 nHalf = nValue > ( SAL_MAX_INT64 - nFactor )? 0 : nFactor/2;
688 return ((nValue+nHalf) / nFactor );
692 // -----------------------------------------------------------------------
694 void NumericFormatter::Reformat()
696 if ( !GetField() )
697 return;
699 if ( GetField()->GetText().isEmpty() && ImplGetEmptyFieldValue() )
700 return;
702 OUString aStr;
703 sal_Int64 nTemp = mnLastValue;
704 sal_Bool bOK = ImplNumericReformat( GetField()->GetText(), nTemp, aStr );
705 mnLastValue = nTemp;
706 if ( !bOK )
707 return;
709 if ( !aStr.isEmpty() )
710 ImplSetText( aStr );
711 else
712 SetValue( mnLastValue );
715 // -----------------------------------------------------------------------
717 void NumericFormatter::FieldUp()
719 sal_Int64 nValue = GetValue();
720 nValue += mnSpinSize;
721 if ( nValue > mnMax )
722 nValue = mnMax;
724 ImplNewFieldValue( nValue );
727 // -----------------------------------------------------------------------
729 void NumericFormatter::FieldDown()
731 sal_Int64 nValue = GetValue();
732 nValue -= mnSpinSize;
733 if ( nValue < mnMin )
734 nValue = mnMin;
736 ImplNewFieldValue( nValue );
739 // -----------------------------------------------------------------------
741 void NumericFormatter::FieldFirst()
743 ImplNewFieldValue( mnFirst );
746 // -----------------------------------------------------------------------
748 void NumericFormatter::FieldLast()
750 ImplNewFieldValue( mnLast );
753 // -----------------------------------------------------------------------
755 void NumericFormatter::ImplNewFieldValue( sal_Int64 nNewValue )
757 if ( GetField() )
759 // !!! We should check why we do not validate in ImplSetUserValue() if the value was
760 // changed. This should be done there as well since otherwise the call to Modify would not
761 // be allowed. Anyway, the paths from ImplNewFieldValue, ImplSetUserValue, and ImplSetText
762 // should be checked and clearly traced (with comment) in order to find out what happens.
764 Selection aSelection = GetField()->GetSelection();
765 aSelection.Justify();
766 OUString aText = GetField()->GetText();
767 // leave it as is if selected until end
768 if ( (sal_Int32)aSelection.Max() == aText.getLength() )
770 if ( !aSelection.Len() )
771 aSelection.Min() = SELECTION_MAX;
772 aSelection.Max() = SELECTION_MAX;
775 sal_Int64 nOldLastValue = mnLastValue;
776 ImplSetUserValue( nNewValue, &aSelection );
777 mnLastValue = nOldLastValue;
779 // Modify during Edit is only set during KeyInput
780 if ( GetField()->GetText() != aText )
782 GetField()->SetModifyFlag();
783 GetField()->Modify();
788 // -----------------------------------------------------------------------
790 NumericField::NumericField( Window* pParent, WinBits nWinStyle ) :
791 SpinField( pParent, nWinStyle )
793 SetField( this );
794 Reformat();
797 // -----------------------------------------------------------------------
799 NumericField::NumericField( Window* pParent, const ResId& rResId ) :
800 SpinField( WINDOW_NUMERICFIELD )
802 rResId.SetRT( RSC_NUMERICFIELD );
803 WinBits nStyle = ImplInitRes( rResId ) ;
804 SpinField::ImplInit( pParent, nStyle );
805 SetField( this );
806 ImplLoadRes( rResId );
807 Reformat();
809 if ( !(nStyle & WB_HIDE ) )
810 Show();
813 bool NumericField::set_property(const OString &rKey, const OString &rValue)
815 if (rKey == "digits")
816 SetDecimalDigits(rValue.toInt32());
817 else
818 return SpinField::set_property(rKey, rValue);
819 return true;
822 // -----------------------------------------------------------------------
824 void NumericField::ImplLoadRes( const ResId& rResId )
826 SpinField::ImplLoadRes( rResId );
827 NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
829 sal_uLong nMask = ReadLongRes();
831 if ( NUMERICFIELD_FIRST & nMask )
832 mnFirst = ReadLongRes();
834 if ( NUMERICFIELD_LAST & nMask )
835 mnLast = ReadLongRes();
837 if ( NUMERICFIELD_SPINSIZE & nMask )
838 mnSpinSize = ReadLongRes();
841 // -----------------------------------------------------------------------
843 NumericField::~NumericField()
847 // -----------------------------------------------------------------------
849 long NumericField::PreNotify( NotifyEvent& rNEvt )
851 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
853 if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
854 return 1;
857 return SpinField::PreNotify( rNEvt );
860 // -----------------------------------------------------------------------
862 long NumericField::Notify( NotifyEvent& rNEvt )
864 if ( rNEvt.GetType() == EVENT_GETFOCUS )
865 MarkToBeReformatted( sal_False );
866 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
868 if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
869 Reformat();
872 return SpinField::Notify( rNEvt );
875 // -----------------------------------------------------------------------
877 void NumericField::DataChanged( const DataChangedEvent& rDCEvt )
879 SpinField::DataChanged( rDCEvt );
881 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
883 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
884 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
885 if ( IsDefaultLocale() )
886 ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
887 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
888 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
889 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
890 ReformatAll();
894 // -----------------------------------------------------------------------
896 void NumericField::Modify()
898 MarkToBeReformatted( sal_True );
899 SpinField::Modify();
902 // -----------------------------------------------------------------------
904 void NumericField::Up()
906 FieldUp();
907 SpinField::Up();
910 // -----------------------------------------------------------------------
912 void NumericField::Down()
914 FieldDown();
915 SpinField::Down();
918 // -----------------------------------------------------------------------
920 void NumericField::First()
922 FieldFirst();
923 SpinField::First();
926 // -----------------------------------------------------------------------
928 void NumericField::Last()
930 FieldLast();
931 SpinField::Last();
934 namespace
936 Size calcMinimumSize(const SpinField &rSpinField, const NumericFormatter &rFormatter)
938 OUStringBuffer aBuf;
939 sal_Int32 nTextLen;
941 nTextLen = OUString::valueOf(rFormatter.GetMin()).getLength();
942 string::padToLength(aBuf, nTextLen, '9');
943 Size aMinTextSize = rSpinField.CalcMinimumSizeForText(
944 rFormatter.CreateFieldText(aBuf.makeStringAndClear().toInt64()));
946 nTextLen = OUString::valueOf(rFormatter.GetMax()).getLength();
947 string::padToLength(aBuf, nTextLen, '9');
948 Size aMaxTextSize = rSpinField.CalcMinimumSizeForText(
949 rFormatter.CreateFieldText(aBuf.makeStringAndClear().toInt64()));
951 Size aRet(std::max(aMinTextSize.Width(), aMaxTextSize.Width()),
952 std::max(aMinTextSize.Height(), aMaxTextSize.Height()));
954 OUStringBuffer sBuf("999999999");
955 sal_uInt16 nDigits = rFormatter.GetDecimalDigits();
956 if (nDigits)
958 sBuf.append('.');
959 string::padToLength(aBuf, aBuf.getLength() + nDigits, '9');
961 aMaxTextSize = rSpinField.CalcMinimumSizeForText(sBuf.makeStringAndClear());
962 aRet.Width() = std::min(aRet.Width(), aMaxTextSize.Width());
964 return aRet;
968 Size NumericField::CalcMinimumSize() const
970 return calcMinimumSize(*this, *this);
973 // -----------------------------------------------------------------------
975 NumericBox::NumericBox( Window* pParent, WinBits nWinStyle ) :
976 ComboBox( pParent, nWinStyle )
978 SetField( this );
979 Reformat();
982 // -----------------------------------------------------------------------
984 NumericBox::NumericBox( Window* pParent, const ResId& rResId ) :
985 ComboBox( WINDOW_NUMERICBOX )
987 rResId.SetRT( RSC_NUMERICBOX );
988 WinBits nStyle = ImplInitRes( rResId );
989 ComboBox::ImplInit( pParent, nStyle );
990 SetField( this );
991 ComboBox::ImplLoadRes( rResId );
992 NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
993 Reformat();
995 if ( !(nStyle & WB_HIDE ) )
996 Show();
999 // -----------------------------------------------------------------------
1001 NumericBox::~NumericBox()
1005 // -----------------------------------------------------------------------
1007 long NumericBox::PreNotify( NotifyEvent& rNEvt )
1009 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
1011 if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
1012 return 1;
1015 return ComboBox::PreNotify( rNEvt );
1018 // -----------------------------------------------------------------------
1020 long NumericBox::Notify( NotifyEvent& rNEvt )
1022 if ( rNEvt.GetType() == EVENT_GETFOCUS )
1023 MarkToBeReformatted( sal_False );
1024 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
1026 if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
1027 Reformat();
1030 return ComboBox::Notify( rNEvt );
1033 // -----------------------------------------------------------------------
1035 void NumericBox::DataChanged( const DataChangedEvent& rDCEvt )
1037 ComboBox::DataChanged( rDCEvt );
1039 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
1041 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
1042 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
1043 if ( IsDefaultLocale() )
1044 ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
1045 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
1046 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
1047 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
1048 ReformatAll();
1052 // -----------------------------------------------------------------------
1054 void NumericBox::Modify()
1056 MarkToBeReformatted( sal_True );
1057 ComboBox::Modify();
1060 // -----------------------------------------------------------------------
1062 void NumericBox::ReformatAll()
1064 sal_Int64 nValue;
1065 OUString aStr;
1066 SetUpdateMode( sal_False );
1067 sal_uInt16 nEntryCount = GetEntryCount();
1068 for ( sal_uInt16 i=0; i < nEntryCount; i++ )
1070 ImplNumericReformat( GetEntry( i ), nValue, aStr );
1071 RemoveEntry( i );
1072 InsertEntry( aStr, i );
1074 NumericFormatter::Reformat();
1075 SetUpdateMode( sal_True );
1078 // -----------------------------------------------------------------------
1080 void NumericBox::InsertValue( sal_Int64 nValue, sal_uInt16 nPos )
1082 ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
1085 // -----------------------------------------------------------------------
1087 static bool ImplMetricProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
1088 bool, bool bUseThousandSep, const LocaleDataWrapper& rWrapper )
1090 // no meaningfull strict format; therefore allow all characters
1091 return ImplNumericProcessKeyInput( pEdit, rKEvt, false, bUseThousandSep, rWrapper );
1094 // -----------------------------------------------------------------------
1096 static OUString ImplMetricGetUnitText(const OUString& rStr)
1098 // fetch unit text
1099 OUStringBuffer aStr;
1100 for (sal_Int32 i = rStr.getLength()-1; i >= 0; --i)
1102 sal_Unicode c = rStr[i];
1103 if ( (c == '\'') || (c == '\"') || (c == '%' ) || unicode::isAlpha(c) || unicode::isControl(c) )
1104 aStr.insert(0, c);
1105 else
1107 if (aStr.getLength())
1108 break;
1111 return aStr.makeStringAndClear();
1114 // -----------------------------------------------------------------------
1116 // #104355# support localized mesaurements
1118 static const OUString ImplMetricToString( FieldUnit rUnit )
1120 FieldUnitStringList* pList = ImplGetFieldUnits();
1121 if( pList )
1123 // return unit's default string (ie, the first one )
1124 for( FieldUnitStringList::const_iterator it = pList->begin(); it != pList->end(); ++it )
1126 if ( it->second == rUnit )
1127 return it->first;
1131 return OUString();
1134 static FieldUnit ImplStringToMetric(const OUString &rMetricString)
1136 FieldUnitStringList* pList = ImplGetCleanedFieldUnits();
1137 if( pList )
1139 // return FieldUnit
1140 OUString aStr(rMetricString.toAsciiLowerCase());
1141 aStr = string::remove(aStr, ' ');
1142 for( FieldUnitStringList::const_iterator it = pList->begin(); it != pList->end(); ++it )
1144 if ( it->first == aStr )
1145 return it->second;
1149 return FUNIT_NONE;
1152 // -----------------------------------------------------------------------
1154 static FieldUnit ImplMetricGetUnit(const OUString& rStr)
1156 OUString aStr = ImplMetricGetUnitText( rStr );
1157 return ImplStringToMetric( aStr );
1160 #define K *1000L
1161 #define M *1000000LL
1162 #define X *5280L
1164 // twip in km = 254 / 14 400 000 000
1165 // expressions too big for default size 32 bit need LL to avoid overflow
1167 static const sal_Int64 aImplFactor[FUNIT_LINE+1][FUNIT_LINE+1] =
1168 { /*
1169 mm/100 mm cm m km twip point pica inch foot mile char line */
1170 { 1, 100, 1 K, 100 K, 100 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X , 53340, 396240},
1171 { 1, 1, 10, 1 K, 1 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X , 5334, 396240},
1172 { 1, 1, 1, 100, 100 K, 254, 254, 254, 254, 254*12, 254*12 X , 5334, 39624},
1173 { 1, 1, 1, 1, 1 K, 254, 254, 254, 254, 254*12, 254*12 X , 533400, 39624},
1174 { 1, 1, 1, 1, 1, 254, 254, 254, 254, 254*12, 254*12 X ,533400 K, 39624},
1175 { 1440,144 K,144 K,14400 K,14400LL M, 1, 20, 240, 1440,1440*12,1440*12 X , 210, 3120},
1176 { 72, 7200, 7200, 720 K, 720 M, 1, 1, 12, 72, 72*12, 72*12 X , 210, 156},
1177 { 6, 600, 600, 60 K, 60 M, 1, 1, 1, 6, 6*12, 6*12 X , 210, 10},
1178 { 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 12, 12 X , 210, 45},
1179 { 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 X , 210, 45},
1180 { 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 , 210, 45},
1181 { 144, 1440,14400, 14400, 14400, 1, 20, 240, 1440,1440*12, 1440*12 X, 1, 156 },
1182 { 720,72000,72000, 7200 K,7200LL M, 20, 10, 13, 11, 11*12, 11*12 X, 105, 1 }
1184 #undef X
1185 #undef M
1186 #undef K
1188 static FieldUnit eDefaultUnit = FUNIT_NONE;
1190 FieldUnit MetricField::GetDefaultUnit() { return eDefaultUnit; }
1191 void MetricField::SetDefaultUnit( FieldUnit meUnit ) { eDefaultUnit = meUnit; }
1193 static FieldUnit ImplMap2FieldUnit( MapUnit meUnit, long& nDecDigits )
1195 switch( meUnit )
1197 case MAP_100TH_MM :
1198 nDecDigits -= 2;
1199 return FUNIT_MM;
1200 case MAP_10TH_MM :
1201 nDecDigits -= 1;
1202 return FUNIT_MM;
1203 case MAP_MM :
1204 return FUNIT_MM;
1205 case MAP_CM :
1206 return FUNIT_CM;
1207 case MAP_1000TH_INCH :
1208 nDecDigits -= 3;
1209 return FUNIT_INCH;
1210 case MAP_100TH_INCH :
1211 nDecDigits -= 2;
1212 return FUNIT_INCH;
1213 case MAP_10TH_INCH :
1214 nDecDigits -= 1;
1215 return FUNIT_INCH;
1216 case MAP_INCH :
1217 return FUNIT_INCH;
1218 case MAP_POINT :
1219 return FUNIT_POINT;
1220 case MAP_TWIP :
1221 return FUNIT_TWIP;
1222 default:
1223 OSL_FAIL( "default eInUnit" );
1224 break;
1226 return FUNIT_NONE;
1229 // -----------------------------------------------------------------------
1231 static double nonValueDoubleToValueDouble( double nValue )
1233 return rtl::math::isFinite( nValue ) ? nValue : 0.0;
1236 sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits,
1237 FieldUnit eInUnit, FieldUnit eOutUnit )
1239 double nDouble = nonValueDoubleToValueDouble( ConvertDoubleValue(
1240 (double)nValue, mnBaseValue, nDecDigits, eInUnit, eOutUnit ) );
1242 // caution: precision loss in double cast
1243 sal_Int64 nLong = static_cast<sal_Int64>( nDouble );
1245 if ( nDouble >= (double)SAL_MAX_INT64 )
1246 nLong = SAL_MAX_INT64;
1247 else if ( nDouble <= (double)SAL_MIN_INT64 )
1248 nLong = SAL_MIN_INT64;
1250 return nLong;
1253 // -----------------------------------------------------------------------
1255 sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_uInt16 nDigits,
1256 MapUnit eInUnit, FieldUnit eOutUnit )
1258 return static_cast<sal_Int64>(
1259 nonValueDoubleToValueDouble(
1260 ConvertDoubleValue( nValue, nDigits, eInUnit, eOutUnit ) ) );
1263 // -----------------------------------------------------------------------
1265 double MetricField::ConvertDoubleValue( double nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits,
1266 FieldUnit eInUnit, FieldUnit eOutUnit )
1268 if ( eInUnit != eOutUnit )
1270 sal_Int64 nMult = 1, nDiv = 1;
1272 if ( eInUnit == FUNIT_PERCENT )
1274 if ( (mnBaseValue <= 0) || (nValue <= 0) )
1275 return nValue;
1276 nDiv = 100 * ImplPower10(nDecDigits);
1278 nMult = mnBaseValue;
1280 else if ( eOutUnit == FUNIT_PERCENT ||
1281 eOutUnit == FUNIT_CUSTOM ||
1282 eOutUnit == FUNIT_NONE ||
1283 eInUnit == FUNIT_CUSTOM ||
1284 eInUnit == FUNIT_NONE )
1285 return nValue;
1286 else
1288 if ( eOutUnit == FUNIT_100TH_MM )
1289 eOutUnit = FUNIT_NONE;
1290 if ( eInUnit == FUNIT_100TH_MM )
1291 eInUnit = FUNIT_NONE;
1293 nDiv = aImplFactor[eInUnit][eOutUnit];
1294 nMult = aImplFactor[eOutUnit][eInUnit];
1296 DBG_ASSERT( nMult > 0, "illegal *" );
1297 DBG_ASSERT( nDiv > 0, "illegal /" );
1300 if ( nMult != 1 && nMult > 0 )
1301 nValue *= nMult;
1302 if ( nDiv != 1 && nDiv > 0 )
1304 nValue += ( nValue < 0 ) ? (-nDiv/2) : (nDiv/2);
1305 nValue /= nDiv;
1309 return nValue;
1312 // -----------------------------------------------------------------------
1314 double MetricField::ConvertDoubleValue( double nValue, sal_uInt16 nDigits,
1315 MapUnit eInUnit, FieldUnit eOutUnit )
1317 if ( eOutUnit == FUNIT_PERCENT ||
1318 eOutUnit == FUNIT_CUSTOM ||
1319 eOutUnit == FUNIT_NONE ||
1320 eInUnit == MAP_PIXEL ||
1321 eInUnit == MAP_SYSFONT ||
1322 eInUnit == MAP_APPFONT ||
1323 eInUnit == MAP_RELATIVE )
1325 OSL_FAIL( "invalid parameters" );
1326 return nValue;
1329 long nDecDigits = nDigits;
1330 FieldUnit eFieldUnit = ImplMap2FieldUnit( eInUnit, nDecDigits );
1332 if ( nDecDigits < 0 )
1334 while ( nDecDigits )
1336 nValue += 5;
1337 nValue /= 10;
1338 nDecDigits++;
1341 else
1343 nValue *= ImplPower10(nDecDigits);
1346 if ( eFieldUnit != eOutUnit )
1348 sal_Int64 nDiv = aImplFactor[eFieldUnit][eOutUnit];
1349 sal_Int64 nMult = aImplFactor[eOutUnit][eFieldUnit];
1351 DBG_ASSERT( nMult > 0, "illegal *" );
1352 DBG_ASSERT( nDiv > 0, "illegal /" );
1354 if ( nMult != 1 && nMult > 0)
1355 nValue *= nMult;
1356 if ( nDiv != 1 && nDiv > 0 )
1358 nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2);
1359 nValue /= nDiv;
1362 return nValue;
1365 // -----------------------------------------------------------------------
1367 double MetricField::ConvertDoubleValue( double nValue, sal_uInt16 nDigits,
1368 FieldUnit eInUnit, MapUnit eOutUnit )
1370 if ( eInUnit == FUNIT_PERCENT ||
1371 eInUnit == FUNIT_CUSTOM ||
1372 eInUnit == FUNIT_NONE ||
1373 eOutUnit == MAP_PIXEL ||
1374 eOutUnit == MAP_SYSFONT ||
1375 eOutUnit == MAP_APPFONT ||
1376 eOutUnit == MAP_RELATIVE )
1378 OSL_FAIL( "invalid parameters" );
1379 return nValue;
1382 long nDecDigits = nDigits;
1383 FieldUnit eFieldUnit = ImplMap2FieldUnit( eOutUnit, nDecDigits );
1385 if ( nDecDigits < 0 )
1387 nValue *= ImplPower10(-nDecDigits);
1389 else
1391 nValue /= ImplPower10(nDecDigits);
1394 if ( eFieldUnit != eInUnit )
1396 sal_Int64 nDiv = aImplFactor[eInUnit][eFieldUnit];
1397 sal_Int64 nMult = aImplFactor[eFieldUnit][eInUnit];
1399 DBG_ASSERT( nMult > 0, "illegal *" );
1400 DBG_ASSERT( nDiv > 0, "illegal /" );
1402 if( nMult != 1 && nMult > 0 )
1403 nValue *= nMult;
1404 if( nDiv != 1 && nDiv > 0 )
1406 nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2);
1407 nValue /= nDiv;
1410 return nValue;
1413 // -----------------------------------------------------------------------
1415 static bool ImplMetricGetValue( const OUString& rStr, double& rValue, sal_Int64 nBaseValue,
1416 sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrapper, FieldUnit eUnit )
1418 // Zahlenwert holen
1419 sal_Int64 nValue;
1420 if ( !ImplNumericGetValue( rStr, nValue, nDecDigits, rLocaleDataWrapper ) )
1421 return false;
1423 // Einheit rausfinden
1424 FieldUnit eEntryUnit = ImplMetricGetUnit( rStr );
1426 // Einheiten umrechnen
1427 // caution: conversion to double loses precision
1428 rValue = MetricField::ConvertDoubleValue( (double)nValue, nBaseValue, nDecDigits, eEntryUnit, eUnit );
1430 return true;
1433 // -----------------------------------------------------------------------
1435 sal_Bool MetricFormatter::ImplMetricReformat( const OUString& rStr, double& rValue, OUString& rOutStr )
1437 if ( !ImplMetricGetValue( rStr, rValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) )
1438 return sal_True;
1439 else
1441 double nTempVal = rValue;
1442 // caution: precision loss in double cast
1443 if ( nTempVal > GetMax() )
1444 nTempVal = (double)GetMax();
1445 else if ( nTempVal < GetMin())
1446 nTempVal = (double)GetMin();
1448 if ( GetErrorHdl().IsSet() && (rValue != nTempVal) )
1450 mnCorrectedValue = (sal_Int64)nTempVal;
1451 if ( !GetErrorHdl().Call( this ) )
1453 mnCorrectedValue = 0;
1454 return sal_False;
1456 else
1457 mnCorrectedValue = 0;
1460 rOutStr = CreateFieldText( (sal_Int64)nTempVal );
1461 return sal_True;
1465 // -----------------------------------------------------------------------
1467 inline void MetricFormatter::ImplInit()
1469 mnBaseValue = 0;
1470 meUnit = MetricField::GetDefaultUnit();
1471 mnType = FORMAT_METRIC;
1474 // -----------------------------------------------------------------------
1476 MetricFormatter::MetricFormatter()
1478 ImplInit();
1481 // -----------------------------------------------------------------------
1483 void MetricFormatter::ImplLoadRes( const ResId& rResId )
1485 NumericFormatter::ImplLoadRes( rResId );
1487 ResMgr* pMgr = rResId.GetResMgr();
1488 if( pMgr )
1490 sal_uLong nMask = pMgr->ReadLong();
1492 if ( METRICFORMATTER_UNIT & nMask )
1493 meUnit = (FieldUnit)pMgr->ReadLong();
1495 if ( METRICFORMATTER_CUSTOMUNITTEXT & nMask )
1496 maCustomUnitText = pMgr->ReadString();
1500 // -----------------------------------------------------------------------
1502 MetricFormatter::~MetricFormatter()
1506 // -----------------------------------------------------------------------
1508 void MetricFormatter::SetUnit( FieldUnit eNewUnit )
1510 if ( eNewUnit == FUNIT_100TH_MM )
1512 SetDecimalDigits( GetDecimalDigits() + 2 );
1513 meUnit = FUNIT_MM;
1515 else
1516 meUnit = eNewUnit;
1517 ReformatAll();
1520 // -----------------------------------------------------------------------
1522 void MetricFormatter::SetCustomUnitText( const OUString& rStr )
1524 maCustomUnitText = rStr;
1525 ReformatAll();
1528 // -----------------------------------------------------------------------
1530 void MetricFormatter::SetValue( sal_Int64 nNewValue, FieldUnit eInUnit )
1532 SetUserValue( nNewValue, eInUnit );
1533 mnFieldValue = mnLastValue;
1536 // -----------------------------------------------------------------------
1538 OUString MetricFormatter::CreateFieldText( sal_Int64 nValue ) const
1540 OUString aStr = NumericFormatter::CreateFieldText( nValue );
1542 if( meUnit == FUNIT_CUSTOM )
1543 aStr += maCustomUnitText;
1544 else
1545 aStr += ImplMetricToString( meUnit );
1547 return aStr;
1550 // -----------------------------------------------------------------------
1552 void MetricFormatter::SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit )
1554 // convert to previously configured units
1555 nNewValue = MetricField::ConvertValue( nNewValue, mnBaseValue, GetDecimalDigits(), eInUnit, meUnit );
1556 NumericFormatter::SetUserValue( nNewValue );
1559 // -----------------------------------------------------------------------
1561 sal_Int64 MetricFormatter::GetValue( FieldUnit eOutUnit ) const
1563 if ( !GetField() )
1564 return 0;
1566 double nTempValue;
1567 // caution: precision loss in double cast
1568 if ( !ImplMetricGetValue( GetField()->GetText(), nTempValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) )
1569 nTempValue = (double)mnLastValue;
1571 // caution: precision loss in double cast
1572 if ( nTempValue > mnMax )
1573 nTempValue = (double)mnMax;
1574 else if ( nTempValue < mnMin )
1575 nTempValue = (double)mnMin;
1577 // convert to requested units
1578 return MetricField::ConvertValue( (sal_Int64)nTempValue, mnBaseValue, GetDecimalDigits(), meUnit, eOutUnit );
1581 // -----------------------------------------------------------------------
1583 void MetricFormatter::SetValue( sal_Int64 nValue )
1585 // Implementation not inline, because it is a virtual Function
1586 SetValue( nValue, FUNIT_NONE );
1589 // -----------------------------------------------------------------------
1591 sal_Int64 MetricFormatter::GetValue() const
1593 // Implementation not inline, because it is a virtual Function
1594 return GetValue( FUNIT_NONE );
1597 // -----------------------------------------------------------------------
1599 void MetricFormatter::SetMin( sal_Int64 nNewMin, FieldUnit eInUnit )
1601 // convert to requested units
1602 NumericFormatter::SetMin( MetricField::ConvertValue( nNewMin, mnBaseValue, GetDecimalDigits(),
1603 eInUnit, meUnit ) );
1606 // -----------------------------------------------------------------------
1608 sal_Int64 MetricFormatter::GetMin( FieldUnit eOutUnit ) const
1610 // convert to requested units
1611 return MetricField::ConvertValue( NumericFormatter::GetMin(), mnBaseValue,
1612 GetDecimalDigits(), meUnit, eOutUnit );
1615 // -----------------------------------------------------------------------
1617 void MetricFormatter::SetMax( sal_Int64 nNewMax, FieldUnit eInUnit )
1619 // convert to requested units
1620 NumericFormatter::SetMax( MetricField::ConvertValue( nNewMax, mnBaseValue, GetDecimalDigits(),
1621 eInUnit, meUnit ) );
1624 // -----------------------------------------------------------------------
1626 sal_Int64 MetricFormatter::GetMax( FieldUnit eOutUnit ) const
1628 // convert to requested units
1629 return MetricField::ConvertValue( NumericFormatter::GetMax(), mnBaseValue,
1630 GetDecimalDigits(), meUnit, eOutUnit );
1633 // -----------------------------------------------------------------------
1635 void MetricFormatter::SetBaseValue( sal_Int64 nNewBase, FieldUnit eInUnit )
1637 mnBaseValue = MetricField::ConvertValue( nNewBase, mnBaseValue, GetDecimalDigits(),
1638 eInUnit, meUnit );
1641 // -----------------------------------------------------------------------
1643 sal_Int64 MetricFormatter::GetBaseValue( FieldUnit eOutUnit ) const
1645 // convert to requested units
1646 return MetricField::ConvertValue( mnBaseValue, mnBaseValue, GetDecimalDigits(),
1647 meUnit, eOutUnit );
1650 // -----------------------------------------------------------------------
1652 void MetricFormatter::Reformat()
1654 if ( !GetField() )
1655 return;
1657 OUString aText = GetField()->GetText();
1658 if ( meUnit == FUNIT_CUSTOM )
1659 maCurUnitText = ImplMetricGetUnitText( aText );
1661 OUString aStr;
1662 // caution: precision loss in double cast
1663 double nTemp = (double)mnLastValue;
1664 sal_Bool bOK = ImplMetricReformat( aText, nTemp, aStr );
1665 mnLastValue = (sal_Int64)nTemp;
1667 if ( !bOK )
1668 return;
1670 if ( !aStr.isEmpty() )
1672 ImplSetText( aStr );
1673 if ( meUnit == FUNIT_CUSTOM )
1674 CustomConvert();
1676 else
1677 SetValue( mnLastValue );
1678 maCurUnitText = OUString();
1681 // -----------------------------------------------------------------------
1683 sal_Int64 MetricFormatter::GetCorrectedValue( FieldUnit eOutUnit ) const
1685 // convert to requested units
1686 return MetricField::ConvertValue( mnCorrectedValue, mnBaseValue, GetDecimalDigits(),
1687 meUnit, eOutUnit );
1690 // -----------------------------------------------------------------------
1692 MetricField::MetricField( Window* pParent, WinBits nWinStyle ) :
1693 SpinField( pParent, nWinStyle )
1695 SetField( this );
1696 Reformat();
1699 MetricField::MetricField( Window* pParent, const ResId& rResId ) :
1700 SpinField( WINDOW_METRICFIELD )
1702 rResId.SetRT( RSC_METRICFIELD );
1703 WinBits nStyle = ImplInitRes( rResId ) ;
1704 SpinField::ImplInit( pParent, nStyle );
1705 SetField( this );
1706 ImplLoadRes( rResId );
1708 if ( !(nStyle & WB_HIDE ) )
1709 Show();
1712 Size MetricField::CalcMinimumSize() const
1714 return calcMinimumSize(*this, *this);
1717 bool MetricField::set_property(const OString &rKey, const OString &rValue)
1719 if (rKey == "format")
1721 maCustomUnitText = OStringToOUString(rValue, RTL_TEXTENCODING_UTF8);
1722 meUnit = FUNIT_CUSTOM;
1724 else if (rKey == "digits")
1725 SetDecimalDigits(rValue.toInt32());
1726 else
1727 return SpinField::set_property(rKey, rValue);
1728 return true;
1731 void MetricField::ImplLoadRes( const ResId& rResId )
1733 SpinField::ImplLoadRes( rResId );
1734 MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
1736 sal_uLong nMask = ReadLongRes();
1738 if ( METRICFIELD_FIRST & nMask )
1739 mnFirst = ReadLongRes();
1741 if ( METRICFIELD_LAST & nMask )
1742 mnLast = ReadLongRes();
1744 if ( METRICFIELD_SPINSIZE & nMask )
1745 mnSpinSize = ReadLongRes();
1747 Reformat();
1750 // -----------------------------------------------------------------------
1752 MetricField::~MetricField()
1756 void MetricField::SetUnit( FieldUnit nNewUnit )
1758 sal_Int64 nRawMax = GetMax( nNewUnit );
1759 sal_Int64 nMax = Denormalize( nRawMax );
1760 sal_Int64 nMin = Denormalize( GetMin( nNewUnit ) );
1761 sal_Int64 nFirst = Denormalize( GetFirst( nNewUnit ) );
1762 sal_Int64 nLast = Denormalize( GetLast( nNewUnit ) );
1764 MetricFormatter::SetUnit( nNewUnit );
1766 SetMax( Normalize( nMax ), nNewUnit );
1767 SetMin( Normalize( nMin ), nNewUnit );
1768 SetFirst( Normalize( nFirst ), nNewUnit );
1769 SetLast( Normalize( nLast ), nNewUnit );
1772 // -----------------------------------------------------------------------
1774 void MetricField::SetFirst( sal_Int64 nNewFirst, FieldUnit eInUnit )
1776 // convert
1777 nNewFirst = MetricField::ConvertValue( nNewFirst, mnBaseValue, GetDecimalDigits(),
1778 eInUnit, meUnit );
1779 mnFirst = nNewFirst;
1782 // -----------------------------------------------------------------------
1784 sal_Int64 MetricField::GetFirst( FieldUnit eOutUnit ) const
1786 // convert
1787 return MetricField::ConvertValue( mnFirst, mnBaseValue, GetDecimalDigits(),
1788 meUnit, eOutUnit );
1791 // -----------------------------------------------------------------------
1793 void MetricField::SetLast( sal_Int64 nNewLast, FieldUnit eInUnit )
1795 // convert
1796 nNewLast = MetricField::ConvertValue( nNewLast, mnBaseValue, GetDecimalDigits(),
1797 eInUnit, meUnit );
1798 mnLast = nNewLast;
1801 // -----------------------------------------------------------------------
1803 sal_Int64 MetricField::GetLast( FieldUnit eOutUnit ) const
1805 // conver
1806 return MetricField::ConvertValue( mnLast, mnBaseValue, GetDecimalDigits(),
1807 meUnit, eOutUnit );
1810 // -----------------------------------------------------------------------
1812 long MetricField::PreNotify( NotifyEvent& rNEvt )
1814 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
1816 if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
1817 return 1;
1820 return SpinField::PreNotify( rNEvt );
1823 // -----------------------------------------------------------------------
1825 long MetricField::Notify( NotifyEvent& rNEvt )
1827 if ( rNEvt.GetType() == EVENT_GETFOCUS )
1828 MarkToBeReformatted( sal_False );
1829 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
1831 if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
1832 Reformat();
1835 return SpinField::Notify( rNEvt );
1838 // -----------------------------------------------------------------------
1840 void MetricField::DataChanged( const DataChangedEvent& rDCEvt )
1842 SpinField::DataChanged( rDCEvt );
1844 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
1846 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
1847 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
1848 if ( IsDefaultLocale() )
1849 ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
1850 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
1851 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
1852 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
1853 ReformatAll();
1857 // -----------------------------------------------------------------------
1859 void MetricField::Modify()
1861 MarkToBeReformatted( sal_True );
1862 SpinField::Modify();
1865 // -----------------------------------------------------------------------
1867 void MetricField::Up()
1869 FieldUp();
1870 SpinField::Up();
1873 // -----------------------------------------------------------------------
1875 void MetricField::Down()
1877 FieldDown();
1878 SpinField::Down();
1881 // -----------------------------------------------------------------------
1883 void MetricField::First()
1885 FieldFirst();
1886 SpinField::First();
1889 // -----------------------------------------------------------------------
1891 void MetricField::Last()
1893 FieldLast();
1894 SpinField::Last();
1897 // -----------------------------------------------------------------------
1899 void MetricField::CustomConvert()
1901 maCustomConvertLink.Call( this );
1904 // -----------------------------------------------------------------------
1906 MetricBox::MetricBox( Window* pParent, WinBits nWinStyle ) :
1907 ComboBox( pParent, nWinStyle )
1909 SetField( this );
1910 Reformat();
1913 // -----------------------------------------------------------------------
1915 MetricBox::MetricBox( Window* pParent, const ResId& rResId ) :
1916 ComboBox( WINDOW_METRICBOX )
1918 rResId.SetRT( RSC_METRICBOX );
1919 WinBits nStyle = ImplInitRes( rResId );
1920 ComboBox::ImplInit( pParent, nStyle );
1921 SetField( this );
1922 Reformat();
1923 ComboBox::ImplLoadRes( rResId );
1924 MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
1926 if ( !(nStyle & WB_HIDE ) )
1927 Show();
1930 // -----------------------------------------------------------------------
1932 MetricBox::~MetricBox()
1936 // -----------------------------------------------------------------------
1938 long MetricBox::PreNotify( NotifyEvent& rNEvt )
1940 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
1942 if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
1943 return 1;
1946 return ComboBox::PreNotify( rNEvt );
1949 // -----------------------------------------------------------------------
1951 long MetricBox::Notify( NotifyEvent& rNEvt )
1953 if ( rNEvt.GetType() == EVENT_GETFOCUS )
1954 MarkToBeReformatted( sal_False );
1955 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
1957 if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
1958 Reformat();
1961 return ComboBox::Notify( rNEvt );
1964 // -----------------------------------------------------------------------
1966 void MetricBox::DataChanged( const DataChangedEvent& rDCEvt )
1968 ComboBox::DataChanged( rDCEvt );
1970 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
1972 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
1973 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
1974 if ( IsDefaultLocale() )
1975 ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
1976 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
1977 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
1978 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
1979 ReformatAll();
1983 // -----------------------------------------------------------------------
1985 void MetricBox::Modify()
1987 MarkToBeReformatted( sal_True );
1988 ComboBox::Modify();
1991 // -----------------------------------------------------------------------
1993 void MetricBox::ReformatAll()
1995 double nValue;
1996 OUString aStr;
1997 SetUpdateMode( sal_False );
1998 sal_uInt16 nEntryCount = GetEntryCount();
1999 for ( sal_uInt16 i=0; i < nEntryCount; i++ )
2001 ImplMetricReformat( GetEntry( i ), nValue, aStr );
2002 RemoveEntry( i );
2003 InsertEntry( aStr, i );
2005 MetricFormatter::Reformat();
2006 SetUpdateMode( sal_True );
2009 // -----------------------------------------------------------------------
2011 void MetricBox::CustomConvert()
2013 maCustomConvertLink.Call( this );
2016 // -----------------------------------------------------------------------
2018 void MetricBox::InsertValue( sal_Int64 nValue, FieldUnit eInUnit, sal_uInt16 nPos )
2020 // convert to previously configured units
2021 nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
2022 eInUnit, meUnit );
2023 ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
2026 // -----------------------------------------------------------------------
2028 sal_Int64 MetricBox::GetValue( sal_uInt16 nPos, FieldUnit eOutUnit ) const
2030 double nValue = 0;
2031 ImplMetricGetValue( ComboBox::GetEntry( nPos ), nValue, mnBaseValue,
2032 GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit );
2034 // convert to previously configured units
2035 sal_Int64 nRetValue = MetricField::ConvertValue( (sal_Int64)nValue, mnBaseValue, GetDecimalDigits(),
2036 meUnit, eOutUnit );
2038 return nRetValue;
2041 // -----------------------------------------------------------------------
2043 sal_uInt16 MetricBox::GetValuePos( sal_Int64 nValue, FieldUnit eInUnit ) const
2045 // convert to previously configured units
2046 nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
2047 eInUnit, meUnit );
2048 return ComboBox::GetEntryPos( CreateFieldText( nValue ) );
2051 // -----------------------------------------------------------------------
2053 sal_Int64 MetricBox::GetValue( FieldUnit eOutUnit ) const
2055 // Implementation not inline, because it is a virtual Function
2056 return MetricFormatter::GetValue( eOutUnit );
2059 // -----------------------------------------------------------------------
2061 sal_Int64 MetricBox::GetValue() const
2063 // Implementation not inline, because it is a virtual Function
2064 return GetValue( FUNIT_NONE );
2067 // -----------------------------------------------------------------------
2069 static bool ImplCurrencyProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
2070 bool, bool bUseThousandSep, const LocaleDataWrapper& rWrapper )
2072 // no strict format set; therefore allow all characters
2073 return ImplNumericProcessKeyInput( pEdit, rKEvt, false, bUseThousandSep, rWrapper );
2076 // -----------------------------------------------------------------------
2078 inline bool ImplCurrencyGetValue( const OUString& rStr, sal_Int64& rValue,
2079 sal_uInt16 nDecDigits, const LocaleDataWrapper& rWrapper )
2081 // fetch number
2082 return ImplNumericGetValue( rStr, rValue, nDecDigits, rWrapper, true );
2085 // -----------------------------------------------------------------------
2087 sal_Bool CurrencyFormatter::ImplCurrencyReformat( const OUString& rStr, OUString& rOutStr )
2089 sal_Int64 nValue;
2090 if ( !ImplNumericGetValue( rStr, nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), true ) )
2091 return sal_True;
2092 else
2094 sal_Int64 nTempVal = nValue;
2095 if ( nTempVal > GetMax() )
2096 nTempVal = GetMax();
2097 else if ( nTempVal < GetMin())
2098 nTempVal = GetMin();
2100 if ( GetErrorHdl().IsSet() && (nValue != nTempVal) )
2102 mnCorrectedValue = nTempVal;
2103 if ( !GetErrorHdl().Call( this ) )
2105 mnCorrectedValue = 0;
2106 return sal_False;
2108 else
2109 mnCorrectedValue = 0;
2112 rOutStr = CreateFieldText( nTempVal );
2113 return sal_True;
2117 // -----------------------------------------------------------------------
2119 inline void CurrencyFormatter::ImplInit()
2121 mnType = FORMAT_CURRENCY;
2124 // -----------------------------------------------------------------------
2126 CurrencyFormatter::CurrencyFormatter()
2128 ImplInit();
2131 // -----------------------------------------------------------------------
2133 CurrencyFormatter::~CurrencyFormatter()
2137 // -----------------------------------------------------------------------
2139 String CurrencyFormatter::GetCurrencySymbol() const
2141 return ImplGetLocaleDataWrapper().getCurrSymbol();
2144 // -----------------------------------------------------------------------
2146 void CurrencyFormatter::SetValue( sal_Int64 nNewValue )
2148 SetUserValue( nNewValue );
2149 mnFieldValue = mnLastValue;
2150 SetEmptyFieldValueData( sal_False );
2153 // -----------------------------------------------------------------------
2155 OUString CurrencyFormatter::CreateFieldText( sal_Int64 nValue ) const
2157 return ImplGetLocaleDataWrapper().getCurr( nValue, GetDecimalDigits(), GetCurrencySymbol(), IsUseThousandSep() );
2160 // -----------------------------------------------------------------------
2162 sal_Int64 CurrencyFormatter::GetValue() const
2164 if ( !GetField() )
2165 return 0;
2167 sal_Int64 nTempValue;
2168 if ( ImplCurrencyGetValue( GetField()->GetText(), nTempValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
2170 if ( nTempValue > mnMax )
2171 nTempValue = mnMax;
2172 else if ( nTempValue < mnMin )
2173 nTempValue = mnMin;
2174 return nTempValue;
2176 else
2177 return mnLastValue;
2180 // -----------------------------------------------------------------------
2182 void CurrencyFormatter::Reformat()
2184 if ( !GetField() )
2185 return;
2187 OUString aStr;
2188 sal_Bool bOK = ImplCurrencyReformat( GetField()->GetText(), aStr );
2189 if ( !bOK )
2190 return;
2192 if ( !aStr.isEmpty() )
2194 ImplSetText( aStr );
2195 sal_Int64 nTemp = mnLastValue;
2196 ImplCurrencyGetValue( aStr, nTemp, GetDecimalDigits(), ImplGetLocaleDataWrapper() );
2197 mnLastValue = nTemp;
2199 else
2200 SetValue( mnLastValue );
2203 // -----------------------------------------------------------------------
2205 CurrencyField::CurrencyField( Window* pParent, WinBits nWinStyle ) :
2206 SpinField( pParent, nWinStyle )
2208 SetField( this );
2209 Reformat();
2212 // -----------------------------------------------------------------------
2214 CurrencyField::~CurrencyField()
2218 // -----------------------------------------------------------------------
2220 long CurrencyField::PreNotify( NotifyEvent& rNEvt )
2222 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
2224 if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
2225 return 1;
2228 return SpinField::PreNotify( rNEvt );
2231 // -----------------------------------------------------------------------
2233 long CurrencyField::Notify( NotifyEvent& rNEvt )
2235 if ( rNEvt.GetType() == EVENT_GETFOCUS )
2236 MarkToBeReformatted( sal_False );
2237 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
2239 if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
2240 Reformat();
2243 return SpinField::Notify( rNEvt );
2246 // -----------------------------------------------------------------------
2248 void CurrencyField::DataChanged( const DataChangedEvent& rDCEvt )
2250 SpinField::DataChanged( rDCEvt );
2252 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
2254 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
2255 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
2256 if ( IsDefaultLocale() )
2257 ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
2258 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
2259 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
2260 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
2261 ReformatAll();
2265 // -----------------------------------------------------------------------
2267 void CurrencyField::Modify()
2269 MarkToBeReformatted( sal_True );
2270 SpinField::Modify();
2273 // -----------------------------------------------------------------------
2275 void CurrencyField::Up()
2277 FieldUp();
2278 SpinField::Up();
2281 // -----------------------------------------------------------------------
2283 void CurrencyField::Down()
2285 FieldDown();
2286 SpinField::Down();
2289 // -----------------------------------------------------------------------
2291 void CurrencyField::First()
2293 FieldFirst();
2294 SpinField::First();
2297 // -----------------------------------------------------------------------
2299 void CurrencyField::Last()
2301 FieldLast();
2302 SpinField::Last();
2305 // -----------------------------------------------------------------------
2307 CurrencyBox::CurrencyBox( Window* pParent, WinBits nWinStyle ) :
2308 ComboBox( pParent, nWinStyle )
2310 SetField( this );
2311 Reformat();
2314 // -----------------------------------------------------------------------
2316 CurrencyBox::~CurrencyBox()
2320 // -----------------------------------------------------------------------
2322 long CurrencyBox::PreNotify( NotifyEvent& rNEvt )
2324 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
2326 if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
2327 return 1;
2330 return ComboBox::PreNotify( rNEvt );
2333 // -----------------------------------------------------------------------
2335 long CurrencyBox::Notify( NotifyEvent& rNEvt )
2337 if ( rNEvt.GetType() == EVENT_GETFOCUS )
2338 MarkToBeReformatted( sal_False );
2339 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
2341 if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
2342 Reformat();
2345 return ComboBox::Notify( rNEvt );
2348 // -----------------------------------------------------------------------
2350 void CurrencyBox::DataChanged( const DataChangedEvent& rDCEvt )
2352 ComboBox::DataChanged( rDCEvt );
2354 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
2356 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
2357 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
2358 if ( IsDefaultLocale() )
2359 ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
2360 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
2361 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
2362 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
2363 ReformatAll();
2367 // -----------------------------------------------------------------------
2369 void CurrencyBox::Modify()
2371 MarkToBeReformatted( sal_True );
2372 ComboBox::Modify();
2375 // -----------------------------------------------------------------------
2377 void CurrencyBox::ReformatAll()
2379 OUString aStr;
2380 SetUpdateMode( sal_False );
2381 sal_uInt16 nEntryCount = GetEntryCount();
2382 for ( sal_uInt16 i=0; i < nEntryCount; i++ )
2384 ImplCurrencyReformat( GetEntry( i ), aStr );
2385 RemoveEntry( i );
2386 InsertEntry( aStr, i );
2388 CurrencyFormatter::Reformat();
2389 SetUpdateMode( sal_True );
2392 // -----------------------------------------------------------------------
2394 sal_Int64 CurrencyBox::GetValue() const
2396 // Implementation not inline, because it is a virtual Function
2397 return CurrencyFormatter::GetValue();
2400 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */