summaryrefslogtreecommitdiff
path: root/vcl/source/control/field.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/control/field.cxx')
-rw-r--r--vcl/source/control/field.cxx2506
1 files changed, 2506 insertions, 0 deletions
diff --git a/vcl/source/control/field.cxx b/vcl/source/control/field.cxx
new file mode 100644
index 000000000000..6c2b06783984
--- /dev/null
+++ b/vcl/source/control/field.cxx
@@ -0,0 +1,2506 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#ifndef _BIGINT_HXX
+#define _TOOLS_BIGINT
+#include "tools/bigint.hxx"
+#endif
+
+#include "tools/debug.hxx"
+
+#include "tools/rc.h"
+#include "tools/resary.hxx"
+#include "vcl/svids.hrc"
+#include "vcl/field.hxx"
+#include "vcl/event.hxx"
+#include "vcl/svapp.hxx"
+#include "vcl/svdata.hxx"
+#include "vcl/unohelp.hxx"
+#include "i18nutil/unicode.hxx"
+
+#include "rtl/math.hxx"
+
+
+#include <unotools/localedatawrapper.hxx>
+
+using namespace ::com::sun::star;
+
+static ResStringArray *strAllUnits = NULL;
+
+// -----------------------------------------------------------------------
+
+#define FORMAT_NUMERIC 1
+#define FORMAT_METRIC 2
+#define FORMAT_CURRENCY 3
+
+// -----------------------------------------------------------------------
+
+static sal_Int64 ImplPower10( USHORT n )
+{
+ USHORT i;
+ sal_Int64 nValue = 1;
+
+ for ( i=0; i < n; i++ )
+ nValue *= 10;
+
+ return nValue;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplNumericProcessKeyInput( Edit*, const KeyEvent& rKEvt,
+ BOOL bStrictFormat, BOOL bThousandSep,
+ const LocaleDataWrapper& rLocaleDataWrappper )
+{
+ if ( !bStrictFormat )
+ return FALSE;
+ else
+ {
+ xub_Unicode cChar = rKEvt.GetCharCode();
+ USHORT nGroup = rKEvt.GetKeyCode().GetGroup();
+
+ if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) ||
+ (nGroup == KEYGROUP_MISC) ||
+ ((cChar >= '0') && (cChar <= '9')) ||
+ (cChar == rLocaleDataWrappper.getNumDecimalSep() ) ||
+ (bThousandSep && (cChar == rLocaleDataWrappper.getNumThousandSep())) ||
+ (cChar == '-') )
+ return FALSE;
+ else
+ return TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplNumericGetValue( const XubString& rStr, double& rValue,
+ USHORT nDecDigits, const LocaleDataWrapper& rLocaleDataWrappper,
+ BOOL bCurrency = FALSE )
+{
+ XubString aStr = rStr;
+ XubString aStr1;
+ XubString aStr2;
+ BOOL bNegative = FALSE;
+ xub_StrLen nDecPos;
+ xub_StrLen i;
+
+ // Reaktion auf leeren String
+ if ( !rStr.Len() )
+ return FALSE;
+
+ // Fuehrende und nachfolgende Leerzeichen entfernen
+ aStr.EraseLeadingAndTrailingChars( ' ' );
+
+ // Position des Dezimalpunktes suchen
+ nDecPos = aStr.Search( rLocaleDataWrappper.getNumDecimalSep() );
+ if ( nDecPos != STRING_NOTFOUND )
+ {
+ aStr1 = aStr.Copy( 0, nDecPos );
+ aStr2 = aStr.Copy( nDecPos+1 );
+ }
+ else
+ aStr1 = aStr;
+
+ // Negativ ?
+ if ( bCurrency )
+ {
+ if ( (aStr.GetChar( 0 ) == '(') && (aStr.GetChar( aStr.Len()-1 ) == ')') )
+ bNegative = TRUE;
+ if ( !bNegative )
+ {
+ for ( i=0; i < aStr.Len(); i++ )
+ {
+ if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') )
+ break;
+ else if ( aStr.GetChar( i ) == '-' )
+ {
+ bNegative = TRUE;
+ break;
+ }
+ }
+ }
+ if ( !bNegative && bCurrency && aStr.Len() )
+ {
+ USHORT nFormat = rLocaleDataWrappper.getCurrNegativeFormat();
+ if ( (nFormat == 3) || (nFormat == 6) ||
+ (nFormat == 7) || (nFormat == 10) )
+ {
+ for ( i = (xub_StrLen)(aStr.Len()-1); i > 0; i++ )
+ {
+ if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') )
+ break;
+ else if ( aStr.GetChar( i ) == '-' )
+ {
+ bNegative = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( aStr1.GetChar( 0 ) == '-' )
+ bNegative = TRUE;
+ }
+
+ // Alle unerwuenschten Zeichen rauswerfen
+ for ( i=0; i < aStr1.Len(); )
+ {
+ if ( (aStr1.GetChar( i ) >= '0') && (aStr1.GetChar( i ) <= '9') )
+ i++;
+ else
+ aStr1.Erase( i, 1 );
+ }
+ for ( i=0; i < aStr2.Len(); )
+ {
+ if ( (aStr2.GetChar( i ) >= '0') && (aStr2.GetChar( i ) <= '9') )
+ i++;
+ else
+ aStr2.Erase( i, 1 );
+ }
+
+ if ( !aStr1.Len() && !aStr2.Len() )
+ return FALSE;
+
+ if ( !aStr1.Len() )
+ aStr1.Insert( '0' );
+ if ( bNegative )
+ aStr1.Insert( '-', 0 );
+
+ // Nachkommateil zurechtstutzen und dabei runden
+ BOOL bRound = FALSE;
+ if ( aStr2.Len() > nDecDigits )
+ {
+ if ( aStr2.GetChar( nDecDigits ) >= '5' )
+ bRound = TRUE;
+ aStr2.Erase( nDecDigits );
+ }
+ if ( aStr2.Len() < nDecDigits )
+ aStr2.Expand( nDecDigits, '0' );
+
+ aStr = aStr1;
+ aStr += aStr2;
+
+ // Bereichsueberpruefung
+ double nValue = aStr.ToDouble();
+ if ( bRound )
+ {
+ if ( !bNegative )
+ nValue++;
+ else
+ nValue--;
+ }
+
+ rValue = nValue;
+
+ return TRUE;
+}
+
+static void ImplUpdateSeparatorString( String& io_rText,
+ const String& rOldDecSep, const String& rNewDecSep,
+ const String& rOldThSep, const String& rNewThSep )
+{
+ rtl::OUStringBuffer aBuf( io_rText.Len() );
+ xub_StrLen nIndexDec = 0, nIndexTh = 0, nIndex = 0;
+
+ const sal_Unicode* pBuffer = io_rText.GetBuffer();
+ while( nIndex != STRING_NOTFOUND )
+ {
+ nIndexDec = io_rText.Search( rOldDecSep, nIndex );
+ nIndexTh = io_rText.Search( rOldThSep, nIndex );
+ if( (nIndexTh != STRING_NOTFOUND && nIndexDec != STRING_NOTFOUND && nIndexTh < nIndexDec )
+ || (nIndexTh != STRING_NOTFOUND && nIndexDec == STRING_NOTFOUND)
+ )
+ {
+ aBuf.append( pBuffer + nIndex, nIndexTh - nIndex );
+ aBuf.append( rNewThSep );
+ nIndex = nIndexTh + rOldThSep.Len();
+ }
+ else if( nIndexDec != STRING_NOTFOUND )
+ {
+ aBuf.append( pBuffer + nIndex, nIndexDec - nIndex );
+ aBuf.append( rNewDecSep );
+ nIndex = nIndexDec + rOldDecSep.Len();
+ }
+ else
+ {
+ aBuf.append( pBuffer + nIndex );
+ nIndex = STRING_NOTFOUND;
+ }
+ }
+
+ io_rText = aBuf.makeStringAndClear();
+}
+
+static void ImplUpdateSeparators( const String& rOldDecSep, const String& rNewDecSep,
+ const String& rOldThSep, const String& rNewThSep,
+ Edit* pEdit )
+{
+ bool bChangeDec = (rOldDecSep != rNewDecSep);
+ bool bChangeTh = (rOldThSep != rNewThSep );
+
+ if( bChangeDec || bChangeTh )
+ {
+ BOOL bUpdateMode = pEdit->IsUpdateMode();
+ pEdit->SetUpdateMode( FALSE );
+ String aText = pEdit->GetText();
+ ImplUpdateSeparatorString( aText, rOldDecSep, rNewDecSep, rOldThSep, rNewThSep );
+ pEdit->SetText( aText );
+
+ ComboBox* pCombo = dynamic_cast<ComboBox*>(pEdit);
+ if( pCombo )
+ {
+ // update box entries
+ USHORT nEntryCount = pCombo->GetEntryCount();
+ for ( USHORT i=0; i < nEntryCount; i++ )
+ {
+ aText = pCombo->GetEntry( i );
+ void* pEntryData = pCombo->GetEntryData( i );
+ ImplUpdateSeparatorString( aText, rOldDecSep, rNewDecSep, rOldThSep, rNewThSep );
+ pCombo->RemoveEntry( i );
+ pCombo->InsertEntry( aText, i );
+ pCombo->SetEntryData( i, pEntryData );
+ }
+ }
+ if( bUpdateMode )
+ pEdit->SetUpdateMode( bUpdateMode );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+FormatterBase::FormatterBase( Edit* pField )
+{
+ mpField = pField;
+ mpLocaleDataWrapper = NULL;
+ mbReformat = FALSE;
+ mbStrictFormat = FALSE;
+ mbEmptyFieldValue = FALSE;
+ mbEmptyFieldValueEnabled = FALSE;
+ mbDefaultLocale = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+FormatterBase::~FormatterBase()
+{
+ delete mpLocaleDataWrapper;
+}
+
+// -----------------------------------------------------------------------
+
+LocaleDataWrapper& FormatterBase::ImplGetLocaleDataWrapper() const
+{
+ if ( !mpLocaleDataWrapper )
+ {
+ ((FormatterBase*)this)->mpLocaleDataWrapper = new LocaleDataWrapper( vcl::unohelper::GetMultiServiceFactory(), GetLocale() );
+ }
+ return *mpLocaleDataWrapper;
+}
+
+const LocaleDataWrapper& FormatterBase::GetLocaleDataWrapper() const
+{
+ return ImplGetLocaleDataWrapper();
+}
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::Reformat()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::ReformatAll()
+{
+ Reformat();
+};
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::SetStrictFormat( BOOL bStrict )
+{
+ if ( bStrict != mbStrictFormat )
+ {
+ mbStrictFormat = bStrict;
+ if ( mbStrictFormat )
+ ReformatAll();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::SetLocale( const lang::Locale& rLocale )
+{
+ ImplGetLocaleDataWrapper().setLocale( rLocale );
+ mbDefaultLocale = FALSE;
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+const lang::Locale& FormatterBase::GetLocale() const
+{
+ if ( !mpLocaleDataWrapper || mbDefaultLocale )
+ {
+ if ( mpField )
+ return mpField->GetSettings().GetLocale();
+ else
+ return Application::GetSettings().GetLocale();
+ }
+
+ return mpLocaleDataWrapper->getLocale();
+}
+
+// -----------------------------------------------------------------------
+
+const AllSettings& FormatterBase::GetFieldSettings() const
+{
+ if ( mpField )
+ return mpField->GetSettings();
+ else
+ return Application::GetSettings();
+}
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::SetFieldText( const XubString& rText, BOOL bKeepSelection )
+{
+ if ( mpField )
+ {
+ Selection aNewSelection( 0xFFFF, 0xFFFF );
+ if ( bKeepSelection )
+ aNewSelection = mpField->GetSelection();
+
+ ImplSetText( rText, &aNewSelection );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::ImplSetText( const XubString& rText, Selection* pNewSelection )
+{
+ if ( mpField )
+ {
+ if ( pNewSelection )
+ mpField->SetText( rText, *pNewSelection );
+ else
+ {
+ Selection aSel = mpField->GetSelection();
+ aSel.Min() = aSel.Max();
+ mpField->SetText( rText, aSel );
+ }
+
+ MarkToBeReformatted( FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FormatterBase::SetEmptyFieldValue()
+{
+ if ( mpField )
+ mpField->SetText( ImplGetSVEmptyStr() );
+ mbEmptyFieldValue = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL FormatterBase::IsEmptyFieldValue() const
+{
+ return (!mpField || !mpField->GetText().Len());
+}
+
+// -----------------------------------------------------------------------
+
+BOOL NumericFormatter::ImplNumericReformat( const XubString& rStr, double& rValue,
+ XubString& rOutStr )
+{
+ if ( !ImplNumericGetValue( rStr, rValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
+ return TRUE;
+ else
+ {
+ double nTempVal = rValue;
+ // caution: precision loss in double cast
+ if ( nTempVal > mnMax )
+ nTempVal = (double)mnMax;
+ else if ( nTempVal < mnMin )
+ nTempVal = (double)mnMin;
+
+ if ( GetErrorHdl().IsSet() && (rValue != nTempVal) )
+ {
+ mnCorrectedValue = (sal_Int64)nTempVal;
+ if ( !GetErrorHdl().Call( this ) )
+ {
+ mnCorrectedValue = 0;
+ return FALSE;
+ }
+ else
+ mnCorrectedValue = 0;
+ }
+
+ rOutStr = CreateFieldText( (sal_Int64)nTempVal );
+ return TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::ImplInit()
+{
+ mnFieldValue = 0;
+ mnLastValue = 0;
+ mnMin = 0;
+ mnMax = 0x7FFFFFFFFFFFFFFFLL;
+ mnCorrectedValue = 0;
+ mnDecimalDigits = 2;
+ mnType = FORMAT_NUMERIC;
+ mbThousandSep = TRUE;
+ mbShowTrailingZeros = TRUE;
+
+ // for fields
+ mnSpinSize = 1;
+ mnFirst = mnMin;
+ mnLast = mnMax;
+
+ SetDecimalDigits( 0 );
+}
+
+// -----------------------------------------------------------------------
+
+NumericFormatter::NumericFormatter()
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::ImplLoadRes( const ResId& rResId )
+{
+ ResMgr* pMgr = rResId.GetResMgr();
+
+ if( pMgr )
+ {
+ ULONG nMask = pMgr->ReadLong();
+
+ if ( NUMERICFORMATTER_MIN & nMask )
+ mnMin = pMgr->ReadLong();
+
+ if ( NUMERICFORMATTER_MAX & nMask )
+ mnMax = pMgr->ReadLong();
+
+ if ( NUMERICFORMATTER_STRICTFORMAT & nMask )
+ SetStrictFormat( (BOOL)pMgr->ReadShort() );
+
+ if ( NUMERICFORMATTER_DECIMALDIGITS & nMask )
+ SetDecimalDigits( pMgr->ReadShort() );
+
+ if ( NUMERICFORMATTER_VALUE & nMask )
+ {
+ mnFieldValue = pMgr->ReadLong();
+ if ( mnFieldValue > mnMax )
+ mnFieldValue = mnMax;
+ else if ( mnFieldValue < mnMin )
+ mnFieldValue = mnMin;
+ mnLastValue = mnFieldValue;
+ }
+
+ if ( NUMERICFORMATTER_NOTHOUSANDSEP & nMask )
+ SetUseThousandSep( !(BOOL)pMgr->ReadShort() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+NumericFormatter::~NumericFormatter()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::SetMin( sal_Int64 nNewMin )
+{
+ mnMin = nNewMin;
+ if ( !IsEmptyFieldValue() )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::SetMax( sal_Int64 nNewMax )
+{
+ mnMax = nNewMax;
+ if ( !IsEmptyFieldValue() )
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::SetUseThousandSep( BOOL b )
+{
+ mbThousandSep = b;
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::SetDecimalDigits( USHORT nDigits )
+{
+ mnDecimalDigits = nDigits;
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::SetShowTrailingZeros( BOOL bShowTrailingZeros )
+{
+ if ( mbShowTrailingZeros != bShowTrailingZeros )
+ {
+ mbShowTrailingZeros = bShowTrailingZeros;
+ ReformatAll();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT NumericFormatter::GetDecimalDigits() const
+{
+ return mnDecimalDigits;
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::SetValue( sal_Int64 nNewValue )
+{
+ SetUserValue( nNewValue );
+ mnFieldValue = mnLastValue;
+ SetEmptyFieldValueData( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+XubString NumericFormatter::CreateFieldText( sal_Int64 nValue ) const
+{
+ return ImplGetLocaleDataWrapper().getNum( nValue, GetDecimalDigits(), IsUseThousandSep(), IsShowTrailingZeros() );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::ImplSetUserValue( sal_Int64 nNewValue, Selection* pNewSelection )
+{
+ if ( nNewValue > mnMax )
+ nNewValue = mnMax;
+ else if ( nNewValue < mnMin )
+ nNewValue = mnMin;
+ mnLastValue = nNewValue;
+
+ if ( GetField() )
+ ImplSetText( CreateFieldText( nNewValue ), pNewSelection );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::SetUserValue( sal_Int64 nNewValue )
+{
+ ImplSetUserValue( nNewValue );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 NumericFormatter::GetValue() const
+{
+ if ( !GetField() )
+ return 0;
+
+ double nTempValue;
+
+ if ( ImplNumericGetValue( GetField()->GetText(), nTempValue,
+ GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
+ {
+ // caution: precision loss in double cast
+ if ( nTempValue > mnMax )
+ nTempValue = (double)mnMax;
+ else if ( nTempValue < mnMin )
+ nTempValue = (double)mnMin;
+ return (sal_Int64)nTempValue;
+ }
+ else
+ return mnLastValue;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL NumericFormatter::IsValueModified() const
+{
+ if ( ImplGetEmptyFieldValue() )
+ return !IsEmptyFieldValue();
+ else if ( GetValue() != mnFieldValue )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Fraction NumericFormatter::ConvertToFraction( sal_Int64 nValue )
+{
+ // caution: precision loss in double cast (and in fraction anyhow)
+ return Fraction( (double)nValue/(double)ImplPower10( GetDecimalDigits() ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 NumericFormatter::ConvertToLong( const Fraction& rValue )
+{
+ Fraction aFract = rValue;
+ aFract *= Fraction( (long)ImplPower10( GetDecimalDigits() ), 1 );
+ return (sal_Int64)(double)aFract;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 NumericFormatter::Normalize( sal_Int64 nValue ) const
+{
+ return (nValue * ImplPower10( GetDecimalDigits() ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 NumericFormatter::Denormalize( sal_Int64 nValue ) const
+{
+ sal_Int64 nFactor = ImplPower10( GetDecimalDigits() );
+ if( nValue < 0 )
+ return ((nValue-(nFactor/2)) / nFactor );
+ else
+ return ((nValue+(nFactor/2)) / nFactor );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::Reformat()
+{
+ if ( !GetField() )
+ return;
+
+ if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() )
+ return;
+
+ XubString aStr;
+ // caution: precision loss in double cast
+ double nTemp = (double)mnLastValue;
+ BOOL bOK = ImplNumericReformat( GetField()->GetText(), nTemp, aStr );
+ mnLastValue = (sal_Int64)nTemp;
+ if ( !bOK )
+ return;
+
+ if ( aStr.Len() )
+ ImplSetText( aStr );
+ else
+ SetValue( mnLastValue );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::FieldUp()
+{
+ sal_Int64 nValue = GetValue();
+ nValue += mnSpinSize;
+ if ( nValue > mnMax )
+ nValue = mnMax;
+
+ ImplNewFieldValue( nValue );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::FieldDown()
+{
+ sal_Int64 nValue = GetValue();
+ nValue -= mnSpinSize;
+ if ( nValue < mnMin )
+ nValue = mnMin;
+
+ ImplNewFieldValue( nValue );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::FieldFirst()
+{
+ ImplNewFieldValue( mnFirst );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::FieldLast()
+{
+ ImplNewFieldValue( mnLast );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericFormatter::ImplNewFieldValue( sal_Int64 nNewValue )
+{
+ if ( GetField() )
+ {
+ // !!! TH-18.2.99: Wenn wir Zeit haben sollte mal geklaert werden,
+ // !!! warum nicht bei ImplSetUserValue() geprueft wird, ob
+ // !!! sich der Wert aendert. Denn auch hier muesste dieses
+ // !!! gemacht werden, da ansonsten der Modify-Aufruf
+ // !!! nicht gemacht werden duerfte. Jedenfalls sollten die
+ // !!! Wege von ImplNewFieldValue, ImplSetUserValue und
+ // !!! ImplSetText ueberprueft und klarer gestalltet (mit Kommentar)
+ // !!! werden, damit wir mal wissen, was dort ablaeuft!!!
+
+ Selection aSelection = GetField()->GetSelection();
+ aSelection.Justify();
+ XubString aText = GetField()->GetText();
+ // Wenn bis ans Ende selektiert war, soll das auch so bleiben...
+ if ( (xub_StrLen)aSelection.Max() == aText.Len() )
+ {
+ if ( !aSelection.Len() )
+ aSelection.Min() = SELECTION_MAX;
+ aSelection.Max() = SELECTION_MAX;
+ }
+
+ sal_Int64 nOldLastValue = mnLastValue;
+ ImplSetUserValue( nNewValue, &aSelection );
+ mnLastValue = nOldLastValue;
+
+ // Modify am Edit wird nur bei KeyInput gesetzt...
+ if ( GetField()->GetText() != aText )
+ {
+ GetField()->SetModifyFlag();
+ GetField()->Modify();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+NumericField::NumericField( Window* pParent, WinBits nWinStyle ) :
+ SpinField( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+NumericField::NumericField( Window* pParent, const ResId& rResId ) :
+ SpinField( WINDOW_NUMERICFIELD )
+{
+ rResId.SetRT( RSC_NUMERICFIELD );
+ WinBits nStyle = ImplInitRes( rResId ) ;
+ SpinField::ImplInit( pParent, nStyle );
+ SetField( this );
+ ImplLoadRes( rResId );
+ Reformat();
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::ImplLoadRes( const ResId& rResId )
+{
+ SpinField::ImplLoadRes( rResId );
+ NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
+
+ ULONG nMask = ReadLongRes();
+
+ if ( NUMERICFIELD_FIRST & nMask )
+ mnFirst = ReadLongRes();
+
+ if ( NUMERICFIELD_LAST & nMask )
+ mnLast = ReadLongRes();
+
+ if ( NUMERICFIELD_SPINSIZE & nMask )
+ mnSpinSize = ReadLongRes();
+}
+
+// -----------------------------------------------------------------------
+
+NumericField::~NumericField()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long NumericField::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
+ {
+ if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
+ return 1;
+ }
+
+ return SpinField::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long NumericField::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return SpinField::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ SpinField::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
+ {
+ String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
+ String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
+ if ( IsDefaultLocale() )
+ ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
+ String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
+ String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
+ ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
+ ReformatAll();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ SpinField::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::Up()
+{
+ FieldUp();
+ SpinField::Up();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::Down()
+{
+ FieldDown();
+ SpinField::Down();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::First()
+{
+ FieldFirst();
+ SpinField::First();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericField::Last()
+{
+ FieldLast();
+ SpinField::Last();
+}
+
+// -----------------------------------------------------------------------
+
+NumericBox::NumericBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+NumericBox::NumericBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( WINDOW_NUMERICBOX )
+{
+ rResId.SetRT( RSC_NUMERICBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ComboBox::ImplInit( pParent, nStyle );
+ SetField( this );
+ ComboBox::ImplLoadRes( rResId );
+ NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
+ Reformat();
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+NumericBox::~NumericBox()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long NumericBox::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
+ {
+ if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
+ return 1;
+ }
+
+ return ComboBox::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long NumericBox::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return ComboBox::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ ComboBox::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
+ {
+ String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
+ String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
+ if ( IsDefaultLocale() )
+ ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
+ String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
+ String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
+ ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
+ ReformatAll();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void NumericBox::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ ComboBox::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void NumericBox::ReformatAll()
+{
+ double nValue;
+ XubString aStr;
+ SetUpdateMode( FALSE );
+ USHORT nEntryCount = GetEntryCount();
+ for ( USHORT i=0; i < nEntryCount; i++ )
+ {
+ ImplNumericReformat( GetEntry( i ), nValue, aStr );
+ RemoveEntry( i );
+ InsertEntry( aStr, i );
+ }
+ NumericFormatter::Reformat();
+ SetUpdateMode( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericBox::InsertValue( sal_Int64 nValue, USHORT nPos )
+{
+ ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
+}
+
+// -----------------------------------------------------------------------
+
+void NumericBox::RemoveValue( sal_Int64 nValue )
+{
+ ComboBox::RemoveEntry( CreateFieldText( nValue ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 NumericBox::GetValue( USHORT nPos ) const
+{
+ double nValue = 0;
+ ImplNumericGetValue( ComboBox::GetEntry( nPos ), nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() );
+ return (sal_Int64)nValue;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT NumericBox::GetValuePos( sal_Int64 nValue ) const
+{
+ return ComboBox::GetEntryPos( CreateFieldText( nValue ) );
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplMetricProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
+ BOOL, BOOL bUseThousandSep, const LocaleDataWrapper& rWrapper )
+{
+ // Es gibt hier kein sinnvolles StrictFormat, also alle
+ // Zeichen erlauben
+ return ImplNumericProcessKeyInput( pEdit, rKEvt, FALSE, bUseThousandSep, rWrapper );
+}
+
+// -----------------------------------------------------------------------
+
+static XubString ImplMetricGetUnitText( const XubString& rStr )
+{
+ // Einheitentext holen
+ XubString aStr;
+ for ( short i = rStr.Len()-1; i >= 0; i-- )
+ {
+ xub_Unicode c = rStr.GetChar( i );
+ if ( unicode::isAlpha( c ) ||
+ (c == '\'') || (c == '\"') || (c == '%' ) )
+ aStr.Insert( c, 0 );
+ else
+ {
+ if ( aStr.Len() )
+ break;
+ }
+ }
+ return aStr;
+
+/*
+ // MT: #90545# Preparation for translated strings...
+ String aMetricText;
+ for ( USHORT n = rStr.Len(); n; )
+ {
+ sal_Unicode c = rStr.GetChar( --n );
+ sal_Int32 nType = xCharClass->getStringType( rStr, n, 1, rLocale );
+
+ if ( CharClass::isLetterType( nType ) )
+ {
+ aMetricText.Insert( c, 0 );
+ }
+ else
+ {
+ if ( aMetricText.Len() )
+ break;
+ }
+ }
+*/
+}
+
+// -----------------------------------------------------------------------
+
+// #104355# support localized mesaurements
+
+static String ImplMetricToString( FieldUnit rUnit )
+{
+ if( !strAllUnits )
+ {
+ ResMgr* pResMgr = ImplGetResMgr();
+ strAllUnits = new ResStringArray( ResId (SV_FUNIT_STRINGS, *pResMgr) );
+ }
+ // return unit's default string (ie, the first one )
+ for( USHORT i=0; i < strAllUnits->Count(); i++ )
+ if( (FieldUnit) strAllUnits->GetValue( i ) == rUnit )
+ return strAllUnits->GetString( i );
+
+ return String();
+}
+
+static FieldUnit ImplStringToMetric( const String &rMetricString )
+{
+ if( !strAllUnits )
+ {
+ ResMgr* pResMgr = ImplGetResMgr();
+ strAllUnits = new ResStringArray( ResId (SV_FUNIT_STRINGS, *pResMgr) );
+ }
+ // return FieldUnit
+ String aStr( rMetricString );
+ aStr.ToLowerAscii();
+ for( USHORT i=0; i < strAllUnits->Count(); i++ )
+ if ( strAllUnits->GetString( i ).Equals( aStr ) )
+ return (FieldUnit) strAllUnits->GetValue( i );
+
+ return FUNIT_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+static FieldUnit ImplMetricGetUnit( const XubString& rStr )
+{
+ XubString aStr = ImplMetricGetUnitText( rStr );
+ return ImplStringToMetric( aStr );
+}
+
+#define K *1000L
+#define M *1000000L
+#define X *5280L
+
+static const sal_Int64 aImplFactor[FUNIT_MILE+1][FUNIT_MILE+1] =
+{ /*
+mm/100 mm cm m km twip point pica inch foot mile */
+{ 1, 100, 1 K, 100 K, 100 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X },
+{ 1, 1, 10, 1 K, 1 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X },
+{ 1, 1, 1, 100, 100 K, 254, 254, 254, 254, 254*12, 254*12 X },
+{ 1, 1, 1, 1, 1 K, 254, 254, 254, 254, 254*12, 254*12 X },
+{ 1, 1, 1, 1, 1, 0, 254, 254, 254, 254*12, 254*12 X },
+{ 1440,144 K,144 K,14400 K, 0, 1, 20, 240, 1440,1440*12,1440*12 X },
+{ 72, 7200, 7200, 720 K, 720 M, 1, 1, 12, 72, 72*12, 72*12 X },
+{ 6, 600, 600, 60 K, 60 M, 1, 1, 1, 6, 6*12, 6*12 X },
+{ 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 12, 12 X },
+{ 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 X },
+{ 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 }
+};
+
+#undef X
+#undef M
+#undef K
+// twip in km 254/14400 M
+
+static FieldUnit eDefaultUnit = FUNIT_NONE;
+
+FieldUnit MetricField::GetDefaultUnit() { return eDefaultUnit; }
+void MetricField::SetDefaultUnit( FieldUnit meUnit ) { eDefaultUnit = meUnit; }
+
+static FieldUnit ImplMap2FieldUnit( MapUnit meUnit, long& nDecDigits )
+{
+ switch( meUnit )
+ {
+ case MAP_100TH_MM :
+ nDecDigits -= 2;
+ return FUNIT_MM;
+ case MAP_10TH_MM :
+ nDecDigits -= 1;
+ return FUNIT_MM;
+ case MAP_MM :
+ return FUNIT_MM;
+ case MAP_CM :
+ return FUNIT_CM;
+ case MAP_1000TH_INCH :
+ nDecDigits -= 3;
+ return FUNIT_INCH;
+ case MAP_100TH_INCH :
+ nDecDigits -= 2;
+ return FUNIT_INCH;
+ case MAP_10TH_INCH :
+ nDecDigits -= 1;
+ return FUNIT_INCH;
+ case MAP_INCH :
+ return FUNIT_INCH;
+ case MAP_POINT :
+ return FUNIT_POINT;
+ case MAP_TWIP :
+ return FUNIT_TWIP;
+ default:
+ DBG_ERROR( "default eInUnit" );
+ break;
+ }
+ return FUNIT_NONE;
+}
+
+// -----------------------------------------------------------------------
+
+static double nonValueDoubleToValueDouble( double nValue )
+{
+ return rtl::math::isFinite( nValue ) ? nValue : 0.0;
+}
+
+sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_Int64 mnBaseValue, USHORT nDecDigits,
+ FieldUnit eInUnit, FieldUnit eOutUnit )
+{
+ // caution: precision loss in double cast
+ return static_cast<sal_Int64>(
+ // #150733# cast double to sal_Int64 can throw a
+ // EXCEPTION_FLT_INVALID_OPERATION on Windows
+ nonValueDoubleToValueDouble(
+ ConvertDoubleValue( (double)nValue, mnBaseValue, nDecDigits,
+ eInUnit, eOutUnit ) ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, USHORT nDigits,
+ MapUnit eInUnit, FieldUnit eOutUnit )
+{
+ return static_cast<sal_Int64>(
+ // #150733# cast double to sal_Int64 can throw a
+ // EXCEPTION_FLT_INVALID_OPERATION on Windows
+ nonValueDoubleToValueDouble(
+ ConvertDoubleValue( nValue, nDigits, eInUnit, eOutUnit ) ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, USHORT nDigits,
+ FieldUnit eInUnit, MapUnit eOutUnit )
+{
+ return static_cast<sal_Int64>(
+ // #150733# cast double to sal_Int64 can throw a
+ // EXCEPTION_FLT_INVALID_OPERATION on Windows
+ nonValueDoubleToValueDouble(
+ ConvertDoubleValue( nValue, nDigits, eInUnit, eOutUnit ) ) );
+}
+
+// -----------------------------------------------------------------------
+
+double MetricField::ConvertDoubleValue( double nValue, sal_Int64 mnBaseValue, USHORT nDecDigits,
+ FieldUnit eInUnit, FieldUnit eOutUnit )
+{
+ if ( eInUnit != eOutUnit )
+ {
+ sal_Int64 nMult = 1, nDiv = 1;
+
+ if ( eInUnit == FUNIT_PERCENT )
+ {
+ if ( (mnBaseValue <= 0) || (nValue <= 0) )
+ return nValue;
+ nDiv = 100;
+ for ( USHORT i=0; i < nDecDigits; i++ )
+ nDiv *= 10;
+
+ nMult = mnBaseValue;
+ }
+ else if ( eOutUnit == FUNIT_PERCENT ||
+ eOutUnit == FUNIT_CUSTOM ||
+ eOutUnit == FUNIT_NONE ||
+ eInUnit == FUNIT_CUSTOM ||
+ eInUnit == FUNIT_NONE )
+ return nValue;
+ else
+ {
+ if ( eOutUnit == FUNIT_100TH_MM )
+ eOutUnit = FUNIT_NONE;
+ if ( eInUnit == FUNIT_100TH_MM )
+ eInUnit = FUNIT_NONE;
+
+ nDiv = aImplFactor[eInUnit][eOutUnit];
+ nMult = aImplFactor[eOutUnit][eInUnit];
+
+ DBG_ASSERT( nMult > 0, "illegal *" );
+ DBG_ASSERT( nDiv > 0, "illegal /" );
+ }
+
+ if ( nMult != 1 && nMult > 0 )
+ nValue *= nMult;
+ if ( nDiv != 1 && nDiv > 0 )
+ {
+ nValue += ( nValue < 0 ) ? (-nDiv/2) : (nDiv/2);
+ nValue /= nDiv;
+ }
+ }
+
+ return nValue;
+}
+
+// -----------------------------------------------------------------------
+
+double MetricField::ConvertDoubleValue( double nValue, USHORT nDigits,
+ MapUnit eInUnit, FieldUnit eOutUnit )
+{
+ if ( eOutUnit == FUNIT_PERCENT ||
+ eOutUnit == FUNIT_CUSTOM ||
+ eOutUnit == FUNIT_NONE ||
+ eInUnit == MAP_PIXEL ||
+ eInUnit == MAP_SYSFONT ||
+ eInUnit == MAP_APPFONT ||
+ eInUnit == MAP_RELATIVE )
+ {
+ DBG_ERROR( "invalid parameters" );
+ return nValue;
+ }
+
+ long nDecDigits = nDigits;
+ FieldUnit eFieldUnit = ImplMap2FieldUnit( eInUnit, nDecDigits );
+
+ if ( nDecDigits < 0 )
+ {
+ while ( nDecDigits )
+ {
+ nValue += 5;
+ nValue /= 10;
+ nDecDigits++;
+ }
+ }
+ else
+ {
+ while ( nDecDigits )
+ {
+ nValue *= 10;
+ nDecDigits--;
+ }
+ }
+
+ if ( eFieldUnit != eOutUnit )
+ {
+ sal_Int64 nDiv = aImplFactor[eFieldUnit][eOutUnit];
+ sal_Int64 nMult = aImplFactor[eOutUnit][eFieldUnit];
+
+ DBG_ASSERT( nMult > 0, "illegal *" );
+ DBG_ASSERT( nDiv > 0, "illegal /" );
+
+ if ( nMult != 1 && nMult > 0)
+ nValue *= nMult;
+ if ( nDiv != 1 && nDiv > 0 )
+ {
+ nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2);
+ nValue /= nDiv;
+ }
+ }
+ return nValue;
+}
+
+// -----------------------------------------------------------------------
+
+double MetricField::ConvertDoubleValue( double nValue, USHORT nDigits,
+ FieldUnit eInUnit, MapUnit eOutUnit )
+{
+ if ( eInUnit == FUNIT_PERCENT ||
+ eInUnit == FUNIT_CUSTOM ||
+ eInUnit == FUNIT_NONE ||
+ eOutUnit == MAP_PIXEL ||
+ eOutUnit == MAP_SYSFONT ||
+ eOutUnit == MAP_APPFONT ||
+ eOutUnit == MAP_RELATIVE )
+ {
+ DBG_ERROR( "invalid parameters" );
+ return nValue;
+ }
+
+ long nDecDigits = nDigits;
+ FieldUnit eFieldUnit = ImplMap2FieldUnit( eOutUnit, nDecDigits );
+
+ if ( nDecDigits < 0 )
+ {
+ while ( nDecDigits )
+ {
+ nValue *= 10;
+ nDecDigits++;
+ }
+ }
+ else
+ {
+ while ( nDecDigits )
+ {
+ nValue += 5;
+ nValue /= 10;
+ nDecDigits--;
+ }
+ }
+
+ if ( eFieldUnit != eInUnit )
+ {
+ sal_Int64 nDiv = aImplFactor[eInUnit][eFieldUnit];
+ sal_Int64 nMult = aImplFactor[eFieldUnit][eInUnit];
+
+ DBG_ASSERT( nMult > 0, "illegal *" );
+ DBG_ASSERT( nDiv > 0, "illegal /" );
+
+ if( nMult != 1 && nMult > 0 )
+ nValue *= nMult;
+ if( nDiv != 1 && nDiv > 0 )
+ {
+ nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2);
+ nValue /= nDiv;
+ }
+ }
+ return nValue;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplMetricGetValue( const XubString& rStr, double& rValue, sal_Int64 nBaseValue,
+ USHORT nDecDigits, const LocaleDataWrapper& rLocaleDataWrapper, FieldUnit eUnit )
+{
+ // Zahlenwert holen
+ if ( !ImplNumericGetValue( rStr, rValue, nDecDigits, rLocaleDataWrapper ) )
+ return FALSE;
+
+ // Einheit rausfinden
+ FieldUnit eEntryUnit = ImplMetricGetUnit( rStr );
+
+ // Einheiten umrechnen
+ rValue = MetricField::ConvertDoubleValue( rValue, nBaseValue, nDecDigits, eEntryUnit, eUnit );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL MetricFormatter::ImplMetricReformat( const XubString& rStr, double& rValue, XubString& rOutStr )
+{
+ if ( !ImplMetricGetValue( rStr, rValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) )
+ return TRUE;
+ else
+ {
+ double nTempVal = rValue;
+ // caution: precision loss in double cast
+ if ( nTempVal > GetMax() )
+ nTempVal = (double)GetMax();
+ else if ( nTempVal < GetMin())
+ nTempVal = (double)GetMin();
+
+ if ( GetErrorHdl().IsSet() && (rValue != nTempVal) )
+ {
+ mnCorrectedValue = (sal_Int64)nTempVal;
+ if ( !GetErrorHdl().Call( this ) )
+ {
+ mnCorrectedValue = 0;
+ return FALSE;
+ }
+ else
+ mnCorrectedValue = 0;
+ }
+
+ rOutStr = CreateFieldText( (sal_Int64)nTempVal );
+ return TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+inline void MetricFormatter::ImplInit()
+{
+ mnBaseValue = 0;
+ meUnit = MetricField::GetDefaultUnit();
+ mnType = FORMAT_METRIC;
+}
+
+// -----------------------------------------------------------------------
+
+MetricFormatter::MetricFormatter()
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::ImplLoadRes( const ResId& rResId )
+{
+ NumericFormatter::ImplLoadRes( rResId );
+
+ ResMgr* pMgr = rResId.GetResMgr();
+ if( pMgr )
+ {
+ ULONG nMask = pMgr->ReadLong();
+
+ if ( METRICFORMATTER_UNIT & nMask )
+ meUnit = (FieldUnit)pMgr->ReadLong();
+
+ if ( METRICFORMATTER_CUSTOMUNITTEXT & nMask )
+ maCustomUnitText = pMgr->ReadString();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+MetricFormatter::~MetricFormatter()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetUnit( FieldUnit eNewUnit )
+{
+ if ( eNewUnit == FUNIT_100TH_MM )
+ {
+ SetDecimalDigits( GetDecimalDigits() + 2 );
+ meUnit = FUNIT_MM;
+ }
+ else
+ meUnit = eNewUnit;
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetCustomUnitText( const XubString& rStr )
+{
+ maCustomUnitText = rStr;
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetValue( sal_Int64 nNewValue, FieldUnit eInUnit )
+{
+ SetUserValue( nNewValue, eInUnit );
+ mnFieldValue = mnLastValue;
+}
+
+// -----------------------------------------------------------------------
+
+XubString MetricFormatter::CreateFieldText( sal_Int64 nValue ) const
+{
+ XubString aStr = NumericFormatter::CreateFieldText( nValue );
+
+ if( meUnit == FUNIT_CUSTOM )
+ aStr += maCustomUnitText;
+ else
+ aStr += ImplMetricToString( meUnit );
+
+ return aStr;
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit )
+{
+ // Umrechnen auf eingestellte Einheiten
+ nNewValue = MetricField::ConvertValue( nNewValue, mnBaseValue, GetDecimalDigits(), eInUnit, meUnit );
+ NumericFormatter::SetUserValue( nNewValue );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 MetricFormatter::GetValue( FieldUnit eOutUnit ) const
+{
+ if ( !GetField() )
+ return 0;
+
+ double nTempValue;
+ // caution: precision loss in double cast
+ if ( !ImplMetricGetValue( GetField()->GetText(), nTempValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) )
+ nTempValue = (double)mnLastValue;
+
+ // caution: precision loss in double cast
+ if ( nTempValue > mnMax )
+ nTempValue = (double)mnMax;
+ else if ( nTempValue < mnMin )
+ nTempValue = (double)mnMin;
+
+ // Umrechnen auf gewuenschte Einheiten
+ return MetricField::ConvertValue( (sal_Int64)nTempValue, mnBaseValue, GetDecimalDigits(), meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetValue( sal_Int64 nValue )
+{
+ // Implementation not inline, because it is a virtual Function
+ SetValue( nValue, FUNIT_NONE );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 MetricFormatter::GetValue() const
+{
+ // Implementation not inline, because it is a virtual Function
+ return GetValue( FUNIT_NONE );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetMin( sal_Int64 nNewMin, FieldUnit eInUnit )
+{
+ // Umrechnen auf gewuenschte Einheiten
+ NumericFormatter::SetMin( MetricField::ConvertValue( nNewMin, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 MetricFormatter::GetMin( FieldUnit eOutUnit ) const
+{
+ // Umrechnen auf gewuenschte Einheiten
+ return MetricField::ConvertValue( NumericFormatter::GetMin(), mnBaseValue,
+ GetDecimalDigits(), meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetMax( sal_Int64 nNewMax, FieldUnit eInUnit )
+{
+ // Umrechnen auf gewuenschte Einheiten
+ NumericFormatter::SetMax( MetricField::ConvertValue( nNewMax, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 MetricFormatter::GetMax( FieldUnit eOutUnit ) const
+{
+ // Umrechnen auf gewuenschte Einheiten
+ return MetricField::ConvertValue( NumericFormatter::GetMax(), mnBaseValue,
+ GetDecimalDigits(), meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::SetBaseValue( sal_Int64 nNewBase, FieldUnit eInUnit )
+{
+ mnBaseValue = MetricField::ConvertValue( nNewBase, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 MetricFormatter::GetBaseValue( FieldUnit eOutUnit ) const
+{
+ // Umrechnen auf gewuenschte Einheiten
+ return MetricField::ConvertValue( mnBaseValue, mnBaseValue, GetDecimalDigits(),
+ meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricFormatter::Reformat()
+{
+ if ( !GetField() )
+ return;
+
+ XubString aText = GetField()->GetText();
+ if ( meUnit == FUNIT_CUSTOM )
+ maCurUnitText = ImplMetricGetUnitText( aText );
+
+ XubString aStr;
+ // caution: precision loss in double cast
+ double nTemp = (double)mnLastValue;
+ BOOL bOK = ImplMetricReformat( aText, nTemp, aStr );
+ mnLastValue = (sal_Int64)nTemp;
+
+ if ( !bOK )
+ return;
+
+ if ( aStr.Len() )
+ {
+ ImplSetText( aStr );
+ if ( meUnit == FUNIT_CUSTOM )
+ CustomConvert();
+ }
+ else
+ SetValue( mnLastValue );
+ maCurUnitText.Erase();
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 MetricFormatter::GetCorrectedValue( FieldUnit eOutUnit ) const
+{
+ // Umrechnen auf gewuenschte Einheiten
+ return MetricField::ConvertValue( mnCorrectedValue, mnBaseValue, GetDecimalDigits(),
+ meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+MetricField::MetricField( Window* pParent, WinBits nWinStyle ) :
+ SpinField( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+MetricField::MetricField( Window* pParent, const ResId& rResId ) :
+ SpinField( WINDOW_METRICFIELD )
+{
+ rResId.SetRT( RSC_METRICFIELD );
+ WinBits nStyle = ImplInitRes( rResId ) ;
+ SpinField::ImplInit( pParent, nStyle );
+ SetField( this );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::ImplLoadRes( const ResId& rResId )
+{
+ SpinField::ImplLoadRes( rResId );
+ MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
+
+ ULONG nMask = ReadLongRes();
+
+ if ( METRICFIELD_FIRST & nMask )
+ mnFirst = ReadLongRes();
+
+ if ( METRICFIELD_LAST & nMask )
+ mnLast = ReadLongRes();
+
+ if ( METRICFIELD_SPINSIZE & nMask )
+ mnSpinSize = ReadLongRes();
+
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+MetricField::~MetricField()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::SetFirst( sal_Int64 nNewFirst, FieldUnit eInUnit )
+{
+ // convert
+ nNewFirst = MetricField::ConvertValue( nNewFirst, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit );
+ mnFirst = nNewFirst;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 MetricField::GetFirst( FieldUnit eOutUnit ) const
+{
+ // convert
+ return MetricField::ConvertValue( mnFirst, mnBaseValue, GetDecimalDigits(),
+ meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::SetLast( sal_Int64 nNewLast, FieldUnit eInUnit )
+{
+ // Umrechnen
+ nNewLast = MetricField::ConvertValue( nNewLast, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit );
+ mnLast = nNewLast;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 MetricField::GetLast( FieldUnit eOutUnit ) const
+{
+ // Umrechnen
+ return MetricField::ConvertValue( mnLast, mnBaseValue, GetDecimalDigits(),
+ meUnit, eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+long MetricField::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
+ {
+ if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
+ return 1;
+ }
+
+ return SpinField::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long MetricField::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return SpinField::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ SpinField::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
+ {
+ String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
+ String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
+ if ( IsDefaultLocale() )
+ ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
+ String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
+ String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
+ ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
+ ReformatAll();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ SpinField::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::Up()
+{
+ FieldUp();
+ SpinField::Up();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::Down()
+{
+ FieldDown();
+ SpinField::Down();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::First()
+{
+ FieldFirst();
+ SpinField::First();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::Last()
+{
+ FieldLast();
+ SpinField::Last();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricField::CustomConvert()
+{
+ maCustomConvertLink.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+MetricBox::MetricBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+MetricBox::MetricBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( WINDOW_METRICBOX )
+{
+ rResId.SetRT( RSC_METRICBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ComboBox::ImplInit( pParent, nStyle );
+ SetField( this );
+ Reformat();
+ ComboBox::ImplLoadRes( rResId );
+ MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+MetricBox::~MetricBox()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long MetricBox::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
+ {
+ if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
+ return 1;
+ }
+
+ return ComboBox::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long MetricBox::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return ComboBox::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ ComboBox::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
+ {
+ String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
+ String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
+ if ( IsDefaultLocale() )
+ ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
+ String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
+ String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
+ ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
+ ReformatAll();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void MetricBox::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ ComboBox::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void MetricBox::ReformatAll()
+{
+ double nValue;
+ XubString aStr;
+ SetUpdateMode( FALSE );
+ USHORT nEntryCount = GetEntryCount();
+ for ( USHORT i=0; i < nEntryCount; i++ )
+ {
+ ImplMetricReformat( GetEntry( i ), nValue, aStr );
+ RemoveEntry( i );
+ InsertEntry( aStr, i );
+ }
+ MetricFormatter::Reformat();
+ SetUpdateMode( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricBox::CustomConvert()
+{
+ maCustomConvertLink.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricBox::InsertValue( sal_Int64 nValue, FieldUnit eInUnit, USHORT nPos )
+{
+ // Umrechnen auf eingestellte Einheiten
+ nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit );
+ ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
+}
+
+// -----------------------------------------------------------------------
+
+void MetricBox::RemoveValue( sal_Int64 nValue, FieldUnit eInUnit )
+{
+ // Umrechnen auf eingestellte Einheiten
+ nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit );
+ ComboBox::RemoveEntry( CreateFieldText( nValue ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 MetricBox::GetValue( USHORT nPos, FieldUnit eOutUnit ) const
+{
+ double nValue = 0;
+ ImplMetricGetValue( ComboBox::GetEntry( nPos ), nValue, mnBaseValue,
+ GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit );
+
+ // Umrechnen auf eingestellte Einheiten
+ sal_Int64 nRetValue = MetricField::ConvertValue( (sal_Int64)nValue, mnBaseValue, GetDecimalDigits(),
+ meUnit, eOutUnit );
+
+ return nRetValue;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT MetricBox::GetValuePos( sal_Int64 nValue, FieldUnit eInUnit ) const
+{
+ // Umrechnen auf eingestellte Einheiten
+ nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
+ eInUnit, meUnit );
+ return ComboBox::GetEntryPos( CreateFieldText( nValue ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 MetricBox::GetValue( FieldUnit eOutUnit ) const
+{
+ // Implementation not inline, because it is a virtual Function
+ return MetricFormatter::GetValue( eOutUnit );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 MetricBox::GetValue() const
+{
+ // Implementation not inline, because it is a virtual Function
+ return GetValue( FUNIT_NONE );
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplCurrencyProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
+ BOOL, BOOL bUseThousandSep, const LocaleDataWrapper& rWrapper )
+{
+ // Es gibt hier kein sinnvolles StrictFormat, also alle
+ // Zeichen erlauben
+ return ImplNumericProcessKeyInput( pEdit, rKEvt, FALSE, bUseThousandSep, rWrapper );
+}
+
+// -----------------------------------------------------------------------
+
+inline BOOL ImplCurrencyGetValue( const XubString& rStr, double& rValue,
+ USHORT nDecDigits, const LocaleDataWrapper& rWrapper )
+{
+ // Zahlenwert holen
+ return ImplNumericGetValue( rStr, rValue, nDecDigits, rWrapper, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL CurrencyFormatter::ImplCurrencyReformat( const XubString& rStr,
+ XubString& rOutStr )
+{
+ double nValue;
+ if ( !ImplNumericGetValue( rStr, nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), TRUE ) )
+ return TRUE;
+ else
+ {
+ double nTempVal = nValue;
+ // caution: precision loss in double cast
+ if ( nTempVal > GetMax() )
+ nTempVal = (double)GetMax();
+ else if ( nTempVal < GetMin())
+ nTempVal = (double)GetMin();
+
+ if ( GetErrorHdl().IsSet() && (nValue != nTempVal) )
+ {
+ mnCorrectedValue = (sal_Int64)nTempVal;
+ if ( !GetErrorHdl().Call( this ) )
+ {
+ mnCorrectedValue = 0;
+ return FALSE;
+ }
+ else
+ mnCorrectedValue = 0;
+ }
+
+ rOutStr = CreateFieldText( (long)nTempVal );
+ return TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+inline void CurrencyFormatter::ImplInit()
+{
+ mnType = FORMAT_CURRENCY;
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyFormatter::CurrencyFormatter()
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyFormatter::~CurrencyFormatter()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyFormatter::SetCurrencySymbol( const String& rStr )
+{
+ maCurrencySymbol= rStr;
+ ReformatAll();
+}
+
+// -----------------------------------------------------------------------
+
+String CurrencyFormatter::GetCurrencySymbol() const
+{
+ return maCurrencySymbol.Len() ? maCurrencySymbol : ImplGetLocaleDataWrapper().getCurrSymbol();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyFormatter::SetValue( sal_Int64 nNewValue )
+{
+ SetUserValue( nNewValue );
+ mnFieldValue = mnLastValue;
+ SetEmptyFieldValueData( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+XubString CurrencyFormatter::CreateFieldText( sal_Int64 nValue ) const
+{
+ return ImplGetLocaleDataWrapper().getCurr( nValue, GetDecimalDigits(), GetCurrencySymbol(), IsUseThousandSep() );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 CurrencyFormatter::GetValue() const
+{
+ if ( !GetField() )
+ return 0;
+
+ double nTempValue;
+ if ( ImplCurrencyGetValue( GetField()->GetText(), nTempValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
+ {
+ // caution: precision loss in double cast
+ if ( nTempValue > mnMax )
+ nTempValue = (double)mnMax;
+ else if ( nTempValue < mnMin )
+ nTempValue = (double)mnMin;
+ return (sal_Int64)nTempValue;
+ }
+ else
+ return mnLastValue;
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyFormatter::Reformat()
+{
+ if ( !GetField() )
+ return;
+
+ XubString aStr;
+ BOOL bOK = ImplCurrencyReformat( GetField()->GetText(), aStr );
+ if ( !bOK )
+ return;
+
+ if ( aStr.Len() )
+ {
+ ImplSetText( aStr );
+ // caution: precision loss in double cast
+ double nTemp = (double)mnLastValue;
+ ImplCurrencyGetValue( aStr, nTemp, GetDecimalDigits(), ImplGetLocaleDataWrapper() );
+ mnLastValue = (sal_Int64)nTemp;
+ }
+ else
+ SetValue( mnLastValue );
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyField::CurrencyField( Window* pParent, WinBits nWinStyle ) :
+ SpinField( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyField::CurrencyField( Window* pParent, const ResId& rResId ) :
+ SpinField( WINDOW_CURRENCYFIELD )
+{
+ rResId.SetRT( RSC_CURRENCYFIELD );
+ WinBits nStyle = ImplInitRes( rResId );
+ SpinField::ImplInit( pParent, nStyle);
+ SetField( this );
+ ImplLoadRes( rResId );
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::ImplLoadRes( const ResId& rResId )
+{
+ SpinField::ImplLoadRes( rResId );
+ CurrencyFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
+
+ ULONG nMask = ReadLongRes();
+
+ if ( CURRENCYFIELD_FIRST & nMask )
+ mnFirst = ReadLongRes();
+
+ if ( CURRENCYFIELD_LAST & nMask )
+ mnLast = ReadLongRes();
+
+ if ( CURRENCYFIELD_SPINSIZE & nMask )
+ mnSpinSize = ReadLongRes();
+
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyField::~CurrencyField()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long CurrencyField::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
+ {
+ if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
+ return 1;
+ }
+
+ return SpinField::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long CurrencyField::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return SpinField::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ SpinField::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
+ {
+ String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
+ String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
+ if ( IsDefaultLocale() )
+ ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
+ String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
+ String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
+ ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
+ ReformatAll();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ SpinField::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::Up()
+{
+ FieldUp();
+ SpinField::Up();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::Down()
+{
+ FieldDown();
+ SpinField::Down();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::First()
+{
+ FieldFirst();
+ SpinField::First();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyField::Last()
+{
+ FieldLast();
+ SpinField::Last();
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyBox::CurrencyBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle )
+{
+ SetField( this );
+ Reformat();
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyBox::CurrencyBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( WINDOW_CURRENCYBOX )
+{
+ rResId.SetRT( RSC_CURRENCYBOX );
+ WinBits nStyle = ImplInitRes( rResId );
+ ComboBox::ImplInit( pParent, nStyle );
+ CurrencyFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
+ SetField( this );
+ ComboBox::ImplLoadRes( rResId );
+ Reformat();
+
+ if ( !(nStyle & WB_HIDE ) )
+ Show();
+}
+
+// -----------------------------------------------------------------------
+
+CurrencyBox::~CurrencyBox()
+{
+}
+
+// -----------------------------------------------------------------------
+
+long CurrencyBox::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
+ {
+ if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
+ return 1;
+ }
+
+ return ComboBox::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+long CurrencyBox::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_GETFOCUS )
+ MarkToBeReformatted( FALSE );
+ else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
+ {
+ if ( MustBeReformatted() && (GetText().Len() || !IsEmptyFieldValueEnabled()) )
+ Reformat();
+ }
+
+ return ComboBox::Notify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ ComboBox::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
+ {
+ String sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
+ String sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
+ if ( IsDefaultLocale() )
+ ImplGetLocaleDataWrapper().setLocale( GetSettings().GetLocale() );
+ String sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
+ String sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
+ ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
+ ReformatAll();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyBox::Modify()
+{
+ MarkToBeReformatted( TRUE );
+ ComboBox::Modify();
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyBox::ReformatAll()
+{
+ XubString aStr;
+ SetUpdateMode( FALSE );
+ USHORT nEntryCount = GetEntryCount();
+ for ( USHORT i=0; i < nEntryCount; i++ )
+ {
+ ImplCurrencyReformat( GetEntry( i ), aStr );
+ RemoveEntry( i );
+ InsertEntry( aStr, i );
+ }
+ CurrencyFormatter::Reformat();
+ SetUpdateMode( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyBox::InsertValue( sal_Int64 nValue, USHORT nPos )
+{
+ ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
+}
+
+// -----------------------------------------------------------------------
+
+void CurrencyBox::RemoveValue( sal_Int64 nValue )
+{
+ ComboBox::RemoveEntry( CreateFieldText( nValue ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 CurrencyBox::GetValue( USHORT nPos ) const
+{
+ double nValue = 0;
+ ImplCurrencyGetValue( ComboBox::GetEntry( nPos ), nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() );
+ return (sal_Int64)nValue;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT CurrencyBox::GetValuePos( sal_Int64 nValue ) const
+{
+ return ComboBox::GetEntryPos( CreateFieldText( nValue ) );
+}
+
+// -----------------------------------------------------------------------
+
+sal_Int64 CurrencyBox::GetValue() const
+{
+ // Implementation not inline, because it is a virtual Function
+ return CurrencyFormatter::GetValue();
+}