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