update dev300-m58
[ooovba.git] / vcl / source / control / field.cxx
blobfbbabec7af4f16109734460c2bde5417b7113603
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: field.cxx,v $
10 * $Revision: 1.26.86.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #ifndef _BIGINT_HXX
35 #define _TOOLS_BIGINT
36 #include "tools/bigint.hxx"
37 #endif
39 #include "tools/debug.hxx"
41 #include "tools/rc.h"
42 #include "tools/resary.hxx"
43 #include "vcl/svids.hrc"
44 #include "vcl/field.hxx"
45 #include "vcl/event.hxx"
46 #include "vcl/svapp.hxx"
47 #include "vcl/svdata.hxx"
48 #include "vcl/unohelp.hxx"
49 #include "i18nutil/unicode.hxx"
51 #include "rtl/math.hxx"
54 #include <unotools/localedatawrapper.hxx>
56 using namespace ::com::sun::star;
58 static ResStringArray *strAllUnits = NULL;
60 // -----------------------------------------------------------------------
62 #define FORMAT_NUMERIC 1
63 #define FORMAT_METRIC 2
64 #define FORMAT_CURRENCY 3
66 // -----------------------------------------------------------------------
68 static sal_Int64 ImplPower10( USHORT n )
70 USHORT i;
71 sal_Int64 nValue = 1;
73 for ( i=0; i < n; i++ )
74 nValue *= 10;
76 return nValue;
79 // -----------------------------------------------------------------------
81 static BOOL ImplNumericProcessKeyInput( Edit*, const KeyEvent& rKEvt,
82 BOOL bStrictFormat, BOOL bThousandSep,
83 const LocaleDataWrapper& rLocaleDataWrappper )
85 if ( !bStrictFormat )
86 return FALSE;
87 else
89 xub_Unicode cChar = rKEvt.GetCharCode();
90 USHORT nGroup = rKEvt.GetKeyCode().GetGroup();
92 if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) ||
93 (nGroup == KEYGROUP_MISC) ||
94 ((cChar >= '0') && (cChar <= '9')) ||
95 (cChar == rLocaleDataWrappper.getNumDecimalSep() ) ||
96 (bThousandSep && (cChar == rLocaleDataWrappper.getNumThousandSep())) ||
97 (cChar == '-') )
98 return FALSE;
99 else
100 return TRUE;
104 // -----------------------------------------------------------------------
106 static BOOL ImplNumericGetValue( const XubString& rStr, double& rValue,
107 USHORT nDecDigits, const LocaleDataWrapper& rLocaleDataWrappper,
108 BOOL bCurrency = FALSE )
110 XubString aStr = rStr;
111 XubString aStr1;
112 XubString aStr2;
113 BOOL bNegative = FALSE;
114 xub_StrLen nDecPos;
115 xub_StrLen i;
117 // Reaktion auf leeren String
118 if ( !rStr.Len() )
119 return FALSE;
121 // Fuehrende und nachfolgende Leerzeichen entfernen
122 aStr.EraseLeadingAndTrailingChars( ' ' );
124 // Position des Dezimalpunktes suchen
125 nDecPos = aStr.Search( rLocaleDataWrappper.getNumDecimalSep() );
126 if ( nDecPos != STRING_NOTFOUND )
128 aStr1 = aStr.Copy( 0, nDecPos );
129 aStr2 = aStr.Copy( nDecPos+1 );
131 else
132 aStr1 = aStr;
134 // Negativ ?
135 if ( bCurrency )
137 if ( (aStr.GetChar( 0 ) == '(') && (aStr.GetChar( aStr.Len()-1 ) == ')') )
138 bNegative = TRUE;
139 if ( !bNegative )
141 for ( i=0; i < aStr.Len(); i++ )
143 if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') )
144 break;
145 else if ( aStr.GetChar( i ) == '-' )
147 bNegative = TRUE;
148 break;
152 if ( !bNegative && bCurrency && aStr.Len() )
154 USHORT nFormat = rLocaleDataWrappper.getCurrNegativeFormat();
155 if ( (nFormat == 3) || (nFormat == 6) ||
156 (nFormat == 7) || (nFormat == 10) )
158 for ( i = (xub_StrLen)(aStr.Len()-1); i > 0; i++ )
160 if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') )
161 break;
162 else if ( aStr.GetChar( i ) == '-' )
164 bNegative = TRUE;
165 break;
171 else
173 if ( aStr1.GetChar( 0 ) == '-' )
174 bNegative = TRUE;
177 // Alle unerwuenschten Zeichen rauswerfen
178 for ( i=0; i < aStr1.Len(); )
180 if ( (aStr1.GetChar( i ) >= '0') && (aStr1.GetChar( i ) <= '9') )
181 i++;
182 else
183 aStr1.Erase( i, 1 );
185 for ( i=0; i < aStr2.Len(); )
187 if ( (aStr2.GetChar( i ) >= '0') && (aStr2.GetChar( i ) <= '9') )
188 i++;
189 else
190 aStr2.Erase( i, 1 );
193 if ( !aStr1.Len() && !aStr2.Len() )
194 return FALSE;
196 if ( !aStr1.Len() )
197 aStr1.Insert( '0' );
198 if ( bNegative )
199 aStr1.Insert( '-', 0 );
201 // Nachkommateil zurechtstutzen und dabei runden
202 BOOL bRound = FALSE;
203 if ( aStr2.Len() > nDecDigits )
205 if ( aStr2.GetChar( nDecDigits ) >= '5' )
206 bRound = TRUE;
207 aStr2.Erase( nDecDigits );
209 if ( aStr2.Len() < nDecDigits )
210 aStr2.Expand( nDecDigits, '0' );
212 aStr = aStr1;
213 aStr += aStr2;
215 // Bereichsueberpruefung
216 double nValue = aStr.ToDouble();
217 if ( bRound )
219 if ( !bNegative )
220 nValue++;
221 else
222 nValue--;
225 rValue = nValue;
227 return TRUE;
230 static void ImplUpdateSeparators( const String& rOldDecSep, const String& rNewDecSep,
231 const String& rOldThSep, const String& rNewThSep,
232 Edit* pEdit )
234 bool bChangeDec = (rOldDecSep != rNewDecSep);
235 bool bChangeTh = (rOldThSep != rNewThSep );
237 if( bChangeDec || bChangeTh )
239 BOOL bUpdateMode = pEdit->IsUpdateMode();
240 pEdit->SetUpdateMode( FALSE );
241 String aText = pEdit->GetText();
242 if( bChangeDec )
243 aText.SearchAndReplaceAll( rNewDecSep, rOldDecSep );
244 if( bChangeTh )
245 aText.SearchAndReplaceAll( rNewThSep, rOldThSep );
246 pEdit->SetText( aText );
248 ComboBox* pCombo = dynamic_cast<ComboBox*>(pEdit);
249 if( pCombo )
251 // update box entries
252 USHORT nEntryCount = pCombo->GetEntryCount();
253 for ( USHORT i=0; i < nEntryCount; i++ )
255 aText = pCombo->GetEntry( i );
256 if( bChangeDec )
257 aText.SearchAndReplaceAll( rNewDecSep, rOldDecSep );
258 if( bChangeTh )
259 aText.SearchAndReplaceAll( rNewThSep, rOldThSep );
260 pCombo->RemoveEntry( i );
261 pCombo->InsertEntry( aText, i );
264 if( bUpdateMode )
265 pEdit->SetUpdateMode( bUpdateMode );
269 // -----------------------------------------------------------------------
271 FormatterBase::FormatterBase( Edit* pField )
273 mpField = pField;
274 mpLocaleDataWrapper = NULL;
275 mbReformat = FALSE;
276 mbStrictFormat = FALSE;
277 mbEmptyFieldValue = FALSE;
278 mbEmptyFieldValueEnabled = FALSE;
279 mbDefaultLocale = TRUE;
282 // -----------------------------------------------------------------------
284 FormatterBase::~FormatterBase()
286 delete mpLocaleDataWrapper;
289 // -----------------------------------------------------------------------
291 LocaleDataWrapper& FormatterBase::ImplGetLocaleDataWrapper() const
293 if ( !mpLocaleDataWrapper )
295 ((FormatterBase*)this)->mpLocaleDataWrapper = new LocaleDataWrapper( vcl::unohelper::GetMultiServiceFactory(), GetLocale() );
297 return *mpLocaleDataWrapper;
300 const LocaleDataWrapper& FormatterBase::GetLocaleDataWrapper() const
302 return ImplGetLocaleDataWrapper();
305 // -----------------------------------------------------------------------
307 void FormatterBase::Reformat()
311 // -----------------------------------------------------------------------
313 void FormatterBase::ReformatAll()
315 Reformat();
318 // -----------------------------------------------------------------------
320 void FormatterBase::SetStrictFormat( BOOL bStrict )
322 if ( bStrict != mbStrictFormat )
324 mbStrictFormat = bStrict;
325 if ( mbStrictFormat )
326 ReformatAll();
330 // -----------------------------------------------------------------------
332 void FormatterBase::SetLocale( const lang::Locale& rLocale )
334 ImplGetLocaleDataWrapper().setLocale( rLocale );
335 mbDefaultLocale = FALSE;
336 ReformatAll();
339 // -----------------------------------------------------------------------
341 const lang::Locale& FormatterBase::GetLocale() const
343 if ( !mpLocaleDataWrapper || mbDefaultLocale )
345 if ( mpField )
346 return mpField->GetSettings().GetLocale();
347 else
348 return Application::GetSettings().GetLocale();
351 return mpLocaleDataWrapper->getLocale();
354 // -----------------------------------------------------------------------
356 const AllSettings& FormatterBase::GetFieldSettings() const
358 if ( mpField )
359 return mpField->GetSettings();
360 else
361 return Application::GetSettings();
364 // -----------------------------------------------------------------------
366 void FormatterBase::SetFieldText( const XubString& rText, BOOL bKeepSelection )
368 if ( mpField )
370 Selection aNewSelection( 0xFFFF, 0xFFFF );
371 if ( bKeepSelection )
372 aNewSelection = mpField->GetSelection();
374 ImplSetText( rText, &aNewSelection );
378 // -----------------------------------------------------------------------
380 void FormatterBase::ImplSetText( const XubString& rText, Selection* pNewSelection )
382 if ( mpField )
384 if ( pNewSelection )
385 mpField->SetText( rText, *pNewSelection );
386 else
388 Selection aSel = mpField->GetSelection();
389 aSel.Min() = aSel.Max();
390 mpField->SetText( rText, aSel );
393 MarkToBeReformatted( FALSE );
397 // -----------------------------------------------------------------------
399 void FormatterBase::SetEmptyFieldValue()
401 if ( mpField )
402 mpField->SetText( ImplGetSVEmptyStr() );
403 mbEmptyFieldValue = TRUE;
406 // -----------------------------------------------------------------------
408 BOOL FormatterBase::IsEmptyFieldValue() const
410 return (!mpField || !mpField->GetText().Len());
413 // -----------------------------------------------------------------------
415 BOOL NumericFormatter::ImplNumericReformat( const XubString& rStr, double& rValue,
416 XubString& rOutStr )
418 if ( !ImplNumericGetValue( rStr, rValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
419 return TRUE;
420 else
422 double nTempVal = rValue;
423 // caution: precision loss in double cast
424 if ( nTempVal > mnMax )
425 nTempVal = (double)mnMax;
426 else if ( nTempVal < mnMin )
427 nTempVal = (double)mnMin;
429 if ( GetErrorHdl().IsSet() && (rValue != nTempVal) )
431 mnCorrectedValue = (sal_Int64)nTempVal;
432 if ( !GetErrorHdl().Call( this ) )
434 mnCorrectedValue = 0;
435 return FALSE;
437 else
438 mnCorrectedValue = 0;
441 rOutStr = CreateFieldText( (sal_Int64)nTempVal );
442 return TRUE;
446 // -----------------------------------------------------------------------
448 void NumericFormatter::ImplInit()
450 mnFieldValue = 0;
451 mnLastValue = 0;
452 mnMin = 0;
453 mnMax = 0x7FFFFFFFFFFFFFFFLL;
454 mnCorrectedValue = 0;
455 mnDecimalDigits = 2;
456 mnType = FORMAT_NUMERIC;
457 mbThousandSep = TRUE;
458 mbShowTrailingZeros = TRUE;
460 // for fields
461 mnSpinSize = 1;
462 mnFirst = mnMin;
463 mnLast = mnMax;
465 SetDecimalDigits( 0 );
468 // -----------------------------------------------------------------------
470 NumericFormatter::NumericFormatter()
472 ImplInit();
475 // -----------------------------------------------------------------------
477 void NumericFormatter::ImplLoadRes( const ResId& rResId )
479 ResMgr* pMgr = rResId.GetResMgr();
481 if( pMgr )
483 ULONG nMask = pMgr->ReadLong();
485 if ( NUMERICFORMATTER_MIN & nMask )
486 mnMin = pMgr->ReadLong();
488 if ( NUMERICFORMATTER_MAX & nMask )
489 mnMax = pMgr->ReadLong();
491 if ( NUMERICFORMATTER_STRICTFORMAT & nMask )
492 SetStrictFormat( (BOOL)pMgr->ReadShort() );
494 if ( NUMERICFORMATTER_DECIMALDIGITS & nMask )
495 SetDecimalDigits( pMgr->ReadShort() );
497 if ( NUMERICFORMATTER_VALUE & nMask )
499 mnFieldValue = pMgr->ReadLong();
500 if ( mnFieldValue > mnMax )
501 mnFieldValue = mnMax;
502 else if ( mnFieldValue < mnMin )
503 mnFieldValue = mnMin;
504 mnLastValue = mnFieldValue;
509 // -----------------------------------------------------------------------
511 NumericFormatter::~NumericFormatter()
515 // -----------------------------------------------------------------------
517 void NumericFormatter::SetMin( sal_Int64 nNewMin )
519 mnMin = nNewMin;
520 if ( !IsEmptyFieldValue() )
521 ReformatAll();
524 // -----------------------------------------------------------------------
526 void NumericFormatter::SetMax( sal_Int64 nNewMax )
528 mnMax = nNewMax;
529 if ( !IsEmptyFieldValue() )
530 ReformatAll();
533 // -----------------------------------------------------------------------
535 void NumericFormatter::SetUseThousandSep( BOOL b )
537 mbThousandSep = b;
538 ReformatAll();
541 // -----------------------------------------------------------------------
543 void NumericFormatter::SetDecimalDigits( USHORT nDigits )
545 mnDecimalDigits = nDigits;
546 ReformatAll();
549 // -----------------------------------------------------------------------
551 void NumericFormatter::SetShowTrailingZeros( BOOL bShowTrailingZeros )
553 if ( mbShowTrailingZeros != bShowTrailingZeros )
555 mbShowTrailingZeros = bShowTrailingZeros;
556 ReformatAll();
560 // -----------------------------------------------------------------------
562 USHORT NumericFormatter::GetDecimalDigits() const
564 return mnDecimalDigits;
567 // -----------------------------------------------------------------------
569 void NumericFormatter::SetValue( sal_Int64 nNewValue )
571 SetUserValue( nNewValue );
572 mnFieldValue = mnLastValue;
573 SetEmptyFieldValueData( FALSE );
576 // -----------------------------------------------------------------------
578 XubString NumericFormatter::CreateFieldText( sal_Int64 nValue ) const
580 return ImplGetLocaleDataWrapper().getNum( nValue, GetDecimalDigits(), IsUseThousandSep(), IsShowTrailingZeros() );
583 // -----------------------------------------------------------------------
585 void NumericFormatter::ImplSetUserValue( sal_Int64 nNewValue, Selection* pNewSelection )
587 if ( nNewValue > mnMax )
588 nNewValue = mnMax;
589 else if ( nNewValue < mnMin )
590 nNewValue = mnMin;
591 mnLastValue = nNewValue;
593 if ( GetField() )
594 ImplSetText( CreateFieldText( nNewValue ), pNewSelection );
597 // -----------------------------------------------------------------------
599 void NumericFormatter::SetUserValue( sal_Int64 nNewValue )
601 ImplSetUserValue( nNewValue );
604 // -----------------------------------------------------------------------
606 sal_Int64 NumericFormatter::GetValue() const
608 if ( !GetField() )
609 return 0;
611 double nTempValue;
613 if ( ImplNumericGetValue( GetField()->GetText(), nTempValue,
614 GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
616 // caution: precision loss in double cast
617 if ( nTempValue > mnMax )
618 nTempValue = (double)mnMax;
619 else if ( nTempValue < mnMin )
620 nTempValue = (double)mnMin;
621 return (sal_Int64)nTempValue;
623 else
624 return mnLastValue;
627 // -----------------------------------------------------------------------
629 BOOL NumericFormatter::IsValueModified() const
631 if ( ImplGetEmptyFieldValue() )
632 return !IsEmptyFieldValue();
633 else if ( GetValue() != mnFieldValue )
634 return TRUE;
635 else
636 return FALSE;
639 // -----------------------------------------------------------------------
641 Fraction NumericFormatter::ConvertToFraction( sal_Int64 nValue )
643 // caution: precision loss in double cast (and in fraction anyhow)
644 return Fraction( (double)nValue/(double)ImplPower10( GetDecimalDigits() ) );
647 // -----------------------------------------------------------------------
649 sal_Int64 NumericFormatter::ConvertToLong( const Fraction& rValue )
651 Fraction aFract = rValue;
652 aFract *= Fraction( (long)ImplPower10( GetDecimalDigits() ), 1 );
653 return (sal_Int64)(double)aFract;
656 // -----------------------------------------------------------------------
658 sal_Int64 NumericFormatter::Normalize( sal_Int64 nValue ) const
660 return (nValue * ImplPower10( GetDecimalDigits() ) );
663 // -----------------------------------------------------------------------
665 sal_Int64 NumericFormatter::Denormalize( sal_Int64 nValue ) const
667 sal_Int64 nFactor = ImplPower10( GetDecimalDigits() );
668 if( nValue < 0 )
669 return ((nValue-(nFactor/2)) / nFactor );
670 else
671 return ((nValue+(nFactor/2)) / nFactor );
674 // -----------------------------------------------------------------------
676 void NumericFormatter::Reformat()
678 if ( !GetField() )
679 return;
681 if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() )
682 return;
684 XubString aStr;
685 // caution: precision loss in double cast
686 double nTemp = (double)mnLastValue;
687 BOOL bOK = ImplNumericReformat( GetField()->GetText(), nTemp, aStr );
688 mnLastValue = (sal_Int64)nTemp;
689 if ( !bOK )
690 return;
692 if ( aStr.Len() )
693 ImplSetText( aStr );
694 else
695 SetValue( mnLastValue );
698 // -----------------------------------------------------------------------
700 void NumericFormatter::FieldUp()
702 sal_Int64 nValue = GetValue();
703 nValue += mnSpinSize;
704 if ( nValue > mnMax )
705 nValue = mnMax;
707 ImplNewFieldValue( nValue );
710 // -----------------------------------------------------------------------
712 void NumericFormatter::FieldDown()
714 sal_Int64 nValue = GetValue();
715 nValue -= mnSpinSize;
716 if ( nValue < mnMin )
717 nValue = mnMin;
719 ImplNewFieldValue( nValue );
722 // -----------------------------------------------------------------------
724 void NumericFormatter::FieldFirst()
726 ImplNewFieldValue( mnFirst );
729 // -----------------------------------------------------------------------
731 void NumericFormatter::FieldLast()
733 ImplNewFieldValue( mnLast );
736 // -----------------------------------------------------------------------
738 void NumericFormatter::ImplNewFieldValue( sal_Int64 nNewValue )
740 if ( GetField() )
742 // !!! TH-18.2.99: Wenn wir Zeit haben sollte mal geklaert werden,
743 // !!! warum nicht bei ImplSetUserValue() geprueft wird, ob
744 // !!! sich der Wert aendert. Denn auch hier muesste dieses
745 // !!! gemacht werden, da ansonsten der Modify-Aufruf
746 // !!! nicht gemacht werden duerfte. Jedenfalls sollten die
747 // !!! Wege von ImplNewFieldValue, ImplSetUserValue und
748 // !!! ImplSetText ueberprueft und klarer gestalltet (mit Kommentar)
749 // !!! werden, damit wir mal wissen, was dort ablaeuft!!!
751 Selection aSelection = GetField()->GetSelection();
752 aSelection.Justify();
753 XubString aText = GetField()->GetText();
754 // Wenn bis ans Ende selektiert war, soll das auch so bleiben...
755 if ( (xub_StrLen)aSelection.Max() == aText.Len() )
757 if ( !aSelection.Len() )
758 aSelection.Min() = SELECTION_MAX;
759 aSelection.Max() = SELECTION_MAX;
762 sal_Int64 nOldLastValue = mnLastValue;
763 ImplSetUserValue( nNewValue, &aSelection );
764 mnLastValue = nOldLastValue;
766 // Modify am Edit wird nur bei KeyInput gesetzt...
767 if ( GetField()->GetText() != aText )
769 GetField()->SetModifyFlag();
770 GetField()->Modify();
775 // -----------------------------------------------------------------------
777 NumericField::NumericField( Window* pParent, WinBits nWinStyle ) :
778 SpinField( pParent, nWinStyle )
780 SetField( this );
781 Reformat();
784 // -----------------------------------------------------------------------
786 NumericField::NumericField( Window* pParent, const ResId& rResId ) :
787 SpinField( WINDOW_NUMERICFIELD )
789 rResId.SetRT( RSC_NUMERICFIELD );
790 WinBits nStyle = ImplInitRes( rResId ) ;
791 SpinField::ImplInit( pParent, nStyle );
792 SetField( this );
793 ImplLoadRes( rResId );
794 Reformat();
796 if ( !(nStyle & WB_HIDE ) )
797 Show();
800 // -----------------------------------------------------------------------
802 void NumericField::ImplLoadRes( const ResId& rResId )
804 SpinField::ImplLoadRes( rResId );
805 NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
807 ULONG nMask = ReadLongRes();
809 if ( NUMERICFIELD_FIRST & nMask )
810 mnFirst = ReadLongRes();
812 if ( NUMERICFIELD_LAST & nMask )
813 mnLast = ReadLongRes();
815 if ( NUMERICFIELD_SPINSIZE & nMask )
816 mnSpinSize = ReadLongRes();
819 // -----------------------------------------------------------------------
821 NumericField::~NumericField()
825 // -----------------------------------------------------------------------
827 long NumericField::PreNotify( NotifyEvent& rNEvt )
829 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
831 if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
832 return 1;
835 return SpinField::PreNotify( rNEvt );
838 // -----------------------------------------------------------------------
840 long NumericField::Notify( NotifyEvent& rNEvt )
842 if ( rNEvt.GetType() == EVENT_GETFOCUS )
843 MarkToBeReformatted( FALSE );
844 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
846 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
847 Reformat();
850 return SpinField::Notify( rNEvt );
853 // -----------------------------------------------------------------------
855 void NumericField::DataChanged( const DataChangedEvent& rDCEvt )
857 SpinField::DataChanged( rDCEvt );
859 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
861 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
862 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
863 if ( IsDefaultLocale() )
864 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
865 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
866 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
867 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
868 ReformatAll();
872 // -----------------------------------------------------------------------
874 void NumericField::Modify()
876 MarkToBeReformatted( TRUE );
877 SpinField::Modify();
880 // -----------------------------------------------------------------------
882 void NumericField::Up()
884 FieldUp();
885 SpinField::Up();
888 // -----------------------------------------------------------------------
890 void NumericField::Down()
892 FieldDown();
893 SpinField::Down();
896 // -----------------------------------------------------------------------
898 void NumericField::First()
900 FieldFirst();
901 SpinField::First();
904 // -----------------------------------------------------------------------
906 void NumericField::Last()
908 FieldLast();
909 SpinField::Last();
912 // -----------------------------------------------------------------------
914 NumericBox::NumericBox( Window* pParent, WinBits nWinStyle ) :
915 ComboBox( pParent, nWinStyle )
917 SetField( this );
918 Reformat();
921 // -----------------------------------------------------------------------
923 NumericBox::NumericBox( Window* pParent, const ResId& rResId ) :
924 ComboBox( WINDOW_NUMERICBOX )
926 rResId.SetRT( RSC_NUMERICBOX );
927 WinBits nStyle = ImplInitRes( rResId );
928 ComboBox::ImplInit( pParent, nStyle );
929 SetField( this );
930 ComboBox::ImplLoadRes( rResId );
931 NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
932 Reformat();
934 if ( !(nStyle & WB_HIDE ) )
935 Show();
938 // -----------------------------------------------------------------------
940 NumericBox::~NumericBox()
944 // -----------------------------------------------------------------------
946 long NumericBox::PreNotify( NotifyEvent& rNEvt )
948 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
950 if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
951 return 1;
954 return ComboBox::PreNotify( rNEvt );
957 // -----------------------------------------------------------------------
959 long NumericBox::Notify( NotifyEvent& rNEvt )
961 if ( rNEvt.GetType() == EVENT_GETFOCUS )
962 MarkToBeReformatted( FALSE );
963 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
965 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
966 Reformat();
969 return ComboBox::Notify( rNEvt );
972 // -----------------------------------------------------------------------
974 void NumericBox::DataChanged( const DataChangedEvent& rDCEvt )
976 ComboBox::DataChanged( rDCEvt );
978 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
980 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
981 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
982 if ( IsDefaultLocale() )
983 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
984 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
985 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
986 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
987 ReformatAll();
991 // -----------------------------------------------------------------------
993 void NumericBox::Modify()
995 MarkToBeReformatted( TRUE );
996 ComboBox::Modify();
999 // -----------------------------------------------------------------------
1001 void NumericBox::ReformatAll()
1003 double nValue;
1004 XubString aStr;
1005 SetUpdateMode( FALSE );
1006 USHORT nEntryCount = GetEntryCount();
1007 for ( USHORT i=0; i < nEntryCount; i++ )
1009 ImplNumericReformat( GetEntry( i ), nValue, aStr );
1010 RemoveEntry( i );
1011 InsertEntry( aStr, i );
1013 NumericFormatter::Reformat();
1014 SetUpdateMode( TRUE );
1017 // -----------------------------------------------------------------------
1019 void NumericBox::InsertValue( sal_Int64 nValue, USHORT nPos )
1021 ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
1024 // -----------------------------------------------------------------------
1026 void NumericBox::RemoveValue( sal_Int64 nValue )
1028 ComboBox::RemoveEntry( CreateFieldText( nValue ) );
1031 // -----------------------------------------------------------------------
1033 sal_Int64 NumericBox::GetValue( USHORT nPos ) const
1035 double nValue = 0;
1036 ImplNumericGetValue( ComboBox::GetEntry( nPos ), nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() );
1037 return (sal_Int64)nValue;
1040 // -----------------------------------------------------------------------
1042 USHORT NumericBox::GetValuePos( sal_Int64 nValue ) const
1044 return ComboBox::GetEntryPos( CreateFieldText( nValue ) );
1047 // -----------------------------------------------------------------------
1049 static BOOL ImplMetricProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
1050 BOOL, BOOL bUseThousandSep, const LocaleDataWrapper& rWrapper )
1052 // Es gibt hier kein sinnvolles StrictFormat, also alle
1053 // Zeichen erlauben
1054 return ImplNumericProcessKeyInput( pEdit, rKEvt, FALSE, bUseThousandSep, rWrapper );
1057 // -----------------------------------------------------------------------
1059 static XubString ImplMetricGetUnitText( const XubString& rStr )
1061 // Einheitentext holen
1062 XubString aStr;
1063 for ( short i = rStr.Len()-1; i >= 0; i-- )
1065 xub_Unicode c = rStr.GetChar( i );
1066 if ( unicode::isAlpha( c ) ||
1067 (c == '\'') || (c == '\"') || (c == '%' ) )
1068 aStr.Insert( c, 0 );
1069 else
1071 if ( aStr.Len() )
1072 break;
1075 return aStr;
1078 // MT: #90545# Preparation for translated strings...
1079 String aMetricText;
1080 for ( USHORT n = rStr.Len(); n; )
1082 sal_Unicode c = rStr.GetChar( --n );
1083 sal_Int32 nType = xCharClass->getStringType( rStr, n, 1, rLocale );
1085 if ( CharClass::isLetterType( nType ) )
1087 aMetricText.Insert( c, 0 );
1089 else
1091 if ( aMetricText.Len() )
1092 break;
1098 // -----------------------------------------------------------------------
1100 // #104355# support localized mesaurements
1102 static String ImplMetricToString( FieldUnit rUnit )
1104 if( !strAllUnits )
1106 ResMgr* pResMgr = ImplGetResMgr();
1107 strAllUnits = new ResStringArray( ResId (SV_FUNIT_STRINGS, *pResMgr) );
1109 // return unit's default string (ie, the first one )
1110 for( USHORT i=0; i < strAllUnits->Count(); i++ )
1111 if( (FieldUnit) strAllUnits->GetValue( i ) == rUnit )
1112 return strAllUnits->GetString( i );
1114 return String();
1117 static FieldUnit ImplStringToMetric( const String &rMetricString )
1119 if( !strAllUnits )
1121 ResMgr* pResMgr = ImplGetResMgr();
1122 strAllUnits = new ResStringArray( ResId (SV_FUNIT_STRINGS, *pResMgr) );
1124 // return FieldUnit
1125 String aStr( rMetricString );
1126 aStr.ToLowerAscii();
1127 for( USHORT i=0; i < strAllUnits->Count(); i++ )
1128 if ( strAllUnits->GetString( i ).Equals( aStr ) )
1129 return (FieldUnit) strAllUnits->GetValue( i );
1131 // Amelia : about character unit
1132 if (aStr.EqualsIgnoreCaseAscii("cm"))
1133 return FUNIT_CM;
1135 return FUNIT_NONE;
1138 // -----------------------------------------------------------------------
1140 static FieldUnit ImplMetricGetUnit( const XubString& rStr )
1142 XubString aStr = ImplMetricGetUnitText( rStr );
1143 return ImplStringToMetric( aStr );
1146 #define K *1000L
1147 #define M *1000000L
1148 #define X *5280L
1150 // Amelia : about measurement unit, 'char' and 'line'
1151 //static const sal_Int64 aImplFactor[FUNIT_MILE+1][FUNIT_MILE+1] =
1152 static const sal_Int64 aImplFactor[FUNIT_LINE+1][FUNIT_LINE+1] =
1153 { /*
1154 mm/100 mm cm m km twip point pica inch foot mile char line*/
1155 { 1, 100, 1 K, 100 K, 100 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X , 53340, 396240},
1156 { 1, 1, 10, 1 K, 1 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X , 5334, 396240},
1157 { 1, 1, 1, 100, 100 K, 254, 254, 254, 254, 254*12, 254*12 X , 5334, 39624},
1158 { 1, 1, 1, 1, 1 K, 254, 254, 254, 254, 254*12, 254*12 X , 533400, 39624},
1159 { 1, 1, 1, 1, 1, 0, 254, 254, 254, 254*12, 254*12 X ,533400 K, 39624},
1160 { 1440,144 K,144 K,14400 K, 0, 1, 20, 240, 1440,1440*12,1440*12 X , 210, 3120},
1161 { 72, 7200, 7200, 720 K, 720 M, 1, 1, 12, 72, 72*12, 72*12 X , 210, 156},
1162 { 6, 600, 600, 60 K, 60 M, 1, 1, 1, 6, 6*12, 6*12 X , 210, 10},
1163 { 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 12, 12 X , 210, 45},
1164 { 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 X , 210, 45},
1165 { 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 , 210, 45},
1166 { 144, 1440,14400, 14400, 14400, 1, 20, 240, 1440,1440*12, 1440*12 X, 1, 156 },
1167 { 720,72000,72000, 7200 K,7200 M, 20, 10, 13, 11, 11*12, 11*12 X, 105, 1 }
1170 #undef X
1171 #undef M
1172 #undef K
1173 // twip in km 254/14400 M
1175 static FieldUnit eDefaultUnit = FUNIT_NONE;
1177 FieldUnit MetricField::GetDefaultUnit() { return eDefaultUnit; }
1178 void MetricField::SetDefaultUnit( FieldUnit meUnit ) { eDefaultUnit = meUnit; }
1180 static FieldUnit ImplMap2FieldUnit( MapUnit meUnit, long& nDecDigits )
1182 switch( meUnit )
1184 case MAP_100TH_MM :
1185 nDecDigits -= 2;
1186 return FUNIT_MM;
1187 case MAP_10TH_MM :
1188 nDecDigits -= 1;
1189 return FUNIT_MM;
1190 case MAP_MM :
1191 return FUNIT_MM;
1192 case MAP_CM :
1193 return FUNIT_CM;
1194 case MAP_1000TH_INCH :
1195 nDecDigits -= 3;
1196 return FUNIT_INCH;
1197 case MAP_100TH_INCH :
1198 nDecDigits -= 2;
1199 return FUNIT_INCH;
1200 case MAP_10TH_INCH :
1201 nDecDigits -= 1;
1202 return FUNIT_INCH;
1203 case MAP_INCH :
1204 return FUNIT_INCH;
1205 case MAP_POINT :
1206 return FUNIT_POINT;
1207 case MAP_TWIP :
1208 return FUNIT_TWIP;
1209 default:
1210 DBG_ERROR( "default eInUnit" );
1211 break;
1213 return FUNIT_NONE;
1216 // -----------------------------------------------------------------------
1218 static double nonValueDoubleToValueDouble( double nValue )
1220 return rtl::math::isFinite( nValue ) ? nValue : 0.0;
1223 sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_Int64 mnBaseValue, USHORT nDecDigits,
1224 FieldUnit eInUnit, FieldUnit eOutUnit )
1226 // caution: precision loss in double cast
1227 return static_cast<sal_Int64>(
1228 // #150733# cast double to sal_Int64 can throw a
1229 // EXCEPTION_FLT_INVALID_OPERATION on Windows
1230 nonValueDoubleToValueDouble(
1231 ConvertDoubleValue( (double)nValue, mnBaseValue, nDecDigits,
1232 eInUnit, eOutUnit ) ) );
1235 // -----------------------------------------------------------------------
1237 sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, USHORT nDigits,
1238 MapUnit eInUnit, FieldUnit eOutUnit )
1240 return static_cast<sal_Int64>(
1241 // #150733# cast double to sal_Int64 can throw a
1242 // EXCEPTION_FLT_INVALID_OPERATION on Windows
1243 nonValueDoubleToValueDouble(
1244 ConvertDoubleValue( nValue, nDigits, eInUnit, eOutUnit ) ) );
1247 // -----------------------------------------------------------------------
1249 sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, USHORT nDigits,
1250 FieldUnit eInUnit, MapUnit eOutUnit )
1252 return static_cast<sal_Int64>(
1253 // #150733# cast double to sal_Int64 can throw a
1254 // EXCEPTION_FLT_INVALID_OPERATION on Windows
1255 nonValueDoubleToValueDouble(
1256 ConvertDoubleValue( nValue, nDigits, eInUnit, eOutUnit ) ) );
1259 // -----------------------------------------------------------------------
1261 double MetricField::ConvertDoubleValue( double nValue, sal_Int64 mnBaseValue, USHORT nDecDigits,
1262 FieldUnit eInUnit, FieldUnit eOutUnit )
1264 if ( eInUnit != eOutUnit )
1266 sal_Int64 nMult = 1, nDiv = 1;
1268 if ( eInUnit == FUNIT_PERCENT )
1270 if ( (mnBaseValue <= 0) || (nValue <= 0) )
1271 return nValue;
1272 nDiv = 100;
1273 for ( USHORT i=0; i < nDecDigits; i++ )
1274 nDiv *= 10;
1276 nMult = mnBaseValue;
1278 else if ( eOutUnit == FUNIT_PERCENT ||
1279 eOutUnit == FUNIT_CUSTOM ||
1280 eOutUnit == FUNIT_NONE ||
1281 eInUnit == FUNIT_CUSTOM ||
1282 eInUnit == FUNIT_NONE )
1283 return nValue;
1284 else
1286 if ( eOutUnit == FUNIT_100TH_MM )
1287 eOutUnit = FUNIT_NONE;
1288 if ( eInUnit == FUNIT_100TH_MM )
1289 eInUnit = FUNIT_NONE;
1291 nDiv = aImplFactor[eInUnit][eOutUnit];
1292 nMult = aImplFactor[eOutUnit][eInUnit];
1294 DBG_ASSERT( nMult > 0, "illegal *" );
1295 DBG_ASSERT( nDiv > 0, "illegal /" );
1298 if ( nMult != 1 && nMult > 0 )
1299 nValue *= nMult;
1300 if ( nDiv != 1 && nDiv > 0 )
1302 nValue += ( nValue < 0 ) ? (-nDiv/2) : (nDiv/2);
1303 nValue /= nDiv;
1307 return nValue;
1310 // -----------------------------------------------------------------------
1312 double MetricField::ConvertDoubleValue( double nValue, USHORT nDigits,
1313 MapUnit eInUnit, FieldUnit eOutUnit )
1315 if ( eOutUnit == FUNIT_PERCENT ||
1316 eOutUnit == FUNIT_CUSTOM ||
1317 eOutUnit == FUNIT_NONE ||
1318 eInUnit == MAP_PIXEL ||
1319 eInUnit == MAP_SYSFONT ||
1320 eInUnit == MAP_APPFONT ||
1321 eInUnit == MAP_RELATIVE )
1323 DBG_ERROR( "invalid parameters" );
1324 return nValue;
1327 long nDecDigits = nDigits;
1328 FieldUnit eFieldUnit = ImplMap2FieldUnit( eInUnit, nDecDigits );
1330 if ( nDecDigits < 0 )
1332 while ( nDecDigits )
1334 nValue += 5;
1335 nValue /= 10;
1336 nDecDigits++;
1339 else
1341 while ( nDecDigits )
1343 nValue *= 10;
1344 nDecDigits--;
1348 if ( eFieldUnit != eOutUnit )
1350 sal_Int64 nDiv = aImplFactor[eFieldUnit][eOutUnit];
1351 sal_Int64 nMult = aImplFactor[eOutUnit][eFieldUnit];
1353 DBG_ASSERT( nMult > 0, "illegal *" );
1354 DBG_ASSERT( nDiv > 0, "illegal /" );
1356 if ( nMult != 1 && nMult > 0)
1357 nValue *= nMult;
1358 if ( nDiv != 1 && nDiv > 0 )
1360 nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2);
1361 nValue /= nDiv;
1364 return nValue;
1367 // -----------------------------------------------------------------------
1369 double MetricField::ConvertDoubleValue( double nValue, USHORT nDigits,
1370 FieldUnit eInUnit, MapUnit eOutUnit )
1372 if ( eInUnit == FUNIT_PERCENT ||
1373 eInUnit == FUNIT_CUSTOM ||
1374 eInUnit == FUNIT_NONE ||
1375 eOutUnit == MAP_PIXEL ||
1376 eOutUnit == MAP_SYSFONT ||
1377 eOutUnit == MAP_APPFONT ||
1378 eOutUnit == MAP_RELATIVE )
1380 DBG_ERROR( "invalid parameters" );
1381 return nValue;
1384 long nDecDigits = nDigits;
1385 FieldUnit eFieldUnit = ImplMap2FieldUnit( eOutUnit, nDecDigits );
1387 if ( nDecDigits < 0 )
1389 while ( nDecDigits )
1391 nValue *= 10;
1392 nDecDigits++;
1395 else
1397 while ( nDecDigits )
1399 nValue += 5;
1400 nValue /= 10;
1401 nDecDigits--;
1405 if ( eFieldUnit != eInUnit )
1407 sal_Int64 nDiv = aImplFactor[eInUnit][eFieldUnit];
1408 sal_Int64 nMult = aImplFactor[eFieldUnit][eInUnit];
1410 DBG_ASSERT( nMult > 0, "illegal *" );
1411 DBG_ASSERT( nDiv > 0, "illegal /" );
1413 if( nMult != 1 && nMult > 0 )
1414 nValue *= nMult;
1415 if( nDiv != 1 && nDiv > 0 )
1417 nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2);
1418 nValue /= nDiv;
1421 return nValue;
1424 // -----------------------------------------------------------------------
1426 static BOOL ImplMetricGetValue( const XubString& rStr, double& rValue, sal_Int64 nBaseValue,
1427 USHORT nDecDigits, const LocaleDataWrapper& rLocaleDataWrapper, FieldUnit eUnit )
1429 // Zahlenwert holen
1430 if ( !ImplNumericGetValue( rStr, rValue, nDecDigits, rLocaleDataWrapper ) )
1431 return FALSE;
1433 // Einheit rausfinden
1434 FieldUnit eEntryUnit = ImplMetricGetUnit( rStr );
1436 // Einheiten umrechnen
1437 rValue = MetricField::ConvertDoubleValue( rValue, nBaseValue, nDecDigits, eEntryUnit, eUnit );
1439 return TRUE;
1442 // -----------------------------------------------------------------------
1444 BOOL MetricFormatter::ImplMetricReformat( const XubString& rStr, double& rValue, XubString& rOutStr )
1446 if ( !ImplMetricGetValue( rStr, rValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) )
1447 return TRUE;
1448 else
1450 double nTempVal = rValue;
1451 // caution: precision loss in double cast
1452 if ( nTempVal > GetMax() )
1453 nTempVal = (double)GetMax();
1454 else if ( nTempVal < GetMin())
1455 nTempVal = (double)GetMin();
1457 if ( GetErrorHdl().IsSet() && (rValue != nTempVal) )
1459 mnCorrectedValue = (sal_Int64)nTempVal;
1460 if ( !GetErrorHdl().Call( this ) )
1462 mnCorrectedValue = 0;
1463 return FALSE;
1465 else
1466 mnCorrectedValue = 0;
1469 rOutStr = CreateFieldText( (sal_Int64)nTempVal );
1470 return TRUE;
1474 // -----------------------------------------------------------------------
1476 inline void MetricFormatter::ImplInit()
1478 mnBaseValue = 0;
1479 meUnit = MetricField::GetDefaultUnit();
1480 mnType = FORMAT_METRIC;
1483 // -----------------------------------------------------------------------
1485 MetricFormatter::MetricFormatter()
1487 ImplInit();
1490 // -----------------------------------------------------------------------
1492 void MetricFormatter::ImplLoadRes( const ResId& rResId )
1494 NumericFormatter::ImplLoadRes( rResId );
1496 ResMgr* pMgr = rResId.GetResMgr();
1497 if( pMgr )
1499 ULONG nMask = pMgr->ReadLong();
1501 if ( METRICFORMATTER_UNIT & nMask )
1502 meUnit = (FieldUnit)pMgr->ReadLong();
1504 if ( METRICFORMATTER_CUSTOMUNITTEXT & nMask )
1505 maCustomUnitText = pMgr->ReadString();
1509 // -----------------------------------------------------------------------
1511 MetricFormatter::~MetricFormatter()
1515 // -----------------------------------------------------------------------
1517 void MetricFormatter::SetUnit( FieldUnit eNewUnit )
1519 if ( eNewUnit == FUNIT_100TH_MM )
1521 SetDecimalDigits( GetDecimalDigits() + 2 );
1522 meUnit = FUNIT_MM;
1524 else
1525 meUnit = eNewUnit;
1526 ReformatAll();
1529 // -----------------------------------------------------------------------
1531 void MetricFormatter::SetCustomUnitText( const XubString& rStr )
1533 maCustomUnitText = rStr;
1534 ReformatAll();
1537 // -----------------------------------------------------------------------
1539 void MetricFormatter::SetValue( sal_Int64 nNewValue, FieldUnit eInUnit )
1541 SetUserValue( nNewValue, eInUnit );
1542 mnFieldValue = mnLastValue;
1545 // -----------------------------------------------------------------------
1547 XubString MetricFormatter::CreateFieldText( sal_Int64 nValue ) const
1549 XubString aStr = NumericFormatter::CreateFieldText( nValue );
1551 if( meUnit == FUNIT_CUSTOM )
1552 aStr += maCustomUnitText;
1553 else
1554 aStr += ImplMetricToString( meUnit );
1556 return aStr;
1559 // -----------------------------------------------------------------------
1561 void MetricFormatter::SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit )
1563 // Umrechnen auf eingestellte Einheiten
1564 nNewValue = MetricField::ConvertValue( nNewValue, mnBaseValue, GetDecimalDigits(), eInUnit, meUnit );
1565 NumericFormatter::SetUserValue( nNewValue );
1568 // -----------------------------------------------------------------------
1570 sal_Int64 MetricFormatter::GetValue( FieldUnit eOutUnit ) const
1572 if ( !GetField() )
1573 return 0;
1575 double nTempValue;
1576 // caution: precision loss in double cast
1577 if ( !ImplMetricGetValue( GetField()->GetText(), nTempValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) )
1578 nTempValue = (double)mnLastValue;
1580 // caution: precision loss in double cast
1581 if ( nTempValue > mnMax )
1582 nTempValue = (double)mnMax;
1583 else if ( nTempValue < mnMin )
1584 nTempValue = (double)mnMin;
1586 // Umrechnen auf gewuenschte Einheiten
1587 return MetricField::ConvertValue( (sal_Int64)nTempValue, mnBaseValue, GetDecimalDigits(), meUnit, eOutUnit );
1590 // -----------------------------------------------------------------------
1592 void MetricFormatter::SetValue( sal_Int64 nValue )
1594 // Implementation not inline, because it is a virtual Function
1595 SetValue( nValue, FUNIT_NONE );
1598 // -----------------------------------------------------------------------
1600 sal_Int64 MetricFormatter::GetValue() const
1602 // Implementation not inline, because it is a virtual Function
1603 return GetValue( FUNIT_NONE );
1606 // -----------------------------------------------------------------------
1608 void MetricFormatter::SetMin( sal_Int64 nNewMin, FieldUnit eInUnit )
1610 // Umrechnen auf gewuenschte Einheiten
1611 NumericFormatter::SetMin( MetricField::ConvertValue( nNewMin, mnBaseValue, GetDecimalDigits(),
1612 eInUnit, meUnit ) );
1615 // -----------------------------------------------------------------------
1617 sal_Int64 MetricFormatter::GetMin( FieldUnit eOutUnit ) const
1619 // Umrechnen auf gewuenschte Einheiten
1620 return MetricField::ConvertValue( NumericFormatter::GetMin(), mnBaseValue,
1621 GetDecimalDigits(), meUnit, eOutUnit );
1624 // -----------------------------------------------------------------------
1626 void MetricFormatter::SetMax( sal_Int64 nNewMax, FieldUnit eInUnit )
1628 // Umrechnen auf gewuenschte Einheiten
1629 NumericFormatter::SetMax( MetricField::ConvertValue( nNewMax, mnBaseValue, GetDecimalDigits(),
1630 eInUnit, meUnit ) );
1633 // -----------------------------------------------------------------------
1635 sal_Int64 MetricFormatter::GetMax( FieldUnit eOutUnit ) const
1637 // Umrechnen auf gewuenschte Einheiten
1638 return MetricField::ConvertValue( NumericFormatter::GetMax(), mnBaseValue,
1639 GetDecimalDigits(), meUnit, eOutUnit );
1642 // -----------------------------------------------------------------------
1644 void MetricFormatter::SetBaseValue( sal_Int64 nNewBase, FieldUnit eInUnit )
1646 mnBaseValue = MetricField::ConvertValue( nNewBase, mnBaseValue, GetDecimalDigits(),
1647 eInUnit, meUnit );
1650 // -----------------------------------------------------------------------
1652 sal_Int64 MetricFormatter::GetBaseValue( FieldUnit eOutUnit ) const
1654 // Umrechnen auf gewuenschte Einheiten
1655 return MetricField::ConvertValue( mnBaseValue, mnBaseValue, GetDecimalDigits(),
1656 meUnit, eOutUnit );
1659 // -----------------------------------------------------------------------
1661 void MetricFormatter::Reformat()
1663 if ( !GetField() )
1664 return;
1666 XubString aText = GetField()->GetText();
1667 if ( meUnit == FUNIT_CUSTOM )
1668 maCurUnitText = ImplMetricGetUnitText( aText );
1670 XubString aStr;
1671 // caution: precision loss in double cast
1672 double nTemp = (double)mnLastValue;
1673 BOOL bOK = ImplMetricReformat( aText, nTemp, aStr );
1674 mnLastValue = (sal_Int64)nTemp;
1676 if ( !bOK )
1677 return;
1679 if ( aStr.Len() )
1681 ImplSetText( aStr );
1682 if ( meUnit == FUNIT_CUSTOM )
1683 CustomConvert();
1685 else
1686 SetValue( mnLastValue );
1687 maCurUnitText.Erase();
1690 // -----------------------------------------------------------------------
1692 sal_Int64 MetricFormatter::GetCorrectedValue( FieldUnit eOutUnit ) const
1694 // Umrechnen auf gewuenschte Einheiten
1695 return MetricField::ConvertValue( mnCorrectedValue, mnBaseValue, GetDecimalDigits(),
1696 meUnit, eOutUnit );
1699 // -----------------------------------------------------------------------
1701 MetricField::MetricField( Window* pParent, WinBits nWinStyle ) :
1702 SpinField( pParent, nWinStyle )
1704 SetField( this );
1705 Reformat();
1708 // -----------------------------------------------------------------------
1710 MetricField::MetricField( Window* pParent, const ResId& rResId ) :
1711 SpinField( WINDOW_METRICFIELD )
1713 rResId.SetRT( RSC_METRICFIELD );
1714 WinBits nStyle = ImplInitRes( rResId ) ;
1715 SpinField::ImplInit( pParent, nStyle );
1716 SetField( this );
1717 ImplLoadRes( rResId );
1719 if ( !(nStyle & WB_HIDE ) )
1720 Show();
1723 // -----------------------------------------------------------------------
1725 void MetricField::ImplLoadRes( const ResId& rResId )
1727 SpinField::ImplLoadRes( rResId );
1728 MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
1730 ULONG nMask = ReadLongRes();
1732 if ( METRICFIELD_FIRST & nMask )
1733 mnFirst = ReadLongRes();
1735 if ( METRICFIELD_LAST & nMask )
1736 mnLast = ReadLongRes();
1738 if ( METRICFIELD_SPINSIZE & nMask )
1739 mnSpinSize = ReadLongRes();
1741 Reformat();
1744 // -----------------------------------------------------------------------
1746 MetricField::~MetricField()
1750 // -----------------------------------------------------------------------
1752 void MetricField::SetFirst( sal_Int64 nNewFirst, FieldUnit eInUnit )
1754 // convert
1755 nNewFirst = MetricField::ConvertValue( nNewFirst, mnBaseValue, GetDecimalDigits(),
1756 eInUnit, meUnit );
1757 mnFirst = nNewFirst;
1760 // -----------------------------------------------------------------------
1762 sal_Int64 MetricField::GetFirst( FieldUnit eOutUnit ) const
1764 // convert
1765 return MetricField::ConvertValue( mnFirst, mnBaseValue, GetDecimalDigits(),
1766 meUnit, eOutUnit );
1769 // -----------------------------------------------------------------------
1771 void MetricField::SetLast( sal_Int64 nNewLast, FieldUnit eInUnit )
1773 // Umrechnen
1774 nNewLast = MetricField::ConvertValue( nNewLast, mnBaseValue, GetDecimalDigits(),
1775 eInUnit, meUnit );
1776 mnLast = nNewLast;
1779 // -----------------------------------------------------------------------
1781 sal_Int64 MetricField::GetLast( FieldUnit eOutUnit ) const
1783 // Umrechnen
1784 return MetricField::ConvertValue( mnLast, mnBaseValue, GetDecimalDigits(),
1785 meUnit, eOutUnit );
1788 // -----------------------------------------------------------------------
1790 long MetricField::PreNotify( NotifyEvent& rNEvt )
1792 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
1794 if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
1795 return 1;
1798 return SpinField::PreNotify( rNEvt );
1801 // -----------------------------------------------------------------------
1803 long MetricField::Notify( NotifyEvent& rNEvt )
1805 if ( rNEvt.GetType() == EVENT_GETFOCUS )
1806 MarkToBeReformatted( FALSE );
1807 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
1809 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
1810 Reformat();
1813 return SpinField::Notify( rNEvt );
1816 // -----------------------------------------------------------------------
1818 void MetricField::DataChanged( const DataChangedEvent& rDCEvt )
1820 SpinField::DataChanged( rDCEvt );
1822 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
1824 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
1825 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
1826 if ( IsDefaultLocale() )
1827 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
1828 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
1829 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
1830 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
1831 ReformatAll();
1835 // -----------------------------------------------------------------------
1837 void MetricField::Modify()
1839 MarkToBeReformatted( TRUE );
1840 SpinField::Modify();
1843 // -----------------------------------------------------------------------
1845 void MetricField::Up()
1847 FieldUp();
1848 SpinField::Up();
1851 // -----------------------------------------------------------------------
1853 void MetricField::Down()
1855 FieldDown();
1856 SpinField::Down();
1859 // -----------------------------------------------------------------------
1861 void MetricField::First()
1863 FieldFirst();
1864 SpinField::First();
1867 // -----------------------------------------------------------------------
1869 void MetricField::Last()
1871 FieldLast();
1872 SpinField::Last();
1875 // -----------------------------------------------------------------------
1877 void MetricField::CustomConvert()
1879 maCustomConvertLink.Call( this );
1882 // -----------------------------------------------------------------------
1884 MetricBox::MetricBox( Window* pParent, WinBits nWinStyle ) :
1885 ComboBox( pParent, nWinStyle )
1887 SetField( this );
1888 Reformat();
1891 // -----------------------------------------------------------------------
1893 MetricBox::MetricBox( Window* pParent, const ResId& rResId ) :
1894 ComboBox( WINDOW_METRICBOX )
1896 rResId.SetRT( RSC_METRICBOX );
1897 WinBits nStyle = ImplInitRes( rResId );
1898 ComboBox::ImplInit( pParent, nStyle );
1899 SetField( this );
1900 Reformat();
1901 ComboBox::ImplLoadRes( rResId );
1902 MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
1904 if ( !(nStyle & WB_HIDE ) )
1905 Show();
1908 // -----------------------------------------------------------------------
1910 MetricBox::~MetricBox()
1914 // -----------------------------------------------------------------------
1916 long MetricBox::PreNotify( NotifyEvent& rNEvt )
1918 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
1920 if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
1921 return 1;
1924 return ComboBox::PreNotify( rNEvt );
1927 // -----------------------------------------------------------------------
1929 long MetricBox::Notify( NotifyEvent& rNEvt )
1931 if ( rNEvt.GetType() == EVENT_GETFOCUS )
1932 MarkToBeReformatted( FALSE );
1933 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
1935 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
1936 Reformat();
1939 return ComboBox::Notify( rNEvt );
1942 // -----------------------------------------------------------------------
1944 void MetricBox::DataChanged( const DataChangedEvent& rDCEvt )
1946 ComboBox::DataChanged( rDCEvt );
1948 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
1950 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
1951 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
1952 if ( IsDefaultLocale() )
1953 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
1954 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
1955 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
1956 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
1957 ReformatAll();
1961 // -----------------------------------------------------------------------
1963 void MetricBox::Modify()
1965 MarkToBeReformatted( TRUE );
1966 ComboBox::Modify();
1969 // -----------------------------------------------------------------------
1971 void MetricBox::ReformatAll()
1973 double nValue;
1974 XubString aStr;
1975 SetUpdateMode( FALSE );
1976 USHORT nEntryCount = GetEntryCount();
1977 for ( USHORT i=0; i < nEntryCount; i++ )
1979 ImplMetricReformat( GetEntry( i ), nValue, aStr );
1980 RemoveEntry( i );
1981 InsertEntry( aStr, i );
1983 MetricFormatter::Reformat();
1984 SetUpdateMode( TRUE );
1987 // -----------------------------------------------------------------------
1989 void MetricBox::CustomConvert()
1991 maCustomConvertLink.Call( this );
1994 // -----------------------------------------------------------------------
1996 void MetricBox::InsertValue( sal_Int64 nValue, FieldUnit eInUnit, USHORT nPos )
1998 // Umrechnen auf eingestellte Einheiten
1999 nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
2000 eInUnit, meUnit );
2001 ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
2004 // -----------------------------------------------------------------------
2006 void MetricBox::RemoveValue( sal_Int64 nValue, FieldUnit eInUnit )
2008 // Umrechnen auf eingestellte Einheiten
2009 nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
2010 eInUnit, meUnit );
2011 ComboBox::RemoveEntry( CreateFieldText( nValue ) );
2014 // -----------------------------------------------------------------------
2016 sal_Int64 MetricBox::GetValue( USHORT nPos, FieldUnit eOutUnit ) const
2018 double nValue = 0;
2019 ImplMetricGetValue( ComboBox::GetEntry( nPos ), nValue, mnBaseValue,
2020 GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit );
2022 // Umrechnen auf eingestellte Einheiten
2023 sal_Int64 nRetValue = MetricField::ConvertValue( (sal_Int64)nValue, mnBaseValue, GetDecimalDigits(),
2024 meUnit, eOutUnit );
2026 return nRetValue;
2029 // -----------------------------------------------------------------------
2031 USHORT MetricBox::GetValuePos( sal_Int64 nValue, FieldUnit eInUnit ) const
2033 // Umrechnen auf eingestellte Einheiten
2034 nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
2035 eInUnit, meUnit );
2036 return ComboBox::GetEntryPos( CreateFieldText( nValue ) );
2039 // -----------------------------------------------------------------------
2041 sal_Int64 MetricBox::GetValue( FieldUnit eOutUnit ) const
2043 // Implementation not inline, because it is a virtual Function
2044 return MetricFormatter::GetValue( eOutUnit );
2047 // -----------------------------------------------------------------------
2049 sal_Int64 MetricBox::GetValue() const
2051 // Implementation not inline, because it is a virtual Function
2052 return GetValue( FUNIT_NONE );
2055 // -----------------------------------------------------------------------
2057 static BOOL ImplCurrencyProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
2058 BOOL, BOOL bUseThousandSep, const LocaleDataWrapper& rWrapper )
2060 // Es gibt hier kein sinnvolles StrictFormat, also alle
2061 // Zeichen erlauben
2062 return ImplNumericProcessKeyInput( pEdit, rKEvt, FALSE, bUseThousandSep, rWrapper );
2065 // -----------------------------------------------------------------------
2067 inline BOOL ImplCurrencyGetValue( const XubString& rStr, double& rValue,
2068 USHORT nDecDigits, const LocaleDataWrapper& rWrapper )
2070 // Zahlenwert holen
2071 return ImplNumericGetValue( rStr, rValue, nDecDigits, rWrapper, TRUE );
2074 // -----------------------------------------------------------------------
2076 BOOL CurrencyFormatter::ImplCurrencyReformat( const XubString& rStr,
2077 XubString& rOutStr )
2079 double nValue;
2080 if ( !ImplNumericGetValue( rStr, nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), TRUE ) )
2081 return TRUE;
2082 else
2084 double nTempVal = nValue;
2085 // caution: precision loss in double cast
2086 if ( nTempVal > GetMax() )
2087 nTempVal = (double)GetMax();
2088 else if ( nTempVal < GetMin())
2089 nTempVal = (double)GetMin();
2091 if ( GetErrorHdl().IsSet() && (nValue != nTempVal) )
2093 mnCorrectedValue = (sal_Int64)nTempVal;
2094 if ( !GetErrorHdl().Call( this ) )
2096 mnCorrectedValue = 0;
2097 return FALSE;
2099 else
2100 mnCorrectedValue = 0;
2103 rOutStr = CreateFieldText( (long)nTempVal );
2104 return TRUE;
2108 // -----------------------------------------------------------------------
2110 inline void CurrencyFormatter::ImplInit()
2112 mnType = FORMAT_CURRENCY;
2115 // -----------------------------------------------------------------------
2117 CurrencyFormatter::CurrencyFormatter()
2119 ImplInit();
2122 // -----------------------------------------------------------------------
2124 CurrencyFormatter::~CurrencyFormatter()
2128 // -----------------------------------------------------------------------
2130 void CurrencyFormatter::SetCurrencySymbol( const String& rStr )
2132 maCurrencySymbol= rStr;
2133 ReformatAll();
2136 // -----------------------------------------------------------------------
2138 String CurrencyFormatter::GetCurrencySymbol() const
2140 return maCurrencySymbol.Len() ? maCurrencySymbol : ImplGetLocaleDataWrapper().getCurrSymbol();
2143 // -----------------------------------------------------------------------
2145 void CurrencyFormatter::SetValue( sal_Int64 nNewValue )
2147 SetUserValue( nNewValue );
2148 mnFieldValue = mnLastValue;
2149 SetEmptyFieldValueData( FALSE );
2152 // -----------------------------------------------------------------------
2154 XubString CurrencyFormatter::CreateFieldText( sal_Int64 nValue ) const
2156 return ImplGetLocaleDataWrapper().getCurr( nValue, GetDecimalDigits(), GetCurrencySymbol(), IsUseThousandSep() );
2159 // -----------------------------------------------------------------------
2161 sal_Int64 CurrencyFormatter::GetValue() const
2163 if ( !GetField() )
2164 return 0;
2166 double nTempValue;
2167 if ( ImplCurrencyGetValue( GetField()->GetText(), nTempValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
2169 // caution: precision loss in double cast
2170 if ( nTempValue > mnMax )
2171 nTempValue = (double)mnMax;
2172 else if ( nTempValue < mnMin )
2173 nTempValue = (double)mnMin;
2174 return (sal_Int64)nTempValue;
2176 else
2177 return mnLastValue;
2180 // -----------------------------------------------------------------------
2182 void CurrencyFormatter::Reformat()
2184 if ( !GetField() )
2185 return;
2187 XubString aStr;
2188 BOOL bOK = ImplCurrencyReformat( GetField()->GetText(), aStr );
2189 if ( !bOK )
2190 return;
2192 if ( aStr.Len() )
2194 ImplSetText( aStr );
2195 // caution: precision loss in double cast
2196 double nTemp = (double)mnLastValue;
2197 ImplCurrencyGetValue( aStr, nTemp, GetDecimalDigits(), ImplGetLocaleDataWrapper() );
2198 mnLastValue = (sal_Int64)nTemp;
2200 else
2201 SetValue( mnLastValue );
2204 // -----------------------------------------------------------------------
2206 CurrencyField::CurrencyField( Window* pParent, WinBits nWinStyle ) :
2207 SpinField( pParent, nWinStyle )
2209 SetField( this );
2210 Reformat();
2213 // -----------------------------------------------------------------------
2215 CurrencyField::CurrencyField( Window* pParent, const ResId& rResId ) :
2216 SpinField( WINDOW_CURRENCYFIELD )
2218 rResId.SetRT( RSC_CURRENCYFIELD );
2219 WinBits nStyle = ImplInitRes( rResId );
2220 SpinField::ImplInit( pParent, nStyle);
2221 SetField( this );
2222 ImplLoadRes( rResId );
2224 if ( !(nStyle & WB_HIDE ) )
2225 Show();
2228 // -----------------------------------------------------------------------
2230 void CurrencyField::ImplLoadRes( const ResId& rResId )
2232 SpinField::ImplLoadRes( rResId );
2233 CurrencyFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
2235 ULONG nMask = ReadLongRes();
2237 if ( CURRENCYFIELD_FIRST & nMask )
2238 mnFirst = ReadLongRes();
2240 if ( CURRENCYFIELD_LAST & nMask )
2241 mnLast = ReadLongRes();
2243 if ( CURRENCYFIELD_SPINSIZE & nMask )
2244 mnSpinSize = ReadLongRes();
2246 Reformat();
2249 // -----------------------------------------------------------------------
2251 CurrencyField::~CurrencyField()
2255 // -----------------------------------------------------------------------
2257 long CurrencyField::PreNotify( NotifyEvent& rNEvt )
2259 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
2261 if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
2262 return 1;
2265 return SpinField::PreNotify( rNEvt );
2268 // -----------------------------------------------------------------------
2270 long CurrencyField::Notify( NotifyEvent& rNEvt )
2272 if ( rNEvt.GetType() == EVENT_GETFOCUS )
2273 MarkToBeReformatted( FALSE );
2274 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
2276 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
2277 Reformat();
2280 return SpinField::Notify( rNEvt );
2283 // -----------------------------------------------------------------------
2285 void CurrencyField::DataChanged( const DataChangedEvent& rDCEvt )
2287 SpinField::DataChanged( rDCEvt );
2289 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
2291 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
2292 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
2293 if ( IsDefaultLocale() )
2294 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
2295 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
2296 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
2297 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
2298 ReformatAll();
2302 // -----------------------------------------------------------------------
2304 void CurrencyField::Modify()
2306 MarkToBeReformatted( TRUE );
2307 SpinField::Modify();
2310 // -----------------------------------------------------------------------
2312 void CurrencyField::Up()
2314 FieldUp();
2315 SpinField::Up();
2318 // -----------------------------------------------------------------------
2320 void CurrencyField::Down()
2322 FieldDown();
2323 SpinField::Down();
2326 // -----------------------------------------------------------------------
2328 void CurrencyField::First()
2330 FieldFirst();
2331 SpinField::First();
2334 // -----------------------------------------------------------------------
2336 void CurrencyField::Last()
2338 FieldLast();
2339 SpinField::Last();
2342 // -----------------------------------------------------------------------
2344 CurrencyBox::CurrencyBox( Window* pParent, WinBits nWinStyle ) :
2345 ComboBox( pParent, nWinStyle )
2347 SetField( this );
2348 Reformat();
2351 // -----------------------------------------------------------------------
2353 CurrencyBox::CurrencyBox( Window* pParent, const ResId& rResId ) :
2354 ComboBox( WINDOW_CURRENCYBOX )
2356 rResId.SetRT( RSC_CURRENCYBOX );
2357 WinBits nStyle = ImplInitRes( rResId );
2358 ComboBox::ImplInit( pParent, nStyle );
2359 CurrencyFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
2360 SetField( this );
2361 ComboBox::ImplLoadRes( rResId );
2362 Reformat();
2364 if ( !(nStyle & WB_HIDE ) )
2365 Show();
2368 // -----------------------------------------------------------------------
2370 CurrencyBox::~CurrencyBox()
2374 // -----------------------------------------------------------------------
2376 long CurrencyBox::PreNotify( NotifyEvent& rNEvt )
2378 if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
2380 if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
2381 return 1;
2384 return ComboBox::PreNotify( rNEvt );
2387 // -----------------------------------------------------------------------
2389 long CurrencyBox::Notify( NotifyEvent& rNEvt )
2391 if ( rNEvt.GetType() == EVENT_GETFOCUS )
2392 MarkToBeReformatted( FALSE );
2393 else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
2395 if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
2396 Reformat();
2399 return ComboBox::Notify( rNEvt );
2402 // -----------------------------------------------------------------------
2404 void CurrencyBox::DataChanged( const DataChangedEvent& rDCEvt )
2406 ComboBox::DataChanged( rDCEvt );
2408 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
2410 String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
2411 String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
2412 if ( IsDefaultLocale() )
2413 ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
2414 String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
2415 String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
2416 ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
2417 ReformatAll();
2421 // -----------------------------------------------------------------------
2423 void CurrencyBox::Modify()
2425 MarkToBeReformatted( TRUE );
2426 ComboBox::Modify();
2429 // -----------------------------------------------------------------------
2431 void CurrencyBox::ReformatAll()
2433 XubString aStr;
2434 SetUpdateMode( FALSE );
2435 USHORT nEntryCount = GetEntryCount();
2436 for ( USHORT i=0; i < nEntryCount; i++ )
2438 ImplCurrencyReformat( GetEntry( i ), aStr );
2439 RemoveEntry( i );
2440 InsertEntry( aStr, i );
2442 CurrencyFormatter::Reformat();
2443 SetUpdateMode( TRUE );
2446 // -----------------------------------------------------------------------
2448 void CurrencyBox::InsertValue( sal_Int64 nValue, USHORT nPos )
2450 ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
2453 // -----------------------------------------------------------------------
2455 void CurrencyBox::RemoveValue( sal_Int64 nValue )
2457 ComboBox::RemoveEntry( CreateFieldText( nValue ) );
2460 // -----------------------------------------------------------------------
2462 sal_Int64 CurrencyBox::GetValue( USHORT nPos ) const
2464 double nValue = 0;
2465 ImplCurrencyGetValue( ComboBox::GetEntry( nPos ), nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() );
2466 return (sal_Int64)nValue;
2469 // -----------------------------------------------------------------------
2471 USHORT CurrencyBox::GetValuePos( sal_Int64 nValue ) const
2473 return ComboBox::GetEntryPos( CreateFieldText( nValue ) );
2476 // -----------------------------------------------------------------------
2478 sal_Int64 CurrencyBox::GetValue() const
2480 // Implementation not inline, because it is a virtual Function
2481 return CurrencyFormatter::GetValue();