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

Generated by: LCOV version 1.10