xref: /trunk/main/vcl/source/control/longcurr.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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