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