LCOV - code coverage report
Current view: top level - vcl/source/control - field.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1175 0.0 %
Date: 2014-04-14 Functions: 0 178 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "sal/config.h"
      21             : 
      22             : #include <comphelper/processfactory.hxx>
      23             : #include <comphelper/string.hxx>
      24             : 
      25             : #include "tools/debug.hxx"
      26             : 
      27             : #include "tools/rc.h"
      28             : 
      29             : #include "vcl/dialog.hxx"
      30             : #include "vcl/field.hxx"
      31             : #include "vcl/event.hxx"
      32             : #include "vcl/svapp.hxx"
      33             : #include "vcl/settings.hxx"
      34             : 
      35             : #include "svids.hrc"
      36             : #include "svdata.hxx"
      37             : 
      38             : #include "i18nutil/unicode.hxx"
      39             : 
      40             : #include "rtl/math.hxx"
      41             : 
      42             : #include <unotools/localedatawrapper.hxx>
      43             : 
      44             : using namespace ::com::sun::star;
      45             : using namespace ::comphelper;
      46             : 
      47             : namespace
      48             : {
      49             : 
      50             : #define FORMAT_NUMERIC       1
      51             : #define FORMAT_METRIC        2
      52             : #define FORMAT_CURRENCY      3
      53             : 
      54           0 : static sal_Int64 ImplPower10( sal_uInt16 n )
      55             : {
      56             :     sal_uInt16  i;
      57           0 :     sal_Int64   nValue = 1;
      58             : 
      59           0 :     for ( i=0; i < n; i++ )
      60           0 :         nValue *= 10;
      61             : 
      62           0 :     return nValue;
      63             : }
      64             : 
      65           0 : static bool ImplNumericProcessKeyInput( Edit*, const KeyEvent& rKEvt,
      66             :                                         bool bStrictFormat, bool bThousandSep,
      67             :                                         const LocaleDataWrapper& rLocaleDataWrappper )
      68             : {
      69           0 :     if ( !bStrictFormat )
      70           0 :         return false;
      71             :     else
      72             :     {
      73           0 :         sal_Unicode cChar = rKEvt.GetCharCode();
      74           0 :         sal_uInt16      nGroup = rKEvt.GetKeyCode().GetGroup();
      75             : 
      76           0 :         if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) ||
      77           0 :              (nGroup == KEYGROUP_MISC) ||
      78           0 :              ((cChar >= '0') && (cChar <= '9')) ||
      79           0 :              string::equals(rLocaleDataWrappper.getNumDecimalSep(), cChar) ||
      80           0 :              (bThousandSep && string::equals(rLocaleDataWrappper.getNumThousandSep(), cChar)) ||
      81             :              (cChar == '-') )
      82           0 :             return false;
      83             :         else
      84           0 :             return true;
      85             :     }
      86             : }
      87             : 
      88           0 : static bool ImplNumericGetValue( const OUString& rStr, sal_Int64& rValue,
      89             :                                  sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrappper,
      90             :                                  bool bCurrency = false )
      91             : {
      92           0 :     OUString            aStr = rStr;
      93           0 :     OUStringBuffer aStr1, aStr2;
      94           0 :     bool                bNegative = false;
      95             :     sal_Int32           nDecPos;
      96             : 
      97             :     // react on empty string
      98           0 :     if ( rStr.isEmpty() )
      99           0 :         return false;
     100             : 
     101             :     // remove leading and trailing spaces
     102           0 :     aStr = aStr.trim();
     103             : 
     104             :     // find position of decimal point
     105           0 :     nDecPos = aStr.indexOf( rLocaleDataWrappper.getNumDecimalSep() );
     106           0 :     if ( nDecPos >= 0)
     107             :     {
     108           0 :         aStr1.append(aStr.getStr(), nDecPos);
     109           0 :         aStr2.append(aStr.getStr()+nDecPos+1);
     110             :     }
     111             :     else
     112           0 :         aStr1 = aStr;
     113             : 
     114             :     // negative?
     115           0 :     if ( bCurrency )
     116             :     {
     117           0 :         if ( aStr.startsWith("(") && aStr.endsWith(")") )
     118           0 :             bNegative = true;
     119           0 :         if ( !bNegative )
     120             :         {
     121           0 :             for (sal_Int32 i=0; i < aStr.getLength(); i++ )
     122             :             {
     123           0 :                 if ( (aStr[i] >= '0') && (aStr[i] <= '9') )
     124           0 :                     break;
     125           0 :                 else if ( aStr[i] == '-' )
     126             :                 {
     127           0 :                     bNegative = true;
     128           0 :                     break;
     129             :                 }
     130             :             }
     131             :         }
     132           0 :         if ( !bNegative && bCurrency && !aStr.isEmpty() )
     133             :         {
     134           0 :             sal_uInt16 nFormat = rLocaleDataWrappper.getCurrNegativeFormat();
     135           0 :             if ( (nFormat == 3) || (nFormat == 6)  || // $1- || 1-$
     136           0 :                  (nFormat == 7) || (nFormat == 10) )  // 1$- || 1 $-
     137             :             {
     138           0 :                 for (sal_Int32 i = aStr.getLength()-1; i > 0; --i )
     139             :                 {
     140           0 :                     if ( (aStr[i] >= '0') && (aStr[i] <= '9') )
     141           0 :                         break;
     142           0 :                     else if ( aStr[i] == '-' )
     143             :                     {
     144           0 :                         bNegative = true;
     145           0 :                         break;
     146             :                     }
     147             :                 }
     148             :             }
     149             :         }
     150             :     }
     151             :     else
     152             :     {
     153           0 :         if ( !aStr1.isEmpty() && aStr1[0] == '-')
     154           0 :             bNegative = true;
     155             :     }
     156             : 
     157             :     // remove all unwanted charaters
     158           0 :     for (sal_Int32 i=0; i < aStr1.getLength(); )
     159             :     {
     160           0 :         if ( (aStr1[i] >= '0') && (aStr1[i] <= '9') )
     161           0 :             i++;
     162             :         else
     163           0 :             aStr1.remove( i, 1 );
     164             :     }
     165           0 :     for (sal_Int32 i=0; i < aStr2.getLength(); )
     166             :     {
     167           0 :         if ((aStr2[i] >= '0') && (aStr2[i] <= '9'))
     168           0 :             ++i;
     169             :         else
     170           0 :             aStr2.remove(i, 1);
     171             :     }
     172             : 
     173           0 :     if ( aStr1.isEmpty() && aStr2.isEmpty() )
     174           0 :         return false;
     175             : 
     176           0 :     if ( aStr1.isEmpty() )
     177           0 :         aStr1 = "0";
     178           0 :     if ( bNegative )
     179           0 :         aStr1 = "-" + aStr1;
     180             : 
     181             :     // prune and round fraction
     182           0 :     bool bRound = false;
     183           0 :     if (aStr2.getLength() > nDecDigits)
     184             :     {
     185           0 :         if (aStr2[nDecDigits] >= '5')
     186           0 :             bRound = true;
     187           0 :         string::truncateToLength(aStr2, nDecDigits);
     188             :     }
     189           0 :     if (aStr2.getLength() < nDecDigits)
     190           0 :         string::padToLength(aStr2, nDecDigits, '0');
     191             : 
     192           0 :     aStr  = aStr1.makeStringAndClear() + aStr2.makeStringAndClear();
     193             : 
     194             :     // check range
     195           0 :     sal_Int64 nValue = aStr.toInt64();
     196           0 :     if( nValue == 0 )
     197             :     {
     198             :         // check if string is equivalent to zero
     199           0 :         sal_Int16 nIndex = bNegative ? 1 : 0;
     200           0 :         while (nIndex < aStr.getLength() && aStr[nIndex] == '0')
     201           0 :             ++nIndex;
     202           0 :         if( nIndex < aStr.getLength() )
     203             :         {
     204           0 :             rValue = bNegative ? SAL_MIN_INT64 : SAL_MAX_INT64;
     205           0 :             return true;
     206             :         }
     207             :     }
     208           0 :     if (bRound)
     209             :     {
     210           0 :         if ( !bNegative )
     211           0 :             nValue++;
     212             :         else
     213           0 :             nValue--;
     214             :     }
     215             : 
     216           0 :     rValue = nValue;
     217             : 
     218           0 :     return true;
     219             : }
     220             : 
     221           0 : static void ImplUpdateSeparatorString( OUString& io_rText,
     222             :                                        const OUString& rOldDecSep, const OUString& rNewDecSep,
     223             :                                        const OUString& rOldThSep, const OUString& rNewThSep )
     224             : {
     225           0 :     OUStringBuffer aBuf( io_rText.getLength() );
     226           0 :     sal_Int32 nIndexDec = 0, nIndexTh = 0, nIndex = 0;
     227             : 
     228           0 :     const sal_Unicode* pBuffer = io_rText.getStr();
     229           0 :     while( nIndex != -1 )
     230             :     {
     231           0 :         nIndexDec = io_rText.indexOf( rOldDecSep, nIndex );
     232           0 :         nIndexTh = io_rText.indexOf( rOldThSep, nIndex );
     233           0 :         if(   (nIndexTh != -1 && nIndexDec != -1 && nIndexTh < nIndexDec )
     234           0 :            || (nIndexTh != -1 && nIndexDec == -1)
     235             :            )
     236             :         {
     237           0 :             aBuf.append( pBuffer + nIndex, nIndexTh - nIndex );
     238           0 :             aBuf.append( rNewThSep );
     239           0 :             nIndex = nIndexTh + rOldThSep.getLength();
     240             :         }
     241           0 :         else if( nIndexDec != -1 )
     242             :         {
     243           0 :             aBuf.append( pBuffer + nIndex, nIndexDec - nIndex );
     244           0 :             aBuf.append( rNewDecSep );
     245           0 :             nIndex = nIndexDec + rOldDecSep.getLength();
     246             :         }
     247             :         else
     248             :         {
     249           0 :             aBuf.append( pBuffer + nIndex );
     250           0 :             nIndex = -1;
     251             :         }
     252             :     }
     253             : 
     254           0 :     io_rText = aBuf.makeStringAndClear();
     255           0 : }
     256             : 
     257           0 : static void ImplUpdateSeparators( const OUString& rOldDecSep, const OUString& rNewDecSep,
     258             :                                   const OUString& rOldThSep, const OUString& rNewThSep,
     259             :                                   Edit* pEdit )
     260             : {
     261           0 :     bool bChangeDec = (rOldDecSep != rNewDecSep);
     262           0 :     bool bChangeTh = (rOldThSep != rNewThSep );
     263             : 
     264           0 :     if( bChangeDec || bChangeTh )
     265             :     {
     266           0 :         bool bUpdateMode = pEdit->IsUpdateMode();
     267           0 :         pEdit->SetUpdateMode( false );
     268           0 :         OUString aText = pEdit->GetText();
     269           0 :         ImplUpdateSeparatorString( aText, rOldDecSep, rNewDecSep, rOldThSep, rNewThSep );
     270           0 :         pEdit->SetText( aText );
     271             : 
     272           0 :         ComboBox* pCombo = dynamic_cast<ComboBox*>(pEdit);
     273           0 :         if( pCombo )
     274             :         {
     275             :             // update box entries
     276           0 :             sal_Int32 nEntryCount = pCombo->GetEntryCount();
     277           0 :             for ( sal_Int32 i=0; i < nEntryCount; i++ )
     278             :             {
     279           0 :                 aText = pCombo->GetEntry( i );
     280           0 :                 void* pEntryData = pCombo->GetEntryData( i );
     281           0 :                 ImplUpdateSeparatorString( aText, rOldDecSep, rNewDecSep, rOldThSep, rNewThSep );
     282           0 :                 pCombo->RemoveEntryAt(i);
     283           0 :                 pCombo->InsertEntry( aText, i );
     284           0 :                 pCombo->SetEntryData( i, pEntryData );
     285             :             }
     286             :         }
     287           0 :         if( bUpdateMode )
     288           0 :             pEdit->SetUpdateMode( bUpdateMode );
     289             :     }
     290           0 : }
     291             : 
     292             : } // namespace
     293             : 
     294           0 : FormatterBase::FormatterBase( Edit* pField )
     295             : {
     296           0 :     mpField                     = pField;
     297           0 :     mpLocaleDataWrapper         = NULL;
     298           0 :     mbReformat                  = false;
     299           0 :     mbStrictFormat              = false;
     300           0 :     mbEmptyFieldValue           = false;
     301           0 :     mbEmptyFieldValueEnabled    = false;
     302           0 :     mbDefaultLocale             = true;
     303           0 : }
     304             : 
     305           0 : FormatterBase::~FormatterBase()
     306             : {
     307           0 :     delete mpLocaleDataWrapper;
     308           0 : }
     309             : 
     310           0 : LocaleDataWrapper& FormatterBase::ImplGetLocaleDataWrapper() const
     311             : {
     312           0 :     if ( !mpLocaleDataWrapper )
     313             :     {
     314           0 :         ((FormatterBase*)this)->mpLocaleDataWrapper = new LocaleDataWrapper( GetLanguageTag() );
     315             :     }
     316           0 :     return *mpLocaleDataWrapper;
     317             : }
     318             : 
     319           0 : const LocaleDataWrapper& FormatterBase::GetLocaleDataWrapper() const
     320             : {
     321           0 :     return ImplGetLocaleDataWrapper();
     322             : }
     323             : 
     324           0 : void FormatterBase::Reformat()
     325             : {
     326           0 : }
     327             : 
     328           0 : void FormatterBase::ReformatAll()
     329             : {
     330           0 :     Reformat();
     331           0 : };
     332             : 
     333           0 : void FormatterBase::SetStrictFormat( bool bStrict )
     334             : {
     335           0 :     if ( bStrict != mbStrictFormat )
     336             :     {
     337           0 :         mbStrictFormat = bStrict;
     338           0 :         if ( mbStrictFormat )
     339           0 :             ReformatAll();
     340             :     }
     341           0 : }
     342             : 
     343           0 : void FormatterBase::SetLocale( const lang::Locale& rLocale )
     344             : {
     345           0 :     ImplGetLocaleDataWrapper().setLanguageTag( LanguageTag( rLocale) );
     346           0 :     mbDefaultLocale = false;
     347           0 :     ReformatAll();
     348           0 : }
     349             : 
     350           0 : const lang::Locale& FormatterBase::GetLocale() const
     351             : {
     352           0 :     if ( !mpLocaleDataWrapper || mbDefaultLocale )
     353             :     {
     354           0 :         if ( mpField )
     355           0 :             return mpField->GetSettings().GetLanguageTag().getLocale();
     356             :         else
     357           0 :             return Application::GetSettings().GetLanguageTag().getLocale();
     358             :     }
     359             : 
     360           0 :     return mpLocaleDataWrapper->getLanguageTag().getLocale();
     361             : }
     362             : 
     363           0 : const LanguageTag& FormatterBase::GetLanguageTag() const
     364             : {
     365           0 :     if ( !mpLocaleDataWrapper || mbDefaultLocale )
     366             :     {
     367           0 :         if ( mpField )
     368           0 :             return mpField->GetSettings().GetLanguageTag();
     369             :         else
     370           0 :             return Application::GetSettings().GetLanguageTag();
     371             :     }
     372             : 
     373           0 :     return mpLocaleDataWrapper->getLanguageTag();
     374             : }
     375             : 
     376           0 : const AllSettings& FormatterBase::GetFieldSettings() const
     377             : {
     378           0 :     if ( mpField )
     379           0 :         return mpField->GetSettings();
     380             :     else
     381           0 :         return Application::GetSettings();
     382             : }
     383             : 
     384           0 : void FormatterBase::ImplSetText( const OUString& rText, Selection* pNewSelection )
     385             : {
     386           0 :     if ( mpField )
     387             :     {
     388           0 :         if ( pNewSelection )
     389           0 :             mpField->SetText( rText, *pNewSelection );
     390             :         else
     391             :         {
     392           0 :             Selection aSel = mpField->GetSelection();
     393           0 :             aSel.Min() = aSel.Max();
     394           0 :             mpField->SetText( rText, aSel );
     395             :         }
     396             : 
     397           0 :         MarkToBeReformatted( false );
     398             :     }
     399           0 : }
     400             : 
     401           0 : void FormatterBase::SetEmptyFieldValue()
     402             : {
     403           0 :     if ( mpField )
     404           0 :         mpField->SetText( OUString() );
     405           0 :     mbEmptyFieldValue = true;
     406           0 : }
     407             : 
     408           0 : bool FormatterBase::IsEmptyFieldValue() const
     409             : {
     410           0 :     return (!mpField || mpField->GetText().isEmpty());
     411             : }
     412             : 
     413           0 : bool NumericFormatter::ImplNumericReformat( const OUString& rStr, sal_Int64& rValue,
     414             :                                                 OUString& rOutStr )
     415             : {
     416           0 :     if ( !ImplNumericGetValue( rStr, rValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
     417           0 :         return true;
     418             :     else
     419             :     {
     420           0 :         sal_Int64 nTempVal = rValue;
     421           0 :         if ( nTempVal > mnMax )
     422           0 :             nTempVal = mnMax;
     423           0 :         else if ( nTempVal < mnMin )
     424           0 :             nTempVal = mnMin;
     425             : 
     426           0 :         if ( GetErrorHdl().IsSet() && (rValue != nTempVal) )
     427             :         {
     428           0 :             mnCorrectedValue = nTempVal;
     429           0 :             if ( !GetErrorHdl().Call( this ) )
     430             :             {
     431           0 :                 mnCorrectedValue = 0;
     432           0 :                 return false;
     433             :             }
     434             :             else
     435           0 :                 mnCorrectedValue = 0;
     436             :         }
     437             : 
     438           0 :         rOutStr = CreateFieldText( nTempVal );
     439           0 :         return true;
     440             :     }
     441             : }
     442             : 
     443           0 : void NumericFormatter::ImplInit()
     444             : {
     445           0 :     mnFieldValue        = 0;
     446           0 :     mnLastValue         = 0;
     447           0 :     mnMin               = 0;
     448           0 :     mnMax               = SAL_MAX_INT64;
     449           0 :     mnCorrectedValue    = 0;
     450           0 :     mnDecimalDigits     = 2;
     451           0 :     mnType              = FORMAT_NUMERIC;
     452           0 :     mbThousandSep       = true;
     453           0 :     mbShowTrailingZeros = true;
     454             : 
     455             :     // for fields
     456           0 :     mnSpinSize          = 1;
     457           0 :     mnFirst             = mnMin;
     458           0 :     mnLast              = mnMax;
     459             : 
     460           0 :     SetDecimalDigits( 0 );
     461           0 : }
     462             : 
     463           0 : NumericFormatter::NumericFormatter()
     464             : {
     465           0 :     ImplInit();
     466           0 : }
     467             : 
     468           0 : void NumericFormatter::ImplLoadRes( const ResId& rResId )
     469             : {
     470           0 :     ResMgr*     pMgr = rResId.GetResMgr();
     471             : 
     472           0 :     if( pMgr )
     473             :     {
     474           0 :         sal_uLong nMask = pMgr->ReadLong();
     475             : 
     476           0 :         if ( NUMERICFORMATTER_MIN & nMask )
     477           0 :             mnMin = pMgr->ReadLong();
     478             : 
     479           0 :         if ( NUMERICFORMATTER_MAX & nMask )
     480           0 :             mnMax = pMgr->ReadLong();
     481             : 
     482           0 :         if ( NUMERICFORMATTER_STRICTFORMAT & nMask )
     483           0 :             SetStrictFormat( pMgr->ReadShort() != 0 );
     484             : 
     485           0 :         if ( NUMERICFORMATTER_DECIMALDIGITS & nMask )
     486           0 :             SetDecimalDigits( pMgr->ReadShort() );
     487             : 
     488           0 :         if ( NUMERICFORMATTER_VALUE & nMask )
     489             :         {
     490           0 :             mnFieldValue = pMgr->ReadLong();
     491           0 :             if ( mnFieldValue > mnMax )
     492           0 :                 mnFieldValue = mnMax;
     493           0 :             else if ( mnFieldValue < mnMin )
     494           0 :                 mnFieldValue = mnMin;
     495           0 :             mnLastValue = mnFieldValue;
     496             :         }
     497             : 
     498           0 :         if ( NUMERICFORMATTER_NOTHOUSANDSEP & nMask )
     499           0 :             SetUseThousandSep( pMgr->ReadShort() == 0 );
     500             :     }
     501           0 : }
     502             : 
     503           0 : NumericFormatter::~NumericFormatter()
     504             : {
     505           0 : }
     506             : 
     507           0 : void NumericFormatter::SetMin( sal_Int64 nNewMin )
     508             : {
     509           0 :     mnMin = nNewMin;
     510           0 :     if ( !IsEmptyFieldValue() )
     511           0 :         ReformatAll();
     512           0 : }
     513             : 
     514           0 : void NumericFormatter::SetMax( sal_Int64 nNewMax )
     515             : {
     516           0 :     mnMax = nNewMax;
     517           0 :     if ( !IsEmptyFieldValue() )
     518           0 :         ReformatAll();
     519           0 : }
     520             : 
     521           0 : void NumericFormatter::SetUseThousandSep( bool bValue )
     522             : {
     523           0 :     mbThousandSep = bValue;
     524           0 :     ReformatAll();
     525           0 : }
     526             : 
     527           0 : void NumericFormatter::SetDecimalDigits( sal_uInt16 nDigits )
     528             : {
     529           0 :     mnDecimalDigits = nDigits;
     530           0 :     ReformatAll();
     531           0 : }
     532             : 
     533           0 : void NumericFormatter::SetShowTrailingZeros( bool bShowTrailingZeros )
     534             : {
     535           0 :     if ( mbShowTrailingZeros != bShowTrailingZeros )
     536             :     {
     537           0 :         mbShowTrailingZeros = bShowTrailingZeros;
     538           0 :         ReformatAll();
     539             :     }
     540           0 : }
     541             : 
     542           0 : sal_uInt16 NumericFormatter::GetDecimalDigits() const
     543             : {
     544           0 :     return mnDecimalDigits;
     545             : }
     546             : 
     547           0 : void NumericFormatter::SetValue( sal_Int64 nNewValue )
     548             : {
     549           0 :     SetUserValue( nNewValue );
     550           0 :     mnFieldValue = mnLastValue;
     551           0 :     SetEmptyFieldValueData( false );
     552           0 : }
     553             : 
     554           0 : OUString NumericFormatter::CreateFieldText( sal_Int64 nValue ) const
     555             : {
     556           0 :     return OUString(ImplGetLocaleDataWrapper().getNum( nValue, GetDecimalDigits(), IsUseThousandSep(), IsShowTrailingZeros() ));
     557             : }
     558             : 
     559           0 : void NumericFormatter::ImplSetUserValue( sal_Int64 nNewValue, Selection* pNewSelection )
     560             : {
     561           0 :     if ( nNewValue > mnMax )
     562           0 :         nNewValue = mnMax;
     563           0 :     else if ( nNewValue < mnMin )
     564           0 :         nNewValue = mnMin;
     565           0 :     mnLastValue = nNewValue;
     566             : 
     567           0 :     if ( GetField() )
     568           0 :         ImplSetText( CreateFieldText( nNewValue ), pNewSelection );
     569           0 : }
     570             : 
     571           0 : void NumericFormatter::SetUserValue( sal_Int64 nNewValue )
     572             : {
     573           0 :     ImplSetUserValue( nNewValue );
     574           0 : }
     575             : 
     576           0 : sal_Int64 NumericFormatter::GetValue() const
     577             : {
     578           0 :     if ( !GetField() )
     579           0 :         return 0;
     580             : 
     581             :     sal_Int64 nTempValue;
     582             : 
     583           0 :     if ( ImplNumericGetValue( GetField()->GetText(), nTempValue,
     584           0 :                               GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
     585             :     {
     586           0 :         if ( nTempValue > mnMax )
     587           0 :             nTempValue = mnMax;
     588           0 :         else if ( nTempValue < mnMin )
     589           0 :             nTempValue = mnMin;
     590           0 :         return nTempValue;
     591             :     }
     592             :     else
     593           0 :         return mnLastValue;
     594             : }
     595             : 
     596           0 : bool NumericFormatter::IsValueModified() const
     597             : {
     598           0 :     if ( ImplGetEmptyFieldValue() )
     599           0 :         return !IsEmptyFieldValue();
     600           0 :     else if ( GetValue() != mnFieldValue )
     601           0 :         return true;
     602             :     else
     603           0 :         return false;
     604             : }
     605             : 
     606           0 : sal_Int64 NumericFormatter::Normalize( sal_Int64 nValue ) const
     607             : {
     608           0 :     return (nValue * ImplPower10( GetDecimalDigits() ) );
     609             : }
     610             : 
     611           0 : sal_Int64 NumericFormatter::Denormalize( sal_Int64 nValue ) const
     612             : {
     613           0 :     sal_Int64 nFactor = ImplPower10( GetDecimalDigits() );
     614             : 
     615           0 :     if ((nValue < ( SAL_MIN_INT64 + nFactor )) ||
     616           0 :         (nValue > ( SAL_MAX_INT64 - nFactor )))
     617             :     {
     618           0 :         return ( nValue / nFactor );
     619             :     }
     620             : 
     621           0 :     if( nValue < 0 )
     622             :     {
     623           0 :         sal_Int64 nHalf = nFactor / 2;
     624           0 :         return ((nValue - nHalf) / nFactor );
     625             :     }
     626             :     else
     627             :     {
     628           0 :         sal_Int64 nHalf = nFactor / 2;
     629           0 :         return ((nValue + nHalf) / nFactor );
     630             :     }
     631             : }
     632             : 
     633           0 : void NumericFormatter::Reformat()
     634             : {
     635           0 :     if ( !GetField() )
     636           0 :         return;
     637             : 
     638           0 :     if ( GetField()->GetText().isEmpty() && ImplGetEmptyFieldValue() )
     639           0 :         return;
     640             : 
     641           0 :     OUString aStr;
     642           0 :     sal_Int64 nTemp = mnLastValue;
     643           0 :     bool bOK = ImplNumericReformat( GetField()->GetText(), nTemp, aStr );
     644           0 :     mnLastValue = nTemp;
     645           0 :     if ( !bOK )
     646           0 :         return;
     647             : 
     648           0 :     if ( !aStr.isEmpty() )
     649           0 :         ImplSetText( aStr );
     650             :     else
     651           0 :         SetValue( mnLastValue );
     652             : }
     653             : 
     654           0 : void NumericFormatter::FieldUp()
     655             : {
     656           0 :     sal_Int64 nValue = GetValue();
     657           0 :     sal_Int64 nRemainder = nValue % mnSpinSize;
     658           0 :     if (nValue >= 0)
     659           0 :         nValue = (nRemainder == 0) ? nValue + mnSpinSize : nValue + mnSpinSize - nRemainder;
     660             :     else
     661           0 :         nValue = (nRemainder == 0) ? nValue + mnSpinSize : nValue - nRemainder;
     662             : 
     663           0 :     if ( nValue > mnMax )
     664           0 :         nValue = mnMax;
     665             : 
     666           0 :     ImplNewFieldValue( nValue );
     667           0 : }
     668             : 
     669           0 : void NumericFormatter::FieldDown()
     670             : {
     671           0 :     sal_Int64 nValue = GetValue();
     672           0 :     sal_Int64 nRemainder = nValue % mnSpinSize;
     673           0 :     if (nValue >= 0)
     674           0 :         nValue = (nRemainder == 0) ? nValue - mnSpinSize : nValue - nRemainder;
     675             :     else
     676           0 :         nValue = (nRemainder == 0) ? nValue - mnSpinSize : nValue - mnSpinSize - nRemainder;
     677             : 
     678           0 :     if ( nValue < mnMin )
     679           0 :         nValue = mnMin;
     680             : 
     681           0 :     ImplNewFieldValue( nValue );
     682           0 : }
     683             : 
     684           0 : void NumericFormatter::FieldFirst()
     685             : {
     686           0 :     ImplNewFieldValue( mnFirst );
     687           0 : }
     688             : 
     689           0 : void NumericFormatter::FieldLast()
     690             : {
     691           0 :     ImplNewFieldValue( mnLast );
     692           0 : }
     693             : 
     694           0 : void NumericFormatter::ImplNewFieldValue( sal_Int64 nNewValue )
     695             : {
     696           0 :     if ( GetField() )
     697             :     {
     698             :         // !!! We should check why we do not validate in ImplSetUserValue() if the value was
     699             :         // changed. This should be done there as well since otherwise the call to Modify would not
     700             :         // be allowed. Anyway, the paths from ImplNewFieldValue, ImplSetUserValue, and ImplSetText
     701             :         // should be checked and clearly traced (with comment) in order to find out what happens.
     702             : 
     703           0 :         Selection aSelection = GetField()->GetSelection();
     704           0 :         aSelection.Justify();
     705           0 :         OUString aText = GetField()->GetText();
     706             :         // leave it as is if selected until end
     707           0 :         if ( (sal_Int32)aSelection.Max() == aText.getLength() )
     708             :         {
     709           0 :             if ( !aSelection.Len() )
     710           0 :                 aSelection.Min() = SELECTION_MAX;
     711           0 :             aSelection.Max() = SELECTION_MAX;
     712             :         }
     713             : 
     714           0 :         sal_Int64 nOldLastValue  = mnLastValue;
     715           0 :         ImplSetUserValue( nNewValue, &aSelection );
     716           0 :         mnLastValue = nOldLastValue;
     717             : 
     718             :         // Modify during Edit is only set during KeyInput
     719           0 :         if ( GetField()->GetText() != aText )
     720             :         {
     721           0 :             GetField()->SetModifyFlag();
     722           0 :             GetField()->Modify();
     723           0 :         }
     724             :     }
     725           0 : }
     726             : 
     727           0 : NumericField::NumericField( Window* pParent, WinBits nWinStyle ) :
     728           0 :     SpinField( pParent, nWinStyle )
     729             : {
     730           0 :     SetField( this );
     731           0 :     Reformat();
     732           0 : }
     733             : 
     734           0 : NumericField::NumericField( Window* pParent, const ResId& rResId ) :
     735           0 :     SpinField( WINDOW_NUMERICFIELD )
     736             : {
     737           0 :     rResId.SetRT( RSC_NUMERICFIELD );
     738           0 :     WinBits nStyle = ImplInitRes( rResId ) ;
     739           0 :     SpinField::ImplInit( pParent, nStyle );
     740           0 :     SetField( this );
     741           0 :     ImplLoadRes( rResId );
     742           0 :     Reformat();
     743             : 
     744           0 :     if ( !(nStyle & WB_HIDE ) )
     745           0 :         Show();
     746           0 : }
     747             : 
     748           0 : bool NumericField::set_property(const OString &rKey, const OString &rValue)
     749             : {
     750           0 :     if (rKey == "digits")
     751           0 :         SetDecimalDigits(rValue.toInt32());
     752           0 :     else if (rKey == "spin-size")
     753           0 :         SetSpinSize(rValue.toInt32());
     754             :     else
     755           0 :         return SpinField::set_property(rKey, rValue);
     756           0 :     return true;
     757             : }
     758             : 
     759           0 : void NumericField::ImplLoadRes( const ResId& rResId )
     760             : {
     761           0 :     SpinField::ImplLoadRes( rResId );
     762           0 :     NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
     763             : 
     764           0 :     sal_uLong      nMask = ReadLongRes();
     765             : 
     766           0 :     if ( NUMERICFIELD_FIRST & nMask )
     767           0 :         mnFirst = ReadLongRes();
     768             : 
     769           0 :     if ( NUMERICFIELD_LAST & nMask )
     770           0 :         mnLast = ReadLongRes();
     771             : 
     772           0 :     if ( NUMERICFIELD_SPINSIZE & nMask )
     773           0 :         mnSpinSize = ReadLongRes();
     774           0 : }
     775             : 
     776           0 : NumericField::~NumericField()
     777             : {
     778           0 : }
     779             : 
     780           0 : bool NumericField::PreNotify( NotifyEvent& rNEvt )
     781             : {
     782           0 :         if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
     783             :     {
     784           0 :         if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
     785           0 :             return true;
     786             :     }
     787             : 
     788           0 :     return SpinField::PreNotify( rNEvt );
     789             : }
     790             : 
     791           0 : bool NumericField::Notify( NotifyEvent& rNEvt )
     792             : {
     793           0 :     if ( rNEvt.GetType() == EVENT_GETFOCUS )
     794           0 :         MarkToBeReformatted( false );
     795           0 :     else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
     796             :     {
     797           0 :         if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
     798           0 :             Reformat();
     799             :     }
     800             : 
     801           0 :     return SpinField::Notify( rNEvt );
     802             : }
     803             : 
     804           0 : void NumericField::DataChanged( const DataChangedEvent& rDCEvt )
     805             : {
     806           0 :     SpinField::DataChanged( rDCEvt );
     807             : 
     808           0 :     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
     809             :     {
     810           0 :         OUString sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
     811           0 :         OUString sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
     812           0 :         if ( IsDefaultLocale() )
     813           0 :             ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
     814           0 :         OUString sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
     815           0 :         OUString sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
     816           0 :         ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
     817           0 :         ReformatAll();
     818             :     }
     819           0 : }
     820             : 
     821           0 : void NumericField::Modify()
     822             : {
     823           0 :     MarkToBeReformatted( true );
     824           0 :     SpinField::Modify();
     825           0 : }
     826             : 
     827           0 : void NumericField::Up()
     828             : {
     829           0 :     FieldUp();
     830           0 :     SpinField::Up();
     831           0 : }
     832             : 
     833           0 : void NumericField::Down()
     834             : {
     835           0 :     FieldDown();
     836           0 :     SpinField::Down();
     837           0 : }
     838             : 
     839           0 : void NumericField::First()
     840             : {
     841           0 :     FieldFirst();
     842           0 :     SpinField::First();
     843           0 : }
     844             : 
     845           0 : void NumericField::Last()
     846             : {
     847           0 :     FieldLast();
     848           0 :     SpinField::Last();
     849           0 : }
     850             : 
     851             : namespace
     852             : {
     853           0 :     Size calcMinimumSize(const Edit &rSpinField, const NumericFormatter &rFormatter)
     854             :     {
     855           0 :         OUStringBuffer aBuf;
     856             :         sal_Int32 nTextLen;
     857             : 
     858           0 :         nTextLen = OUString::number(rFormatter.GetMin()).getLength();
     859           0 :         string::padToLength(aBuf, nTextLen, '9');
     860             :         Size aMinTextSize = rSpinField.CalcMinimumSizeForText(
     861           0 :             rFormatter.CreateFieldText(aBuf.makeStringAndClear().toInt64()));
     862             : 
     863           0 :         nTextLen = OUString::number(rFormatter.GetMax()).getLength();
     864           0 :         string::padToLength(aBuf, nTextLen, '9');
     865             :         Size aMaxTextSize = rSpinField.CalcMinimumSizeForText(
     866           0 :             rFormatter.CreateFieldText(aBuf.makeStringAndClear().toInt64()));
     867             : 
     868           0 :         Size aRet(std::max(aMinTextSize.Width(), aMaxTextSize.Width()),
     869           0 :                   std::max(aMinTextSize.Height(), aMaxTextSize.Height()));
     870             : 
     871           0 :         OUStringBuffer sBuf("999999999");
     872           0 :         sal_uInt16 nDigits = rFormatter.GetDecimalDigits();
     873           0 :         if (nDigits)
     874             :         {
     875           0 :             sBuf.append('.');
     876           0 :             string::padToLength(aBuf, aBuf.getLength() + nDigits, '9');
     877             :         }
     878           0 :         aMaxTextSize = rSpinField.CalcMinimumSizeForText(sBuf.makeStringAndClear());
     879           0 :         aRet.Width() = std::min(aRet.Width(), aMaxTextSize.Width());
     880             : 
     881           0 :         return aRet;
     882             :     }
     883             : }
     884             : 
     885           0 : Size NumericField::CalcMinimumSize() const
     886             : {
     887           0 :     return calcMinimumSize(*this, *this);
     888             : }
     889             : 
     890           0 : NumericBox::NumericBox( Window* pParent, WinBits nWinStyle ) :
     891           0 :     ComboBox( pParent, nWinStyle )
     892             : {
     893           0 :     SetField( this );
     894           0 :     Reformat();
     895           0 :     if ( !(nWinStyle & WB_HIDE ) )
     896           0 :         Show();
     897           0 : }
     898             : 
     899           0 : NumericBox::NumericBox( Window* pParent, const ResId& rResId ) :
     900           0 :     ComboBox( WINDOW_NUMERICBOX )
     901             : {
     902           0 :     rResId.SetRT( RSC_NUMERICBOX );
     903           0 :     WinBits nStyle = ImplInitRes( rResId );
     904           0 :     ComboBox::ImplInit( pParent, nStyle );
     905           0 :     SetField( this );
     906           0 :     ComboBox::ImplLoadRes( rResId );
     907           0 :     NumericFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
     908           0 :     Reformat();
     909             : 
     910           0 :     if ( !(nStyle & WB_HIDE ) )
     911           0 :         Show();
     912           0 : }
     913             : 
     914           0 : Size NumericBox::CalcMinimumSize() const
     915             : {
     916           0 :     Size aRet(calcMinimumSize(*this, *this));
     917             : 
     918           0 :     if (IsDropDownBox())
     919             :     {
     920           0 :         Size aComboSugg(ComboBox::CalcMinimumSize());
     921           0 :         aRet.Width() = std::max(aRet.Width(), aComboSugg.Width());
     922           0 :         aRet.Height() = std::max(aRet.Height(), aComboSugg.Height());
     923             :     }
     924             : 
     925           0 :     return aRet;
     926             : }
     927             : 
     928           0 : NumericBox::~NumericBox()
     929             : {
     930           0 : }
     931             : 
     932           0 : bool NumericBox::PreNotify( NotifyEvent& rNEvt )
     933             : {
     934           0 :     if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
     935             :     {
     936           0 :         if ( ImplNumericProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
     937           0 :             return true;
     938             :     }
     939             : 
     940           0 :     return ComboBox::PreNotify( rNEvt );
     941             : }
     942             : 
     943           0 : bool NumericBox::Notify( NotifyEvent& rNEvt )
     944             : {
     945           0 :     if ( rNEvt.GetType() == EVENT_GETFOCUS )
     946           0 :         MarkToBeReformatted( false );
     947           0 :     else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
     948             :     {
     949           0 :         if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
     950           0 :             Reformat();
     951             :     }
     952             : 
     953           0 :     return ComboBox::Notify( rNEvt );
     954             : }
     955             : 
     956           0 : void NumericBox::DataChanged( const DataChangedEvent& rDCEvt )
     957             : {
     958           0 :     ComboBox::DataChanged( rDCEvt );
     959             : 
     960           0 :     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
     961             :     {
     962           0 :         OUString sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
     963           0 :         OUString sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
     964           0 :         if ( IsDefaultLocale() )
     965           0 :             ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
     966           0 :         OUString sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
     967           0 :         OUString sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
     968           0 :         ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
     969           0 :         ReformatAll();
     970             :     }
     971           0 : }
     972             : 
     973           0 : void NumericBox::Modify()
     974             : {
     975           0 :     MarkToBeReformatted( true );
     976           0 :     ComboBox::Modify();
     977           0 : }
     978             : 
     979           0 : void NumericBox::ReformatAll()
     980             : {
     981             :     sal_Int64 nValue;
     982           0 :     OUString aStr;
     983           0 :     SetUpdateMode( false );
     984           0 :     sal_Int32 nEntryCount = GetEntryCount();
     985           0 :     for ( sal_Int32 i=0; i < nEntryCount; i++ )
     986             :     {
     987           0 :         ImplNumericReformat( GetEntry( i ), nValue, aStr );
     988           0 :         RemoveEntryAt(i);
     989           0 :         InsertEntry( aStr, i );
     990             :     }
     991           0 :     NumericFormatter::Reformat();
     992           0 :     SetUpdateMode( true );
     993           0 : }
     994             : 
     995           0 : void NumericBox::InsertValue( sal_Int64 nValue, sal_Int32 nPos )
     996             : {
     997           0 :     ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
     998           0 : }
     999             : 
    1000           0 : static bool ImplMetricProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
    1001             :                                        bool, bool bUseThousandSep, const LocaleDataWrapper& rWrapper )
    1002             : {
    1003             :     // no meaningfull strict format; therefore allow all characters
    1004           0 :     return ImplNumericProcessKeyInput( pEdit, rKEvt, false, bUseThousandSep, rWrapper );
    1005             : }
    1006             : 
    1007           0 : static OUString ImplMetricGetUnitText(const OUString& rStr)
    1008             : {
    1009             :     // fetch unit text
    1010           0 :     OUStringBuffer aStr;
    1011           0 :     for (sal_Int32 i = rStr.getLength()-1; i >= 0; --i)
    1012             :     {
    1013           0 :         sal_Unicode c = rStr[i];
    1014           0 :         if ( (c == '\'') || (c == '\"') || (c == '%' ) || unicode::isAlpha(c) || unicode::isControl(c) )
    1015           0 :             aStr.insert(0, c);
    1016             :         else
    1017             :         {
    1018           0 :             if (!aStr.isEmpty())
    1019           0 :                 break;
    1020             :         }
    1021             :     }
    1022           0 :     return aStr.makeStringAndClear();
    1023             : }
    1024             : 
    1025             : // #104355# support localized mesaurements
    1026             : 
    1027           0 : static const OUString ImplMetricToString( FieldUnit rUnit )
    1028             : {
    1029           0 :     FieldUnitStringList* pList = ImplGetFieldUnits();
    1030           0 :     if( pList )
    1031             :     {
    1032             :         // return unit's default string (ie, the first one )
    1033           0 :         for( FieldUnitStringList::const_iterator it = pList->begin(); it != pList->end(); ++it )
    1034             :         {
    1035           0 :             if ( it->second == rUnit )
    1036           0 :                 return it->first;
    1037             :         }
    1038             :     }
    1039             : 
    1040           0 :     return OUString();
    1041             : }
    1042             : 
    1043           0 : static FieldUnit ImplStringToMetric(const OUString &rMetricString)
    1044             : {
    1045           0 :     FieldUnitStringList* pList = ImplGetCleanedFieldUnits();
    1046           0 :     if( pList )
    1047             :     {
    1048             :         // return FieldUnit
    1049           0 :         OUString aStr(rMetricString.toAsciiLowerCase());
    1050           0 :         aStr = string::remove(aStr, ' ');
    1051           0 :         for( FieldUnitStringList::const_iterator it = pList->begin(); it != pList->end(); ++it )
    1052             :         {
    1053           0 :             if ( it->first == aStr )
    1054           0 :                 return it->second;
    1055           0 :         }
    1056             :     }
    1057             : 
    1058           0 :     return FUNIT_NONE;
    1059             : }
    1060             : 
    1061           0 : static FieldUnit ImplMetricGetUnit(const OUString& rStr)
    1062             : {
    1063           0 :     OUString aStr = ImplMetricGetUnitText( rStr );
    1064           0 :     return ImplStringToMetric( aStr );
    1065             : }
    1066             : 
    1067             : #define K *1000L
    1068             : #define M *1000000LL
    1069             : #define X *5280L
    1070             : 
    1071             : // twip in km = 254 / 14 400 000 000
    1072             : // expressions too big for default size 32 bit need LL to avoid overflow
    1073             : 
    1074             : static const sal_Int64 aImplFactor[FUNIT_LINE+1][FUNIT_LINE+1] =
    1075             : { /*
    1076             : mm/100    mm    cm       m     km  twip point  pica  inch    foot       mile     char     line  */
    1077             : {    1,  100,  1 K,  100 K, 100 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X ,   53340, 396240},
    1078             : {    1,    1,   10,    1 K,   1 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X ,    5334, 396240},
    1079             : {    1,    1,    1,    100, 100 K,  254,  254,  254,  254, 254*12, 254*12 X ,    5334,  39624},
    1080             : {    1,    1,    1,      1,   1 K,  254,  254,  254,  254, 254*12, 254*12 X ,  533400,  39624},
    1081             : {    1,    1,    1,      1,     1,  254,  254,  254,  254, 254*12, 254*12 X ,533400 K,  39624},
    1082             : { 1440,144 K,144 K,14400 K,14400LL M, 1,   20,  240, 1440,1440*12,1440*12 X ,     210,   3120},
    1083             : {   72, 7200, 7200,  720 K, 720 M,    1,    1,   12,   72,  72*12,  72*12 X ,     210,    156},
    1084             : {    6,  600,  600,   60 K,  60 M,    1,    1,    1,    6,   6*12,   6*12 X ,     210,     10},
    1085             : {    1,  100,  100,   10 K,  10 M,    1,    1,    1,    1,     12,     12 X ,     210,     45},
    1086             : {    1,  100,  100,   10 K,  10 M,    1,    1,    1,    1,      1,      1 X ,     210,     45},
    1087             : {    1,  100,  100,   10 K,  10 M,    1,    1,    1,    1,      1,        1 ,     210,     45},
    1088             : {  144, 1440,14400,  14400, 14400,    1,   20,  240, 1440,1440*12, 1440*12 X,       1,   156 },
    1089             : {  720,72000,72000, 7200 K,7200LL M, 20,   10,   13,   11,  11*12,   11*12 X,     105,     1 }
    1090             : };
    1091             : #undef X
    1092             : #undef M
    1093             : #undef K
    1094             : 
    1095             : static FieldUnit eDefaultUnit = FUNIT_NONE;
    1096             : 
    1097           0 : FieldUnit MetricField::GetDefaultUnit() { return eDefaultUnit; }
    1098           0 : void MetricField::SetDefaultUnit( FieldUnit meUnit ) { eDefaultUnit = meUnit; }
    1099             : 
    1100           0 : static FieldUnit ImplMap2FieldUnit( MapUnit meUnit, long& nDecDigits )
    1101             : {
    1102           0 :     switch( meUnit )
    1103             :     {
    1104             :         case MAP_100TH_MM :
    1105           0 :             nDecDigits -= 2;
    1106           0 :             return FUNIT_MM;
    1107             :         case MAP_10TH_MM :
    1108           0 :             nDecDigits -= 1;
    1109           0 :             return FUNIT_MM;
    1110             :         case MAP_MM :
    1111           0 :             return FUNIT_MM;
    1112             :         case MAP_CM :
    1113           0 :             return FUNIT_CM;
    1114             :         case MAP_1000TH_INCH :
    1115           0 :             nDecDigits -= 3;
    1116           0 :             return FUNIT_INCH;
    1117             :         case MAP_100TH_INCH :
    1118           0 :             nDecDigits -= 2;
    1119           0 :             return FUNIT_INCH;
    1120             :         case MAP_10TH_INCH :
    1121           0 :             nDecDigits -= 1;
    1122           0 :             return FUNIT_INCH;
    1123             :         case MAP_INCH :
    1124           0 :             return FUNIT_INCH;
    1125             :         case MAP_POINT :
    1126           0 :             return FUNIT_POINT;
    1127             :         case MAP_TWIP :
    1128           0 :             return FUNIT_TWIP;
    1129             :         default:
    1130             :             OSL_FAIL( "default eInUnit" );
    1131           0 :             break;
    1132             :     }
    1133           0 :     return FUNIT_NONE;
    1134             : }
    1135             : 
    1136           0 : static double nonValueDoubleToValueDouble( double nValue )
    1137             : {
    1138           0 :     return rtl::math::isFinite( nValue ) ? nValue : 0.0;
    1139             : }
    1140             : 
    1141           0 : sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits,
    1142             :                                      FieldUnit eInUnit, FieldUnit eOutUnit )
    1143             : {
    1144             :     double nDouble = nonValueDoubleToValueDouble( ConvertDoubleValue(
    1145           0 :                 (double)nValue, mnBaseValue, nDecDigits, eInUnit, eOutUnit ) );
    1146             :     sal_Int64 nLong ;
    1147             : 
    1148             :     // caution: precision loss in double cast
    1149           0 :     if ( nDouble <= (double)SAL_MIN_INT64 )
    1150           0 :         nLong = SAL_MIN_INT64;
    1151           0 :     else if ( nDouble >= (double)SAL_MAX_INT64 )
    1152           0 :         nLong = SAL_MAX_INT64;
    1153             :     else
    1154           0 :         nLong = static_cast<sal_Int64>( nDouble );
    1155             : 
    1156           0 :     return nLong;
    1157             : }
    1158             : 
    1159           0 : sal_Int64 MetricField::ConvertValue( sal_Int64 nValue, sal_uInt16 nDigits,
    1160             :                                      MapUnit eInUnit, FieldUnit eOutUnit )
    1161             : {
    1162             :     return static_cast<sal_Int64>(
    1163             :         nonValueDoubleToValueDouble(
    1164           0 :             ConvertDoubleValue( nValue, nDigits, eInUnit, eOutUnit ) ) );
    1165             : }
    1166             : 
    1167           0 : double MetricField::ConvertDoubleValue( double nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits,
    1168             :                                         FieldUnit eInUnit, FieldUnit eOutUnit )
    1169             : {
    1170           0 :     if ( eInUnit != eOutUnit )
    1171             :     {
    1172           0 :         sal_Int64 nMult = 1, nDiv = 1;
    1173             : 
    1174           0 :         if ( eInUnit == FUNIT_PERCENT )
    1175             :         {
    1176           0 :             if ( (mnBaseValue <= 0) || (nValue <= 0) )
    1177           0 :                 return nValue;
    1178           0 :             nDiv = 100 * ImplPower10(nDecDigits);
    1179             : 
    1180           0 :             nMult = mnBaseValue;
    1181             :         }
    1182           0 :         else if ( eOutUnit == FUNIT_PERCENT ||
    1183           0 :                   eOutUnit == FUNIT_CUSTOM ||
    1184           0 :                   eOutUnit == FUNIT_NONE ||
    1185           0 :                   eOutUnit == FUNIT_DEGREE ||
    1186           0 :                   eOutUnit == FUNIT_SECOND ||
    1187           0 :                   eOutUnit == FUNIT_MILLISECOND ||
    1188           0 :                   eOutUnit == FUNIT_PIXEL ||
    1189           0 :                   eInUnit  == FUNIT_CUSTOM ||
    1190           0 :                   eInUnit  == FUNIT_NONE ||
    1191           0 :                   eInUnit  == FUNIT_DEGREE ||
    1192           0 :                   eInUnit  == FUNIT_MILLISECOND ||
    1193             :                   eInUnit  == FUNIT_PIXEL )
    1194           0 :              return nValue;
    1195             :         else
    1196             :         {
    1197           0 :             if ( eOutUnit == FUNIT_100TH_MM )
    1198           0 :                 eOutUnit = FUNIT_NONE;
    1199           0 :             if ( eInUnit == FUNIT_100TH_MM )
    1200           0 :                 eInUnit = FUNIT_NONE;
    1201             : 
    1202           0 :             nDiv  = aImplFactor[eInUnit][eOutUnit];
    1203           0 :             nMult = aImplFactor[eOutUnit][eInUnit];
    1204             : 
    1205             :             DBG_ASSERT( nMult > 0, "illegal *" );
    1206             :             DBG_ASSERT( nDiv  > 0, "illegal /" );
    1207             :         }
    1208             : 
    1209           0 :         if ( nMult != 1 && nMult > 0 )
    1210           0 :             nValue *= nMult;
    1211           0 :         if ( nDiv != 1 && nDiv > 0 )
    1212             :         {
    1213           0 :             nValue += ( nValue < 0 ) ? (-nDiv/2) : (nDiv/2);
    1214           0 :             nValue /= nDiv;
    1215             :         }
    1216             :     }
    1217             : 
    1218           0 :     return nValue;
    1219             : }
    1220             : 
    1221           0 : double MetricField::ConvertDoubleValue( double nValue, sal_uInt16 nDigits,
    1222             :                                         MapUnit eInUnit, FieldUnit eOutUnit )
    1223             : {
    1224           0 :     if ( eOutUnit == FUNIT_PERCENT ||
    1225           0 :          eOutUnit == FUNIT_CUSTOM ||
    1226           0 :          eOutUnit == FUNIT_NONE ||
    1227           0 :          eInUnit == MAP_PIXEL ||
    1228           0 :          eInUnit == MAP_SYSFONT ||
    1229           0 :          eInUnit == MAP_APPFONT ||
    1230             :          eInUnit == MAP_RELATIVE )
    1231             :     {
    1232             :         OSL_FAIL( "invalid parameters" );
    1233           0 :         return nValue;
    1234             :     }
    1235             : 
    1236           0 :     long nDecDigits = nDigits;
    1237           0 :     FieldUnit eFieldUnit = ImplMap2FieldUnit( eInUnit, nDecDigits );
    1238             : 
    1239           0 :     if ( nDecDigits < 0 )
    1240             :     {
    1241           0 :         while ( nDecDigits )
    1242             :         {
    1243           0 :             nValue += 5;
    1244           0 :             nValue /= 10;
    1245           0 :             nDecDigits++;
    1246             :         }
    1247             :     }
    1248             :     else
    1249             :     {
    1250           0 :         nValue *= ImplPower10(nDecDigits);
    1251             :     }
    1252             : 
    1253           0 :     if ( eFieldUnit != eOutUnit )
    1254             :     {
    1255           0 :         sal_Int64 nDiv  = aImplFactor[eFieldUnit][eOutUnit];
    1256           0 :         sal_Int64 nMult = aImplFactor[eOutUnit][eFieldUnit];
    1257             : 
    1258             :         DBG_ASSERT( nMult > 0, "illegal *" );
    1259             :         DBG_ASSERT( nDiv  > 0, "illegal /" );
    1260             : 
    1261           0 :         if ( nMult != 1 && nMult > 0)
    1262           0 :             nValue *= nMult;
    1263           0 :         if ( nDiv != 1 && nDiv > 0 )
    1264             :         {
    1265           0 :             nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2);
    1266           0 :             nValue /= nDiv;
    1267             :         }
    1268             :     }
    1269           0 :     return nValue;
    1270             : }
    1271             : 
    1272           0 : double MetricField::ConvertDoubleValue( double nValue, sal_uInt16 nDigits,
    1273             :                                         FieldUnit eInUnit, MapUnit eOutUnit )
    1274             : {
    1275           0 :     if ( eInUnit == FUNIT_PERCENT ||
    1276           0 :          eInUnit == FUNIT_CUSTOM ||
    1277           0 :          eInUnit == FUNIT_NONE ||
    1278           0 :          eInUnit == FUNIT_DEGREE ||
    1279           0 :          eInUnit == FUNIT_SECOND ||
    1280           0 :          eInUnit == FUNIT_MILLISECOND ||
    1281           0 :          eInUnit == FUNIT_PIXEL ||
    1282           0 :          eOutUnit == MAP_PIXEL ||
    1283           0 :          eOutUnit == MAP_SYSFONT ||
    1284           0 :          eOutUnit == MAP_APPFONT ||
    1285             :          eOutUnit == MAP_RELATIVE )
    1286             :     {
    1287             :         OSL_FAIL( "invalid parameters" );
    1288           0 :         return nValue;
    1289             :     }
    1290             : 
    1291           0 :     long nDecDigits = nDigits;
    1292           0 :     FieldUnit eFieldUnit = ImplMap2FieldUnit( eOutUnit, nDecDigits );
    1293             : 
    1294           0 :     if ( nDecDigits < 0 )
    1295             :     {
    1296           0 :         nValue *= ImplPower10(-nDecDigits);
    1297             :     }
    1298             :     else
    1299             :     {
    1300           0 :         nValue /= ImplPower10(nDecDigits);
    1301             :     }
    1302             : 
    1303           0 :     if ( eFieldUnit != eInUnit )
    1304             :     {
    1305           0 :         sal_Int64 nDiv  = aImplFactor[eInUnit][eFieldUnit];
    1306           0 :         sal_Int64 nMult = aImplFactor[eFieldUnit][eInUnit];
    1307             : 
    1308             :         DBG_ASSERT( nMult > 0, "illegal *" );
    1309             :         DBG_ASSERT( nDiv  > 0, "illegal /" );
    1310             : 
    1311           0 :         if( nMult != 1 && nMult > 0 )
    1312           0 :             nValue *= nMult;
    1313           0 :         if( nDiv != 1 && nDiv > 0 )
    1314             :         {
    1315           0 :             nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2);
    1316           0 :             nValue /= nDiv;
    1317             :         }
    1318             :     }
    1319           0 :     return nValue;
    1320             : }
    1321             : 
    1322           0 : static bool ImplMetricGetValue( const OUString& rStr, double& rValue, sal_Int64 nBaseValue,
    1323             :                                 sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrapper, FieldUnit eUnit )
    1324             : {
    1325             :     // Get value
    1326             :     sal_Int64 nValue;
    1327           0 :     if ( !ImplNumericGetValue( rStr, nValue, nDecDigits, rLocaleDataWrapper ) )
    1328           0 :         return false;
    1329             : 
    1330             :     // Determine unit
    1331           0 :     FieldUnit eEntryUnit = ImplMetricGetUnit( rStr );
    1332             : 
    1333             :     // Recalculate unit
    1334             :     // caution: conversion to double loses precision
    1335           0 :     rValue = MetricField::ConvertDoubleValue( (double)nValue, nBaseValue, nDecDigits, eEntryUnit, eUnit );
    1336             : 
    1337           0 :     return true;
    1338             : }
    1339             : 
    1340           0 : bool MetricFormatter::ImplMetricReformat( const OUString& rStr, double& rValue, OUString& rOutStr )
    1341             : {
    1342           0 :     if ( !ImplMetricGetValue( rStr, rValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) )
    1343           0 :         return true;
    1344             :     else
    1345             :     {
    1346           0 :         double nTempVal = rValue;
    1347             :         // caution: precision loss in double cast
    1348           0 :         if ( nTempVal > GetMax() )
    1349           0 :             nTempVal = (double)GetMax();
    1350           0 :         else if ( nTempVal < GetMin())
    1351           0 :             nTempVal = (double)GetMin();
    1352             : 
    1353           0 :         if ( GetErrorHdl().IsSet() && (rValue != nTempVal) )
    1354             :         {
    1355           0 :             mnCorrectedValue = (sal_Int64)nTempVal;
    1356           0 :             if ( !GetErrorHdl().Call( this ) )
    1357             :             {
    1358           0 :                 mnCorrectedValue = 0;
    1359           0 :                 return false;
    1360             :             }
    1361             :             else
    1362           0 :                 mnCorrectedValue = 0;
    1363             :         }
    1364             : 
    1365           0 :         rOutStr = CreateFieldText( (sal_Int64)nTempVal );
    1366           0 :         return true;
    1367             :     }
    1368             : }
    1369             : 
    1370           0 : inline void MetricFormatter::ImplInit()
    1371             : {
    1372           0 :     mnBaseValue = 0;
    1373           0 :     meUnit = MetricField::GetDefaultUnit();
    1374           0 :     mnType = FORMAT_METRIC;
    1375           0 : }
    1376             : 
    1377           0 : MetricFormatter::MetricFormatter()
    1378             : {
    1379           0 :     ImplInit();
    1380           0 : }
    1381             : 
    1382           0 : void MetricFormatter::ImplLoadRes( const ResId& rResId )
    1383             : {
    1384           0 :     NumericFormatter::ImplLoadRes( rResId );
    1385             : 
    1386           0 :     ResMgr*     pMgr = rResId.GetResMgr();
    1387           0 :     if( pMgr )
    1388             :     {
    1389           0 :         sal_uLong       nMask = pMgr->ReadLong();
    1390             : 
    1391           0 :         if ( METRICFORMATTER_UNIT & nMask )
    1392           0 :             meUnit = (FieldUnit)pMgr->ReadLong();
    1393             : 
    1394           0 :         if ( METRICFORMATTER_CUSTOMUNITTEXT & nMask )
    1395           0 :             maCustomUnitText = pMgr->ReadString();
    1396             :     }
    1397           0 : }
    1398             : 
    1399           0 : MetricFormatter::~MetricFormatter()
    1400             : {
    1401           0 : }
    1402             : 
    1403           0 : void MetricFormatter::SetUnit( FieldUnit eNewUnit )
    1404             : {
    1405           0 :     if ( eNewUnit == FUNIT_100TH_MM )
    1406             :     {
    1407           0 :         SetDecimalDigits( GetDecimalDigits() + 2 );
    1408           0 :         meUnit = FUNIT_MM;
    1409             :     }
    1410             :     else
    1411           0 :         meUnit = eNewUnit;
    1412           0 :     ReformatAll();
    1413           0 : }
    1414             : 
    1415           0 : void MetricFormatter::SetCustomUnitText( const OUString& rStr )
    1416             : {
    1417           0 :     maCustomUnitText = rStr;
    1418           0 :     ReformatAll();
    1419           0 : }
    1420             : 
    1421           0 : void MetricFormatter::SetValue( sal_Int64 nNewValue, FieldUnit eInUnit )
    1422             : {
    1423           0 :     SetUserValue( nNewValue, eInUnit );
    1424           0 :     mnFieldValue = mnLastValue;
    1425           0 : }
    1426             : 
    1427           0 : OUString MetricFormatter::CreateFieldText( sal_Int64 nValue ) const
    1428             : {
    1429             :     //whether percent is separated from its number is locale
    1430             :     //specific, pawn it off to icu to decide
    1431           0 :     if (meUnit == FUNIT_PERCENT)
    1432             :     {
    1433           0 :         double dValue = nValue;
    1434           0 :         dValue /= ImplPower10(GetDecimalDigits());
    1435           0 :         return unicode::formatPercent(dValue, Application::GetSettings().GetUILanguageTag());
    1436             :     }
    1437             : 
    1438           0 :     OUString aStr = NumericFormatter::CreateFieldText( nValue );
    1439             : 
    1440           0 :     if( meUnit == FUNIT_CUSTOM )
    1441           0 :         aStr += maCustomUnitText;
    1442             :     else
    1443             :     {
    1444           0 :         if (meUnit != FUNIT_NONE && meUnit != FUNIT_DEGREE)
    1445           0 :             aStr += " ";
    1446             :         assert(meUnit != FUNIT_PERCENT);
    1447           0 :         aStr += ImplMetricToString( meUnit );
    1448             :     }
    1449           0 :     return aStr;
    1450             : }
    1451             : 
    1452           0 : void MetricFormatter::SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit )
    1453             : {
    1454             :     // convert to previously configured units
    1455           0 :     nNewValue = MetricField::ConvertValue( nNewValue, mnBaseValue, GetDecimalDigits(), eInUnit, meUnit );
    1456           0 :     NumericFormatter::SetUserValue( nNewValue );
    1457           0 : }
    1458             : 
    1459           0 : sal_Int64 MetricFormatter::GetValue( FieldUnit eOutUnit ) const
    1460             : {
    1461           0 :     if ( !GetField() )
    1462           0 :         return 0;
    1463             : 
    1464             :     double nTempValue;
    1465             :     // caution: precision loss in double cast
    1466           0 :     if ( !ImplMetricGetValue( GetField()->GetText(), nTempValue, mnBaseValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit ) )
    1467           0 :         nTempValue = (double)mnLastValue;
    1468             : 
    1469             :     // caution: precision loss in double cast
    1470           0 :     if ( nTempValue > mnMax )
    1471           0 :         nTempValue = (double)mnMax;
    1472           0 :     else if ( nTempValue < mnMin )
    1473           0 :         nTempValue = (double)mnMin;
    1474             : 
    1475             :     // convert to requested units
    1476           0 :     return MetricField::ConvertValue( (sal_Int64)nTempValue, mnBaseValue, GetDecimalDigits(), meUnit, eOutUnit );
    1477             : }
    1478             : 
    1479           0 : void MetricFormatter::SetValue( sal_Int64 nValue )
    1480             : {
    1481             :     // Implementation not inline, because it is a virtual Function
    1482           0 :     SetValue( nValue, FUNIT_NONE );
    1483           0 : }
    1484             : 
    1485           0 : sal_Int64 MetricFormatter::GetValue() const
    1486             : {
    1487             :     // Implementation not inline, because it is a virtual Function
    1488           0 :     return GetValue( FUNIT_NONE );
    1489             : }
    1490             : 
    1491           0 : void MetricFormatter::SetMin( sal_Int64 nNewMin, FieldUnit eInUnit )
    1492             : {
    1493             :     // convert to requested units
    1494           0 :     NumericFormatter::SetMin( MetricField::ConvertValue( nNewMin, mnBaseValue, GetDecimalDigits(),
    1495           0 :                                                          eInUnit, meUnit ) );
    1496           0 : }
    1497             : 
    1498           0 : sal_Int64 MetricFormatter::GetMin( FieldUnit eOutUnit ) const
    1499             : {
    1500             :     // convert to requested units
    1501             :     return MetricField::ConvertValue( NumericFormatter::GetMin(), mnBaseValue,
    1502           0 :                                       GetDecimalDigits(), meUnit, eOutUnit );
    1503             : }
    1504             : 
    1505           0 : void MetricFormatter::SetMax( sal_Int64 nNewMax, FieldUnit eInUnit )
    1506             : {
    1507             :     // convert to requested units
    1508           0 :     NumericFormatter::SetMax( MetricField::ConvertValue( nNewMax, mnBaseValue, GetDecimalDigits(),
    1509           0 :                                                          eInUnit, meUnit ) );
    1510           0 : }
    1511             : 
    1512           0 : sal_Int64 MetricFormatter::GetMax( FieldUnit eOutUnit ) const
    1513             : {
    1514             :     // convert to requested units
    1515             :     return MetricField::ConvertValue( NumericFormatter::GetMax(), mnBaseValue,
    1516           0 :                                       GetDecimalDigits(), meUnit, eOutUnit );
    1517             : }
    1518             : 
    1519           0 : void MetricFormatter::SetBaseValue( sal_Int64 nNewBase, FieldUnit eInUnit )
    1520             : {
    1521           0 :     mnBaseValue = MetricField::ConvertValue( nNewBase, mnBaseValue, GetDecimalDigits(),
    1522           0 :                                              eInUnit, meUnit );
    1523           0 : }
    1524             : 
    1525           0 : sal_Int64 MetricFormatter::GetBaseValue( FieldUnit eOutUnit ) const
    1526             : {
    1527             :     // convert to requested units
    1528           0 :     return MetricField::ConvertValue( mnBaseValue, mnBaseValue, GetDecimalDigits(),
    1529           0 :                                       meUnit, eOutUnit );
    1530             : }
    1531             : 
    1532           0 : void MetricFormatter::Reformat()
    1533             : {
    1534           0 :     if ( !GetField() )
    1535           0 :         return;
    1536             : 
    1537           0 :     OUString aText = GetField()->GetText();
    1538           0 :     if ( meUnit == FUNIT_CUSTOM )
    1539           0 :         maCurUnitText = ImplMetricGetUnitText( aText );
    1540             : 
    1541           0 :     OUString aStr;
    1542             :     // caution: precision loss in double cast
    1543           0 :     double nTemp = (double)mnLastValue;
    1544           0 :     bool bOK = ImplMetricReformat( aText, nTemp, aStr );
    1545           0 :     mnLastValue = (sal_Int64)nTemp;
    1546             : 
    1547           0 :     if ( !bOK )
    1548           0 :         return;
    1549             : 
    1550           0 :     if ( !aStr.isEmpty() )
    1551             :     {
    1552           0 :         ImplSetText( aStr );
    1553           0 :         if ( meUnit == FUNIT_CUSTOM )
    1554           0 :             CustomConvert();
    1555             :     }
    1556             :     else
    1557           0 :         SetValue( mnLastValue );
    1558           0 :     maCurUnitText = OUString();
    1559             : }
    1560             : 
    1561           0 : sal_Int64 MetricFormatter::GetCorrectedValue( FieldUnit eOutUnit ) const
    1562             : {
    1563             :     // convert to requested units
    1564           0 :     return MetricField::ConvertValue( mnCorrectedValue, mnBaseValue, GetDecimalDigits(),
    1565           0 :                                       meUnit, eOutUnit );
    1566             : }
    1567             : 
    1568           0 : MetricField::MetricField( Window* pParent, WinBits nWinStyle ) :
    1569           0 :     SpinField( pParent, nWinStyle )
    1570             : {
    1571           0 :     SetField( this );
    1572           0 :     Reformat();
    1573           0 : }
    1574             : 
    1575           0 : MetricField::MetricField( Window* pParent, const ResId& rResId ) :
    1576           0 :     SpinField( WINDOW_METRICFIELD )
    1577             : {
    1578           0 :     rResId.SetRT( RSC_METRICFIELD );
    1579           0 :     WinBits nStyle = ImplInitRes( rResId ) ;
    1580           0 :     SpinField::ImplInit( pParent, nStyle );
    1581           0 :     SetField( this );
    1582           0 :     ImplLoadRes( rResId );
    1583             : 
    1584           0 :     if ( !(nStyle & WB_HIDE ) )
    1585           0 :         Show();
    1586           0 : }
    1587             : 
    1588           0 : Size MetricField::CalcMinimumSize() const
    1589             : {
    1590           0 :     return calcMinimumSize(*this, *this);
    1591             : }
    1592             : 
    1593           0 : bool MetricField::set_property(const OString &rKey, const OString &rValue)
    1594             : {
    1595           0 :     if (rKey == "digits")
    1596           0 :         SetDecimalDigits(rValue.toInt32());
    1597           0 :     else if (rKey == "spin-size")
    1598           0 :         SetSpinSize(rValue.toInt32());
    1599             :     else
    1600           0 :         return SpinField::set_property(rKey, rValue);
    1601           0 :     return true;
    1602             : }
    1603             : 
    1604           0 : void MetricField::ImplLoadRes( const ResId& rResId )
    1605             : {
    1606           0 :     SpinField::ImplLoadRes( rResId );
    1607           0 :     MetricFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
    1608             : 
    1609           0 :     sal_uLong      nMask = ReadLongRes();
    1610             : 
    1611           0 :     if ( METRICFIELD_FIRST & nMask )
    1612           0 :         mnFirst = ReadLongRes();
    1613             : 
    1614           0 :     if ( METRICFIELD_LAST & nMask )
    1615           0 :         mnLast = ReadLongRes();
    1616             : 
    1617           0 :     if ( METRICFIELD_SPINSIZE & nMask )
    1618           0 :         mnSpinSize = ReadLongRes();
    1619             : 
    1620           0 :     Reformat();
    1621           0 : }
    1622             : 
    1623           0 : MetricField::~MetricField()
    1624             : {
    1625           0 : }
    1626             : 
    1627           0 : void MetricField::SetUnit( FieldUnit nNewUnit )
    1628             : {
    1629           0 :     sal_Int64 nRawMax = GetMax( nNewUnit );
    1630           0 :     sal_Int64 nMax = Denormalize( nRawMax );
    1631           0 :     sal_Int64 nMin = Denormalize( GetMin( nNewUnit ) );
    1632           0 :     sal_Int64 nFirst = Denormalize( GetFirst( nNewUnit ) );
    1633           0 :     sal_Int64 nLast = Denormalize( GetLast( nNewUnit ) );
    1634             : 
    1635           0 :     MetricFormatter::SetUnit( nNewUnit );
    1636             : 
    1637           0 :     SetMax( Normalize( nMax ), nNewUnit );
    1638           0 :     SetMin( Normalize( nMin ), nNewUnit );
    1639           0 :     SetFirst( Normalize( nFirst ), nNewUnit );
    1640           0 :     SetLast( Normalize( nLast ), nNewUnit );
    1641           0 : }
    1642             : 
    1643           0 : void MetricField::SetFirst( sal_Int64 nNewFirst, FieldUnit eInUnit )
    1644             : {
    1645             :     // convert
    1646           0 :     nNewFirst = MetricField::ConvertValue( nNewFirst, mnBaseValue, GetDecimalDigits(),
    1647           0 :                                            eInUnit, meUnit );
    1648           0 :     mnFirst = nNewFirst;
    1649           0 : }
    1650             : 
    1651           0 : sal_Int64 MetricField::GetFirst( FieldUnit eOutUnit ) const
    1652             : {
    1653             :     // convert
    1654           0 :     return MetricField::ConvertValue( mnFirst, mnBaseValue, GetDecimalDigits(),
    1655           0 :                                       meUnit, eOutUnit );
    1656             : }
    1657             : 
    1658           0 : void MetricField::SetLast( sal_Int64 nNewLast, FieldUnit eInUnit )
    1659             : {
    1660             :     // convert
    1661           0 :     nNewLast = MetricField::ConvertValue( nNewLast, mnBaseValue, GetDecimalDigits(),
    1662           0 :                                           eInUnit, meUnit );
    1663           0 :     mnLast = nNewLast;
    1664           0 : }
    1665             : 
    1666           0 : sal_Int64 MetricField::GetLast( FieldUnit eOutUnit ) const
    1667             : {
    1668             :     // conver
    1669           0 :     return MetricField::ConvertValue( mnLast, mnBaseValue, GetDecimalDigits(),
    1670           0 :                                       meUnit, eOutUnit );
    1671             : }
    1672             : 
    1673           0 : bool MetricField::PreNotify( NotifyEvent& rNEvt )
    1674             : {
    1675           0 :     if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
    1676             :     {
    1677           0 :         if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
    1678           0 :             return true;
    1679             :     }
    1680             : 
    1681           0 :     return SpinField::PreNotify( rNEvt );
    1682             : }
    1683             : 
    1684           0 : bool MetricField::Notify( NotifyEvent& rNEvt )
    1685             : {
    1686           0 :     if ( rNEvt.GetType() == EVENT_GETFOCUS )
    1687           0 :         MarkToBeReformatted( false );
    1688           0 :     else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
    1689             :     {
    1690           0 :         if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
    1691           0 :             Reformat();
    1692             :     }
    1693             : 
    1694           0 :     return SpinField::Notify( rNEvt );
    1695             : }
    1696             : 
    1697           0 : void MetricField::DataChanged( const DataChangedEvent& rDCEvt )
    1698             : {
    1699           0 :     SpinField::DataChanged( rDCEvt );
    1700             : 
    1701           0 :     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
    1702             :     {
    1703           0 :         OUString sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
    1704           0 :         OUString sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
    1705           0 :         if ( IsDefaultLocale() )
    1706           0 :             ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
    1707           0 :         OUString sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
    1708           0 :         OUString sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
    1709           0 :         ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
    1710           0 :         ReformatAll();
    1711             :     }
    1712           0 : }
    1713             : 
    1714           0 : void MetricField::Modify()
    1715             : {
    1716           0 :     MarkToBeReformatted( true );
    1717           0 :     SpinField::Modify();
    1718           0 : }
    1719             : 
    1720           0 : void MetricField::Up()
    1721             : {
    1722           0 :     FieldUp();
    1723           0 :     SpinField::Up();
    1724           0 : }
    1725             : 
    1726           0 : void MetricField::Down()
    1727             : {
    1728           0 :     FieldDown();
    1729           0 :     SpinField::Down();
    1730           0 : }
    1731             : 
    1732           0 : void MetricField::First()
    1733             : {
    1734           0 :     FieldFirst();
    1735           0 :     SpinField::First();
    1736           0 : }
    1737             : 
    1738           0 : void MetricField::Last()
    1739             : {
    1740           0 :     FieldLast();
    1741           0 :     SpinField::Last();
    1742           0 : }
    1743             : 
    1744           0 : void MetricField::CustomConvert()
    1745             : {
    1746           0 :     maCustomConvertLink.Call( this );
    1747           0 : }
    1748             : 
    1749           0 : MetricBox::MetricBox( Window* pParent, WinBits nWinStyle ) :
    1750           0 :     ComboBox( pParent, nWinStyle )
    1751             : {
    1752           0 :     SetField( this );
    1753           0 :     Reformat();
    1754           0 : }
    1755             : 
    1756           0 : Size MetricBox::CalcMinimumSize() const
    1757             : {
    1758           0 :     Size aRet(calcMinimumSize(*this, *this));
    1759             : 
    1760           0 :     if (IsDropDownBox())
    1761             :     {
    1762           0 :         Size aComboSugg(ComboBox::CalcMinimumSize());
    1763           0 :         aRet.Width() = std::max(aRet.Width(), aComboSugg.Width());
    1764           0 :         aRet.Height() = std::max(aRet.Height(), aComboSugg.Height());
    1765             :     }
    1766             : 
    1767           0 :     return aRet;
    1768             : }
    1769             : 
    1770           0 : MetricBox::~MetricBox()
    1771             : {
    1772           0 : }
    1773             : 
    1774           0 : bool MetricBox::PreNotify( NotifyEvent& rNEvt )
    1775             : {
    1776           0 :     if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2()  )
    1777             :     {
    1778           0 :         if ( ImplMetricProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
    1779           0 :             return true;
    1780             :     }
    1781             : 
    1782           0 :     return ComboBox::PreNotify( rNEvt );
    1783             : }
    1784             : 
    1785           0 : bool MetricBox::Notify( NotifyEvent& rNEvt )
    1786             : {
    1787           0 :     if ( rNEvt.GetType() == EVENT_GETFOCUS )
    1788           0 :         MarkToBeReformatted( false );
    1789           0 :     else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
    1790             :     {
    1791           0 :         if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
    1792           0 :             Reformat();
    1793             :     }
    1794             : 
    1795           0 :     return ComboBox::Notify( rNEvt );
    1796             : }
    1797             : 
    1798           0 : void MetricBox::DataChanged( const DataChangedEvent& rDCEvt )
    1799             : {
    1800           0 :     ComboBox::DataChanged( rDCEvt );
    1801             : 
    1802           0 :     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
    1803             :     {
    1804           0 :         OUString sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
    1805           0 :         OUString sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
    1806           0 :         if ( IsDefaultLocale() )
    1807           0 :             ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
    1808           0 :         OUString sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
    1809           0 :         OUString sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
    1810           0 :         ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
    1811           0 :         ReformatAll();
    1812             :     }
    1813           0 : }
    1814             : 
    1815           0 : void MetricBox::Modify()
    1816             : {
    1817           0 :     MarkToBeReformatted( true );
    1818           0 :     ComboBox::Modify();
    1819           0 : }
    1820             : 
    1821           0 : void MetricBox::ReformatAll()
    1822             : {
    1823             :     double nValue;
    1824           0 :     OUString aStr;
    1825           0 :     SetUpdateMode( false );
    1826           0 :     sal_Int32 nEntryCount = GetEntryCount();
    1827           0 :     for ( sal_Int32 i=0; i < nEntryCount; i++ )
    1828             :     {
    1829           0 :         ImplMetricReformat( GetEntry( i ), nValue, aStr );
    1830           0 :         RemoveEntryAt(i);
    1831           0 :         InsertEntry( aStr, i );
    1832             :     }
    1833           0 :     MetricFormatter::Reformat();
    1834           0 :     SetUpdateMode( true );
    1835           0 : }
    1836             : 
    1837           0 : void MetricBox::CustomConvert()
    1838             : {
    1839           0 :     maCustomConvertLink.Call( this );
    1840           0 : }
    1841             : 
    1842           0 : void MetricBox::InsertValue( sal_Int64 nValue, FieldUnit eInUnit, sal_Int32 nPos )
    1843             : {
    1844             :     // convert to previously configured units
    1845           0 :     nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
    1846           0 :                                         eInUnit, meUnit );
    1847           0 :     ComboBox::InsertEntry( CreateFieldText( nValue ), nPos );
    1848           0 : }
    1849             : 
    1850           0 : sal_Int64 MetricBox::GetValue( sal_Int32 nPos, FieldUnit eOutUnit ) const
    1851             : {
    1852           0 :     double nValue = 0;
    1853             :     ImplMetricGetValue( ComboBox::GetEntry( nPos ), nValue, mnBaseValue,
    1854           0 :                         GetDecimalDigits(), ImplGetLocaleDataWrapper(), meUnit );
    1855             : 
    1856             :     // convert to previously configured units
    1857           0 :     sal_Int64 nRetValue = MetricField::ConvertValue( (sal_Int64)nValue, mnBaseValue, GetDecimalDigits(),
    1858           0 :                                                      meUnit, eOutUnit );
    1859             : 
    1860           0 :     return nRetValue;
    1861             : }
    1862             : 
    1863           0 : sal_Int32 MetricBox::GetValuePos( sal_Int64 nValue, FieldUnit eInUnit ) const
    1864             : {
    1865             :     // convert to previously configured units
    1866           0 :     nValue = MetricField::ConvertValue( nValue, mnBaseValue, GetDecimalDigits(),
    1867           0 :                                         eInUnit, meUnit );
    1868           0 :     return ComboBox::GetEntryPos( CreateFieldText( nValue ) );
    1869             : }
    1870             : 
    1871           0 : sal_Int64 MetricBox::GetValue( FieldUnit eOutUnit ) const
    1872             : {
    1873             :     // Implementation not inline, because it is a virtual Function
    1874           0 :     return MetricFormatter::GetValue( eOutUnit );
    1875             : }
    1876             : 
    1877           0 : sal_Int64 MetricBox::GetValue() const
    1878             : {
    1879             :     // Implementation not inline, because it is a virtual Function
    1880           0 :     return GetValue( FUNIT_NONE );
    1881             : }
    1882             : 
    1883           0 : static bool ImplCurrencyProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
    1884             :                                          bool, bool bUseThousandSep, const LocaleDataWrapper& rWrapper )
    1885             : {
    1886             :     // no strict format set; therefore allow all characters
    1887           0 :     return ImplNumericProcessKeyInput( pEdit, rKEvt, false, bUseThousandSep, rWrapper );
    1888             : }
    1889             : 
    1890           0 : inline bool ImplCurrencyGetValue( const OUString& rStr, sal_Int64& rValue,
    1891             :                                   sal_uInt16 nDecDigits, const LocaleDataWrapper& rWrapper )
    1892             : {
    1893             :     // fetch number
    1894           0 :     return ImplNumericGetValue( rStr, rValue, nDecDigits, rWrapper, true );
    1895             : }
    1896             : 
    1897           0 : bool CurrencyFormatter::ImplCurrencyReformat( const OUString& rStr, OUString& rOutStr )
    1898             : {
    1899             :     sal_Int64 nValue;
    1900           0 :     if ( !ImplNumericGetValue( rStr, nValue, GetDecimalDigits(), ImplGetLocaleDataWrapper(), true ) )
    1901           0 :         return true;
    1902             :     else
    1903             :     {
    1904           0 :         sal_Int64 nTempVal = nValue;
    1905           0 :         if ( nTempVal > GetMax() )
    1906           0 :             nTempVal = GetMax();
    1907           0 :         else if ( nTempVal < GetMin())
    1908           0 :             nTempVal = GetMin();
    1909             : 
    1910           0 :         if ( GetErrorHdl().IsSet() && (nValue != nTempVal) )
    1911             :         {
    1912           0 :             mnCorrectedValue = nTempVal;
    1913           0 :             if ( !GetErrorHdl().Call( this ) )
    1914             :             {
    1915           0 :                 mnCorrectedValue = 0;
    1916           0 :                 return false;
    1917             :             }
    1918             :             else
    1919           0 :                 mnCorrectedValue = 0;
    1920             :         }
    1921             : 
    1922           0 :         rOutStr = CreateFieldText( nTempVal );
    1923           0 :         return true;
    1924             :     }
    1925             : }
    1926             : 
    1927           0 : inline void CurrencyFormatter::ImplInit()
    1928             : {
    1929           0 :     mnType = FORMAT_CURRENCY;
    1930           0 : }
    1931             : 
    1932           0 : CurrencyFormatter::CurrencyFormatter()
    1933             : {
    1934           0 :     ImplInit();
    1935           0 : }
    1936             : 
    1937           0 : CurrencyFormatter::~CurrencyFormatter()
    1938             : {
    1939           0 : }
    1940             : 
    1941           0 : OUString CurrencyFormatter::GetCurrencySymbol() const
    1942             : {
    1943           0 :     return ImplGetLocaleDataWrapper().getCurrSymbol();
    1944             : }
    1945             : 
    1946           0 : void CurrencyFormatter::SetValue( sal_Int64 nNewValue )
    1947             : {
    1948           0 :     SetUserValue( nNewValue );
    1949           0 :     mnFieldValue = mnLastValue;
    1950           0 :     SetEmptyFieldValueData( false );
    1951           0 : }
    1952             : 
    1953           0 : OUString CurrencyFormatter::CreateFieldText( sal_Int64 nValue ) const
    1954             : {
    1955           0 :     return ImplGetLocaleDataWrapper().getCurr( nValue, GetDecimalDigits(), GetCurrencySymbol(), IsUseThousandSep() );
    1956             : }
    1957             : 
    1958           0 : sal_Int64 CurrencyFormatter::GetValue() const
    1959             : {
    1960           0 :     if ( !GetField() )
    1961           0 :         return 0;
    1962             : 
    1963             :     sal_Int64 nTempValue;
    1964           0 :     if ( ImplCurrencyGetValue( GetField()->GetText(), nTempValue, GetDecimalDigits(), ImplGetLocaleDataWrapper() ) )
    1965             :     {
    1966           0 :         if ( nTempValue > mnMax )
    1967           0 :             nTempValue = mnMax;
    1968           0 :         else if ( nTempValue < mnMin )
    1969           0 :             nTempValue = mnMin;
    1970           0 :         return nTempValue;
    1971             :     }
    1972             :     else
    1973           0 :         return mnLastValue;
    1974             : }
    1975             : 
    1976           0 : void CurrencyFormatter::Reformat()
    1977             : {
    1978           0 :     if ( !GetField() )
    1979           0 :         return;
    1980             : 
    1981           0 :     OUString aStr;
    1982           0 :     bool bOK = ImplCurrencyReformat( GetField()->GetText(), aStr );
    1983           0 :     if ( !bOK )
    1984           0 :         return;
    1985             : 
    1986           0 :     if ( !aStr.isEmpty() )
    1987             :     {
    1988           0 :         ImplSetText( aStr  );
    1989           0 :         sal_Int64 nTemp = mnLastValue;
    1990           0 :         ImplCurrencyGetValue( aStr, nTemp, GetDecimalDigits(), ImplGetLocaleDataWrapper() );
    1991           0 :         mnLastValue = nTemp;
    1992             :     }
    1993             :     else
    1994           0 :         SetValue( mnLastValue );
    1995             : }
    1996             : 
    1997           0 : CurrencyField::CurrencyField( Window* pParent, WinBits nWinStyle ) :
    1998           0 :     SpinField( pParent, nWinStyle )
    1999             : {
    2000           0 :     SetField( this );
    2001           0 :     Reformat();
    2002           0 : }
    2003             : 
    2004           0 : CurrencyField::~CurrencyField()
    2005             : {
    2006           0 : }
    2007             : 
    2008           0 : bool CurrencyField::PreNotify( NotifyEvent& rNEvt )
    2009             : {
    2010           0 :     if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
    2011             :     {
    2012           0 :         if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
    2013           0 :             return true;
    2014             :     }
    2015             : 
    2016           0 :     return SpinField::PreNotify( rNEvt );
    2017             : }
    2018             : 
    2019           0 : bool CurrencyField::Notify( NotifyEvent& rNEvt )
    2020             : {
    2021           0 :     if ( rNEvt.GetType() == EVENT_GETFOCUS )
    2022           0 :         MarkToBeReformatted( false );
    2023           0 :     else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
    2024             :     {
    2025           0 :         if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
    2026           0 :             Reformat();
    2027             :     }
    2028             : 
    2029           0 :     return SpinField::Notify( rNEvt );
    2030             : }
    2031             : 
    2032           0 : void CurrencyField::DataChanged( const DataChangedEvent& rDCEvt )
    2033             : {
    2034           0 :     SpinField::DataChanged( rDCEvt );
    2035             : 
    2036           0 :     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
    2037             :     {
    2038           0 :         OUString sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
    2039           0 :         OUString sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
    2040           0 :         if ( IsDefaultLocale() )
    2041           0 :             ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
    2042           0 :         OUString sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
    2043           0 :         OUString sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
    2044           0 :         ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
    2045           0 :         ReformatAll();
    2046             :     }
    2047           0 : }
    2048             : 
    2049           0 : void CurrencyField::Modify()
    2050             : {
    2051           0 :     MarkToBeReformatted( true );
    2052           0 :     SpinField::Modify();
    2053           0 : }
    2054             : 
    2055           0 : void CurrencyField::Up()
    2056             : {
    2057           0 :     FieldUp();
    2058           0 :     SpinField::Up();
    2059           0 : }
    2060             : 
    2061           0 : void CurrencyField::Down()
    2062             : {
    2063           0 :     FieldDown();
    2064           0 :     SpinField::Down();
    2065           0 : }
    2066             : 
    2067           0 : void CurrencyField::First()
    2068             : {
    2069           0 :     FieldFirst();
    2070           0 :     SpinField::First();
    2071           0 : }
    2072             : 
    2073           0 : void CurrencyField::Last()
    2074             : {
    2075           0 :     FieldLast();
    2076           0 :     SpinField::Last();
    2077           0 : }
    2078             : 
    2079           0 : CurrencyBox::CurrencyBox( Window* pParent, WinBits nWinStyle ) :
    2080           0 :     ComboBox( pParent, nWinStyle )
    2081             : {
    2082           0 :     SetField( this );
    2083           0 :     Reformat();
    2084           0 : }
    2085             : 
    2086           0 : CurrencyBox::~CurrencyBox()
    2087             : {
    2088           0 : }
    2089             : 
    2090           0 : bool CurrencyBox::PreNotify( NotifyEvent& rNEvt )
    2091             : {
    2092           0 :     if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
    2093             :     {
    2094           0 :         if ( ImplCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), ImplGetLocaleDataWrapper() ) )
    2095           0 :             return true;
    2096             :     }
    2097             : 
    2098           0 :     return ComboBox::PreNotify( rNEvt );
    2099             : }
    2100             : 
    2101           0 : bool CurrencyBox::Notify( NotifyEvent& rNEvt )
    2102             : {
    2103           0 :     if ( rNEvt.GetType() == EVENT_GETFOCUS )
    2104           0 :         MarkToBeReformatted( false );
    2105           0 :     else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
    2106             :     {
    2107           0 :         if ( MustBeReformatted() && (!GetText().isEmpty() || !IsEmptyFieldValueEnabled()) )
    2108           0 :             Reformat();
    2109             :     }
    2110             : 
    2111           0 :     return ComboBox::Notify( rNEvt );
    2112             : }
    2113             : 
    2114           0 : void CurrencyBox::DataChanged( const DataChangedEvent& rDCEvt )
    2115             : {
    2116           0 :     ComboBox::DataChanged( rDCEvt );
    2117             : 
    2118           0 :     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_LOCALE) )
    2119             :     {
    2120           0 :         OUString sOldDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
    2121           0 :         OUString sOldThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
    2122           0 :         if ( IsDefaultLocale() )
    2123           0 :             ImplGetLocaleDataWrapper().setLanguageTag( GetSettings().GetLanguageTag() );
    2124           0 :         OUString sNewDecSep = ImplGetLocaleDataWrapper().getNumDecimalSep();
    2125           0 :         OUString sNewThSep = ImplGetLocaleDataWrapper().getNumThousandSep();
    2126           0 :         ImplUpdateSeparators( sOldDecSep, sNewDecSep, sOldThSep, sNewThSep, this );
    2127           0 :         ReformatAll();
    2128             :     }
    2129           0 : }
    2130             : 
    2131           0 : void CurrencyBox::Modify()
    2132             : {
    2133           0 :     MarkToBeReformatted( true );
    2134           0 :     ComboBox::Modify();
    2135           0 : }
    2136             : 
    2137           0 : void CurrencyBox::ReformatAll()
    2138             : {
    2139           0 :     OUString aStr;
    2140           0 :     SetUpdateMode( false );
    2141           0 :     sal_Int32 nEntryCount = GetEntryCount();
    2142           0 :     for ( sal_Int32 i=0; i < nEntryCount; i++ )
    2143             :     {
    2144           0 :         ImplCurrencyReformat( GetEntry( i ), aStr );
    2145           0 :         RemoveEntryAt(i);
    2146           0 :         InsertEntry( aStr, i );
    2147             :     }
    2148           0 :     CurrencyFormatter::Reformat();
    2149           0 :     SetUpdateMode( true );
    2150           0 : }
    2151             : 
    2152           0 : sal_Int64 CurrencyBox::GetValue() const
    2153             : {
    2154             :     // Implementation not inline, because it is a virtual Function
    2155           0 :     return CurrencyFormatter::GetValue();
    2156             : }
    2157             : 
    2158             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10