1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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"
36 #include "tools/bigint.hxx"
39 #include "tools/debug.hxx"
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
)
73 for ( i
=0; i
< n
; i
++ )
79 // -----------------------------------------------------------------------
81 static BOOL
ImplNumericProcessKeyInput( Edit
*, const KeyEvent
& rKEvt
,
82 BOOL bStrictFormat
, BOOL bThousandSep
,
83 const LocaleDataWrapper
& rLocaleDataWrappper
)
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())) ||
104 // -----------------------------------------------------------------------
106 static BOOL
ImplNumericGetValue( const XubString
& rStr
, double& rValue
,
107 USHORT nDecDigits
, const LocaleDataWrapper
& rLocaleDataWrappper
,
108 BOOL bCurrency
= FALSE
)
110 XubString aStr
= rStr
;
113 BOOL bNegative
= FALSE
;
117 // Reaktion auf leeren String
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 );
137 if ( (aStr
.GetChar( 0 ) == '(') && (aStr
.GetChar( aStr
.Len()-1 ) == ')') )
141 for ( i
=0; i
< aStr
.Len(); i
++ )
143 if ( (aStr
.GetChar( i
) >= '0') && (aStr
.GetChar( i
) <= '9') )
145 else if ( aStr
.GetChar( i
) == '-' )
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') )
162 else if ( aStr
.GetChar( i
) == '-' )
173 if ( aStr1
.GetChar( 0 ) == '-' )
177 // Alle unerwuenschten Zeichen rauswerfen
178 for ( i
=0; i
< aStr1
.Len(); )
180 if ( (aStr1
.GetChar( i
) >= '0') && (aStr1
.GetChar( i
) <= '9') )
185 for ( i
=0; i
< aStr2
.Len(); )
187 if ( (aStr2
.GetChar( i
) >= '0') && (aStr2
.GetChar( i
) <= '9') )
193 if ( !aStr1
.Len() && !aStr2
.Len() )
199 aStr1
.Insert( '-', 0 );
201 // Nachkommateil zurechtstutzen und dabei runden
203 if ( aStr2
.Len() > nDecDigits
)
205 if ( aStr2
.GetChar( nDecDigits
) >= '5' )
207 aStr2
.Erase( nDecDigits
);
209 if ( aStr2
.Len() < nDecDigits
)
210 aStr2
.Expand( nDecDigits
, '0' );
215 // Bereichsueberpruefung
216 double nValue
= aStr
.ToDouble();
230 static void ImplUpdateSeparators( const String
& rOldDecSep
, const String
& rNewDecSep
,
231 const String
& rOldThSep
, const String
& rNewThSep
,
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();
243 aText
.SearchAndReplaceAll( rNewDecSep
, rOldDecSep
);
245 aText
.SearchAndReplaceAll( rNewThSep
, rOldThSep
);
246 pEdit
->SetText( aText
);
248 ComboBox
* pCombo
= dynamic_cast<ComboBox
*>(pEdit
);
251 // update box entries
252 USHORT nEntryCount
= pCombo
->GetEntryCount();
253 for ( USHORT i
=0; i
< nEntryCount
; i
++ )
255 aText
= pCombo
->GetEntry( i
);
257 aText
.SearchAndReplaceAll( rNewDecSep
, rOldDecSep
);
259 aText
.SearchAndReplaceAll( rNewThSep
, rOldThSep
);
260 pCombo
->RemoveEntry( i
);
261 pCombo
->InsertEntry( aText
, i
);
265 pEdit
->SetUpdateMode( bUpdateMode
);
269 // -----------------------------------------------------------------------
271 FormatterBase::FormatterBase( Edit
* pField
)
274 mpLocaleDataWrapper
= NULL
;
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()
318 // -----------------------------------------------------------------------
320 void FormatterBase::SetStrictFormat( BOOL bStrict
)
322 if ( bStrict
!= mbStrictFormat
)
324 mbStrictFormat
= bStrict
;
325 if ( mbStrictFormat
)
330 // -----------------------------------------------------------------------
332 void FormatterBase::SetLocale( const lang::Locale
& rLocale
)
334 ImplGetLocaleDataWrapper().setLocale( rLocale
);
335 mbDefaultLocale
= FALSE
;
339 // -----------------------------------------------------------------------
341 const lang::Locale
& FormatterBase::GetLocale() const
343 if ( !mpLocaleDataWrapper
|| mbDefaultLocale
)
346 return mpField
->GetSettings().GetLocale();
348 return Application::GetSettings().GetLocale();
351 return mpLocaleDataWrapper
->getLocale();
354 // -----------------------------------------------------------------------
356 const AllSettings
& FormatterBase::GetFieldSettings() const
359 return mpField
->GetSettings();
361 return Application::GetSettings();
364 // -----------------------------------------------------------------------
366 void FormatterBase::SetFieldText( const XubString
& rText
, BOOL bKeepSelection
)
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
)
385 mpField
->SetText( rText
, *pNewSelection
);
388 Selection aSel
= mpField
->GetSelection();
389 aSel
.Min() = aSel
.Max();
390 mpField
->SetText( rText
, aSel
);
393 MarkToBeReformatted( FALSE
);
397 // -----------------------------------------------------------------------
399 void FormatterBase::SetEmptyFieldValue()
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
,
418 if ( !ImplNumericGetValue( rStr
, rValue
, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
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;
438 mnCorrectedValue
= 0;
441 rOutStr
= CreateFieldText( (sal_Int64
)nTempVal
);
446 // -----------------------------------------------------------------------
448 void NumericFormatter::ImplInit()
453 mnMax
= 0x7FFFFFFFFFFFFFFFLL
;
454 mnCorrectedValue
= 0;
456 mnType
= FORMAT_NUMERIC
;
457 mbThousandSep
= TRUE
;
458 mbShowTrailingZeros
= TRUE
;
465 SetDecimalDigits( 0 );
468 // -----------------------------------------------------------------------
470 NumericFormatter::NumericFormatter()
475 // -----------------------------------------------------------------------
477 void NumericFormatter::ImplLoadRes( const ResId
& rResId
)
479 ResMgr
* pMgr
= rResId
.GetResMgr();
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
)
520 if ( !IsEmptyFieldValue() )
524 // -----------------------------------------------------------------------
526 void NumericFormatter::SetMax( sal_Int64 nNewMax
)
529 if ( !IsEmptyFieldValue() )
533 // -----------------------------------------------------------------------
535 void NumericFormatter::SetUseThousandSep( BOOL b
)
541 // -----------------------------------------------------------------------
543 void NumericFormatter::SetDecimalDigits( USHORT nDigits
)
545 mnDecimalDigits
= nDigits
;
549 // -----------------------------------------------------------------------
551 void NumericFormatter::SetShowTrailingZeros( BOOL bShowTrailingZeros
)
553 if ( mbShowTrailingZeros
!= bShowTrailingZeros
)
555 mbShowTrailingZeros
= bShowTrailingZeros
;
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
)
589 else if ( nNewValue
< mnMin
)
591 mnLastValue
= nNewValue
;
594 ImplSetText( CreateFieldText( nNewValue
), pNewSelection
);
597 // -----------------------------------------------------------------------
599 void NumericFormatter::SetUserValue( sal_Int64 nNewValue
)
601 ImplSetUserValue( nNewValue
);
604 // -----------------------------------------------------------------------
606 sal_Int64
NumericFormatter::GetValue() const
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
;
627 // -----------------------------------------------------------------------
629 BOOL
NumericFormatter::IsValueModified() const
631 if ( ImplGetEmptyFieldValue() )
632 return !IsEmptyFieldValue();
633 else if ( GetValue() != mnFieldValue
)
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() );
669 return ((nValue
-(nFactor
/2)) / nFactor
);
671 return ((nValue
+(nFactor
/2)) / nFactor
);
674 // -----------------------------------------------------------------------
676 void NumericFormatter::Reformat()
681 if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() )
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
;
695 SetValue( mnLastValue
);
698 // -----------------------------------------------------------------------
700 void NumericFormatter::FieldUp()
702 sal_Int64 nValue
= GetValue();
703 nValue
+= mnSpinSize
;
704 if ( nValue
> mnMax
)
707 ImplNewFieldValue( nValue
);
710 // -----------------------------------------------------------------------
712 void NumericFormatter::FieldDown()
714 sal_Int64 nValue
= GetValue();
715 nValue
-= mnSpinSize
;
716 if ( 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
)
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
)
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
);
793 ImplLoadRes( rResId
);
796 if ( !(nStyle
& WB_HIDE
) )
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() ) )
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()) )
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 );
872 // -----------------------------------------------------------------------
874 void NumericField::Modify()
876 MarkToBeReformatted( TRUE
);
880 // -----------------------------------------------------------------------
882 void NumericField::Up()
888 // -----------------------------------------------------------------------
890 void NumericField::Down()
896 // -----------------------------------------------------------------------
898 void NumericField::First()
904 // -----------------------------------------------------------------------
906 void NumericField::Last()
912 // -----------------------------------------------------------------------
914 NumericBox::NumericBox( Window
* pParent
, WinBits nWinStyle
) :
915 ComboBox( pParent
, nWinStyle
)
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
);
930 ComboBox::ImplLoadRes( rResId
);
931 NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE
*)GetClassRes(), *rResId
.GetResMgr() ) );
934 if ( !(nStyle
& WB_HIDE
) )
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() ) )
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()) )
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 );
991 // -----------------------------------------------------------------------
993 void NumericBox::Modify()
995 MarkToBeReformatted( TRUE
);
999 // -----------------------------------------------------------------------
1001 void NumericBox::ReformatAll()
1005 SetUpdateMode( FALSE
);
1006 USHORT nEntryCount
= GetEntryCount();
1007 for ( USHORT i
=0; i
< nEntryCount
; i
++ )
1009 ImplNumericReformat( GetEntry( i
), nValue
, aStr
);
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
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
1054 return ImplNumericProcessKeyInput( pEdit
, rKEvt
, FALSE
, bUseThousandSep
, rWrapper
);
1057 // -----------------------------------------------------------------------
1059 static XubString
ImplMetricGetUnitText( const XubString
& rStr
)
1061 // Einheitentext holen
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 );
1078 // MT: #90545# Preparation for translated strings...
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 );
1091 if ( aMetricText.Len() )
1098 // -----------------------------------------------------------------------
1100 // #104355# support localized mesaurements
1102 static String
ImplMetricToString( FieldUnit rUnit
)
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
);
1117 static FieldUnit
ImplStringToMetric( const String
&rMetricString
)
1121 ResMgr
* pResMgr
= ImplGetResMgr();
1122 strAllUnits
= new ResStringArray( ResId (SV_FUNIT_STRINGS
, *pResMgr
) );
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"))
1138 // -----------------------------------------------------------------------
1140 static FieldUnit
ImplMetricGetUnit( const XubString
& rStr
)
1142 XubString aStr
= ImplMetricGetUnitText( rStr
);
1143 return ImplStringToMetric( aStr
);
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] =
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 }
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
)
1194 case MAP_1000TH_INCH
:
1197 case MAP_100TH_INCH
:
1200 case MAP_10TH_INCH
:
1210 DBG_ERROR( "default eInUnit" );
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) )
1273 for ( USHORT i
=0; i
< nDecDigits
; i
++ )
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
)
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 )
1300 if ( nDiv
!= 1 && nDiv
> 0 )
1302 nValue
+= ( nValue
< 0 ) ? (-nDiv
/2) : (nDiv
/2);
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" );
1327 long nDecDigits
= nDigits
;
1328 FieldUnit eFieldUnit
= ImplMap2FieldUnit( eInUnit
, nDecDigits
);
1330 if ( nDecDigits
< 0 )
1332 while ( nDecDigits
)
1341 while ( 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)
1358 if ( nDiv
!= 1 && nDiv
> 0 )
1360 nValue
+= (nValue
< 0) ? (-nDiv
/2) : (nDiv
/2);
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" );
1384 long nDecDigits
= nDigits
;
1385 FieldUnit eFieldUnit
= ImplMap2FieldUnit( eOutUnit
, nDecDigits
);
1387 if ( nDecDigits
< 0 )
1389 while ( nDecDigits
)
1397 while ( 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 )
1415 if( nDiv
!= 1 && nDiv
> 0 )
1417 nValue
+= (nValue
< 0) ? (-nDiv
/2) : (nDiv
/2);
1424 // -----------------------------------------------------------------------
1426 static BOOL
ImplMetricGetValue( const XubString
& rStr
, double& rValue
, sal_Int64 nBaseValue
,
1427 USHORT nDecDigits
, const LocaleDataWrapper
& rLocaleDataWrapper
, FieldUnit eUnit
)
1430 if ( !ImplNumericGetValue( rStr
, rValue
, nDecDigits
, rLocaleDataWrapper
) )
1433 // Einheit rausfinden
1434 FieldUnit eEntryUnit
= ImplMetricGetUnit( rStr
);
1436 // Einheiten umrechnen
1437 rValue
= MetricField::ConvertDoubleValue( rValue
, nBaseValue
, nDecDigits
, eEntryUnit
, eUnit
);
1442 // -----------------------------------------------------------------------
1444 BOOL
MetricFormatter::ImplMetricReformat( const XubString
& rStr
, double& rValue
, XubString
& rOutStr
)
1446 if ( !ImplMetricGetValue( rStr
, rValue
, mnBaseValue
, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit
) )
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;
1466 mnCorrectedValue
= 0;
1469 rOutStr
= CreateFieldText( (sal_Int64
)nTempVal
);
1474 // -----------------------------------------------------------------------
1476 inline void MetricFormatter::ImplInit()
1479 meUnit
= MetricField::GetDefaultUnit();
1480 mnType
= FORMAT_METRIC
;
1483 // -----------------------------------------------------------------------
1485 MetricFormatter::MetricFormatter()
1490 // -----------------------------------------------------------------------
1492 void MetricFormatter::ImplLoadRes( const ResId
& rResId
)
1494 NumericFormatter::ImplLoadRes( rResId
);
1496 ResMgr
* pMgr
= rResId
.GetResMgr();
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 );
1529 // -----------------------------------------------------------------------
1531 void MetricFormatter::SetCustomUnitText( const XubString
& rStr
)
1533 maCustomUnitText
= rStr
;
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
;
1554 aStr
+= ImplMetricToString( meUnit
);
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
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(),
1650 // -----------------------------------------------------------------------
1652 sal_Int64
MetricFormatter::GetBaseValue( FieldUnit eOutUnit
) const
1654 // Umrechnen auf gewuenschte Einheiten
1655 return MetricField::ConvertValue( mnBaseValue
, mnBaseValue
, GetDecimalDigits(),
1659 // -----------------------------------------------------------------------
1661 void MetricFormatter::Reformat()
1666 XubString aText
= GetField()->GetText();
1667 if ( meUnit
== FUNIT_CUSTOM
)
1668 maCurUnitText
= ImplMetricGetUnitText( aText
);
1671 // caution: precision loss in double cast
1672 double nTemp
= (double)mnLastValue
;
1673 BOOL bOK
= ImplMetricReformat( aText
, nTemp
, aStr
);
1674 mnLastValue
= (sal_Int64
)nTemp
;
1681 ImplSetText( aStr
);
1682 if ( meUnit
== FUNIT_CUSTOM
)
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(),
1699 // -----------------------------------------------------------------------
1701 MetricField::MetricField( Window
* pParent
, WinBits nWinStyle
) :
1702 SpinField( pParent
, nWinStyle
)
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
);
1717 ImplLoadRes( rResId
);
1719 if ( !(nStyle
& WB_HIDE
) )
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();
1744 // -----------------------------------------------------------------------
1746 MetricField::~MetricField()
1750 // -----------------------------------------------------------------------
1752 void MetricField::SetFirst( sal_Int64 nNewFirst
, FieldUnit eInUnit
)
1755 nNewFirst
= MetricField::ConvertValue( nNewFirst
, mnBaseValue
, GetDecimalDigits(),
1757 mnFirst
= nNewFirst
;
1760 // -----------------------------------------------------------------------
1762 sal_Int64
MetricField::GetFirst( FieldUnit eOutUnit
) const
1765 return MetricField::ConvertValue( mnFirst
, mnBaseValue
, GetDecimalDigits(),
1769 // -----------------------------------------------------------------------
1771 void MetricField::SetLast( sal_Int64 nNewLast
, FieldUnit eInUnit
)
1774 nNewLast
= MetricField::ConvertValue( nNewLast
, mnBaseValue
, GetDecimalDigits(),
1779 // -----------------------------------------------------------------------
1781 sal_Int64
MetricField::GetLast( FieldUnit eOutUnit
) const
1784 return MetricField::ConvertValue( mnLast
, mnBaseValue
, GetDecimalDigits(),
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() ) )
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()) )
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 );
1835 // -----------------------------------------------------------------------
1837 void MetricField::Modify()
1839 MarkToBeReformatted( TRUE
);
1840 SpinField::Modify();
1843 // -----------------------------------------------------------------------
1845 void MetricField::Up()
1851 // -----------------------------------------------------------------------
1853 void MetricField::Down()
1859 // -----------------------------------------------------------------------
1861 void MetricField::First()
1867 // -----------------------------------------------------------------------
1869 void MetricField::Last()
1875 // -----------------------------------------------------------------------
1877 void MetricField::CustomConvert()
1879 maCustomConvertLink
.Call( this );
1882 // -----------------------------------------------------------------------
1884 MetricBox::MetricBox( Window
* pParent
, WinBits nWinStyle
) :
1885 ComboBox( pParent
, nWinStyle
)
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
);
1901 ComboBox::ImplLoadRes( rResId
);
1902 MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE
*)GetClassRes(), *rResId
.GetResMgr() ) );
1904 if ( !(nStyle
& WB_HIDE
) )
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() ) )
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()) )
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 );
1961 // -----------------------------------------------------------------------
1963 void MetricBox::Modify()
1965 MarkToBeReformatted( TRUE
);
1969 // -----------------------------------------------------------------------
1971 void MetricBox::ReformatAll()
1975 SetUpdateMode( FALSE
);
1976 USHORT nEntryCount
= GetEntryCount();
1977 for ( USHORT i
=0; i
< nEntryCount
; i
++ )
1979 ImplMetricReformat( GetEntry( i
), nValue
, aStr
);
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(),
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(),
2011 ComboBox::RemoveEntry( CreateFieldText( nValue
) );
2014 // -----------------------------------------------------------------------
2016 sal_Int64
MetricBox::GetValue( USHORT nPos
, FieldUnit eOutUnit
) const
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(),
2029 // -----------------------------------------------------------------------
2031 USHORT
MetricBox::GetValuePos( sal_Int64 nValue
, FieldUnit eInUnit
) const
2033 // Umrechnen auf eingestellte Einheiten
2034 nValue
= MetricField::ConvertValue( nValue
, mnBaseValue
, GetDecimalDigits(),
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
2062 return ImplNumericProcessKeyInput( pEdit
, rKEvt
, FALSE
, bUseThousandSep
, rWrapper
);
2065 // -----------------------------------------------------------------------
2067 inline BOOL
ImplCurrencyGetValue( const XubString
& rStr
, double& rValue
,
2068 USHORT nDecDigits
, const LocaleDataWrapper
& rWrapper
)
2071 return ImplNumericGetValue( rStr
, rValue
, nDecDigits
, rWrapper
, TRUE
);
2074 // -----------------------------------------------------------------------
2076 BOOL
CurrencyFormatter::ImplCurrencyReformat( const XubString
& rStr
,
2077 XubString
& rOutStr
)
2080 if ( !ImplNumericGetValue( rStr
, nValue
, GetDecimalDigits(), ImplGetLocaleDataWrapper(), TRUE
) )
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;
2100 mnCorrectedValue
= 0;
2103 rOutStr
= CreateFieldText( (long)nTempVal
);
2108 // -----------------------------------------------------------------------
2110 inline void CurrencyFormatter::ImplInit()
2112 mnType
= FORMAT_CURRENCY
;
2115 // -----------------------------------------------------------------------
2117 CurrencyFormatter::CurrencyFormatter()
2122 // -----------------------------------------------------------------------
2124 CurrencyFormatter::~CurrencyFormatter()
2128 // -----------------------------------------------------------------------
2130 void CurrencyFormatter::SetCurrencySymbol( const String
& rStr
)
2132 maCurrencySymbol
= rStr
;
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
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
;
2180 // -----------------------------------------------------------------------
2182 void CurrencyFormatter::Reformat()
2188 BOOL bOK
= ImplCurrencyReformat( GetField()->GetText(), aStr
);
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
;
2201 SetValue( mnLastValue
);
2204 // -----------------------------------------------------------------------
2206 CurrencyField::CurrencyField( Window
* pParent
, WinBits nWinStyle
) :
2207 SpinField( pParent
, nWinStyle
)
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
);
2222 ImplLoadRes( rResId
);
2224 if ( !(nStyle
& WB_HIDE
) )
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();
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() ) )
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()) )
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 );
2302 // -----------------------------------------------------------------------
2304 void CurrencyField::Modify()
2306 MarkToBeReformatted( TRUE
);
2307 SpinField::Modify();
2310 // -----------------------------------------------------------------------
2312 void CurrencyField::Up()
2318 // -----------------------------------------------------------------------
2320 void CurrencyField::Down()
2326 // -----------------------------------------------------------------------
2328 void CurrencyField::First()
2334 // -----------------------------------------------------------------------
2336 void CurrencyField::Last()
2342 // -----------------------------------------------------------------------
2344 CurrencyBox::CurrencyBox( Window
* pParent
, WinBits nWinStyle
) :
2345 ComboBox( pParent
, nWinStyle
)
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() ) );
2361 ComboBox::ImplLoadRes( rResId
);
2364 if ( !(nStyle
& WB_HIDE
) )
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() ) )
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()) )
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 );
2421 // -----------------------------------------------------------------------
2423 void CurrencyBox::Modify()
2425 MarkToBeReformatted( TRUE
);
2429 // -----------------------------------------------------------------------
2431 void CurrencyBox::ReformatAll()
2434 SetUpdateMode( FALSE
);
2435 USHORT nEntryCount
= GetEntryCount();
2436 for ( USHORT i
=0; i
< nEntryCount
; i
++ )
2438 ImplCurrencyReformat( GetEntry( i
), aStr
);
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
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();