xref: /AOO41X/main/basic/inc/basic/sbxform.hxx (revision 234bd5c559aaf7abbd02d045859137b774cd8b34)
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 <tools/string.hxx>
83 
84 class SbxBasicFormater {
85   public:
86     // Constructor takes signs for decimal point, thousand separation sign
87     // and necessary resource strings.
88     SbxBasicFormater( sal_Unicode _cDecPoint, sal_Unicode _cThousandSep,
89                       String _sOnStrg,
90                       String _sOffStrg,
91                       String _sYesStrg,
92                       String _sNoStrg,
93                       String _sTrueStrg,
94                       String _sFalseStrg,
95                       String _sCurrencyStrg,
96                       String _sCurrencyFormatStrg );
97 
98     /* Basic command: Format$( number,format-string )
99 
100        Parameter:
101         dNumber     : number to be formated
102         sFormatStrg : the Format-String, e.g. ###0.0###
103 
104        Return value:
105         String containing the formatted output
106     */
107     String  BasicFormat( double dNumber, String sFormatStrg );
108     String  BasicFormatNull( String sFormatStrg );
109 
110     static  sal_Bool isBasicFormat( String sFormatStrg );
111 
112   private:
113     //*** some helper methods ***
114     //void  ShowError( char *sErrMsg );
115     inline void ShiftString( String& sStrg, sal_uInt16 nStartPos );
116     inline void StrAppendChar( String& sStrg, sal_Unicode ch );
117     void    AppendDigit( String& sStrg, short nDigit );
118     void    LeftShiftDecimalPoint( String& sStrg );
119     void    StrRoundDigit( String& sStrg, short nPos, sal_Bool& bOverflow );
120     void    StrRoundDigit( String& sStrg, short nPos );
121     void    ParseBack( String& sStrg, const String& sFormatStrg,
122                 short nFormatPos );
123 #ifdef _with_sprintf
124     // Methods for string conversion with sprintf():
125     void    InitScan( double _dNum );
126     void    InitExp( double _dNewExp );
127     short   GetDigitAtPosScan( short nPos, sal_Bool& bFoundFirstDigit );
128     short   GetDigitAtPosExpScan( double dNewExponent, short nPos,
129                 sal_Bool& bFoundFirstDigit );
130     short   GetDigitAtPosExpScan( short nPos, sal_Bool& bFoundFirstDigit );
131 #else
132     // Methods for direct 'calculation' with log10() and pow():
133     short   GetDigitAtPos( double dNumber, short nPos, double& dNextNumber,
134                 sal_Bool& bFoundFirstDigit );
135     short   RoundDigit( double dNumber );
136 #endif
137     String  GetPosFormatString( const String& sFormatStrg, sal_Bool & bFound );
138     String  GetNegFormatString( const String& sFormatStrg, sal_Bool & bFound );
139     String  Get0FormatString( const String& sFormatStrg, sal_Bool & bFound );
140     String  GetNullFormatString( const String& sFormatStrg, sal_Bool & bFound );
141     short   AnalyseFormatString( const String& sFormatStrg,
142                 short& nNoOfDigitsLeft, short& nNoOfDigitsRight,
143                 short& nNoOfOptionalDigitsLeft,
144                 short& nNoOfExponentDigits,
145                 short& nNoOfOptionalExponentDigits,
146                 sal_Bool& bPercent, sal_Bool& bCurrency, sal_Bool& bScientific,
147                 sal_Bool& bGenerateThousandSeparator,
148                 short& nMultipleThousandSeparators );
149     void    ScanFormatString( double dNumber, const String& sFormatStrg,
150                 String& sReturnStrg, sal_Bool bCreateSign );
151 
152     //*** Data ***
153     sal_Unicode cDecPoint;      // sign for the decimal point
154     sal_Unicode cThousandSep;   // sign for thousand delimiter
155     // Text for output:
156     String  sOnStrg;
157     String  sOffStrg;
158     String  sYesStrg;
159     String  sNoStrg;
160     String  sTrueStrg;
161     String  sFalseStrg;
162     String  sCurrencyStrg;
163     String  sCurrencyFormatStrg;
164 
165     //*** temporary data for scan loop ***
166     //-----------------------------------------------
167     // String containing the number in scientific format
168     String  sSciNumStrg;
169     // String containing the exponent of the number
170     String  sNumExpStrg;
171     double  dNum;           // the number that is scanned
172     short   nNumExp;        // the exponent of the number
173     short   nExpExp;        // the number of digits in the exponent
174 };
175 
176 #endif
177 
178