1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
23 #include <basic/sbxform.hxx>
24 #include <rtl/ustrbuf.hxx>
26 #include <rtl/character.hxx>
29 TODO: are there any Star-Basic characteristics unconsidered?
31 what means: * as placeholder
33 COMMENT: Visual-Basic treats the following (invalid) format-strings
36 ##0##.##0## --> ##000.000##
38 (this class behaves the same way)
47 #define MAX_NO_OF_DIGITS DBL_DIG
48 #define MAX_DOUBLE_BUFFER_LENGTH MAX_NO_OF_DIGITS + 9
49 // +1 for leading sign
50 // +1 for digit before the decimal point
51 // +1 for decimal point
52 // +2 for exponent E and exp. leading sign
53 // +3 for the exponent's value
56 #define CREATE_1000SEP_CHAR '@'
58 #define FORMAT_SEPARATOR ';'
60 // predefined formats for the Format$()-command:
61 #define BASICFORMAT_GENERALNUMBER "General Number"
62 #define BASICFORMAT_CURRENCY "Currency"
63 #define BASICFORMAT_FIXED "Fixed"
64 #define BASICFORMAT_STANDARD "Standard"
65 #define BASICFORMAT_PERCENT "Percent"
66 #define BASICFORMAT_SCIENTIFIC "Scientific"
67 #define BASICFORMAT_YESNO "Yes/No"
68 #define BASICFORMAT_TRUEFALSE "True/False"
69 #define BASICFORMAT_ONOFF "On/Off"
71 // Comment: Visual-Basic has a maximum of 12 positions after the
72 // decimal point for floating-point-numbers.
73 // all format-strings are compatible to Visual-Basic:
74 #define GENERALNUMBER_FORMAT "0.############"
75 #define FIXED_FORMAT "0.00"
76 #define STANDARD_FORMAT "@0.00"
77 #define PERCENT_FORMAT "0.00%"
78 #define SCIENTIFIC_FORMAT "#.00E+00"
79 // Comment: the character @ means that thousand-separators shall
80 // be generated. That's a StarBasic 'extension'.
83 static double get_number_of_digits( double dNumber
)
84 //double floor_log10_fabs( double dNumber )
87 return 0.0; // used to be 1.0, now 0.0 because of #40025;
89 return floor( log10( fabs( dNumber
) ) );
93 SbxBasicFormater::SbxBasicFormater( sal_Unicode _cDecPoint
, sal_Unicode _cThousandSep
,
94 const OUString
& _sOnStrg
,
95 const OUString
& _sOffStrg
,
96 const OUString
& _sYesStrg
,
97 const OUString
& _sNoStrg
,
98 const OUString
& _sTrueStrg
,
99 const OUString
& _sFalseStrg
,
100 const OUString
& _sCurrencyStrg
,
101 const OUString
& _sCurrencyFormatStrg
)
102 : cDecPoint(_cDecPoint
)
103 , cThousandSep(_cThousandSep
)
105 , sOffStrg(_sOffStrg
)
106 , sYesStrg(_sYesStrg
)
108 , sTrueStrg(_sTrueStrg
)
109 , sFalseStrg(_sFalseStrg
)
110 , sCurrencyStrg(_sCurrencyStrg
)
111 , sCurrencyFormatStrg(_sCurrencyFormatStrg
)
118 // function to output an error-text (for debugging)
119 // displaces all characters of the string, starting from nStartPos
120 // for one position to larger indexes, i. e. place for a new
121 // character (which is to be inserted) is created.
122 // ATTENTION: the string MUST be long enough!
123 inline void SbxBasicFormater::ShiftString( OUStringBuffer
& sStrg
, sal_uInt16 nStartPos
)
125 sStrg
.remove(nStartPos
,1);
128 void SbxBasicFormater::AppendDigit( OUStringBuffer
& sStrg
, short nDigit
)
130 if( nDigit
>=0 && nDigit
<=9 )
132 sStrg
.append(static_cast<sal_Unicode
>(nDigit
+'0'));
136 void SbxBasicFormater::LeftShiftDecimalPoint( OUStringBuffer
& sStrg
)
140 for(sal_Int32 i
= 0; i
< sStrg
.getLength(); i
++)
142 if(sStrg
[i
] == cDecPoint
)
150 sStrg
[nPos
] = sStrg
[nPos
- 1];
151 sStrg
[nPos
- 1] = cDecPoint
;
155 // returns a flag if rounding a 9
156 void SbxBasicFormater::StrRoundDigit( OUStringBuffer
& sStrg
, short nPos
, bool& bOverflow
)
163 sal_Unicode c
= sStrg
[nPos
];
164 if( nPos
> 0 && (c
== cDecPoint
|| c
== cThousandSep
) )
166 StrRoundDigit( sStrg
, nPos
- 1, bOverflow
);
167 // CHANGE from 9.3.1997: end the method immediately after recursive call!
172 // in a valid format-string the number's output should be done
173 // in one piece, i. e. special characters should ONLY be in
174 // front OR behind the number and not right in the middle of
175 // the format information for the number
176 while( nPos
>= 0 && ! rtl::isAsciiDigit(sStrg
[nPos
]))
182 ShiftString( sStrg
, 0 );
188 sal_Unicode c2
= sStrg
[nPos
];
189 if( rtl::isAsciiDigit(c2
) )
194 StrRoundDigit( sStrg
, nPos
- 1, bOverflow
);
198 sStrg
[nPos
] = c2
+ 1;
203 ShiftString( sStrg
,nPos
+1 );
204 sStrg
[nPos
+ 1] = '1';
210 void SbxBasicFormater::StrRoundDigit( OUStringBuffer
& sStrg
, short nPos
)
214 StrRoundDigit( sStrg
, nPos
, bOverflow
);
217 void SbxBasicFormater::ParseBack( OUStringBuffer
& sStrg
, const OUString
& sFormatStrg
,
220 for( sal_Int32 i
= nFormatPos
;
221 i
>0 && sFormatStrg
[ i
] == '#' && sStrg
[sStrg
.getLength() - 1] == '0';
224 sStrg
.setLength(sStrg
.getLength() - 1 );
228 void SbxBasicFormater::InitScan( double _dNum
)
230 char sBuffer
[ MAX_DOUBLE_BUFFER_LENGTH
];
233 InitExp( get_number_of_digits( dNum
) );
234 // maximum of 15 positions behind the decimal point, example: -1.234000000000000E-001
235 /*int nCount =*/ sprintf( sBuffer
,"%+22.15lE",dNum
);
236 sSciNumStrg
= OUString::createFromAscii( sBuffer
);
240 void SbxBasicFormater::InitExp( double _dNewExp
)
242 char sBuffer
[ MAX_DOUBLE_BUFFER_LENGTH
];
243 nNumExp
= static_cast<short>(_dNewExp
);
244 /*int nCount =*/ sprintf( sBuffer
,"%+i",nNumExp
);
245 sNumExpStrg
= OUString::createFromAscii( sBuffer
);
246 nExpExp
= static_cast<short>(get_number_of_digits( static_cast<double>(nNumExp
) ));
250 short SbxBasicFormater::GetDigitAtPosScan( short nPos
, bool& bFoundFirstDigit
)
252 // trying to read a higher digit,
253 // e. g. position 4 in 1.234,
254 // or to read a digit outside of the
255 // number's dissolution (double)
256 if( nPos
>nNumExp
|| abs(nNumExp
-nPos
)>MAX_NO_OF_DIGITS
)
260 // determine the index of the position in the number-string:
261 // skip the leading sign
263 // skip the decimal point if necessary
267 // query of the number's first valid digit --> set flag
269 bFoundFirstDigit
= true;
270 return static_cast<short>(sSciNumStrg
[ no
] - '0');
273 short SbxBasicFormater::GetDigitAtPosExpScan( short nPos
, bool& bFoundFirstDigit
)
282 bFoundFirstDigit
= true;
283 return static_cast<short>(sNumExpStrg
[ no
] - '0');
286 // a value for the exponent can be given because the number maybe shall
287 // not be displayed in a normed way (e. g. 1.2345e-03) but maybe 123.345e-3 !
288 short SbxBasicFormater::GetDigitAtPosExpScan( double dNewExponent
, short nPos
,
289 bool& bFoundFirstDigit
)
291 InitExp( dNewExponent
);
293 return GetDigitAtPosExpScan( nPos
,bFoundFirstDigit
);
296 // Copies the respective part of the format-string, if existing, and returns it.
297 // So a new string is created, which has to be freed by the caller later.
298 OUString
SbxBasicFormater::GetPosFormatString( const OUString
& sFormatStrg
, bool & bFound
)
300 bFound
= false; // default...
301 sal_Int32 nPos
= sFormatStrg
.indexOf( FORMAT_SEPARATOR
);
306 // the format-string for positive numbers is
307 // everything before the first ';'
308 return sFormatStrg
.copy( 0,nPos
);
314 // see also GetPosFormatString()
315 OUString
SbxBasicFormater::GetNegFormatString( const OUString
& sFormatStrg
, bool & bFound
)
317 bFound
= false; // default...
318 sal_Int32 nPos
= sFormatStrg
.indexOf( FORMAT_SEPARATOR
);
322 // the format-string for negative numbers is
323 // everything between the first and the second ';'
324 OUString sTempStrg
= sFormatStrg
.copy( nPos
+1 );
325 nPos
= sTempStrg
.indexOf( FORMAT_SEPARATOR
);
333 return sTempStrg
.copy( 0,nPos
);
339 // see also GetPosFormatString()
340 OUString
SbxBasicFormater::Get0FormatString( const OUString
& sFormatStrg
, bool & bFound
)
342 bFound
= false; // default...
343 sal_Int32 nPos
= sFormatStrg
.indexOf( FORMAT_SEPARATOR
);
347 // the format string for the zero is
348 // everything after the second ';'
349 OUString sTempStrg
= sFormatStrg
.copy( nPos
+1 );
350 nPos
= sTempStrg
.indexOf( FORMAT_SEPARATOR
);
354 sTempStrg
= sTempStrg
.copy( nPos
+1 );
355 nPos
= sTempStrg
.indexOf( FORMAT_SEPARATOR
);
362 return sTempStrg
.copy( 0,nPos
);
370 // see also GetPosFormatString()
371 OUString
SbxBasicFormater::GetNullFormatString( const OUString
& sFormatStrg
, bool & bFound
)
373 bFound
= false; // default...
374 sal_Int32 nPos
= sFormatStrg
.indexOf( FORMAT_SEPARATOR
);
378 // the format-string for the Null is
379 // everything after the third ';'
380 OUString sTempStrg
= sFormatStrg
.copy( nPos
+1 );
381 nPos
= sTempStrg
.indexOf( FORMAT_SEPARATOR
);
384 sTempStrg
= sTempStrg
.copy( nPos
+1 );
385 nPos
= sTempStrg
.indexOf( FORMAT_SEPARATOR
);
389 return sTempStrg
.copy( nPos
+1 );
397 // returns value <> 0 in case of an error
398 void SbxBasicFormater::AnalyseFormatString( const OUString
& sFormatStrg
,
399 short& nNoOfDigitsLeft
, short& nNoOfDigitsRight
,
400 short& nNoOfOptionalDigitsLeft
,
401 short& nNoOfExponentDigits
, short& nNoOfOptionalExponentDigits
,
402 bool& bPercent
, bool& bCurrency
, bool& bScientific
,
403 bool& bGenerateThousandSeparator
,
404 short& nMultipleThousandSeparators
)
409 nLen
= sFormatStrg
.getLength();
411 nNoOfDigitsRight
= 0;
412 nNoOfOptionalDigitsLeft
= 0;
413 nNoOfExponentDigits
= 0;
414 nNoOfOptionalExponentDigits
= 0;
418 // from 11.7.97: as soon as a comma (point?) is found in the format string,
419 // all three decimal powers are marked (i. e. thousand, million, ...)
420 bGenerateThousandSeparator
= sFormatStrg
.indexOf( ',' ) >= 0;
421 nMultipleThousandSeparators
= 0;
423 for( sal_Int32 i
= 0; i
< nLen
; i
++ )
425 sal_Unicode c
= sFormatStrg
[ i
];
433 // TODO here maybe better error inspection of the mantissa for valid syntax (see grammar)h
434 // ATTENTION: 'undefined' behaviour if # and 0 are combined!
435 // REMARK: #-placeholders are actually useless for
436 // scientific display before the decimal point!
439 nNoOfOptionalDigitsLeft
++;
446 else if( nState
==-1 ) // search 0 in the exponent
448 if( c
=='#' ) // # switches on the condition
450 nNoOfOptionalExponentDigits
++;
453 nNoOfExponentDigits
++;
455 else if( nState
==-2 ) // search # in the exponent
459 // ERROR: 0 after # in the exponent is NOT allowed!!
462 nNoOfOptionalExponentDigits
++;
463 nNoOfExponentDigits
++;
470 return; // ERROR: too many decimal points
481 sal_Unicode ch
= sFormatStrg
[ i
+1 ];
483 if( ch
!=0 && (ch
==',' || ch
=='.') )
485 nMultipleThousandSeparators
++;
491 // #i13821 not when no digits before
492 if( nNoOfDigitsLeft
> 0 || nNoOfDigitsRight
> 0 )
494 nState
= -1; // abort counting digits
498 // OWN command-character which turns on
499 // the creation of thousand-separators
504 case CREATE_1000SEP_CHAR
:
505 bGenerateThousandSeparator
= true;
511 // the flag bCreateSign says that at the mantissa a leading sign
513 void SbxBasicFormater::ScanFormatString( double dNumber
,
514 const OUString
& sFormatStrg
, OUString
& sReturnStrgFinal
,
517 short /*nErr,*/nNoOfDigitsLeft
,nNoOfDigitsRight
,nNoOfOptionalDigitsLeft
,
518 nNoOfExponentDigits
,nNoOfOptionalExponentDigits
,
519 nMultipleThousandSeparators
;
520 bool bPercent
,bCurrency
,bScientific
,bGenerateThousandSeparator
;
522 OUStringBuffer
sReturnStrg(32);
524 // analyse the format-string, i. e. determine the following values:
526 - number of digits before decimal point
527 - number of digits after decimal point
528 - optional digits before decimal point
529 - number of digits in the exponent
530 - optional digits in the exponent
531 - percent-character found?
532 - () for negative leading sign?
533 - exponential-notation?
534 - shall thousand-separators be generated?
535 - is a percent-character being found? --> dNumber *= 100.0;
536 - are there thousand-separators in a row?
537 ,, or ,. --> dNumber /= 1000.0;
538 - other errors? multiple decimal points, E's, etc.
539 --> errors are simply ignored at the moment
541 AnalyseFormatString( sFormatStrg
, nNoOfDigitsLeft
, nNoOfDigitsRight
,
542 nNoOfOptionalDigitsLeft
, nNoOfExponentDigits
,
543 nNoOfOptionalExponentDigits
,
544 bPercent
, bCurrency
, bScientific
,
545 bGenerateThousandSeparator
, nMultipleThousandSeparators
);
546 // special handling for special characters
551 // TODO: this condition (,, or ,.) is NOT Visual-Basic compatible!
552 // Question: shall this stay here (requirements)?
553 if( nMultipleThousandSeparators
)
559 short nState
,nDigitPos
,nExponentPos
,nMaxDigit
,nMaxExponentDigit
;
560 bool bFirstDigit
,bFirstExponentDigit
,bFoundFirstDigit
,
561 bIsNegative
,bZeroSpaceOn
, bSignHappend
,bDigitPosNegative
;
563 bSignHappend
= false;
564 bFoundFirstDigit
= false;
565 bIsNegative
= dNumber
< 0.0;
566 nLen
= sFormatStrg
.getLength();
567 dExponent
= get_number_of_digits( dNumber
);
569 nMaxExponentDigit
= 0;
570 nMaxDigit
= static_cast<short>(dExponent
);
571 bDigitPosNegative
= false;
574 dExponent
= dExponent
- static_cast<double>(nNoOfDigitsLeft
-1);
575 nDigitPos
= nMaxDigit
;
576 nMaxExponentDigit
= static_cast<short>(get_number_of_digits( dExponent
));
577 nExponentPos
= nNoOfExponentDigits
- 1 - nNoOfOptionalExponentDigits
;
581 nDigitPos
= nNoOfDigitsLeft
- 1; // counting starts at 0, 10^0
582 // no exponent-data is needed here!
583 bDigitPosNegative
= (nDigitPos
< 0);
586 bFirstExponentDigit
= true;
587 nState
= 0; // 0 --> mantissa; 1 --> exponent
588 bZeroSpaceOn
= false;
592 // scanning the format-string:
593 sal_Unicode cForce
= 0;
594 for( i
= 0; i
< nLen
; i
++ )
604 c
= sFormatStrg
[ i
];
612 // handling of the mantissa
615 // remark: at bCurrency the negative
616 // leading sign shall be shown with ()
617 if( bIsNegative
&& !bCreateSign
&& !bSignHappend
)
620 sReturnStrg
.append('-');
622 // output redundant positions, i. e. those which
623 // are undocumented by the format-string
624 if( nMaxDigit
> nDigitPos
)
626 for( short j
= nMaxDigit
; j
> nDigitPos
; j
-- )
628 short nTempDigit
= GetDigitAtPosScan( j
, bFoundFirstDigit
);
629 AppendDigit( sReturnStrg
, nTempDigit
);
630 if( nTempDigit
!= NO_DIGIT_
)
634 // coverity[copy_paste_error : FALSE] - this is correct and nDigitPos should not be j
635 if( bGenerateThousandSeparator
&& ( c
=='0' || nMaxDigit
>= nDigitPos
) && j
> 0 && (j
% 3 == 0) )
637 sReturnStrg
.append(cThousandSep
);
643 if( nMaxDigit
<nDigitPos
&& ( c
=='0' || bZeroSpaceOn
) )
645 AppendDigit( sReturnStrg
, 0 );
648 // Remark: in Visual-Basic the first 0 turns on the 0 for
649 // all the following # (up to the decimal point),
650 // this behaviour is simulated here with the flag.
651 if (bGenerateThousandSeparator
&& c
== '0' && nDigitPos
> 0 && (nDigitPos
% 3 == 0))
653 sReturnStrg
.append(cThousandSep
);
658 short nTempDigit
= GetDigitAtPosScan( nDigitPos
, bFoundFirstDigit
) ;
659 AppendDigit( sReturnStrg
, nTempDigit
);
661 if( nTempDigit
!= NO_DIGIT_
)
665 if( bGenerateThousandSeparator
&& ( c
=='0' || nMaxDigit
>=nDigitPos
) && nDigitPos
>0 && (nDigitPos
% 3 == 0) )
667 sReturnStrg
.append(cThousandSep
);
674 // handling the exponent
675 if( bFirstExponentDigit
)
677 // leading sign has been given out at e/E already
678 bFirstExponentDigit
= false;
679 if( nMaxExponentDigit
> nExponentPos
)
680 // output redundant positions, i. e. those which
681 // are undocumented by the format-string
683 for( short j
= nMaxExponentDigit
; j
> nExponentPos
; j
-- )
685 AppendDigit( sReturnStrg
, GetDigitAtPosExpScan( dExponent
, j
, bFoundFirstDigit
) );
690 if( nMaxExponentDigit
< nExponentPos
&& c
=='0' )
692 AppendDigit( sReturnStrg
, 0 );
696 AppendDigit( sReturnStrg
, GetDigitAtPosExpScan( dExponent
, nExponentPos
, bFoundFirstDigit
) );
702 if( bDigitPosNegative
) // #i13821: If no digits before .
704 bDigitPosNegative
= false;
710 sReturnStrg
.append(cDecPoint
);
713 // maybe remove redundant 0s, e. g. 4.500e4 in 0.0##e-00
714 ParseBack( sReturnStrg
, sFormatStrg
, i
-1 );
715 sReturnStrg
.append('%');
719 // does mantissa have to be rounded, before the exponent is displayed?
721 // is there a mantissa at all?
724 // apparently not, i. e. invalid format string, e. g. E000.00
725 // so ignore these e and E characters
726 // maybe output an error (like in Visual Basic)?
728 // #i13821: VB 6 behaviour
729 sReturnStrg
.append(c
);
733 bool bOverflow
= false;
734 short nNextDigit
= GetDigitAtPosScan( nDigitPos
, bFoundFirstDigit
);
737 StrRoundDigit( sReturnStrg
, sReturnStrg
.getLength() - 1, bOverflow
);
741 // a leading 9 has been rounded
742 LeftShiftDecimalPoint( sReturnStrg
);
743 sReturnStrg
[sReturnStrg
.getLength() - 1] = 0;
746 // maybe remove redundant 0s, e. g. 4.500e4 in 0.0##e-00
747 ParseBack( sReturnStrg
, sFormatStrg
, i
-1 );
749 // change the scanner's condition
751 // output exponent character
752 sReturnStrg
.append(c
);
753 // i++; // MANIPULATION of the loop-variable!
754 c
= sFormatStrg
[ ++i
];
755 // output leading sign / exponent
760 if( dExponent
< 0.0 )
762 sReturnStrg
.append('-');
767 if( dExponent
< 0.0 )
769 sReturnStrg
.append('-');
773 sReturnStrg
.append('+');
784 // maybe remove redundant 0s, e. g. 4.500e4 in 0.0##e-00
785 ParseBack( sReturnStrg
, sFormatStrg
, i
-1 );
788 sReturnStrg
.append(c
);
792 // append the string for the currency:
793 sReturnStrg
.append(sCurrencyStrg
);
798 ParseBack( sReturnStrg
, sFormatStrg
, i
-1 );
799 sReturnStrg
.append(c
);
802 ParseBack( sReturnStrg
, sFormatStrg
, i
-1 );
803 // special character found, output next
804 // character directly (if existing)
805 c
= sFormatStrg
[ ++i
];
808 sReturnStrg
.append(c
);
811 case CREATE_1000SEP_CHAR
:
812 // ignore here, action has already been
813 // executed in AnalyseFormatString
816 // output characters and digits, too (like in Visual-Basic)
817 if( ( c
>='a' && c
<='z' ) ||
818 ( c
>='A' && c
<='Z' ) ||
819 ( c
>='1' && c
<='9' ) )
821 sReturnStrg
.append(c
);
826 // scan completed - rounding necessary?
829 short nNextDigit
= GetDigitAtPosScan( nDigitPos
, bFoundFirstDigit
);
832 StrRoundDigit( sReturnStrg
, sReturnStrg
.getLength() - 1 );
836 if( nNoOfDigitsRight
>0 )
838 ParseBack( sReturnStrg
, sFormatStrg
, sFormatStrg
.getLength()-1 );
840 sReturnStrgFinal
= sReturnStrg
.makeStringAndClear();
843 OUString
SbxBasicFormater::BasicFormatNull( const OUString
& sFormatStrg
)
845 bool bNullFormatFound
;
846 OUString sNullFormatStrg
= GetNullFormatString( sFormatStrg
, bNullFormatFound
);
848 if( bNullFormatFound
)
850 return sNullFormatStrg
;
855 OUString
SbxBasicFormater::BasicFormat( double dNumber
, const OUString
& _sFormatStrg
)
857 bool bPosFormatFound
,bNegFormatFound
,b0FormatFound
;
858 OUString sFormatStrg
= _sFormatStrg
;
860 // analyse format-string concerning predefined formats:
861 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_GENERALNUMBER
) )
863 sFormatStrg
= GENERALNUMBER_FORMAT
;
865 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_CURRENCY
) )
867 sFormatStrg
= sCurrencyFormatStrg
;
869 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_FIXED
) )
871 sFormatStrg
= FIXED_FORMAT
;
873 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_STANDARD
) )
875 sFormatStrg
= STANDARD_FORMAT
;
877 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_PERCENT
) )
879 sFormatStrg
= PERCENT_FORMAT
;
881 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_SCIENTIFIC
) )
883 sFormatStrg
= SCIENTIFIC_FORMAT
;
885 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_YESNO
) )
887 return ( dNumber
==0.0 ) ? sNoStrg
: sYesStrg
;
889 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_TRUEFALSE
) )
891 return ( dNumber
==0.0 ) ? sFalseStrg
: sTrueStrg
;
893 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_ONOFF
) )
895 return ( dNumber
==0.0 ) ? sOffStrg
: sOnStrg
;
898 // analyse format-string concerning ';', i. e. format-strings for
899 // positive-, negative- and 0-values
900 OUString sPosFormatStrg
= GetPosFormatString( sFormatStrg
, bPosFormatFound
);
901 OUString sNegFormatStrg
= GetNegFormatString( sFormatStrg
, bNegFormatFound
);
902 OUString s0FormatStrg
= Get0FormatString( sFormatStrg
, b0FormatFound
);
904 OUString sReturnStrg
;
909 sTempStrg
= sFormatStrg
;
912 if( s0FormatStrg
.isEmpty() && bPosFormatFound
)
914 sTempStrg
= sPosFormatStrg
;
918 sTempStrg
= s0FormatStrg
;
921 else if( bPosFormatFound
)
923 sTempStrg
= sPosFormatStrg
;
925 ScanFormatString( dNumber
, sTempStrg
, sReturnStrg
,/*bCreateSign=*/false );
931 if( bNegFormatFound
)
933 if( sNegFormatStrg
.isEmpty() && bPosFormatFound
)
935 sTempStrg
= "-" + sPosFormatStrg
;
939 sTempStrg
= sNegFormatStrg
;
944 sTempStrg
= sFormatStrg
;
946 // if NO format-string especially for negative
947 // values is given, output the leading sign
948 ScanFormatString( dNumber
, sTempStrg
, sReturnStrg
,/*bCreateSign=*/bNegFormatFound
/*sNegFormatStrg!=EMPTYFORMATSTRING*/ );
950 else // if( dNumber>0.0 )
952 ScanFormatString( dNumber
,
953 (/*sPosFormatStrg!=EMPTYFORMATSTRING*/bPosFormatFound
? sPosFormatStrg
: sFormatStrg
),
954 sReturnStrg
,/*bCreateSign=*/false );
960 bool SbxBasicFormater::isBasicFormat( const OUString
& sFormatStrg
)
962 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_GENERALNUMBER
) )
966 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_CURRENCY
) )
970 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_FIXED
) )
974 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_STANDARD
) )
978 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_PERCENT
) )
982 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_SCIENTIFIC
) )
986 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_YESNO
) )
990 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_TRUEFALSE
) )
994 if( sFormatStrg
.equalsIgnoreAsciiCase( BASICFORMAT_ONOFF
) )
1001 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */