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

Generated by: LCOV version 1.10