xref: /AOO42X/main/basic/inc/basic/sbxform.hxx (revision 9bce9b0d387299c68bd81d539e1478357a103de5)
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 #ifndef _SBXFORM_HXX
25 #define _SBXFORM_HXX
26 
27 //====================================================================
28 // Implementation class for Basic command: Format$( d,formatStr )
29 //====================================================================
30 /*
31   Grammar of format string (a try):
32   -----------------------------------------------
33 
34   format_string     := {\special_char} general_format | scientific_format {\special_char} {;format_string}
35   general_format    := {#[,]}{0[,]}[.{0}{#}]
36   scientific_format := {0}[.{0}{#}](e | E)(+ | -){#}{0}
37 
38   percent_char      := '%'
39   special_char      := \char | + | - | ( | ) | $ | space_char
40   char              := all_ascii_chars
41   space_char        := ' '
42 
43   {}    repeated multiple times (incl. zero times)
44   []    exactly one or zero times
45   ()    parenthesis, e.g. (e | E) means e or E times
46 
47   Additional predefined formats for the format string:
48     "General Number"
49     "Currency"
50     "Fixed"
51     "Standard"
52     "Percent"
53     "Scientific"
54     "Yes/No"
55     "True/False"
56     "On/Off"
57 
58  Note: invalid format string are ignored just as in VisualBasic, the output is
59        probably 'undefined'. ASCII letters are outputted directly.
60 
61  Constraints in VisualBasic:
62     - the exponent (scientific syntax) has a maximum of three digits!
63 
64  Constraints of new implementation:
65     - the '+' sign is not allowed as wildcard in the mantissa
66 
67  TODO:
68     - Date formatting
69         Wildcards are: 'h', 'm', 's', 'y'
70         predefined String-Constants/Commands:
71             "AMPM", "Long Date", "Long Time"
72 */
73 
74 /*
75   There are two possibilities to get the number of digits of a number:
76 
77         a) use sprintf()
78         b) use log10() and pow() digit
79 */
80 #define _with_sprintf   // use a)
81 
82 #include "basic/basicdllapi.h"
83 #include <tools/string.hxx>
84 
85 class BASIC_DLLPUBLIC SbxBasicFormater {
86   public:
87     // Constructor takes signs for decimal point, thousand separation sign
88     // and necessary resource strings.
89     SbxBasicFormater( sal_Unicode _cDecPoint, sal_Unicode _cThousandSep,
90                       String _sOnStrg,
91                       String _sOffStrg,
92                       String _sYesStrg,
93                       String _sNoStrg,
94                       String _sTrueStrg,
95                       String _sFalseStrg,
96                       String _sCurrencyStrg,
97                       String _sCurrencyFormatStrg );
98 
99     /* Basic command: Format$( number,format-string )
100 
101        Parameter:
102         dNumber     : number to be formatted
103         sFormatStrg : the Format-String, e.g. ###0.0###
104 
105        Return value:
106         String containing the formatted output
107     */
108     String  BasicFormat( double dNumber, String sFormatStrg );
109     String  BasicFormatNull( String sFormatStrg );
110 
111     static  sal_Bool isBasicFormat( String sFormatStrg );
112 
113   private:
114     //*** some helper methods ***
115     //void  ShowError( char *sErrMsg );
116     inline void ShiftString( String& sStrg, sal_uInt16 nStartPos );
117     inline void StrAppendChar( String& sStrg, sal_Unicode ch );
118     void    AppendDigit( String& sStrg, short nDigit );
119     void    LeftShiftDecimalPoint( String& sStrg );
120     void    StrRoundDigit( String& sStrg, short nPos, sal_Bool& bOverflow );
121     void    StrRoundDigit( String& sStrg, short nPos );
122     void    ParseBack( String& sStrg, const String& sFormatStrg,
123                 short nFormatPos );
124 #ifdef _with_sprintf
125     // Methods for string conversion with sprintf():
126     void    InitScan( double _dNum );
127     void    InitExp( double _dNewExp );
128     short   GetDigitAtPosScan( short nPos, sal_Bool& bFoundFirstDigit );
129     short   GetDigitAtPosExpScan( double dNewExponent, short nPos,
130                 sal_Bool& bFoundFirstDigit );
131     short   GetDigitAtPosExpScan( short nPos, sal_Bool& bFoundFirstDigit );
132 #else
133     // Methods for direct 'calculation' with log10() and pow():
134     short   GetDigitAtPos( double dNumber, short nPos, double& dNextNumber,
135                 sal_Bool& bFoundFirstDigit );
136     short   RoundDigit( double dNumber );
137 #endif
138     String  GetPosFormatString( const String& sFormatStrg, sal_Bool & bFound );
139     String  GetNegFormatString( const String& sFormatStrg, sal_Bool & bFound );
140     String  Get0FormatString( const String& sFormatStrg, sal_Bool & bFound );
141     String  GetNullFormatString( const String& sFormatStrg, sal_Bool & bFound );
142     short   AnalyseFormatString( const String& sFormatStrg,
143                 short& nNoOfDigitsLeft, short& nNoOfDigitsRight,
144                 short& nNoOfOptionalDigitsLeft,
145                 short& nNoOfExponentDigits,
146                 short& nNoOfOptionalExponentDigits,
147                 sal_Bool& bPercent, sal_Bool& bCurrency, sal_Bool& bScientific,
148                 sal_Bool& bGenerateThousandSeparator,
149                 short& nMultipleThousandSeparators );
150     void    ScanFormatString( double dNumber, const String& sFormatStrg,
151                 String& sReturnStrg, sal_Bool bCreateSign );
152 
153     //*** Data ***
154     sal_Unicode cDecPoint;      // sign for the decimal point
155     sal_Unicode cThousandSep;   // sign for thousand delimiter
156     // Text for output:
157     String  sOnStrg;
158     String  sOffStrg;
159     String  sYesStrg;
160     String  sNoStrg;
161     String  sTrueStrg;
162     String  sFalseStrg;
163     String  sCurrencyStrg;
164     String  sCurrencyFormatStrg;
165 
166     //*** temporary data for scan loop ***
167     //-----------------------------------------------
168     // String containing the number in scientific format
169     String  sSciNumStrg;
170     // String containing the exponent of the number
171     String  sNumExpStrg;
172     double  dNum;           // the number that is scanned
173     short   nNumExp;        // the exponent of the number
174     short   nExpExp;        // the number of digits in the exponent
175 };
176 
177 #endif
178