xref: /AOO41X/main/svtools/source/control/fmtfield.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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