xref: /trunk/main/vcl/source/control/longcurr.cxx (revision 9f62ea84)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26 
27 #include <sot/object.hxx>
28 #define _TOOLS_BIGINT
29 #include <sot/factory.hxx>
30 #include <tools/debug.hxx>
31 #include <tools/bigint.hxx>
32 
33 #include <tools/rc.h>
34 
35 #include <vcl/event.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/longcurr.hxx>
38 
39 #include <svdata.hxx>
40 
41 #include <unotools/localedatawrapper.hxx>
42 
43 
44 // =======================================================================
45 
46 #define FORMAT_LONGCURRENCY 	 4
47 
48 // =======================================================================
49 
ImplPower10(sal_uInt16 n)50 static BigInt ImplPower10( sal_uInt16 n )
51 {
52 	sal_uInt16 i;
53 	BigInt	 nValue = 1;
54 
55 	for ( i=0; i < n; i++ )
56 		nValue *= 10;
57 
58 	return nValue;
59 }
60 
61 // -----------------------------------------------------------------------
62 
ImplGetCurr(const LocaleDataWrapper & rLocaleDataWrapper,const BigInt & rNumber,sal_uInt16 nDigits,const String & rCurrSymbol,sal_Bool bShowThousandSep)63 static XubString ImplGetCurr( const LocaleDataWrapper& rLocaleDataWrapper, const BigInt &rNumber, sal_uInt16 nDigits, const String& rCurrSymbol, sal_Bool bShowThousandSep )
64 {
65 	DBG_ASSERT( nDigits < 10, "LongCurrency duerfen nur maximal 9 Nachkommastellen haben" );
66 
67 	if ( rNumber.IsZero() || (long)rNumber )
68 		return rLocaleDataWrapper.getCurr( (long)rNumber, nDigits, rCurrSymbol, bShowThousandSep );
69 
70 	BigInt aTmp( ImplPower10( nDigits ) );
71 	BigInt aInteger( rNumber );
72 	aInteger.Abs();
73 	aInteger  /= aTmp;
74 	BigInt aFraction( rNumber );
75 	aFraction.Abs();
76 	aFraction %= aTmp;
77 	if ( !aInteger.IsZero() )
78 	{
79 		aFraction += aTmp;
80 		aTmp	   = 1000000000L;
81 	}
82 	if ( rNumber.IsNeg() )
83 		aFraction *= -1;
84 
85 	XubString aTemplate = rLocaleDataWrapper.getCurr( (long)aFraction, nDigits, rCurrSymbol, bShowThousandSep );
86 	while( !aInteger.IsZero() )
87 	{
88 		aFraction  = aInteger;
89 		aFraction %= aTmp;
90 		aInteger  /= aTmp;
91 		if( !aInteger.IsZero() )
92 			aFraction += aTmp;
93 
94 		XubString aFractionStr = rLocaleDataWrapper.getNum( (long)aFraction, 0 );
95 
96 		xub_StrLen nSPos = aTemplate.Search( '1' );
97 		if ( aFractionStr.Len() == 1 )
98 			aTemplate.SetChar( nSPos, aFractionStr.GetChar( 0 ) );
99 		else
100 		{
101 			aTemplate.Erase( nSPos, 1 );
102 			aTemplate.Insert( aFractionStr, nSPos );
103 		}
104 	}
105 
106 	return aTemplate;
107 }
108 
109 // -----------------------------------------------------------------------
110 
ImplNumericProcessKeyInput(Edit *,const KeyEvent & rKEvt,sal_Bool bStrictFormat,sal_Bool bThousandSep,const LocaleDataWrapper & rLocaleDataWrapper)111 static sal_Bool ImplNumericProcessKeyInput( Edit*, const KeyEvent& rKEvt,
112 										sal_Bool bStrictFormat, sal_Bool bThousandSep,
113 										const LocaleDataWrapper& rLocaleDataWrapper )
114 {
115 	if ( !bStrictFormat )
116 		return sal_False;
117 	else
118 	{
119 		sal_Unicode cChar = rKEvt.GetCharCode();
120 		sal_uInt16		nGroup = rKEvt.GetKeyCode().GetGroup();
121 
122 		if ( (nGroup == KEYGROUP_FKEYS) || (nGroup == KEYGROUP_CURSOR) ||
123 			 (nGroup == KEYGROUP_MISC) ||
124 			 ((cChar >= '0') && (cChar <= '9')) ||
125 			 (bThousandSep && (cChar == rLocaleDataWrapper.getNumThousandSep())) ||
126 			 (cChar == rLocaleDataWrapper.getNumDecimalSep() ) ||
127 			 (cChar == '-') )
128 			return sal_False;
129 		else
130 			return sal_True;
131 	}
132 }
133 
134 // -----------------------------------------------------------------------
135 
ImplNumericGetValue(const XubString & rStr,BigInt & rValue,sal_uInt16 nDecDigits,const LocaleDataWrapper & rLocaleDataWrapper,sal_Bool bCurrency=sal_False)136 static sal_Bool ImplNumericGetValue( const XubString& rStr, BigInt& rValue,
137 								 sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrapper,
138 								 sal_Bool bCurrency = sal_False )
139 {
140 	XubString	aStr = rStr;
141 	XubString	aStr1;
142 	XubString	aStr2;
143 	sal_uInt16		nDecPos;
144 	sal_Bool		bNegative = sal_False;
145 	xub_StrLen	i;
146 
147 	// Reaktion auf leeren String
148 	if ( !rStr.Len() )
149 		return sal_False;
150 
151 	// Fuehrende und nachfolgende Leerzeichen entfernen
152 	aStr.EraseLeadingAndTrailingChars( ' ' );
153 
154 	// Position des Dezimalpunktes suchen
155 	nDecPos = aStr.Search( rLocaleDataWrapper.getNumDecimalSep() );
156 
157 	if ( nDecPos != STRING_NOTFOUND )
158 	{
159 		aStr1 = aStr.Copy( 0, nDecPos );
160 		aStr2 = aStr.Copy( nDecPos+1 );
161 	}
162 	else
163 		aStr1 = aStr;
164 
165 	// Negativ ?
166 	if ( bCurrency )
167 	{
168 		if ( (aStr.GetChar( 0 ) == '(') && (aStr.GetChar( aStr.Len()-1 ) == ')') )
169 			bNegative = sal_True;
170 		if ( !bNegative )
171 		{
172 			for ( i=0; i < aStr.Len(); i++ )
173 			{
174 				if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') )
175 					break;
176 				else if ( aStr.GetChar( i ) == '-' )
177 				{
178 					bNegative = sal_True;
179 					break;
180 				}
181 			}
182 		}
183 		if ( !bNegative && bCurrency && aStr.Len() )
184 		{
185 			sal_uInt16 nFormat = rLocaleDataWrapper.getCurrNegativeFormat();
186 			if ( (nFormat == 3) || (nFormat == 6)  ||
187 				 (nFormat == 7) || (nFormat == 10) )
188 			{
189 				for ( i = (sal_uInt16)(aStr.Len()-1); i > 0; i++ )
190 				{
191 					if ( (aStr.GetChar( i ) >= '0') && (aStr.GetChar( i ) <= '9') )
192 						break;
193 					else if ( aStr.GetChar( i ) == '-' )
194 					{
195 						bNegative = sal_True;
196 						break;
197 					}
198 				}
199 			}
200 		}
201 	}
202 	else
203 	{
204 		if ( aStr1.GetChar( 0 ) == '-' )
205 			bNegative = sal_True;
206 	}
207 
208 	// Alle unerwuenschten Zeichen rauswerfen
209 	for ( i=0; i < aStr1.Len(); )
210 	{
211 		if ( (aStr1.GetChar( i ) >= '0') && (aStr1.GetChar( i ) <= '9') )
212 			i++;
213 		else
214 			aStr1.Erase( i, 1 );
215 	}
216 	for ( i=0; i < aStr2.Len(); )
217 	{
218 		if ( (aStr2.GetChar( i ) >= '0') && (aStr2.GetChar( i ) <= '9') )
219 			i++;
220 		else
221 			aStr2.Erase( i, 1 );
222 	}
223 
224 	if ( !aStr1.Len() && !aStr2.Len() )
225 		return sal_False;
226 
227 	if ( !aStr1.Len() )
228 		aStr1.Insert( '0' );
229 	if ( bNegative )
230 		aStr1.Insert( '-', 0 );
231 
232 	// Nachkommateil zurechtstutzen und dabei runden
233 	sal_Bool bRound = sal_False;
234 	if ( aStr2.Len() > nDecDigits )
235 	{
236 		if ( aStr2.GetChar( nDecDigits ) >= '5' )
237 			bRound = sal_True;
238 		aStr2.Erase( nDecDigits );
239 	}
240 	if ( aStr2.Len() < nDecDigits )
241 		aStr2.Expand( nDecDigits, '0' );
242 
243 	aStr  = aStr1;
244 	aStr += aStr2;
245 
246 	// Bereichsueberpruefung
247 	BigInt nValue( aStr );
248 	if ( bRound )
249 	{
250 		if ( !bNegative )
251 			nValue+=1;
252 		else
253 			nValue-=1;
254 	}
255 
256 	rValue = nValue;
257 
258 	return sal_True;
259 }
260 
261 // =======================================================================
262 
ImplLongCurrencyProcessKeyInput(Edit * pEdit,const KeyEvent & rKEvt,sal_Bool,sal_Bool bUseThousandSep,const LocaleDataWrapper & rLocaleDataWrapper)263 static sal_Bool ImplLongCurrencyProcessKeyInput( Edit* pEdit, const KeyEvent& rKEvt,
264 											 sal_Bool, sal_Bool bUseThousandSep, const LocaleDataWrapper& rLocaleDataWrapper )
265 {
266 	// Es gibt hier kein sinnvolles StrictFormat, also alle
267 	// Zeichen erlauben
268 	return ImplNumericProcessKeyInput( pEdit, rKEvt, sal_False, bUseThousandSep, rLocaleDataWrapper  );
269 }
270 
271 // -----------------------------------------------------------------------
272 
ImplLongCurrencyGetValue(const XubString & rStr,BigInt & rValue,sal_uInt16 nDecDigits,const LocaleDataWrapper & rLocaleDataWrapper)273 inline sal_Bool ImplLongCurrencyGetValue( const XubString& rStr, BigInt& rValue,
274 									  sal_uInt16 nDecDigits, const LocaleDataWrapper& rLocaleDataWrapper )
275 {
276 	// Zahlenwert holen
277 	return ImplNumericGetValue( rStr, rValue, nDecDigits, rLocaleDataWrapper, sal_True );
278 }
279 
280 // -----------------------------------------------------------------------
281 
ImplLongCurrencyReformat(const XubString & rStr,BigInt nMin,BigInt nMax,sal_uInt16 nDecDigits,const LocaleDataWrapper & rLocaleDataWrapper,String & rOutStr,LongCurrencyFormatter & rFormatter)282 sal_Bool ImplLongCurrencyReformat( const XubString& rStr, BigInt nMin, BigInt nMax,
283 							   sal_uInt16 nDecDigits,
284 							   const LocaleDataWrapper& rLocaleDataWrapper, String& rOutStr,
285 							   LongCurrencyFormatter& rFormatter )
286 {
287 	BigInt nValue;
288 	if ( !ImplNumericGetValue( rStr, nValue, nDecDigits, rLocaleDataWrapper, sal_True ) )
289 		return sal_True;
290 	else
291 	{
292 		BigInt nTempVal = nValue;
293 		if ( nTempVal > nMax )
294 			nTempVal = nMax;
295 		else if ( nTempVal < nMin )
296 			nTempVal = nMin;
297 
298 		if ( rFormatter.GetErrorHdl().IsSet() && (nValue != nTempVal) )
299 		{
300             rFormatter.mnCorrectedValue = nTempVal;
301 			if ( !rFormatter.GetErrorHdl().Call( &rFormatter ) )
302 			{
303                 rFormatter.mnCorrectedValue = 0;
304 				return sal_False;
305 			}
306 			else
307             {
308                 rFormatter.mnCorrectedValue = 0;
309             }
310 		}
311 
312 		rOutStr = ImplGetCurr( rLocaleDataWrapper, nTempVal, nDecDigits, rFormatter.GetCurrencySymbol(), rFormatter.IsUseThousandSep() );
313 		return sal_True;
314 	}
315 }
316 
317 
318 // =======================================================================
319 
ImpInit()320 void LongCurrencyFormatter::ImpInit()
321 {
322 	mnFieldValue		= 0;
323 	mnLastValue 		= 0;
324 	mnMin				= 0;
325 	mnMax				= 0x7FFFFFFF;
326 	mnMax			   *= 0x7FFFFFFF;
327 	mnCorrectedValue	= 0;
328     mnDecimalDigits     = 0;
329 	mnType				= FORMAT_LONGCURRENCY;
330     mbThousandSep       = sal_True;
331 	SetDecimalDigits( 0 );
332 }
333 
334 // -----------------------------------------------------------------------
335 
LongCurrencyFormatter()336 LongCurrencyFormatter::LongCurrencyFormatter()
337 {
338 	ImpInit();
339 }
340 
341 // -----------------------------------------------------------------------
342 
ImplLoadRes(const ResId & rResId)343 void LongCurrencyFormatter::ImplLoadRes( const ResId& rResId )
344 {
345 	ImpInit();
346 
347 	ResMgr* 	pMgr = rResId.GetResMgr();
348     if( pMgr )
349     {
350         sal_uLong		nMask = pMgr->ReadLong();
351 
352         if ( NUMERICFORMATTER_MIN & nMask )
353             mnMin = pMgr->ReadLong();
354 
355         if ( NUMERICFORMATTER_MAX & nMask )
356             mnMax = pMgr->ReadLong();
357 
358         if ( NUMERICFORMATTER_STRICTFORMAT & nMask )
359             SetStrictFormat(  (sal_Bool)pMgr->ReadShort() );
360 
361         if ( NUMERICFORMATTER_DECIMALDIGITS & nMask )
362             SetDecimalDigits( pMgr->ReadShort() );
363 
364         if ( NUMERICFORMATTER_VALUE & nMask )
365         {
366             mnFieldValue = pMgr->ReadLong();
367             if ( mnFieldValue > mnMax )
368                 mnFieldValue = mnMax;
369             else if ( mnFieldValue < mnMin )
370                 mnFieldValue = mnMin;
371             mnLastValue = mnFieldValue;
372         }
373     }
374 }
375 
376 // -----------------------------------------------------------------------
377 
~LongCurrencyFormatter()378 LongCurrencyFormatter::~LongCurrencyFormatter()
379 {
380 }
381 
382 // -----------------------------------------------------------------------
383 
SetCurrencySymbol(const String & rStr)384 void LongCurrencyFormatter::SetCurrencySymbol( const String& rStr )
385 {
386     maCurrencySymbol= rStr;
387     ReformatAll();
388 }
389 
390 // -----------------------------------------------------------------------
391 
GetCurrencySymbol() const392 String LongCurrencyFormatter::GetCurrencySymbol() const
393 {
394     return maCurrencySymbol.Len() ? maCurrencySymbol : GetLocaleDataWrapper().getCurrSymbol();
395 }
396 
397 // -----------------------------------------------------------------------
398 
SetValue(BigInt nNewValue)399 void LongCurrencyFormatter::SetValue( BigInt nNewValue )
400 {
401 	SetUserValue( nNewValue );
402 	mnFieldValue = mnLastValue;
403 	SetEmptyFieldValueData( sal_False );
404 }
405 
406 // -----------------------------------------------------------------------
407 
SetUserValue(BigInt nNewValue)408 void LongCurrencyFormatter::SetUserValue( BigInt nNewValue )
409 {
410 	if ( nNewValue > mnMax )
411 		nNewValue = mnMax;
412 	else if ( nNewValue < mnMin )
413 		nNewValue = mnMin;
414 	mnLastValue = nNewValue;
415 
416 	if ( !GetField() )
417 		return;
418 
419 	XubString aStr = ImplGetCurr( GetLocaleDataWrapper(), nNewValue, GetDecimalDigits(), GetCurrencySymbol(), IsUseThousandSep() );
420 	if ( GetField()->HasFocus() )
421 	{
422 		Selection aSelection = GetField()->GetSelection();
423 		GetField()->SetText( aStr );
424 		GetField()->SetSelection( aSelection );
425 	}
426 	else
427 		GetField()->SetText( aStr );
428 	MarkToBeReformatted( sal_False );
429 }
430 
431 // -----------------------------------------------------------------------
432 
GetValue() const433 BigInt LongCurrencyFormatter::GetValue() const
434 {
435 	if ( !GetField() )
436 		return 0;
437 
438 	BigInt nTempValue;
439 	if ( ImplLongCurrencyGetValue( GetField()->GetText(), nTempValue, GetDecimalDigits(), GetLocaleDataWrapper() ) )
440 	{
441 		if ( nTempValue > mnMax )
442 			nTempValue = mnMax;
443 		else if ( nTempValue < mnMin )
444 			nTempValue = mnMin;
445 		return nTempValue;
446 	}
447 	else
448 		return mnLastValue;
449 }
450 
451 // -----------------------------------------------------------------------
452 
Reformat()453 void LongCurrencyFormatter::Reformat()
454 {
455 	if ( !GetField() )
456 		return;
457 
458 	if ( !GetField()->GetText().Len() && ImplGetEmptyFieldValue() )
459 		return;
460 
461 	XubString aStr;
462 	sal_Bool bOK = ImplLongCurrencyReformat( GetField()->GetText(), mnMin, mnMax,
463 										 GetDecimalDigits(), GetLocaleDataWrapper(), aStr, *this );
464 	if ( !bOK )
465 		return;
466 
467 	if ( aStr.Len() )
468 	{
469 		GetField()->SetText( aStr );
470 		MarkToBeReformatted( sal_False );
471 		ImplLongCurrencyGetValue( aStr, mnLastValue, GetDecimalDigits(), GetLocaleDataWrapper() );
472 	}
473 	else
474 		SetValue( mnLastValue );
475 }
476 
477 // -----------------------------------------------------------------------
478 
ReformatAll()479 void LongCurrencyFormatter::ReformatAll()
480 {
481 	Reformat();
482 }
483 
484 // -----------------------------------------------------------------------
485 
SetMin(BigInt nNewMin)486 void LongCurrencyFormatter::SetMin( BigInt nNewMin )
487 {
488 	mnMin = nNewMin;
489 	ReformatAll();
490 }
491 
492 // -----------------------------------------------------------------------
493 
SetMax(BigInt nNewMax)494 void LongCurrencyFormatter::SetMax( BigInt nNewMax )
495 {
496 	mnMax = nNewMax;
497 	ReformatAll();
498 }
499 
500 // -----------------------------------------------------------------------
501 
SetUseThousandSep(sal_Bool b)502 void LongCurrencyFormatter::SetUseThousandSep( sal_Bool b )
503 {
504     mbThousandSep = b;
505     ReformatAll();
506 }
507 
508 
509 // -----------------------------------------------------------------------
510 
SetDecimalDigits(sal_uInt16 nDigits)511 void LongCurrencyFormatter::SetDecimalDigits( sal_uInt16 nDigits )
512 {
513 //	DBG_ASSERT( nDigits < 10, "LongCurrency duerfen nur maximal 9 Nachkommastellen haben" );
514 
515 	if ( nDigits > 9 )
516 		nDigits = 9;
517 
518 	mnDecimalDigits = nDigits;
519 	ReformatAll();
520 }
521 
522 // -----------------------------------------------------------------------
523 
GetDecimalDigits() const524 sal_uInt16 LongCurrencyFormatter::GetDecimalDigits() const
525 {
526 	return mnDecimalDigits;
527 }
528 
529 // -----------------------------------------------------------------------
530 
IsValueModified() const531 sal_Bool LongCurrencyFormatter::IsValueModified() const
532 {
533 	if ( ImplGetEmptyFieldValue() )
534 		return !IsEmptyValue();
535 	else if ( GetValue() != mnFieldValue )
536 		return sal_True;
537 	else
538 		return sal_False;
539 }
540 
541 // -----------------------------------------------------------------------
542 
SetEmptyValue()543 void LongCurrencyFormatter::SetEmptyValue()
544 {
545 	GetField()->SetText( ImplGetSVEmptyStr() );
546 	SetEmptyFieldValueData( sal_True );
547 }
548 
549 // -----------------------------------------------------------------------
550 
Normalize(BigInt nValue) const551 BigInt LongCurrencyFormatter::Normalize( BigInt nValue ) const
552 {
553 	return (nValue * ImplPower10( GetDecimalDigits() ) );
554 }
555 
556 // -----------------------------------------------------------------------
557 
Denormalize(BigInt nValue) const558 BigInt LongCurrencyFormatter::Denormalize( BigInt nValue ) const
559 {
560 	BigInt nFactor = ImplPower10( GetDecimalDigits() );
561 	BigInt nTmp    = nFactor;
562 	nTmp /= 2;
563 	nTmp += nValue;
564 	nTmp /= nFactor;
565 	return nTmp;
566 }
567 
568 // =======================================================================
569 
ImplNewLongCurrencyFieldValue(LongCurrencyField * pField,BigInt nNewValue)570 void ImplNewLongCurrencyFieldValue( LongCurrencyField* pField, BigInt nNewValue )
571 {
572 	Selection aSelect = pField->GetSelection();
573 	aSelect.Justify();
574 	XubString aText = pField->GetText();
575 	sal_Bool bLastSelected = ((xub_StrLen)aSelect.Max() == aText.Len()) ? sal_True : sal_False;
576 
577 	BigInt nOldLastValue  = pField->mnLastValue;
578 	pField->SetUserValue( nNewValue );
579 	pField->mnLastValue  = nOldLastValue;
580 
581 	if ( bLastSelected )
582 	{
583 		if ( !aSelect.Len() )
584 			aSelect.Min() = SELECTION_MAX;
585 		aSelect.Max() = SELECTION_MAX;
586 	}
587 	pField->SetSelection( aSelect );
588 	pField->SetModifyFlag();
589 	pField->Modify();
590 }
591 
592 // =======================================================================
593 
LongCurrencyField(Window * pParent,WinBits nWinStyle)594 LongCurrencyField::LongCurrencyField( Window* pParent, WinBits nWinStyle ) :
595 	SpinField( pParent, nWinStyle )
596 {
597 	SetField( this );
598 	mnSpinSize	 = 1;
599 	mnFirst 	 = mnMin;
600 	mnLast		 = mnMax;
601 
602 	Reformat();
603 }
604 
605 // -----------------------------------------------------------------------
606 
LongCurrencyField(Window * pParent,const ResId & rResId)607 LongCurrencyField::LongCurrencyField( Window* pParent, const ResId& rResId ) :
608 	SpinField( WINDOW_NUMERICFIELD )
609 {
610 	rResId.SetRT( RSC_NUMERICFIELD );
611 	WinBits nStyle = ImplInitRes( rResId ) ;
612 	SpinField::ImplInit( pParent, nStyle );
613 
614 	SetField( this );
615 	mnSpinSize	 = 1;
616 	mnFirst 	 = mnMin;
617 	mnLast		 = mnMax;
618 
619 	Reformat();
620 
621 	if ( !(nStyle & WB_HIDE) )
622 		Show();
623 }
624 
625 // -----------------------------------------------------------------------
626 
ImplLoadRes(const ResId & rResId)627 void LongCurrencyField::ImplLoadRes( const ResId& rResId )
628 {
629 	SpinField::ImplLoadRes( rResId );
630 	LongCurrencyFormatter::ImplLoadRes( ResId( (RSHEADER_TYPE *)GetClassRes(), *rResId.GetResMgr() ) );
631 
632 	sal_uLong nMask = ReadLongRes();
633 	if ( CURRENCYFIELD_FIRST & nMask )
634 		mnFirst = ReadLongRes();
635 
636 	if ( CURRENCYFIELD_LAST & nMask )
637 		mnLast = ReadLongRes();
638 
639 	if ( CURRENCYFIELD_SPINSIZE & nMask )
640 		mnSpinSize = ReadLongRes();
641 }
642 
643 // -----------------------------------------------------------------------
644 
~LongCurrencyField()645 LongCurrencyField::~LongCurrencyField()
646 {
647 }
648 
649 // -----------------------------------------------------------------------
650 
PreNotify(NotifyEvent & rNEvt)651 long LongCurrencyField::PreNotify( NotifyEvent& rNEvt )
652 {
653 	if( rNEvt.GetType() == EVENT_KEYINPUT )
654 	{
655 		if ( ImplLongCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), GetLocaleDataWrapper() ) )
656 			return 1;
657 	}
658 	return SpinField::PreNotify( rNEvt );
659 }
660 
661 // -----------------------------------------------------------------------
662 
Notify(NotifyEvent & rNEvt)663 long LongCurrencyField::Notify( NotifyEvent& rNEvt )
664 {
665 	if( rNEvt.GetType() == EVENT_GETFOCUS )
666 	{
667 		MarkToBeReformatted( sal_False );
668 	}
669 	else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
670 	{
671 		if ( MustBeReformatted() )
672 		{
673 			Reformat();
674 			SpinField::Modify();
675 		}
676 	}
677 	return SpinField::Notify( rNEvt );
678 }
679 
680 // -----------------------------------------------------------------------
681 
Modify()682 void LongCurrencyField::Modify()
683 {
684 	MarkToBeReformatted( sal_True );
685 	SpinField::Modify();
686 }
687 
688 // -----------------------------------------------------------------------
689 
Up()690 void LongCurrencyField::Up()
691 {
692 	BigInt nValue = GetValue();
693 	nValue += mnSpinSize;
694 	if ( nValue > mnMax )
695 		nValue = mnMax;
696 
697 	ImplNewLongCurrencyFieldValue( this, nValue );
698 	SpinField::Up();
699 }
700 
701 // -----------------------------------------------------------------------
702 
Down()703 void LongCurrencyField::Down()
704 {
705 	BigInt nValue = GetValue();
706 	nValue -= mnSpinSize;
707 	if ( nValue < mnMin )
708 		nValue = mnMin;
709 
710 	ImplNewLongCurrencyFieldValue( this, nValue );
711 	SpinField::Down();
712 }
713 
714 // -----------------------------------------------------------------------
715 
First()716 void LongCurrencyField::First()
717 {
718 	ImplNewLongCurrencyFieldValue( this, mnFirst );
719 	SpinField::First();
720 }
721 
722 // -----------------------------------------------------------------------
723 
Last()724 void LongCurrencyField::Last()
725 {
726 	ImplNewLongCurrencyFieldValue( this, mnLast );
727 	SpinField::Last();
728 }
729 
730 // =======================================================================
731 
LongCurrencyBox(Window * pParent,WinBits nWinStyle)732 LongCurrencyBox::LongCurrencyBox( Window* pParent, WinBits nWinStyle ) :
733 	ComboBox( pParent, nWinStyle )
734 {
735 	SetField( this );
736 	Reformat();
737 }
738 
739 // -----------------------------------------------------------------------
740 
LongCurrencyBox(Window * pParent,const ResId & rResId)741 LongCurrencyBox::LongCurrencyBox( Window* pParent, const ResId& rResId ) :
742 	ComboBox( WINDOW_NUMERICFIELD )
743 {
744 	SetField( this );
745 	WinBits nStyle = ImplInitRes( rResId ) ;
746 	ComboBox::ImplLoadRes( rResId );
747     ImplInit( pParent, nStyle );
748 	LongCurrencyFormatter::ImplLoadRes( rResId );
749 	Reformat();
750 
751 	if ( !(nStyle & WB_HIDE) )
752 		Show();
753 }
754 
755 // -----------------------------------------------------------------------
756 
~LongCurrencyBox()757 LongCurrencyBox::~LongCurrencyBox()
758 {
759 }
760 
761 // -----------------------------------------------------------------------
762 
PreNotify(NotifyEvent & rNEvt)763 long LongCurrencyBox::PreNotify( NotifyEvent& rNEvt )
764 {
765 	if( rNEvt.GetType() == EVENT_KEYINPUT )
766 	{
767 		if ( ImplLongCurrencyProcessKeyInput( GetField(), *rNEvt.GetKeyEvent(), IsStrictFormat(), IsUseThousandSep(), GetLocaleDataWrapper() ) )
768 			return 1;
769 	}
770 	return ComboBox::PreNotify( rNEvt );
771 }
772 
773 // -----------------------------------------------------------------------
774 
Notify(NotifyEvent & rNEvt)775 long LongCurrencyBox::Notify( NotifyEvent& rNEvt )
776 {
777 	if( rNEvt.GetType() == EVENT_GETFOCUS )
778 	{
779 		MarkToBeReformatted( sal_False );
780 	}
781 	else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
782 	{
783 		if ( MustBeReformatted() )
784 		{
785 			Reformat();
786 			ComboBox::Modify();
787 		}
788 	}
789 	return ComboBox::Notify( rNEvt );
790 }
791 
792 // -----------------------------------------------------------------------
793 
Modify()794 void LongCurrencyBox::Modify()
795 {
796 	MarkToBeReformatted( sal_True );
797 	ComboBox::Modify();
798 }
799 
800 // -----------------------------------------------------------------------
801 
ReformatAll()802 void LongCurrencyBox::ReformatAll()
803 {
804 	XubString aStr;
805 	SetUpdateMode( sal_False );
806 	sal_uInt16 nEntryCount = GetEntryCount();
807 	for ( sal_uInt16 i=0; i < nEntryCount; i++ )
808 	{
809 		ImplLongCurrencyReformat( GetEntry( i ), mnMin, mnMax,
810 								  GetDecimalDigits(), GetLocaleDataWrapper(),
811 								  aStr, *this );
812 		RemoveEntry( i );
813 		InsertEntry( aStr, i );
814 	}
815 	LongCurrencyFormatter::Reformat();
816 	SetUpdateMode( sal_True );
817 }
818 
819 // -----------------------------------------------------------------------
820 
InsertValue(BigInt nValue,sal_uInt16 nPos)821 void LongCurrencyBox::InsertValue( BigInt nValue, sal_uInt16 nPos )
822 {
823 	XubString aStr = ImplGetCurr( GetLocaleDataWrapper(), nValue, GetDecimalDigits(), GetCurrencySymbol(), IsUseThousandSep() );
824 	ComboBox::InsertEntry( aStr, nPos );
825 }
826 
827 // -----------------------------------------------------------------------
828 
RemoveValue(BigInt nValue)829 void LongCurrencyBox::RemoveValue( BigInt nValue )
830 {
831 	XubString aStr = ImplGetCurr( GetLocaleDataWrapper(), nValue, GetDecimalDigits(), GetCurrencySymbol(), IsUseThousandSep() );
832 	ComboBox::RemoveEntry( aStr );
833 }
834 
835 // -----------------------------------------------------------------------
836 
GetValue(sal_uInt16 nPos) const837 BigInt LongCurrencyBox::GetValue( sal_uInt16 nPos ) const
838 {
839 	BigInt nValue = 0;
840 	ImplLongCurrencyGetValue( ComboBox::GetEntry( nPos ), nValue,
841 							  GetDecimalDigits(), GetLocaleDataWrapper() );
842 	return nValue;
843 }
844 
845 // -----------------------------------------------------------------------
846 
GetValuePos(BigInt nValue) const847 sal_uInt16 LongCurrencyBox::GetValuePos( BigInt nValue ) const
848 {
849 	XubString aStr = ImplGetCurr( GetLocaleDataWrapper(), nValue, GetDecimalDigits(), GetCurrencySymbol(), IsUseThousandSep() );
850 	return ComboBox::GetEntryPos( aStr );
851 }
852 
853 // =======================================================================
854