1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_svtools.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <stdio.h> 32*cdf0e10cSrcweir #include <tools/debug.hxx> 33*cdf0e10cSrcweir #include <comphelper/processfactory.hxx> 34*cdf0e10cSrcweir #include <unotools/localedatawrapper.hxx> 35*cdf0e10cSrcweir #include <vcl/svapp.hxx> 36*cdf0e10cSrcweir #include <svl/zformat.hxx> 37*cdf0e10cSrcweir #include <svtools/fmtfield.hxx> 38*cdf0e10cSrcweir #include <i18npool/mslangid.hxx> 39*cdf0e10cSrcweir #include <com/sun/star/lang/Locale.hpp> 40*cdf0e10cSrcweir #include <com/sun/star/util/SearchOptions.hpp> 41*cdf0e10cSrcweir #include <com/sun/star/util/SearchAlgorithms.hpp> 42*cdf0e10cSrcweir #include <com/sun/star/util/SearchResult.hpp> 43*cdf0e10cSrcweir #include <com/sun/star/util/SearchFlags.hpp> 44*cdf0e10cSrcweir #include <com/sun/star/lang/Locale.hpp> 45*cdf0e10cSrcweir #include <unotools/syslocale.hxx> 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir #ifndef REGEXP_SUPPORT 48*cdf0e10cSrcweir #include <map> 49*cdf0e10cSrcweir #endif 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir #if !defined INCLUDED_RTL_MATH_HXX 52*cdf0e10cSrcweir #include <rtl/math.hxx> 53*cdf0e10cSrcweir #endif 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir using namespace ::com::sun::star::lang; 56*cdf0e10cSrcweir using namespace ::com::sun::star::util; 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir #ifdef REGEXP_SUPPORT 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir //============================================================================== 62*cdf0e10cSrcweir // regular expression to validate complete numbers, plus every fragment which can occur during the input 63*cdf0e10cSrcweir // of a complete number 64*cdf0e10cSrcweir // [+/-][{digit}*.]*{digit}*[,{digit}*][e[+/-]{digit}*] 65*cdf0e10cSrcweir const char __FAR_DATA szNumericInput[] = "_[-+]?([0-9]*\\,)*[0-9]*(\\.[0-9]*)?(e[-+]?[0-9]*)?_"; 66*cdf0e10cSrcweir // (the two _ are for normalizing it: With this, we can ensure that a to-be-checked text is always 67*cdf0e10cSrcweir // matched as a _whole_) 68*cdf0e10cSrcweir #else 69*cdf0e10cSrcweir 70*cdf0e10cSrcweir // hmm. No support for regular expression. Well, I always (not really :) wanted to write a finite automat 71*cdf0e10cSrcweir // so here comes a finite automat ... 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir namespace validation 74*cdf0e10cSrcweir { 75*cdf0e10cSrcweir // the states of our automat. 76*cdf0e10cSrcweir enum State 77*cdf0e10cSrcweir { 78*cdf0e10cSrcweir START, // at the very start of the string 79*cdf0e10cSrcweir NUM_START, // the very start of the number 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir DIGIT_PRE_COMMA, // some pre-comma digits are read, perhaps including some thousand separators 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir DIGIT_POST_COMMA, // reading digits after the comma 84*cdf0e10cSrcweir EXPONENT_START, // at the very start of the exponent value 85*cdf0e10cSrcweir // (means: not including the "e" which denotes the exponent) 86*cdf0e10cSrcweir EXPONENT_DIGIT, // currently reading the digits of the exponent 87*cdf0e10cSrcweir 88*cdf0e10cSrcweir END // reached the end of the string 89*cdf0e10cSrcweir }; 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir // a row in the transition table (means the set of states to be reached from a given state) 92*cdf0e10cSrcweir typedef ::std::map< sal_Unicode, State > StateTransitions; 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir // a single transition 95*cdf0e10cSrcweir typedef StateTransitions::value_type Transition; 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir // the complete transition table 98*cdf0e10cSrcweir typedef ::std::map< State, StateTransitions > TransitionTable; 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir // the validator class 101*cdf0e10cSrcweir class NumberValidator 102*cdf0e10cSrcweir { 103*cdf0e10cSrcweir private: 104*cdf0e10cSrcweir TransitionTable m_aTransitions; 105*cdf0e10cSrcweir const sal_Unicode m_cThSep; 106*cdf0e10cSrcweir const sal_Unicode m_cDecSep; 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir public: 109*cdf0e10cSrcweir NumberValidator( const sal_Unicode _cThSep, const sal_Unicode _cDecSep ); 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir sal_Bool isValidNumericFragment( const String& _rText ); 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir private: 114*cdf0e10cSrcweir sal_Bool implValidateNormalized( const String& _rText ); 115*cdf0e10cSrcweir }; 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir //-------------------------------------------------------------------------- 118*cdf0e10cSrcweir //.......................................................................... 119*cdf0e10cSrcweir static void lcl_insertStopTransition( StateTransitions& _rRow ) 120*cdf0e10cSrcweir { 121*cdf0e10cSrcweir _rRow.insert( Transition( '_', END ) ); 122*cdf0e10cSrcweir } 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir //.......................................................................... 125*cdf0e10cSrcweir static void lcl_insertStartExponentTransition( StateTransitions& _rRow ) 126*cdf0e10cSrcweir { 127*cdf0e10cSrcweir _rRow.insert( Transition( 'e', EXPONENT_START ) ); 128*cdf0e10cSrcweir } 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir //.......................................................................... 131*cdf0e10cSrcweir static void lcl_insertSignTransitions( StateTransitions& _rRow, const State eNextState ) 132*cdf0e10cSrcweir { 133*cdf0e10cSrcweir _rRow.insert( Transition( '-', eNextState ) ); 134*cdf0e10cSrcweir _rRow.insert( Transition( '+', eNextState ) ); 135*cdf0e10cSrcweir } 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir //.......................................................................... 138*cdf0e10cSrcweir static void lcl_insertDigitTransitions( StateTransitions& _rRow, const State eNextState ) 139*cdf0e10cSrcweir { 140*cdf0e10cSrcweir for ( sal_Unicode aChar = '0'; aChar <= '9'; ++aChar ) 141*cdf0e10cSrcweir _rRow.insert( Transition( aChar, eNextState ) ); 142*cdf0e10cSrcweir } 143*cdf0e10cSrcweir 144*cdf0e10cSrcweir //.......................................................................... 145*cdf0e10cSrcweir static void lcl_insertCommonPreCommaTransitions( StateTransitions& _rRow, const sal_Unicode _cThSep, const sal_Unicode _cDecSep ) 146*cdf0e10cSrcweir { 147*cdf0e10cSrcweir // digits are allowed 148*cdf0e10cSrcweir lcl_insertDigitTransitions( _rRow, DIGIT_PRE_COMMA ); 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir // the thousand separator is allowed 151*cdf0e10cSrcweir _rRow.insert( Transition( _cThSep, DIGIT_PRE_COMMA ) ); 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir // a comma is allowed 154*cdf0e10cSrcweir _rRow.insert( Transition( _cDecSep, DIGIT_POST_COMMA ) ); 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir //-------------------------------------------------------------------------- 158*cdf0e10cSrcweir NumberValidator::NumberValidator( const sal_Unicode _cThSep, const sal_Unicode _cDecSep ) 159*cdf0e10cSrcweir :m_cThSep( _cThSep ) 160*cdf0e10cSrcweir ,m_cDecSep( _cDecSep ) 161*cdf0e10cSrcweir { 162*cdf0e10cSrcweir // build up our transition table 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir // how to procede from START 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir StateTransitions& rRow = m_aTransitions[ START ]; 167*cdf0e10cSrcweir rRow.insert( Transition( '_', NUM_START ) ); 168*cdf0e10cSrcweir // if we encounter the normalizing character, we want to procede with the number 169*cdf0e10cSrcweir } 170*cdf0e10cSrcweir 171*cdf0e10cSrcweir // how to procede from NUM_START 172*cdf0e10cSrcweir { 173*cdf0e10cSrcweir StateTransitions& rRow = m_aTransitions[ NUM_START ]; 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir // a sign is allowed 176*cdf0e10cSrcweir lcl_insertSignTransitions( rRow, DIGIT_PRE_COMMA ); 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir // common transitions for the two pre-comma states 179*cdf0e10cSrcweir lcl_insertCommonPreCommaTransitions( rRow, m_cThSep, m_cDecSep ); 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir // the exponent may start here 182*cdf0e10cSrcweir // (this would mean string like "_+e10_", but this is a valid fragment, though no valid number) 183*cdf0e10cSrcweir lcl_insertStartExponentTransition( rRow ); 184*cdf0e10cSrcweir } 185*cdf0e10cSrcweir 186*cdf0e10cSrcweir // how to procede from DIGIT_PRE_COMMA 187*cdf0e10cSrcweir { 188*cdf0e10cSrcweir StateTransitions& rRow = m_aTransitions[ DIGIT_PRE_COMMA ]; 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir // common transitions for the two pre-comma states 191*cdf0e10cSrcweir lcl_insertCommonPreCommaTransitions( rRow, m_cThSep, m_cDecSep ); 192*cdf0e10cSrcweir 193*cdf0e10cSrcweir // the exponent may start here 194*cdf0e10cSrcweir lcl_insertStartExponentTransition( rRow ); 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir // the final transition indicating the end of the string 197*cdf0e10cSrcweir // (if there is no comma and no post-comma, then the string may end here) 198*cdf0e10cSrcweir lcl_insertStopTransition( rRow ); 199*cdf0e10cSrcweir } 200*cdf0e10cSrcweir 201*cdf0e10cSrcweir // how to procede from DIGIT_POST_COMMA 202*cdf0e10cSrcweir { 203*cdf0e10cSrcweir StateTransitions& rRow = m_aTransitions[ DIGIT_POST_COMMA ]; 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir // there might be digits, which would keep the state at DIGIT_POST_COMMA 206*cdf0e10cSrcweir lcl_insertDigitTransitions( rRow, DIGIT_POST_COMMA ); 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir // the exponent may start here 209*cdf0e10cSrcweir lcl_insertStartExponentTransition( rRow ); 210*cdf0e10cSrcweir 211*cdf0e10cSrcweir // the string may end here 212*cdf0e10cSrcweir lcl_insertStopTransition( rRow ); 213*cdf0e10cSrcweir } 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir // how to procede from EXPONENT_START 216*cdf0e10cSrcweir { 217*cdf0e10cSrcweir StateTransitions& rRow = m_aTransitions[ EXPONENT_START ]; 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir // there may be a sign 220*cdf0e10cSrcweir lcl_insertSignTransitions( rRow, EXPONENT_DIGIT ); 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir // there may be digits 223*cdf0e10cSrcweir lcl_insertDigitTransitions( rRow, EXPONENT_DIGIT ); 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir // the string may end here 226*cdf0e10cSrcweir lcl_insertStopTransition( rRow ); 227*cdf0e10cSrcweir } 228*cdf0e10cSrcweir 229*cdf0e10cSrcweir // how to procede from EXPONENT_DIGIT 230*cdf0e10cSrcweir { 231*cdf0e10cSrcweir StateTransitions& rRow = m_aTransitions[ EXPONENT_DIGIT ]; 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir // there may be digits 234*cdf0e10cSrcweir lcl_insertDigitTransitions( rRow, EXPONENT_DIGIT ); 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir // the string may end here 237*cdf0e10cSrcweir lcl_insertStopTransition( rRow ); 238*cdf0e10cSrcweir } 239*cdf0e10cSrcweir 240*cdf0e10cSrcweir // how to procede from END 241*cdf0e10cSrcweir { 242*cdf0e10cSrcweir /*StateTransitions& rRow =*/ m_aTransitions[ EXPONENT_DIGIT ]; 243*cdf0e10cSrcweir // no valid transition to leave this state 244*cdf0e10cSrcweir // (note that we, for consistency, nevertheless want to have a row in the table) 245*cdf0e10cSrcweir } 246*cdf0e10cSrcweir } 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir //-------------------------------------------------------------------------- 249*cdf0e10cSrcweir sal_Bool NumberValidator::implValidateNormalized( const String& _rText ) 250*cdf0e10cSrcweir { 251*cdf0e10cSrcweir const sal_Unicode* pCheckPos = _rText.GetBuffer(); 252*cdf0e10cSrcweir State eCurrentState = START; 253*cdf0e10cSrcweir 254*cdf0e10cSrcweir while ( END != eCurrentState ) 255*cdf0e10cSrcweir { 256*cdf0e10cSrcweir // look up the transition row for the current state 257*cdf0e10cSrcweir TransitionTable::const_iterator aRow = m_aTransitions.find( eCurrentState ); 258*cdf0e10cSrcweir DBG_ASSERT( m_aTransitions.end() != aRow, 259*cdf0e10cSrcweir "NumberValidator::implValidateNormalized: invalid transition table (row not found)!" ); 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir if ( m_aTransitions.end() != aRow ) 262*cdf0e10cSrcweir { 263*cdf0e10cSrcweir // look up the current character in this row 264*cdf0e10cSrcweir StateTransitions::const_iterator aTransition = aRow->second.find( *pCheckPos ); 265*cdf0e10cSrcweir if ( aRow->second.end() != aTransition ) 266*cdf0e10cSrcweir { 267*cdf0e10cSrcweir // there is a valid transition for this character 268*cdf0e10cSrcweir eCurrentState = aTransition->second; 269*cdf0e10cSrcweir ++pCheckPos; 270*cdf0e10cSrcweir continue; 271*cdf0e10cSrcweir } 272*cdf0e10cSrcweir } 273*cdf0e10cSrcweir 274*cdf0e10cSrcweir // if we're here, there is no valid transition 275*cdf0e10cSrcweir break; 276*cdf0e10cSrcweir } 277*cdf0e10cSrcweir 278*cdf0e10cSrcweir DBG_ASSERT( ( END != eCurrentState ) || ( 0 == *pCheckPos ), 279*cdf0e10cSrcweir "NumberValidator::implValidateNormalized: inconsistency!" ); 280*cdf0e10cSrcweir // if we're at END, then the string should be done, too - the string should be normalized, means ending 281*cdf0e10cSrcweir // a "_" and not containing any other "_" (except at the start), and "_" is the only possibility 282*cdf0e10cSrcweir // to reach the END state 283*cdf0e10cSrcweir 284*cdf0e10cSrcweir // the string is valid if and only if we reached the final state 285*cdf0e10cSrcweir return ( END == eCurrentState ); 286*cdf0e10cSrcweir } 287*cdf0e10cSrcweir 288*cdf0e10cSrcweir //-------------------------------------------------------------------------- 289*cdf0e10cSrcweir sal_Bool NumberValidator::isValidNumericFragment( const String& _rText ) 290*cdf0e10cSrcweir { 291*cdf0e10cSrcweir if ( !_rText.Len() ) 292*cdf0e10cSrcweir // empty strings are always allowed 293*cdf0e10cSrcweir return sal_True; 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir // normalize the string 296*cdf0e10cSrcweir String sNormalized( RTL_CONSTASCII_STRINGPARAM( "_") ); 297*cdf0e10cSrcweir sNormalized.Append( _rText ); 298*cdf0e10cSrcweir sNormalized.AppendAscii( "_" ); 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir return implValidateNormalized( sNormalized ); 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir } 303*cdf0e10cSrcweir 304*cdf0e10cSrcweir #endif 305*cdf0e10cSrcweir 306*cdf0e10cSrcweir //============================================================================== 307*cdf0e10cSrcweir SvNumberFormatter* FormattedField::StaticFormatter::s_cFormatter = NULL; 308*cdf0e10cSrcweir sal_uLong FormattedField::StaticFormatter::s_nReferences = 0; 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir //------------------------------------------------------------------------------ 311*cdf0e10cSrcweir SvNumberFormatter* FormattedField::StaticFormatter::GetFormatter() 312*cdf0e10cSrcweir { 313*cdf0e10cSrcweir if (!s_cFormatter) 314*cdf0e10cSrcweir { 315*cdf0e10cSrcweir // get the Office's locale and translate 316*cdf0e10cSrcweir LanguageType eSysLanguage = MsLangId::convertLocaleToLanguage( 317*cdf0e10cSrcweir SvtSysLocale().GetLocaleData().getLocale() ); 318*cdf0e10cSrcweir s_cFormatter = new SvNumberFormatter( 319*cdf0e10cSrcweir ::comphelper::getProcessServiceFactory(), 320*cdf0e10cSrcweir eSysLanguage); 321*cdf0e10cSrcweir } 322*cdf0e10cSrcweir return s_cFormatter; 323*cdf0e10cSrcweir } 324*cdf0e10cSrcweir 325*cdf0e10cSrcweir //------------------------------------------------------------------------------ 326*cdf0e10cSrcweir FormattedField::StaticFormatter::StaticFormatter() 327*cdf0e10cSrcweir { 328*cdf0e10cSrcweir ++s_nReferences; 329*cdf0e10cSrcweir } 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir //------------------------------------------------------------------------------ 332*cdf0e10cSrcweir FormattedField::StaticFormatter::~StaticFormatter() 333*cdf0e10cSrcweir { 334*cdf0e10cSrcweir if (--s_nReferences == 0) 335*cdf0e10cSrcweir { 336*cdf0e10cSrcweir delete s_cFormatter; 337*cdf0e10cSrcweir s_cFormatter = NULL; 338*cdf0e10cSrcweir } 339*cdf0e10cSrcweir } 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir //============================================================================== 342*cdf0e10cSrcweir DBG_NAME(FormattedField); 343*cdf0e10cSrcweir 344*cdf0e10cSrcweir #define INIT_MEMBERS() \ 345*cdf0e10cSrcweir m_aLastSelection(0,0) \ 346*cdf0e10cSrcweir ,m_dMinValue(0) \ 347*cdf0e10cSrcweir ,m_dMaxValue(0) \ 348*cdf0e10cSrcweir ,m_bHasMin(sal_False) \ 349*cdf0e10cSrcweir ,m_bHasMax(sal_False) \ 350*cdf0e10cSrcweir ,m_bStrictFormat(sal_True) \ 351*cdf0e10cSrcweir ,m_bValueDirty(sal_True) \ 352*cdf0e10cSrcweir ,m_bEnableEmptyField(sal_True) \ 353*cdf0e10cSrcweir ,m_bAutoColor(sal_False) \ 354*cdf0e10cSrcweir ,m_bEnableNaN(sal_False) \ 355*cdf0e10cSrcweir ,m_dCurrentValue(0) \ 356*cdf0e10cSrcweir ,m_dDefaultValue(0) \ 357*cdf0e10cSrcweir ,m_nFormatKey(0) \ 358*cdf0e10cSrcweir ,m_pFormatter(NULL) \ 359*cdf0e10cSrcweir ,m_dSpinSize(1) \ 360*cdf0e10cSrcweir ,m_dSpinFirst(-1000000) \ 361*cdf0e10cSrcweir ,m_dSpinLast(1000000) \ 362*cdf0e10cSrcweir ,m_bTreatAsNumber(sal_True) \ 363*cdf0e10cSrcweir ,m_pLastOutputColor(NULL) \ 364*cdf0e10cSrcweir ,m_bUseInputStringForFormatting(false) 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir //------------------------------------------------------------------------------ 367*cdf0e10cSrcweir FormattedField::FormattedField(Window* pParent, WinBits nStyle, SvNumberFormatter* pInitialFormatter, sal_Int32 nFormatKey) 368*cdf0e10cSrcweir :SpinField(pParent, nStyle) 369*cdf0e10cSrcweir ,INIT_MEMBERS() 370*cdf0e10cSrcweir { 371*cdf0e10cSrcweir DBG_CTOR(FormattedField, NULL); 372*cdf0e10cSrcweir 373*cdf0e10cSrcweir if (pInitialFormatter) 374*cdf0e10cSrcweir { 375*cdf0e10cSrcweir m_pFormatter = pInitialFormatter; 376*cdf0e10cSrcweir m_nFormatKey = nFormatKey; 377*cdf0e10cSrcweir } 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir 380*cdf0e10cSrcweir //------------------------------------------------------------------------------ 381*cdf0e10cSrcweir FormattedField::FormattedField(Window* pParent, const ResId& rResId, SvNumberFormatter* pInitialFormatter, sal_Int32 nFormatKey) 382*cdf0e10cSrcweir :SpinField(pParent, rResId) 383*cdf0e10cSrcweir ,INIT_MEMBERS() 384*cdf0e10cSrcweir { 385*cdf0e10cSrcweir DBG_CTOR(FormattedField, NULL); 386*cdf0e10cSrcweir 387*cdf0e10cSrcweir if (pInitialFormatter) 388*cdf0e10cSrcweir { 389*cdf0e10cSrcweir m_pFormatter = pInitialFormatter; 390*cdf0e10cSrcweir m_nFormatKey = nFormatKey; 391*cdf0e10cSrcweir } 392*cdf0e10cSrcweir } 393*cdf0e10cSrcweir 394*cdf0e10cSrcweir //------------------------------------------------------------------------------ 395*cdf0e10cSrcweir FormattedField::~FormattedField() 396*cdf0e10cSrcweir { 397*cdf0e10cSrcweir DBG_DTOR(FormattedField, NULL); 398*cdf0e10cSrcweir } 399*cdf0e10cSrcweir 400*cdf0e10cSrcweir //------------------------------------------------------------------------------ 401*cdf0e10cSrcweir void FormattedField::SetValidateText(const XubString& rText, const String* pErrorText) 402*cdf0e10cSrcweir { 403*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 404*cdf0e10cSrcweir 405*cdf0e10cSrcweir if (CheckText(rText)) 406*cdf0e10cSrcweir SetText(rText); 407*cdf0e10cSrcweir else 408*cdf0e10cSrcweir if (pErrorText) 409*cdf0e10cSrcweir ImplSetTextImpl(*pErrorText, NULL); 410*cdf0e10cSrcweir else 411*cdf0e10cSrcweir ImplSetValue(m_dDefaultValue, sal_True); 412*cdf0e10cSrcweir } 413*cdf0e10cSrcweir 414*cdf0e10cSrcweir //------------------------------------------------------------------------------ 415*cdf0e10cSrcweir void FormattedField::SetText(const XubString& rStr) 416*cdf0e10cSrcweir { 417*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 418*cdf0e10cSrcweir 419*cdf0e10cSrcweir SpinField::SetText(rStr); 420*cdf0e10cSrcweir m_bValueDirty = sal_True; 421*cdf0e10cSrcweir } 422*cdf0e10cSrcweir 423*cdf0e10cSrcweir //------------------------------------------------------------------------------ 424*cdf0e10cSrcweir void FormattedField::SetText( const XubString& rStr, const Selection& rNewSelection ) 425*cdf0e10cSrcweir { 426*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir SpinField::SetText( rStr, rNewSelection ); 429*cdf0e10cSrcweir m_bValueDirty = sal_True; 430*cdf0e10cSrcweir } 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir //------------------------------------------------------------------------------ 433*cdf0e10cSrcweir void FormattedField::SetTextFormatted(const XubString& rStr) 434*cdf0e10cSrcweir { 435*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir #if defined DBG_UTIL 438*cdf0e10cSrcweir if (ImplGetFormatter()->IsTextFormat(m_nFormatKey)) 439*cdf0e10cSrcweir DBG_WARNING("FormattedField::SetTextFormatted : valid only with text formats !"); 440*cdf0e10cSrcweir #endif 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir m_sCurrentTextValue = rStr; 443*cdf0e10cSrcweir 444*cdf0e10cSrcweir String sFormatted; 445*cdf0e10cSrcweir double dNumber = 0.0; 446*cdf0e10cSrcweir // IsNumberFormat changes the format key parameter 447*cdf0e10cSrcweir sal_uInt32 nTempFormatKey = static_cast< sal_uInt32 >( m_nFormatKey ); 448*cdf0e10cSrcweir if( IsUsingInputStringForFormatting() && 449*cdf0e10cSrcweir ImplGetFormatter()->IsNumberFormat(m_sCurrentTextValue, nTempFormatKey, dNumber) ) 450*cdf0e10cSrcweir ImplGetFormatter()->GetInputLineString(dNumber, m_nFormatKey, sFormatted); 451*cdf0e10cSrcweir else 452*cdf0e10cSrcweir ImplGetFormatter()->GetOutputString(m_sCurrentTextValue, m_nFormatKey, sFormatted, &m_pLastOutputColor); 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir // calculate the new selection 455*cdf0e10cSrcweir Selection aSel(GetSelection()); 456*cdf0e10cSrcweir Selection aNewSel(aSel); 457*cdf0e10cSrcweir aNewSel.Justify(); 458*cdf0e10cSrcweir sal_uInt16 nNewLen = sFormatted.Len(); 459*cdf0e10cSrcweir sal_uInt16 nCurrentLen = GetText().Len(); 460*cdf0e10cSrcweir if ((nNewLen > nCurrentLen) && (aNewSel.Max() == nCurrentLen)) 461*cdf0e10cSrcweir { // the new text is longer and the cursor was behind the last char (of the old text) 462*cdf0e10cSrcweir if (aNewSel.Min() == 0) 463*cdf0e10cSrcweir { // the whole text was selected -> select the new text on the whole, too 464*cdf0e10cSrcweir aNewSel.Max() = nNewLen; 465*cdf0e10cSrcweir if (!nCurrentLen) 466*cdf0e10cSrcweir { // there wasn't really a previous selection (as there was no previous text), we're setting a new one -> check the selection options 467*cdf0e10cSrcweir sal_uLong nSelOptions = GetSettings().GetStyleSettings().GetSelectionOptions(); 468*cdf0e10cSrcweir if (nSelOptions & SELECTION_OPTION_SHOWFIRST) 469*cdf0e10cSrcweir { // selection should be from right to left -> swap min and max 470*cdf0e10cSrcweir aNewSel.Min() = aNewSel.Max(); 471*cdf0e10cSrcweir aNewSel.Max() = 0; 472*cdf0e10cSrcweir } 473*cdf0e10cSrcweir } 474*cdf0e10cSrcweir } 475*cdf0e10cSrcweir else if (aNewSel.Max() == aNewSel.Min()) 476*cdf0e10cSrcweir { // there was no selection -> set the cursor behind the new last char 477*cdf0e10cSrcweir aNewSel.Max() = nNewLen; 478*cdf0e10cSrcweir aNewSel.Min() = nNewLen; 479*cdf0e10cSrcweir } 480*cdf0e10cSrcweir } 481*cdf0e10cSrcweir else if (aNewSel.Max() > nNewLen) 482*cdf0e10cSrcweir aNewSel.Max() = nNewLen; 483*cdf0e10cSrcweir else 484*cdf0e10cSrcweir aNewSel = aSel; // don't use the justified version 485*cdf0e10cSrcweir SpinField::SetText(sFormatted, aNewSel); 486*cdf0e10cSrcweir m_bValueDirty = sal_False; 487*cdf0e10cSrcweir } 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir //------------------------------------------------------------------------------ 490*cdf0e10cSrcweir String FormattedField::GetTextValue() const 491*cdf0e10cSrcweir { 492*cdf0e10cSrcweir if (m_bValueDirty) 493*cdf0e10cSrcweir { 494*cdf0e10cSrcweir ((FormattedField*)this)->m_sCurrentTextValue = GetText(); 495*cdf0e10cSrcweir ((FormattedField*)this)->m_bValueDirty = sal_False; 496*cdf0e10cSrcweir } 497*cdf0e10cSrcweir return m_sCurrentTextValue; 498*cdf0e10cSrcweir } 499*cdf0e10cSrcweir 500*cdf0e10cSrcweir //------------------------------------------------------------------------------ 501*cdf0e10cSrcweir void FormattedField::EnableNotANumber( sal_Bool _bEnable ) 502*cdf0e10cSrcweir { 503*cdf0e10cSrcweir if ( m_bEnableNaN == _bEnable ) 504*cdf0e10cSrcweir return; 505*cdf0e10cSrcweir 506*cdf0e10cSrcweir m_bEnableNaN = _bEnable; 507*cdf0e10cSrcweir } 508*cdf0e10cSrcweir 509*cdf0e10cSrcweir //------------------------------------------------------------------------------ 510*cdf0e10cSrcweir void FormattedField::SetAutoColor(sal_Bool _bAutomatic) 511*cdf0e10cSrcweir { 512*cdf0e10cSrcweir if (_bAutomatic == m_bAutoColor) 513*cdf0e10cSrcweir return; 514*cdf0e10cSrcweir 515*cdf0e10cSrcweir m_bAutoColor = _bAutomatic; 516*cdf0e10cSrcweir if (m_bAutoColor) 517*cdf0e10cSrcweir { // if auto color is switched on, adjust the current text color, too 518*cdf0e10cSrcweir if (m_pLastOutputColor) 519*cdf0e10cSrcweir SetControlForeground(*m_pLastOutputColor); 520*cdf0e10cSrcweir else 521*cdf0e10cSrcweir SetControlForeground(); 522*cdf0e10cSrcweir } 523*cdf0e10cSrcweir } 524*cdf0e10cSrcweir 525*cdf0e10cSrcweir //------------------------------------------------------------------------------ 526*cdf0e10cSrcweir void FormattedField::Modify() 527*cdf0e10cSrcweir { 528*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir if (!IsStrictFormat()) 531*cdf0e10cSrcweir { 532*cdf0e10cSrcweir m_bValueDirty = sal_True; 533*cdf0e10cSrcweir SpinField::Modify(); 534*cdf0e10cSrcweir return; 535*cdf0e10cSrcweir } 536*cdf0e10cSrcweir 537*cdf0e10cSrcweir String sCheck = GetText(); 538*cdf0e10cSrcweir if (CheckText(sCheck)) 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir m_sLastValidText = sCheck; 541*cdf0e10cSrcweir m_aLastSelection = GetSelection(); 542*cdf0e10cSrcweir m_bValueDirty = sal_True; 543*cdf0e10cSrcweir } 544*cdf0e10cSrcweir else 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir ImplSetTextImpl(m_sLastValidText, &m_aLastSelection); 547*cdf0e10cSrcweir } 548*cdf0e10cSrcweir 549*cdf0e10cSrcweir SpinField::Modify(); 550*cdf0e10cSrcweir } 551*cdf0e10cSrcweir 552*cdf0e10cSrcweir //------------------------------------------------------------------------------ 553*cdf0e10cSrcweir void FormattedField::ImplSetTextImpl(const XubString& rNew, Selection* pNewSel) 554*cdf0e10cSrcweir { 555*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 556*cdf0e10cSrcweir 557*cdf0e10cSrcweir if (m_bAutoColor) 558*cdf0e10cSrcweir { 559*cdf0e10cSrcweir if (m_pLastOutputColor) 560*cdf0e10cSrcweir SetControlForeground(*m_pLastOutputColor); 561*cdf0e10cSrcweir else 562*cdf0e10cSrcweir SetControlForeground(); 563*cdf0e10cSrcweir } 564*cdf0e10cSrcweir 565*cdf0e10cSrcweir if (pNewSel) 566*cdf0e10cSrcweir SpinField::SetText(rNew, *pNewSel); 567*cdf0e10cSrcweir else 568*cdf0e10cSrcweir { 569*cdf0e10cSrcweir Selection aSel(GetSelection()); 570*cdf0e10cSrcweir aSel.Justify(); 571*cdf0e10cSrcweir 572*cdf0e10cSrcweir sal_uInt16 nNewLen = rNew.Len(); 573*cdf0e10cSrcweir sal_uInt16 nCurrentLen = GetText().Len(); 574*cdf0e10cSrcweir 575*cdf0e10cSrcweir if ((nNewLen > nCurrentLen) && (aSel.Max() == nCurrentLen)) 576*cdf0e10cSrcweir { // new new text is longer and the cursor is behind the last char 577*cdf0e10cSrcweir if (aSel.Min() == 0) 578*cdf0e10cSrcweir { // the whole text was selected -> select the new text on the whole, too 579*cdf0e10cSrcweir aSel.Max() = nNewLen; 580*cdf0e10cSrcweir if (!nCurrentLen) 581*cdf0e10cSrcweir { // there wasn't really a previous selection (as there was no previous text), we're setting a new one -> check the selection options 582*cdf0e10cSrcweir sal_uLong nSelOptions = GetSettings().GetStyleSettings().GetSelectionOptions(); 583*cdf0e10cSrcweir if (nSelOptions & SELECTION_OPTION_SHOWFIRST) 584*cdf0e10cSrcweir { // selection should be from right to left -> swap min and max 585*cdf0e10cSrcweir aSel.Min() = aSel.Max(); 586*cdf0e10cSrcweir aSel.Max() = 0; 587*cdf0e10cSrcweir } 588*cdf0e10cSrcweir } 589*cdf0e10cSrcweir } 590*cdf0e10cSrcweir else if (aSel.Max() == aSel.Min()) 591*cdf0e10cSrcweir { // there was no selection -> set the cursor behind the new last char 592*cdf0e10cSrcweir aSel.Max() = nNewLen; 593*cdf0e10cSrcweir aSel.Min() = nNewLen; 594*cdf0e10cSrcweir } 595*cdf0e10cSrcweir } 596*cdf0e10cSrcweir else if (aSel.Max() > nNewLen) 597*cdf0e10cSrcweir aSel.Max() = nNewLen; 598*cdf0e10cSrcweir SpinField::SetText(rNew, aSel); 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir 601*cdf0e10cSrcweir m_bValueDirty = sal_True; 602*cdf0e10cSrcweir // muss nicht stimmen, aber sicherheitshalber ... 603*cdf0e10cSrcweir } 604*cdf0e10cSrcweir 605*cdf0e10cSrcweir //------------------------------------------------------------------------------ 606*cdf0e10cSrcweir long FormattedField::PreNotify(NotifyEvent& rNEvt) 607*cdf0e10cSrcweir { 608*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 609*cdf0e10cSrcweir if (rNEvt.GetType() == EVENT_KEYINPUT) 610*cdf0e10cSrcweir m_aLastSelection = GetSelection(); 611*cdf0e10cSrcweir return SpinField::PreNotify(rNEvt); 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir 614*cdf0e10cSrcweir //------------------------------------------------------------------------------ 615*cdf0e10cSrcweir void FormattedField::ImplSetFormatKey(sal_uLong nFormatKey) 616*cdf0e10cSrcweir { 617*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 618*cdf0e10cSrcweir 619*cdf0e10cSrcweir m_nFormatKey = nFormatKey; 620*cdf0e10cSrcweir sal_Bool bNeedFormatter = (m_pFormatter == NULL) && (nFormatKey != 0); 621*cdf0e10cSrcweir if (bNeedFormatter) 622*cdf0e10cSrcweir { 623*cdf0e10cSrcweir ImplGetFormatter(); // damit wird ein Standard-Formatter angelegt 624*cdf0e10cSrcweir 625*cdf0e10cSrcweir m_nFormatKey = nFormatKey; 626*cdf0e10cSrcweir // kann sein, dass das in dem Standard-Formatter keinen Sinn macht, aber der nimmt dann ein Default-Format an. 627*cdf0e10cSrcweir // Auf diese Weise kann ich einfach einen der - formatteruebergreifended gleichen - Standard-Keys setzen. 628*cdf0e10cSrcweir DBG_ASSERT(m_pFormatter->GetEntry(nFormatKey) != NULL, "FormattedField::ImplSetFormatKey : invalid format key !"); 629*cdf0e10cSrcweir // Wenn SetFormatKey aufgerufen wird, ohne dass ein Formatter existiert, muss der Key einer der Standard-Werte 630*cdf0e10cSrcweir // sein, der in allen Formattern (also auch in meinem neu angelegten) vorhanden ist. 631*cdf0e10cSrcweir } 632*cdf0e10cSrcweir } 633*cdf0e10cSrcweir 634*cdf0e10cSrcweir //------------------------------------------------------------------------------ 635*cdf0e10cSrcweir void FormattedField::SetFormatKey(sal_uLong nFormatKey) 636*cdf0e10cSrcweir { 637*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 638*cdf0e10cSrcweir sal_Bool bNoFormatter = (m_pFormatter == NULL); 639*cdf0e10cSrcweir ImplSetFormatKey(nFormatKey); 640*cdf0e10cSrcweir FormatChanged((bNoFormatter && (m_pFormatter != NULL)) ? FCT_FORMATTER : FCT_KEYONLY); 641*cdf0e10cSrcweir } 642*cdf0e10cSrcweir 643*cdf0e10cSrcweir //------------------------------------------------------------------------------ 644*cdf0e10cSrcweir void FormattedField::SetFormatter(SvNumberFormatter* pFormatter, sal_Bool bResetFormat) 645*cdf0e10cSrcweir { 646*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 647*cdf0e10cSrcweir 648*cdf0e10cSrcweir if (bResetFormat) 649*cdf0e10cSrcweir { 650*cdf0e10cSrcweir m_pFormatter = pFormatter; 651*cdf0e10cSrcweir 652*cdf0e10cSrcweir // calc the default format key from the Office's UI locale 653*cdf0e10cSrcweir if ( m_pFormatter ) 654*cdf0e10cSrcweir { 655*cdf0e10cSrcweir // get the Office's locale and translate 656*cdf0e10cSrcweir LanguageType eSysLanguage = MsLangId::convertLocaleToLanguage( 657*cdf0e10cSrcweir SvtSysLocale().GetLocaleData().getLocale() ); 658*cdf0e10cSrcweir // get the standard numeric format for this language 659*cdf0e10cSrcweir m_nFormatKey = m_pFormatter->GetStandardFormat( NUMBERFORMAT_NUMBER, eSysLanguage ); 660*cdf0e10cSrcweir } 661*cdf0e10cSrcweir else 662*cdf0e10cSrcweir m_nFormatKey = 0; 663*cdf0e10cSrcweir } 664*cdf0e10cSrcweir else 665*cdf0e10cSrcweir { 666*cdf0e10cSrcweir XubString sOldFormat; 667*cdf0e10cSrcweir LanguageType aOldLang; 668*cdf0e10cSrcweir GetFormat(sOldFormat, aOldLang); 669*cdf0e10cSrcweir 670*cdf0e10cSrcweir sal_uInt32 nDestKey = pFormatter->TestNewString(sOldFormat); 671*cdf0e10cSrcweir if (nDestKey == NUMBERFORMAT_ENTRY_NOT_FOUND) 672*cdf0e10cSrcweir { 673*cdf0e10cSrcweir // die Sprache des neuen Formatters 674*cdf0e10cSrcweir const SvNumberformat* pDefaultEntry = pFormatter->GetEntry(0); 675*cdf0e10cSrcweir LanguageType aNewLang = pDefaultEntry ? pDefaultEntry->GetLanguage() : LANGUAGE_DONTKNOW; 676*cdf0e10cSrcweir 677*cdf0e10cSrcweir // den alten Format-String in die neue Sprache konvertieren 678*cdf0e10cSrcweir sal_uInt16 nCheckPos; 679*cdf0e10cSrcweir short nType; 680*cdf0e10cSrcweir pFormatter->PutandConvertEntry(sOldFormat, nCheckPos, nType, nDestKey, aOldLang, aNewLang); 681*cdf0e10cSrcweir m_nFormatKey = nDestKey; 682*cdf0e10cSrcweir } 683*cdf0e10cSrcweir m_pFormatter = pFormatter; 684*cdf0e10cSrcweir } 685*cdf0e10cSrcweir 686*cdf0e10cSrcweir FormatChanged(FCT_FORMATTER); 687*cdf0e10cSrcweir } 688*cdf0e10cSrcweir 689*cdf0e10cSrcweir //------------------------------------------------------------------------------ 690*cdf0e10cSrcweir void FormattedField::GetFormat(XubString& rFormatString, LanguageType& eLang) const 691*cdf0e10cSrcweir { 692*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 693*cdf0e10cSrcweir const SvNumberformat* pFormatEntry = ImplGetFormatter()->GetEntry(m_nFormatKey); 694*cdf0e10cSrcweir DBG_ASSERT(pFormatEntry != NULL, "FormattedField::GetFormat: no number format for the given format key."); 695*cdf0e10cSrcweir rFormatString = pFormatEntry ? pFormatEntry->GetFormatstring() : XubString(); 696*cdf0e10cSrcweir eLang = pFormatEntry ? pFormatEntry->GetLanguage() : LANGUAGE_DONTKNOW; 697*cdf0e10cSrcweir } 698*cdf0e10cSrcweir 699*cdf0e10cSrcweir //------------------------------------------------------------------------------ 700*cdf0e10cSrcweir sal_Bool FormattedField::SetFormat(const XubString& rFormatString, LanguageType eLang) 701*cdf0e10cSrcweir { 702*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 703*cdf0e10cSrcweir sal_uInt32 nNewKey = ImplGetFormatter()->TestNewString(rFormatString, eLang); 704*cdf0e10cSrcweir if (nNewKey == NUMBERFORMAT_ENTRY_NOT_FOUND) 705*cdf0e10cSrcweir { 706*cdf0e10cSrcweir sal_uInt16 nCheckPos; 707*cdf0e10cSrcweir short nType; 708*cdf0e10cSrcweir XubString rFormat(rFormatString); 709*cdf0e10cSrcweir if (!ImplGetFormatter()->PutEntry(rFormat, nCheckPos, nType, nNewKey, eLang)) 710*cdf0e10cSrcweir return sal_False; 711*cdf0e10cSrcweir DBG_ASSERT(nNewKey != NUMBERFORMAT_ENTRY_NOT_FOUND, "FormattedField::SetFormatString : PutEntry returned an invalid key !"); 712*cdf0e10cSrcweir } 713*cdf0e10cSrcweir 714*cdf0e10cSrcweir if (nNewKey != m_nFormatKey) 715*cdf0e10cSrcweir SetFormatKey(nNewKey); 716*cdf0e10cSrcweir return sal_True; 717*cdf0e10cSrcweir } 718*cdf0e10cSrcweir 719*cdf0e10cSrcweir //------------------------------------------------------------------------------ 720*cdf0e10cSrcweir sal_Bool FormattedField::GetThousandsSep() const 721*cdf0e10cSrcweir { 722*cdf0e10cSrcweir DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey), 723*cdf0e10cSrcweir "FormattedField::GetThousandsSep : your'e sure what your'e doing when setting the precision of a text format ?"); 724*cdf0e10cSrcweir 725*cdf0e10cSrcweir sal_Bool bThousand, IsRed; 726*cdf0e10cSrcweir sal_uInt16 nPrecision, nAnzLeading; 727*cdf0e10cSrcweir ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading); 728*cdf0e10cSrcweir 729*cdf0e10cSrcweir return bThousand; 730*cdf0e10cSrcweir } 731*cdf0e10cSrcweir 732*cdf0e10cSrcweir //------------------------------------------------------------------------------ 733*cdf0e10cSrcweir void FormattedField::SetThousandsSep(sal_Bool _bUseSeparator) 734*cdf0e10cSrcweir { 735*cdf0e10cSrcweir DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey), 736*cdf0e10cSrcweir "FormattedField::SetThousandsSep : your'e sure what your'e doing when setting the precision of a text format ?"); 737*cdf0e10cSrcweir 738*cdf0e10cSrcweir // get the current settings 739*cdf0e10cSrcweir sal_Bool bThousand, IsRed; 740*cdf0e10cSrcweir sal_uInt16 nPrecision, nAnzLeading; 741*cdf0e10cSrcweir ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading); 742*cdf0e10cSrcweir if (bThousand == _bUseSeparator) 743*cdf0e10cSrcweir return; 744*cdf0e10cSrcweir 745*cdf0e10cSrcweir // we need the language for the following 746*cdf0e10cSrcweir LanguageType eLang; 747*cdf0e10cSrcweir String sFmtDescription; 748*cdf0e10cSrcweir GetFormat(sFmtDescription, eLang); 749*cdf0e10cSrcweir 750*cdf0e10cSrcweir // generate a new format ... 751*cdf0e10cSrcweir ImplGetFormatter()->GenerateFormat(sFmtDescription, m_nFormatKey, eLang, _bUseSeparator, IsRed, nPrecision, nAnzLeading); 752*cdf0e10cSrcweir // ... and introduce it to the formatter 753*cdf0e10cSrcweir sal_uInt16 nCheckPos; 754*cdf0e10cSrcweir sal_uInt32 nNewKey; 755*cdf0e10cSrcweir short nType; 756*cdf0e10cSrcweir ImplGetFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang); 757*cdf0e10cSrcweir 758*cdf0e10cSrcweir // set the new key 759*cdf0e10cSrcweir ImplSetFormatKey(nNewKey); 760*cdf0e10cSrcweir FormatChanged(FCT_THOUSANDSSEP); 761*cdf0e10cSrcweir } 762*cdf0e10cSrcweir 763*cdf0e10cSrcweir //------------------------------------------------------------------------------ 764*cdf0e10cSrcweir sal_uInt16 FormattedField::GetDecimalDigits() const 765*cdf0e10cSrcweir { 766*cdf0e10cSrcweir DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey), 767*cdf0e10cSrcweir "FormattedField::GetDecimalDigits : your'e sure what your'e doing when setting the precision of a text format ?"); 768*cdf0e10cSrcweir 769*cdf0e10cSrcweir sal_Bool bThousand, IsRed; 770*cdf0e10cSrcweir sal_uInt16 nPrecision, nAnzLeading; 771*cdf0e10cSrcweir ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading); 772*cdf0e10cSrcweir 773*cdf0e10cSrcweir return nPrecision; 774*cdf0e10cSrcweir } 775*cdf0e10cSrcweir 776*cdf0e10cSrcweir //------------------------------------------------------------------------------ 777*cdf0e10cSrcweir void FormattedField::SetDecimalDigits(sal_uInt16 _nPrecision) 778*cdf0e10cSrcweir { 779*cdf0e10cSrcweir DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey), 780*cdf0e10cSrcweir "FormattedField::SetDecimalDigits : your'e sure what your'e doing when setting the precision of a text format ?"); 781*cdf0e10cSrcweir 782*cdf0e10cSrcweir // get the current settings 783*cdf0e10cSrcweir sal_Bool bThousand, IsRed; 784*cdf0e10cSrcweir sal_uInt16 nPrecision, nAnzLeading; 785*cdf0e10cSrcweir ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading); 786*cdf0e10cSrcweir if (nPrecision == _nPrecision) 787*cdf0e10cSrcweir return; 788*cdf0e10cSrcweir 789*cdf0e10cSrcweir // we need the language for the following 790*cdf0e10cSrcweir LanguageType eLang; 791*cdf0e10cSrcweir String sFmtDescription; 792*cdf0e10cSrcweir GetFormat(sFmtDescription, eLang); 793*cdf0e10cSrcweir 794*cdf0e10cSrcweir // generate a new format ... 795*cdf0e10cSrcweir ImplGetFormatter()->GenerateFormat(sFmtDescription, m_nFormatKey, eLang, bThousand, IsRed, _nPrecision, nAnzLeading); 796*cdf0e10cSrcweir // ... and introduce it to the formatter 797*cdf0e10cSrcweir sal_uInt16 nCheckPos; 798*cdf0e10cSrcweir sal_uInt32 nNewKey; 799*cdf0e10cSrcweir short nType; 800*cdf0e10cSrcweir ImplGetFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang); 801*cdf0e10cSrcweir 802*cdf0e10cSrcweir // set the new key 803*cdf0e10cSrcweir ImplSetFormatKey(nNewKey); 804*cdf0e10cSrcweir FormatChanged(FCT_PRECISION); 805*cdf0e10cSrcweir } 806*cdf0e10cSrcweir 807*cdf0e10cSrcweir //------------------------------------------------------------------------------ 808*cdf0e10cSrcweir void FormattedField::FormatChanged( FORMAT_CHANGE_TYPE _nWhat ) 809*cdf0e10cSrcweir { 810*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 811*cdf0e10cSrcweir m_pLastOutputColor = NULL; 812*cdf0e10cSrcweir 813*cdf0e10cSrcweir if ( ( 0 != ( _nWhat & FCT_FORMATTER ) ) && m_pFormatter ) 814*cdf0e10cSrcweir m_pFormatter->SetEvalDateFormat( NF_EVALDATEFORMAT_INTL_FORMAT ); 815*cdf0e10cSrcweir // 95845 - 03.04.2002 - fs@openoffice.org 816*cdf0e10cSrcweir 817*cdf0e10cSrcweir ReFormat(); 818*cdf0e10cSrcweir } 819*cdf0e10cSrcweir 820*cdf0e10cSrcweir //------------------------------------------------------------------------------ 821*cdf0e10cSrcweir void FormattedField::Commit() 822*cdf0e10cSrcweir { 823*cdf0e10cSrcweir // remember the old text 824*cdf0e10cSrcweir String sOld( GetText() ); 825*cdf0e10cSrcweir 826*cdf0e10cSrcweir // do the reformat 827*cdf0e10cSrcweir ReFormat(); 828*cdf0e10cSrcweir 829*cdf0e10cSrcweir // did the text change? 830*cdf0e10cSrcweir if ( GetText() != sOld ) 831*cdf0e10cSrcweir { // consider the field as modified 832*cdf0e10cSrcweir Modify(); 833*cdf0e10cSrcweir // but we have the most recent value now 834*cdf0e10cSrcweir m_bValueDirty = sal_False; 835*cdf0e10cSrcweir } 836*cdf0e10cSrcweir } 837*cdf0e10cSrcweir 838*cdf0e10cSrcweir //------------------------------------------------------------------------------ 839*cdf0e10cSrcweir void FormattedField::ReFormat() 840*cdf0e10cSrcweir { 841*cdf0e10cSrcweir if (!IsEmptyFieldEnabled() || GetText().Len()) 842*cdf0e10cSrcweir { 843*cdf0e10cSrcweir if (TreatingAsNumber()) 844*cdf0e10cSrcweir { 845*cdf0e10cSrcweir double dValue = GetValue(); 846*cdf0e10cSrcweir if ( m_bEnableNaN && ::rtl::math::isNan( dValue ) ) 847*cdf0e10cSrcweir return; 848*cdf0e10cSrcweir ImplSetValue( dValue, sal_True ); 849*cdf0e10cSrcweir } 850*cdf0e10cSrcweir else 851*cdf0e10cSrcweir SetTextFormatted(GetTextValue()); 852*cdf0e10cSrcweir } 853*cdf0e10cSrcweir } 854*cdf0e10cSrcweir 855*cdf0e10cSrcweir //------------------------------------------------------------------------------ 856*cdf0e10cSrcweir long FormattedField::Notify(NotifyEvent& rNEvt) 857*cdf0e10cSrcweir { 858*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 859*cdf0e10cSrcweir 860*cdf0e10cSrcweir if ((rNEvt.GetType() == EVENT_KEYINPUT) && !IsReadOnly()) 861*cdf0e10cSrcweir { 862*cdf0e10cSrcweir const KeyEvent& rKEvt = *rNEvt.GetKeyEvent(); 863*cdf0e10cSrcweir sal_uInt16 nMod = rKEvt.GetKeyCode().GetModifier(); 864*cdf0e10cSrcweir switch ( rKEvt.GetKeyCode().GetCode() ) 865*cdf0e10cSrcweir { 866*cdf0e10cSrcweir case KEY_UP: 867*cdf0e10cSrcweir case KEY_DOWN: 868*cdf0e10cSrcweir case KEY_PAGEUP: 869*cdf0e10cSrcweir case KEY_PAGEDOWN: 870*cdf0e10cSrcweir if (!nMod && ImplGetFormatter()->IsTextFormat(m_nFormatKey)) 871*cdf0e10cSrcweir { 872*cdf0e10cSrcweir // the base class would translate this into calls to Up/Down/First/Last, 873*cdf0e10cSrcweir // but we don't want this if we are text-formatted 874*cdf0e10cSrcweir return 1; 875*cdf0e10cSrcweir } 876*cdf0e10cSrcweir } 877*cdf0e10cSrcweir } 878*cdf0e10cSrcweir 879*cdf0e10cSrcweir if ((rNEvt.GetType() == EVENT_COMMAND) && !IsReadOnly()) 880*cdf0e10cSrcweir { 881*cdf0e10cSrcweir const CommandEvent* pCommand = rNEvt.GetCommandEvent(); 882*cdf0e10cSrcweir if (pCommand->GetCommand() == COMMAND_WHEEL) 883*cdf0e10cSrcweir { 884*cdf0e10cSrcweir const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData(); 885*cdf0e10cSrcweir if ((pData->GetMode() == COMMAND_WHEEL_SCROLL) && ImplGetFormatter()->IsTextFormat(m_nFormatKey)) 886*cdf0e10cSrcweir { 887*cdf0e10cSrcweir // same as above : prevent the base class from doing Up/Down-calls 888*cdf0e10cSrcweir // (normally I should put this test into the Up/Down methods itself, shouldn't I ?) 889*cdf0e10cSrcweir // FS - 71553 - 19.01.00 890*cdf0e10cSrcweir return 1; 891*cdf0e10cSrcweir } 892*cdf0e10cSrcweir } 893*cdf0e10cSrcweir } 894*cdf0e10cSrcweir 895*cdf0e10cSrcweir if (rNEvt.GetType() == EVENT_LOSEFOCUS) 896*cdf0e10cSrcweir { 897*cdf0e10cSrcweir // Sonderbehandlung fuer leere Texte 898*cdf0e10cSrcweir if (GetText().Len() == 0) 899*cdf0e10cSrcweir { 900*cdf0e10cSrcweir if (!IsEmptyFieldEnabled()) 901*cdf0e10cSrcweir { 902*cdf0e10cSrcweir if (TreatingAsNumber()) 903*cdf0e10cSrcweir { 904*cdf0e10cSrcweir ImplSetValue(m_dCurrentValue, sal_True); 905*cdf0e10cSrcweir Modify(); 906*cdf0e10cSrcweir } 907*cdf0e10cSrcweir else 908*cdf0e10cSrcweir { 909*cdf0e10cSrcweir String sNew = GetTextValue(); 910*cdf0e10cSrcweir if (sNew.Len()) 911*cdf0e10cSrcweir SetTextFormatted(sNew); 912*cdf0e10cSrcweir else 913*cdf0e10cSrcweir SetTextFormatted(m_sDefaultText); 914*cdf0e10cSrcweir } 915*cdf0e10cSrcweir m_bValueDirty = sal_False; 916*cdf0e10cSrcweir } 917*cdf0e10cSrcweir } 918*cdf0e10cSrcweir else 919*cdf0e10cSrcweir { 920*cdf0e10cSrcweir Commit(); 921*cdf0e10cSrcweir } 922*cdf0e10cSrcweir } 923*cdf0e10cSrcweir 924*cdf0e10cSrcweir return SpinField::Notify( rNEvt ); 925*cdf0e10cSrcweir } 926*cdf0e10cSrcweir 927*cdf0e10cSrcweir //------------------------------------------------------------------------------ 928*cdf0e10cSrcweir void FormattedField::SetMinValue(double dMin) 929*cdf0e10cSrcweir { 930*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 931*cdf0e10cSrcweir DBG_ASSERT(m_bTreatAsNumber, "FormattedField::SetMinValue : only to be used in numeric mode !"); 932*cdf0e10cSrcweir 933*cdf0e10cSrcweir m_dMinValue = dMin; 934*cdf0e10cSrcweir m_bHasMin = sal_True; 935*cdf0e10cSrcweir // fuer die Ueberpruefung des aktuellen Wertes an der neuen Grenze -> ImplSetValue 936*cdf0e10cSrcweir ReFormat(); 937*cdf0e10cSrcweir } 938*cdf0e10cSrcweir 939*cdf0e10cSrcweir //------------------------------------------------------------------------------ 940*cdf0e10cSrcweir void FormattedField::SetMaxValue(double dMax) 941*cdf0e10cSrcweir { 942*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 943*cdf0e10cSrcweir DBG_ASSERT(m_bTreatAsNumber, "FormattedField::SetMaxValue : only to be used in numeric mode !"); 944*cdf0e10cSrcweir 945*cdf0e10cSrcweir m_dMaxValue = dMax; 946*cdf0e10cSrcweir m_bHasMax = sal_True; 947*cdf0e10cSrcweir // fuer die Ueberpruefung des aktuellen Wertes an der neuen Grenze -> ImplSetValue 948*cdf0e10cSrcweir ReFormat(); 949*cdf0e10cSrcweir } 950*cdf0e10cSrcweir 951*cdf0e10cSrcweir //------------------------------------------------------------------------------ 952*cdf0e10cSrcweir void FormattedField::SetTextValue(const XubString& rText) 953*cdf0e10cSrcweir { 954*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 955*cdf0e10cSrcweir SetText(rText); 956*cdf0e10cSrcweir ReFormat(); 957*cdf0e10cSrcweir } 958*cdf0e10cSrcweir 959*cdf0e10cSrcweir //------------------------------------------------------------------------------ 960*cdf0e10cSrcweir void FormattedField::EnableEmptyField(sal_Bool bEnable) 961*cdf0e10cSrcweir { 962*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 963*cdf0e10cSrcweir if (bEnable == m_bEnableEmptyField) 964*cdf0e10cSrcweir return; 965*cdf0e10cSrcweir 966*cdf0e10cSrcweir m_bEnableEmptyField = bEnable; 967*cdf0e10cSrcweir if (!m_bEnableEmptyField && GetText().Len()==0) 968*cdf0e10cSrcweir ImplSetValue(m_dCurrentValue, sal_True); 969*cdf0e10cSrcweir } 970*cdf0e10cSrcweir 971*cdf0e10cSrcweir //------------------------------------------------------------------------------ 972*cdf0e10cSrcweir void FormattedField::ImplSetValue(double dVal, sal_Bool bForce) 973*cdf0e10cSrcweir { 974*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 975*cdf0e10cSrcweir 976*cdf0e10cSrcweir if (m_bHasMin && (dVal<m_dMinValue)) 977*cdf0e10cSrcweir dVal = m_dMinValue; 978*cdf0e10cSrcweir if (m_bHasMax && (dVal>m_dMaxValue)) 979*cdf0e10cSrcweir dVal = m_dMaxValue; 980*cdf0e10cSrcweir if (!bForce && (dVal == GetValue())) 981*cdf0e10cSrcweir return; 982*cdf0e10cSrcweir 983*cdf0e10cSrcweir DBG_ASSERT(ImplGetFormatter() != NULL, "FormattedField::ImplSetValue : can't set a value without a formatter !"); 984*cdf0e10cSrcweir 985*cdf0e10cSrcweir m_bValueDirty = sal_False; 986*cdf0e10cSrcweir m_dCurrentValue = dVal; 987*cdf0e10cSrcweir 988*cdf0e10cSrcweir String sNewText; 989*cdf0e10cSrcweir if (ImplGetFormatter()->IsTextFormat(m_nFormatKey)) 990*cdf0e10cSrcweir { 991*cdf0e10cSrcweir // zuerst die Zahl als String im Standard-Format 992*cdf0e10cSrcweir String sTemp; 993*cdf0e10cSrcweir ImplGetFormatter()->GetOutputString(dVal, 0, sTemp, &m_pLastOutputColor); 994*cdf0e10cSrcweir // dann den String entsprechend dem Text-Format 995*cdf0e10cSrcweir ImplGetFormatter()->GetOutputString(sTemp, m_nFormatKey, sNewText, &m_pLastOutputColor); 996*cdf0e10cSrcweir } 997*cdf0e10cSrcweir else 998*cdf0e10cSrcweir { 999*cdf0e10cSrcweir if( IsUsingInputStringForFormatting()) 1000*cdf0e10cSrcweir ImplGetFormatter()->GetInputLineString(dVal, m_nFormatKey, sNewText); 1001*cdf0e10cSrcweir else 1002*cdf0e10cSrcweir ImplGetFormatter()->GetOutputString(dVal, m_nFormatKey, sNewText, &m_pLastOutputColor); 1003*cdf0e10cSrcweir } 1004*cdf0e10cSrcweir 1005*cdf0e10cSrcweir ImplSetTextImpl(sNewText, NULL); 1006*cdf0e10cSrcweir m_bValueDirty = sal_False; 1007*cdf0e10cSrcweir DBG_ASSERT(CheckText(sNewText), "FormattedField::ImplSetValue : formatted string doesn't match the criteria !"); 1008*cdf0e10cSrcweir } 1009*cdf0e10cSrcweir 1010*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1011*cdf0e10cSrcweir sal_Bool FormattedField::ImplGetValue(double& dNewVal) 1012*cdf0e10cSrcweir { 1013*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 1014*cdf0e10cSrcweir 1015*cdf0e10cSrcweir dNewVal = m_dCurrentValue; 1016*cdf0e10cSrcweir if (!m_bValueDirty) 1017*cdf0e10cSrcweir return sal_True; 1018*cdf0e10cSrcweir 1019*cdf0e10cSrcweir dNewVal = m_dDefaultValue; 1020*cdf0e10cSrcweir String sText(GetText()); 1021*cdf0e10cSrcweir if (!sText.Len()) 1022*cdf0e10cSrcweir return sal_True; 1023*cdf0e10cSrcweir 1024*cdf0e10cSrcweir DBG_ASSERT(ImplGetFormatter() != NULL, "FormattedField::ImplGetValue : can't give you a current value without a formatter !"); 1025*cdf0e10cSrcweir 1026*cdf0e10cSrcweir sal_uInt32 nFormatKey = m_nFormatKey; // IsNumberFormat veraendert den FormatKey ... 1027*cdf0e10cSrcweir 1028*cdf0e10cSrcweir if (ImplGetFormatter()->IsTextFormat(nFormatKey) && m_bTreatAsNumber) 1029*cdf0e10cSrcweir // damit wir in einem als Text formatierten Feld trotzdem eine Eingabe wie '1,1' erkennen ... 1030*cdf0e10cSrcweir nFormatKey = 0; 1031*cdf0e10cSrcweir 1032*cdf0e10cSrcweir // Sonderbehandlung fuer %-Formatierung 1033*cdf0e10cSrcweir if (ImplGetFormatter()->GetType(m_nFormatKey) == NUMBERFORMAT_PERCENT) 1034*cdf0e10cSrcweir { 1035*cdf0e10cSrcweir // the language of our format 1036*cdf0e10cSrcweir LanguageType eLanguage = m_pFormatter->GetEntry(m_nFormatKey)->GetLanguage(); 1037*cdf0e10cSrcweir // the default number format for this language 1038*cdf0e10cSrcweir sal_uLong nStandardNumericFormat = m_pFormatter->GetStandardFormat(NUMBERFORMAT_NUMBER, eLanguage); 1039*cdf0e10cSrcweir 1040*cdf0e10cSrcweir sal_uInt32 nTempFormat = nStandardNumericFormat; 1041*cdf0e10cSrcweir double dTemp; 1042*cdf0e10cSrcweir if (m_pFormatter->IsNumberFormat(sText, nTempFormat, dTemp) && 1043*cdf0e10cSrcweir NUMBERFORMAT_NUMBER == m_pFormatter->GetType(nTempFormat)) 1044*cdf0e10cSrcweir // der String entspricht einer Number-Formatierung, hat also nur kein % 1045*cdf0e10cSrcweir // -> append it 1046*cdf0e10cSrcweir sText += '%'; 1047*cdf0e10cSrcweir // (with this, a input of '3' becomes '3%', which then by the formatter is translated 1048*cdf0e10cSrcweir // into 0.03. Without this, the formatter would give us the double 3 for an input '3', 1049*cdf0e10cSrcweir // which equals 300 percent. 1050*cdf0e10cSrcweir } 1051*cdf0e10cSrcweir if (!ImplGetFormatter()->IsNumberFormat(sText, nFormatKey, dNewVal)) 1052*cdf0e10cSrcweir return sal_False; 1053*cdf0e10cSrcweir 1054*cdf0e10cSrcweir 1055*cdf0e10cSrcweir if (m_bHasMin && (dNewVal<m_dMinValue)) 1056*cdf0e10cSrcweir dNewVal = m_dMinValue; 1057*cdf0e10cSrcweir if (m_bHasMax && (dNewVal>m_dMaxValue)) 1058*cdf0e10cSrcweir dNewVal = m_dMaxValue; 1059*cdf0e10cSrcweir return sal_True; 1060*cdf0e10cSrcweir } 1061*cdf0e10cSrcweir 1062*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1063*cdf0e10cSrcweir void FormattedField::SetValue(double dVal) 1064*cdf0e10cSrcweir { 1065*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 1066*cdf0e10cSrcweir ImplSetValue(dVal, m_bValueDirty); 1067*cdf0e10cSrcweir } 1068*cdf0e10cSrcweir 1069*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1070*cdf0e10cSrcweir double FormattedField::GetValue() 1071*cdf0e10cSrcweir { 1072*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 1073*cdf0e10cSrcweir 1074*cdf0e10cSrcweir if ( !ImplGetValue( m_dCurrentValue ) ) 1075*cdf0e10cSrcweir { 1076*cdf0e10cSrcweir if ( m_bEnableNaN ) 1077*cdf0e10cSrcweir ::rtl::math::setNan( &m_dCurrentValue ); 1078*cdf0e10cSrcweir else 1079*cdf0e10cSrcweir m_dCurrentValue = m_dDefaultValue; 1080*cdf0e10cSrcweir } 1081*cdf0e10cSrcweir 1082*cdf0e10cSrcweir m_bValueDirty = sal_False; 1083*cdf0e10cSrcweir return m_dCurrentValue; 1084*cdf0e10cSrcweir } 1085*cdf0e10cSrcweir 1086*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1087*cdf0e10cSrcweir void FormattedField::Up() 1088*cdf0e10cSrcweir { 1089*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 1090*cdf0e10cSrcweir SetValue(GetValue() + m_dSpinSize); 1091*cdf0e10cSrcweir // das setValue handelt Bereichsueberschreitungen (min/max) automatisch 1092*cdf0e10cSrcweir SetModifyFlag(); 1093*cdf0e10cSrcweir Modify(); 1094*cdf0e10cSrcweir 1095*cdf0e10cSrcweir SpinField::Up(); 1096*cdf0e10cSrcweir } 1097*cdf0e10cSrcweir 1098*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1099*cdf0e10cSrcweir void FormattedField::Down() 1100*cdf0e10cSrcweir { 1101*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 1102*cdf0e10cSrcweir SetValue(GetValue() - m_dSpinSize); 1103*cdf0e10cSrcweir SetModifyFlag(); 1104*cdf0e10cSrcweir Modify(); 1105*cdf0e10cSrcweir 1106*cdf0e10cSrcweir SpinField::Down(); 1107*cdf0e10cSrcweir } 1108*cdf0e10cSrcweir 1109*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1110*cdf0e10cSrcweir void FormattedField::First() 1111*cdf0e10cSrcweir { 1112*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 1113*cdf0e10cSrcweir if (m_bHasMin) 1114*cdf0e10cSrcweir { 1115*cdf0e10cSrcweir SetValue(m_dMinValue); 1116*cdf0e10cSrcweir SetModifyFlag(); 1117*cdf0e10cSrcweir Modify(); 1118*cdf0e10cSrcweir } 1119*cdf0e10cSrcweir 1120*cdf0e10cSrcweir SpinField::First(); 1121*cdf0e10cSrcweir } 1122*cdf0e10cSrcweir 1123*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1124*cdf0e10cSrcweir void FormattedField::Last() 1125*cdf0e10cSrcweir { 1126*cdf0e10cSrcweir DBG_CHKTHIS(FormattedField, NULL); 1127*cdf0e10cSrcweir if (m_bHasMax) 1128*cdf0e10cSrcweir { 1129*cdf0e10cSrcweir SetValue(m_dMaxValue); 1130*cdf0e10cSrcweir SetModifyFlag(); 1131*cdf0e10cSrcweir Modify(); 1132*cdf0e10cSrcweir } 1133*cdf0e10cSrcweir 1134*cdf0e10cSrcweir SpinField::Last(); 1135*cdf0e10cSrcweir } 1136*cdf0e10cSrcweir 1137*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1138*cdf0e10cSrcweir void FormattedField::UseInputStringForFormatting( bool bUseInputStr /* = true */ ) 1139*cdf0e10cSrcweir { 1140*cdf0e10cSrcweir m_bUseInputStringForFormatting = bUseInputStr; 1141*cdf0e10cSrcweir } 1142*cdf0e10cSrcweir 1143*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1144*cdf0e10cSrcweir bool FormattedField::IsUsingInputStringForFormatting() const 1145*cdf0e10cSrcweir { 1146*cdf0e10cSrcweir return m_bUseInputStringForFormatting; 1147*cdf0e10cSrcweir } 1148*cdf0e10cSrcweir 1149*cdf0e10cSrcweir 1150*cdf0e10cSrcweir //============================================================================== 1151*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1152*cdf0e10cSrcweir DoubleNumericField::~DoubleNumericField() 1153*cdf0e10cSrcweir { 1154*cdf0e10cSrcweir #ifdef REGEXP_SUPPORT 1155*cdf0e10cSrcweir delete m_pConformanceTester; 1156*cdf0e10cSrcweir #else 1157*cdf0e10cSrcweir delete m_pNumberValidator; 1158*cdf0e10cSrcweir #endif 1159*cdf0e10cSrcweir } 1160*cdf0e10cSrcweir 1161*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1162*cdf0e10cSrcweir void DoubleNumericField::FormatChanged(FORMAT_CHANGE_TYPE nWhat) 1163*cdf0e10cSrcweir { 1164*cdf0e10cSrcweir ResetConformanceTester(); 1165*cdf0e10cSrcweir FormattedField::FormatChanged(nWhat); 1166*cdf0e10cSrcweir } 1167*cdf0e10cSrcweir 1168*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1169*cdf0e10cSrcweir sal_Bool DoubleNumericField::CheckText(const XubString& sText) const 1170*cdf0e10cSrcweir { 1171*cdf0e10cSrcweir // We'd like to implement this using the NumberFormatter::IsNumberFormat, but unfortunately, this doesn't 1172*cdf0e10cSrcweir // recognize fragments of numbers (like, for instance "1e", which happens during entering e.g. "1e10") 1173*cdf0e10cSrcweir // Thus, the roundabout way via a regular expression 1174*cdf0e10cSrcweir 1175*cdf0e10cSrcweir #ifdef REGEXP_SUPPORT 1176*cdf0e10cSrcweir if (!sText.Len()) 1177*cdf0e10cSrcweir return sal_True; 1178*cdf0e10cSrcweir 1179*cdf0e10cSrcweir String sForceComplete = '_'; 1180*cdf0e10cSrcweir sForceComplete += sText; 1181*cdf0e10cSrcweir sForceComplete += '_'; 1182*cdf0e10cSrcweir 1183*cdf0e10cSrcweir sal_uInt16 nStart = 0, nEnd = sForceComplete.Len(); 1184*cdf0e10cSrcweir sal_Bool bFound = m_pConformanceTester->SearchFrwrd(sForceComplete, &nStart, &nEnd); 1185*cdf0e10cSrcweir 1186*cdf0e10cSrcweir if (bFound && (nStart == 0) && (nEnd == sForceComplete.Len())) 1187*cdf0e10cSrcweir return sal_True; 1188*cdf0e10cSrcweir 1189*cdf0e10cSrcweir return sal_False; 1190*cdf0e10cSrcweir #else 1191*cdf0e10cSrcweir return m_pNumberValidator->isValidNumericFragment( sText ); 1192*cdf0e10cSrcweir #endif 1193*cdf0e10cSrcweir } 1194*cdf0e10cSrcweir 1195*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1196*cdf0e10cSrcweir void DoubleNumericField::ResetConformanceTester() 1197*cdf0e10cSrcweir { 1198*cdf0e10cSrcweir // the thousands and the decimal separator are language dependent 1199*cdf0e10cSrcweir const SvNumberformat* pFormatEntry = ImplGetFormatter()->GetEntry(m_nFormatKey); 1200*cdf0e10cSrcweir 1201*cdf0e10cSrcweir sal_Unicode cSeparatorThousand = ','; 1202*cdf0e10cSrcweir sal_Unicode cSeparatorDecimal = '.'; 1203*cdf0e10cSrcweir if (pFormatEntry) 1204*cdf0e10cSrcweir { 1205*cdf0e10cSrcweir Locale aLocale; 1206*cdf0e10cSrcweir MsLangId::convertLanguageToLocale( pFormatEntry->GetLanguage(), aLocale ); 1207*cdf0e10cSrcweir LocaleDataWrapper aLocaleInfo(::comphelper::getProcessServiceFactory(), aLocale); 1208*cdf0e10cSrcweir 1209*cdf0e10cSrcweir String sSeparator = aLocaleInfo.getNumThousandSep(); 1210*cdf0e10cSrcweir if (sSeparator.Len()) 1211*cdf0e10cSrcweir cSeparatorThousand = sSeparator.GetBuffer()[0]; 1212*cdf0e10cSrcweir 1213*cdf0e10cSrcweir sSeparator = aLocaleInfo.getNumDecimalSep(); 1214*cdf0e10cSrcweir if (sSeparator.Len()) 1215*cdf0e10cSrcweir cSeparatorDecimal = sSeparator.GetBuffer()[0]; 1216*cdf0e10cSrcweir } 1217*cdf0e10cSrcweir 1218*cdf0e10cSrcweir #ifdef REGEXP_SUPPORT 1219*cdf0e10cSrcweir String sDescription = String::CreateFromAscii(szNumericInput); 1220*cdf0e10cSrcweir 1221*cdf0e10cSrcweir String sReplaceWith((sal_Unicode)'\\'); 1222*cdf0e10cSrcweir sReplaceWith += cSeparatorThousand; 1223*cdf0e10cSrcweir sDescription.SearchAndReplaceAscii("\\,", sReplaceWith); 1224*cdf0e10cSrcweir 1225*cdf0e10cSrcweir sReplaceWith = (sal_Unicode)'\\'; 1226*cdf0e10cSrcweir sReplaceWith += cSeparatorDecimal; 1227*cdf0e10cSrcweir sDescription.SearchAndReplaceAscii("\\.", sReplaceWith); 1228*cdf0e10cSrcweir 1229*cdf0e10cSrcweir delete m_pConformanceTester; 1230*cdf0e10cSrcweir 1231*cdf0e10cSrcweir SearchOptions aParam; 1232*cdf0e10cSrcweir aParam.algorithmType = SearchAlgorithms_REGEXP; 1233*cdf0e10cSrcweir aParam.searchFlag = SearchFlags::ALL_IGNORE_CASE; 1234*cdf0e10cSrcweir aParam.searchString = sDescription; 1235*cdf0e10cSrcweir aParam.transliterateFlags = 0; 1236*cdf0e10cSrcweir 1237*cdf0e10cSrcweir String sLanguage, sCountry; 1238*cdf0e10cSrcweir ConvertLanguageToIsoNames( pFormatEntry ? pFormatEntry->GetLanguage() : LANGUAGE_ENGLISH_US, sLanguage, sCountry ); 1239*cdf0e10cSrcweir aParam.Locale.Language = sLanguage; 1240*cdf0e10cSrcweir aParam.Locale.Country = sCountry; 1241*cdf0e10cSrcweir 1242*cdf0e10cSrcweir m_pConformanceTester = new ::utl::TextSearch(aParam); 1243*cdf0e10cSrcweir #else 1244*cdf0e10cSrcweir delete m_pNumberValidator; 1245*cdf0e10cSrcweir m_pNumberValidator = new validation::NumberValidator( cSeparatorThousand, cSeparatorDecimal ); 1246*cdf0e10cSrcweir #endif 1247*cdf0e10cSrcweir } 1248*cdf0e10cSrcweir 1249*cdf0e10cSrcweir 1250*cdf0e10cSrcweir //============================================================================== 1251*cdf0e10cSrcweir 1252*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1253*cdf0e10cSrcweir DoubleCurrencyField::DoubleCurrencyField(Window* pParent, WinBits nStyle) 1254*cdf0e10cSrcweir :FormattedField(pParent, nStyle) 1255*cdf0e10cSrcweir ,m_bChangingFormat(sal_False) 1256*cdf0e10cSrcweir { 1257*cdf0e10cSrcweir m_bPrependCurrSym = sal_False; 1258*cdf0e10cSrcweir 1259*cdf0e10cSrcweir // initialize with a system currency format 1260*cdf0e10cSrcweir m_sCurrencySymbol = SvtSysLocale().GetLocaleData().getCurrSymbol(); 1261*cdf0e10cSrcweir UpdateCurrencyFormat(); 1262*cdf0e10cSrcweir } 1263*cdf0e10cSrcweir 1264*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1265*cdf0e10cSrcweir DoubleCurrencyField::DoubleCurrencyField(Window* pParent, const ResId& rResId) 1266*cdf0e10cSrcweir :FormattedField(pParent, rResId) 1267*cdf0e10cSrcweir ,m_bChangingFormat(sal_False) 1268*cdf0e10cSrcweir { 1269*cdf0e10cSrcweir m_bPrependCurrSym = sal_False; 1270*cdf0e10cSrcweir 1271*cdf0e10cSrcweir // initialize with a system currency format 1272*cdf0e10cSrcweir m_sCurrencySymbol = SvtSysLocale().GetLocaleData().getCurrSymbol(); 1273*cdf0e10cSrcweir UpdateCurrencyFormat(); 1274*cdf0e10cSrcweir } 1275*cdf0e10cSrcweir 1276*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1277*cdf0e10cSrcweir void DoubleCurrencyField::FormatChanged(FORMAT_CHANGE_TYPE nWhat) 1278*cdf0e10cSrcweir { 1279*cdf0e10cSrcweir if (m_bChangingFormat) 1280*cdf0e10cSrcweir { 1281*cdf0e10cSrcweir FormattedField::FormatChanged(nWhat); 1282*cdf0e10cSrcweir return; 1283*cdf0e10cSrcweir } 1284*cdf0e10cSrcweir 1285*cdf0e10cSrcweir switch (nWhat) 1286*cdf0e10cSrcweir { 1287*cdf0e10cSrcweir case FCT_FORMATTER: 1288*cdf0e10cSrcweir case FCT_PRECISION: 1289*cdf0e10cSrcweir case FCT_THOUSANDSSEP: 1290*cdf0e10cSrcweir // the aspects which changed don't take our currency settings into account (in fact, they most probably 1291*cdf0e10cSrcweir // destroyed them) 1292*cdf0e10cSrcweir UpdateCurrencyFormat(); 1293*cdf0e10cSrcweir break; 1294*cdf0e10cSrcweir case FCT_KEYONLY: 1295*cdf0e10cSrcweir DBG_ERROR("DoubleCurrencyField::FormatChanged : somebody modified my key !"); 1296*cdf0e10cSrcweir // We always build our own format from the settings we get via special methods (setCurrencySymbol etc.). 1297*cdf0e10cSrcweir // Nobody but ourself should modifiy the format key directly ! 1298*cdf0e10cSrcweir break; 1299*cdf0e10cSrcweir } 1300*cdf0e10cSrcweir 1301*cdf0e10cSrcweir FormattedField::FormatChanged(nWhat); 1302*cdf0e10cSrcweir } 1303*cdf0e10cSrcweir 1304*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1305*cdf0e10cSrcweir void DoubleCurrencyField::setCurrencySymbol(const String& _sSymbol) 1306*cdf0e10cSrcweir { 1307*cdf0e10cSrcweir if (m_sCurrencySymbol == _sSymbol) 1308*cdf0e10cSrcweir return; 1309*cdf0e10cSrcweir 1310*cdf0e10cSrcweir m_sCurrencySymbol = _sSymbol; 1311*cdf0e10cSrcweir UpdateCurrencyFormat(); 1312*cdf0e10cSrcweir FormatChanged(FCT_CURRENCY_SYMBOL); 1313*cdf0e10cSrcweir } 1314*cdf0e10cSrcweir 1315*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1316*cdf0e10cSrcweir void DoubleCurrencyField::setPrependCurrSym(sal_Bool _bPrepend) 1317*cdf0e10cSrcweir { 1318*cdf0e10cSrcweir if (m_bPrependCurrSym == _bPrepend) 1319*cdf0e10cSrcweir return; 1320*cdf0e10cSrcweir 1321*cdf0e10cSrcweir m_bPrependCurrSym = _bPrepend; 1322*cdf0e10cSrcweir UpdateCurrencyFormat(); 1323*cdf0e10cSrcweir FormatChanged(FCT_CURRSYM_POSITION); 1324*cdf0e10cSrcweir } 1325*cdf0e10cSrcweir 1326*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1327*cdf0e10cSrcweir void DoubleCurrencyField::UpdateCurrencyFormat() 1328*cdf0e10cSrcweir { 1329*cdf0e10cSrcweir // the old settings 1330*cdf0e10cSrcweir XubString sOldFormat; 1331*cdf0e10cSrcweir LanguageType eLanguage; 1332*cdf0e10cSrcweir GetFormat(sOldFormat, eLanguage); 1333*cdf0e10cSrcweir sal_Bool bThSep = GetThousandsSep(); 1334*cdf0e10cSrcweir sal_uInt16 nDigits = GetDecimalDigits(); 1335*cdf0e10cSrcweir 1336*cdf0e10cSrcweir // build a new format string with the base class' and my own settings 1337*cdf0e10cSrcweir Locale aLocale; 1338*cdf0e10cSrcweir MsLangId::convertLanguageToLocale( eLanguage, aLocale ); 1339*cdf0e10cSrcweir LocaleDataWrapper aLocaleInfo(::comphelper::getProcessServiceFactory(), aLocale); 1340*cdf0e10cSrcweir 1341*cdf0e10cSrcweir XubString sNewFormat; 1342*cdf0e10cSrcweir if (bThSep) 1343*cdf0e10cSrcweir { 1344*cdf0e10cSrcweir sNewFormat = '#'; 1345*cdf0e10cSrcweir sNewFormat += aLocaleInfo.getNumThousandSep(); 1346*cdf0e10cSrcweir sNewFormat.AppendAscii("##0"); 1347*cdf0e10cSrcweir } 1348*cdf0e10cSrcweir else 1349*cdf0e10cSrcweir sNewFormat = '0'; 1350*cdf0e10cSrcweir 1351*cdf0e10cSrcweir if (nDigits) 1352*cdf0e10cSrcweir { 1353*cdf0e10cSrcweir sNewFormat += aLocaleInfo.getNumDecimalSep(); 1354*cdf0e10cSrcweir 1355*cdf0e10cSrcweir XubString sTemp; 1356*cdf0e10cSrcweir sTemp.Fill(nDigits, '0'); 1357*cdf0e10cSrcweir sNewFormat += sTemp; 1358*cdf0e10cSrcweir } 1359*cdf0e10cSrcweir 1360*cdf0e10cSrcweir if (getPrependCurrSym()) 1361*cdf0e10cSrcweir { 1362*cdf0e10cSrcweir XubString sSymbol = getCurrencySymbol(); 1363*cdf0e10cSrcweir sSymbol.EraseLeadingChars(' '); 1364*cdf0e10cSrcweir sSymbol.EraseTrailingChars(' '); 1365*cdf0e10cSrcweir 1366*cdf0e10cSrcweir XubString sTemp = String::CreateFromAscii("[$"); 1367*cdf0e10cSrcweir sTemp += sSymbol; 1368*cdf0e10cSrcweir sTemp.AppendAscii("] "); 1369*cdf0e10cSrcweir sTemp += sNewFormat; 1370*cdf0e10cSrcweir 1371*cdf0e10cSrcweir // for negative values : $ -0.00, not -$ 0.00 ... 1372*cdf0e10cSrcweir // (the real solution would be a possibility to choose a "positive currency format" and a "negative currency format" ... 1373*cdf0e10cSrcweir // But not now ... (and hey, you could take a formatted field for this ....)) 1374*cdf0e10cSrcweir // FS - 31.03.00 74642 1375*cdf0e10cSrcweir sTemp.AppendAscii(";[$"); 1376*cdf0e10cSrcweir sTemp += sSymbol; 1377*cdf0e10cSrcweir sTemp.AppendAscii("] -"); 1378*cdf0e10cSrcweir sTemp += sNewFormat; 1379*cdf0e10cSrcweir 1380*cdf0e10cSrcweir sNewFormat = sTemp; 1381*cdf0e10cSrcweir } 1382*cdf0e10cSrcweir else 1383*cdf0e10cSrcweir { 1384*cdf0e10cSrcweir XubString sTemp = getCurrencySymbol(); 1385*cdf0e10cSrcweir sTemp.EraseLeadingChars(' '); 1386*cdf0e10cSrcweir sTemp.EraseTrailingChars(' '); 1387*cdf0e10cSrcweir 1388*cdf0e10cSrcweir sNewFormat += String::CreateFromAscii(" [$"); 1389*cdf0e10cSrcweir sNewFormat += sTemp; 1390*cdf0e10cSrcweir sNewFormat += ']'; 1391*cdf0e10cSrcweir } 1392*cdf0e10cSrcweir 1393*cdf0e10cSrcweir // set this new basic format 1394*cdf0e10cSrcweir m_bChangingFormat = sal_True; 1395*cdf0e10cSrcweir SetFormat(sNewFormat, eLanguage); 1396*cdf0e10cSrcweir m_bChangingFormat = sal_False; 1397*cdf0e10cSrcweir } 1398*cdf0e10cSrcweir 1399