1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 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/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 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 . 18 */ 19 20 #pragma once 21 22 23 // Implementation class for Basic command: Format$( d,formatStr ) 24 25 /* 26 Grammar of format string (a try): 27 ----------------------------------------------- 28 29 format_string := {\special_char} general_format | scientific_format {\special_char} {;format_string} 30 general_format := {#[,]}{0[,]}[.{0}{#}] 31 scientific_format := {0}[.{0}{#}](e | E)(+ | -){#}{0} 32 33 percent_char := '%' 34 special_char := \char | + | - | ( | ) | $ | space_char 35 char := all_ascii_chars 36 space_char := ' ' 37 38 {} repeated multiple times (incl. zero times) 39 [] exactly one or zero times 40 () parenthesis, e.g. (e | E) means e or E times 41 42 Additional predefined formats for the format string: 43 "General Number" 44 "Currency" 45 "Fixed" 46 "Standard" 47 "Percent" 48 "Scientific" 49 "Yes/No" 50 "True/False" 51 "On/Off" 52 53 Note: invalid format string are ignored just as in VisualBasic, the output is 54 probably 'undefined'. ASCII letters are outputted directly. 55 56 Constraints in VisualBasic: 57 - the exponent (scientific syntax) has a maximum of three digits! 58 59 Constraints of new implementation: 60 - the '+' sign is not allowed as wildcard in the mantissa 61 62 TODO: 63 - Date formatting 64 Wildcards are: 'h', 'm', 's', 'y' 65 predefined String-Constants/Commands: 66 "AMPM", "Long Date", "Long Time" 67 */ 68 69 #include <rtl/ustring.hxx> 70 #include <rtl/ustrbuf.hxx> 71 72 class SbxBasicFormater { 73 public: 74 // Constructor takes signs for decimal point, thousand separation sign 75 // and necessary resource strings. 76 SbxBasicFormater( sal_Unicode _cDecPoint, sal_Unicode _cThousandSep, 77 const OUString& _sOnStrg, 78 const OUString& _sOffStrg, 79 const OUString& _sYesStrg, 80 const OUString& _sNoStrg, 81 const OUString& _sTrueStrg, 82 const OUString& _sFalseStrg, 83 const OUString& _sCurrencyStrg, 84 const OUString& _sCurrencyFormatStrg ); 85 86 /* Basic command: Format$( number,format-string ) 87 88 Parameter: 89 dNumber : number to be formatted 90 sFormatStrg : the Format-String, e.g. ###0.0### 91 92 Return value: 93 String containing the formatted output 94 */ 95 OUString BasicFormat( double dNumber, const OUString& sFormatStrg ); 96 static OUString BasicFormatNull( const OUString& sFormatStrg ); 97 98 static bool isBasicFormat( const OUString& sFormatStrg ); 99 100 private: 101 static inline void ShiftString( OUStringBuffer& sStrg, sal_uInt16 nStartPos ); 102 static void AppendDigit( OUStringBuffer& sStrg, short nDigit ); 103 void LeftShiftDecimalPoint( OUStringBuffer& sStrg ); 104 void StrRoundDigit( OUStringBuffer& sStrg, short nPos, bool& bOverflow ); 105 void StrRoundDigit( OUStringBuffer& sStrg, short nPos ); 106 static void ParseBack( OUStringBuffer& sStrg, std::u16string_view sFormatStrg, 107 short nFormatPos ); 108 // Methods for string conversion with sprintf(): 109 void InitScan( double _dNum ); 110 void InitExp( double _dNewExp ); 111 short GetDigitAtPosScan( short nPos, bool& bFoundFirstDigit ); 112 short GetDigitAtPosExpScan( double dNewExponent, short nPos, 113 bool& bFoundFirstDigit ); 114 short GetDigitAtPosExpScan( short nPos, bool& bFoundFirstDigit ); 115 static OUString GetPosFormatString( const OUString& sFormatStrg, bool & bFound ); 116 static OUString GetNegFormatString( const OUString& sFormatStrg, bool & bFound ); 117 static OUString Get0FormatString( const OUString& sFormatStrg, bool & bFound ); 118 static OUString GetNullFormatString( const OUString& sFormatStrg, bool & bFound ); 119 static void AnalyseFormatString( const OUString& sFormatStrg, 120 short& nNoOfDigitsLeft, short& nNoOfDigitsRight, 121 short& nNoOfOptionalDigitsLeft, 122 short& nNoOfExponentDigits, 123 short& nNoOfOptionalExponentDigits, 124 bool& bPercent, bool& bCurrency, bool& bScientific, 125 bool& bGenerateThousandSeparator, 126 short& nMultipleThousandSeparators ); 127 void ScanFormatString( double dNumber, const OUString& sFormatStrg, 128 OUString& sReturnStrg, bool bCreateSign ); 129 130 //*** Data *** 131 sal_Unicode cDecPoint; // sign for the decimal point 132 sal_Unicode cThousandSep; // sign for thousand delimiter 133 // Text for output: 134 OUString sOnStrg; 135 OUString sOffStrg; 136 OUString sYesStrg; 137 OUString sNoStrg; 138 OUString sTrueStrg; 139 OUString sFalseStrg; 140 OUString sCurrencyStrg; 141 OUString sCurrencyFormatStrg; 142 143 //*** temporary data for scan loop *** 144 145 // String containing the number in scientific format 146 OUString sSciNumStrg; 147 // String containing the exponent of the number 148 OUString sNumExpStrg; 149 double dNum; // the number that is scanned 150 short nNumExp; // the exponent of the number 151 short nExpExp; // the number of digits in the exponent 152 }; 153 154 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 155