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