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 179