| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_basic.hxx" |
| |
| #include <stdlib.h> |
| |
| #include <basic/sbxform.hxx> |
| |
| /* |
| TODO: gibt es noch irgend welche Star-Basic Besonderheiten ? |
| |
| was bedeutet: * als Platzhalter |
| |
| BEMERKUNG: Visual-Basic behandelt folgende (ung"ultige) Format-Strings |
| wie angezeigt: |
| |
| ##0##.##0## --> ##000.000## |
| |
| (diese Klasse verh"alt sich genau so). |
| */ |
| |
| #include <stdio.h> // f"ur: sprintf() |
| #include <float.h> // f"ur: DBL_DIG, DBL_EPSILON |
| #include <math.h> // f"ur: floor(), fabs(), log10(), pow() |
| |
| //================================================================= |
| //=========================== DEFINES ============================= |
| //================================================================= |
| |
| #define _NO_DIGIT -1 |
| |
| #define MAX_NO_OF_EXP_DIGITS 5 |
| // +4 wegen dem Wertebereich: zwischen -308 und +308 |
| // +1 f"ur abschliessende 0 |
| #define MAX_NO_OF_DIGITS DBL_DIG |
| #define MAX_DOUBLE_BUFFER_LENGTH MAX_NO_OF_DIGITS + 9 |
| // +1 f"ur Vorzeichen |
| // +1 f"ur Ziffer vor dem Dezimal-Punkt |
| // +1 f"ur Dezimal-Punkt |
| // +2 f"ur Exponent E und Exp. Vorzeichen |
| // +3 f"ur den Wert des Exponenten |
| // +1 f"ur abschliessende 0 |
| |
| // Defines f"ur die Ziffern: |
| #define ASCII_0 '0' // 48 |
| #define ASCII_9 '9' // 57 |
| |
| #define CREATE_1000SEP_CHAR '@' |
| |
| #define FORMAT_SEPARATOR ';' |
| |
| // vordefinierte Formate f"ur den Format$()-Befehl: |
| #define BASICFORMAT_GENERALNUMBER "General Number" |
| #define BASICFORMAT_CURRENCY "Currency" |
| #define BASICFORMAT_FIXED "Fixed" |
| #define BASICFORMAT_STANDARD "Standard" |
| #define BASICFORMAT_PERCENT "Percent" |
| #define BASICFORMAT_SCIENTIFIC "Scientific" |
| #define BASICFORMAT_YESNO "Yes/No" |
| #define BASICFORMAT_TRUEFALSE "True/False" |
| #define BASICFORMAT_ONOFF "On/Off" |
| |
| #define EMPTYFORMATSTRING "" |
| |
| // Bem.: Visual-Basic hat bei Floating-Point-Zahlen maximal 12 Stellen |
| // nach dem Dezimal-Punkt. |
| // Alle Format-Strings sind kompatibel zu Visual-Basic: |
| #define GENERALNUMBER_FORMAT "0.############" |
| // max. 12 Stellen in Visual-Basic ! |
| #define CURRENCY_FORMAT "@$0.00;@($0.00)" |
| #define FIXED_FORMAT "0.00" |
| #define STANDARD_FORMAT "@0.00" |
| #define PERCENT_FORMAT "0.00%" |
| #define SCIENTIFIC_FORMAT "#.00E+00" |
| // BEMERKUNG: das Zeichen @ bedeutet, das Tausender-Separatoren erzeugt |
| // weden sollen. Dies ist eine StarBasic 'Erweiterung'. |
| |
| //================================================================= |
| |
| // zur Bestimmung der Anzahl Stellen in dNumber |
| double get_number_of_digits( double dNumber ) |
| //double floor_log10_fabs( double dNumber ) |
| { |
| if( dNumber==0.0 ) |
| // 0 hat zumindest auch eine Stelle ! |
| return 0.0; //ehemals 1.0, jetzt 0.0 wegen #40025; |
| else |
| return floor( log10( fabs( dNumber ) ) ); |
| } |
| |
| //================================================================= |
| //======================= IMPLEMENTATION ========================== |
| //================================================================= |
| |
| SbxBasicFormater::SbxBasicFormater( sal_Unicode _cDecPoint, sal_Unicode _cThousandSep, |
| String _sOnStrg, |
| String _sOffStrg, |
| String _sYesStrg, |
| String _sNoStrg, |
| String _sTrueStrg, |
| String _sFalseStrg, |
| String _sCurrencyStrg, |
| String _sCurrencyFormatStrg ) |
| { |
| cDecPoint = _cDecPoint; |
| cThousandSep = _cThousandSep; |
| sOnStrg = _sOnStrg; |
| sOffStrg = _sOffStrg; |
| sYesStrg = _sYesStrg; |
| sNoStrg = _sNoStrg; |
| sTrueStrg = _sTrueStrg; |
| sFalseStrg = _sFalseStrg; |
| sCurrencyStrg = _sCurrencyStrg; |
| sCurrencyFormatStrg = _sCurrencyFormatStrg; |
| } |
| |
| // Funktion zur Ausgabe eines Fehler-Textes (zum Debuggen) |
| /* |
| void SbxBasicFormater::ShowError( char * sErrMsg ) |
| { |
| // cout << "ERROR in Format$(): " << sErrMsg << endl; |
| } |
| */ |
| // verschiebt alle Zeichen des Strings, angefangen von der nStartPos, |
| // um eine Position zu gr"osseren Indizes, d.h. es wird Platz f"ur |
| // ein neues (einzuf"ugendes) Zeichen geschafft. |
| // ACHTUNG: der String MUSS gross genug sein ! |
| inline void SbxBasicFormater::ShiftString( String& sStrg, sal_uInt16 nStartPos ) |
| { |
| sStrg.Erase( nStartPos,1 ); |
| } |
| |
| // Funktion um ein Zeichen an einen String anzuh"angen |
| inline void SbxBasicFormater::StrAppendChar( String& sStrg, sal_Unicode ch ) |
| { |
| sStrg.Insert( ch ); |
| } |
| |
| // h"angt die "ubergebene Ziffer nDigit an den "ubergebenen String sStrg |
| // an, dabei wird "uberpr"uft ob nDigit eine g"ultige Ziffer ist, |
| // falls dies nicht der Fall ist, wird nichts gemacht. |
| void SbxBasicFormater::AppendDigit( String& sStrg, short nDigit ) |
| { |
| if( nDigit>=0 && nDigit<=9 ) |
| StrAppendChar( sStrg, (sal_Unicode)(nDigit+ASCII_0) ); |
| } |
| |
| // verschiebt den Dezimal-Punkt um eine Stelle nach links |
| void SbxBasicFormater::LeftShiftDecimalPoint( String& sStrg ) |
| { |
| sal_uInt16 nPos = sStrg.Search( cDecPoint ); |
| |
| if( nPos!=STRING_NOTFOUND ) |
| { |
| // vertausche Dezimal-Punkt |
| sStrg.SetChar( nPos, sStrg.GetChar( nPos - 1 ) ); |
| sStrg.SetChar( nPos-1, cDecPoint ); |
| } |
| } |
| |
| // rundet in einem String die Ziffer an der angegebenen Stelle, |
| // es wird ein Flag zur"uckgeliefert, falls ein Overflow auftrat, |
| // d.h. 99.99 --> 100.00, d.h. ein Gr"ossenordung ge"andert wurde |
| // (geschieht beim Runden einer 9). |
| void SbxBasicFormater::StrRoundDigit( String& sStrg, short nPos, sal_Bool& bOverflow ) |
| { |
| // wurde ggf ein falscher Index uebergeben --> Aufruf ignorieren |
| if( nPos<0 ) |
| return; |
| |
| bOverflow = sal_False; |
| // "uberspringe den Dezimalpunkt und Tausender-Trennzeichen |
| sal_Unicode c = sStrg.GetChar( nPos ); |
| if( nPos>0 && (c == cDecPoint || c == cThousandSep) ) |
| { |
| StrRoundDigit( sStrg,nPos-1,bOverflow ); |
| // AENDERUNG ab 9.3.1997: nach rekursivem Call die Methode SOFORT beenden ! |
| return; |
| } |
| // "uberspringe alle nicht-Ziffern: |
| // BEMERKUNG: |
| // in einem g"ultigen Format-String sollte die Ausgabe |
| // der Zahl an einem St"uck geschen, d.h. Sonderzeichen sollten |
| // NUR vor ODER nach der Zahl stehen und nicht mitten in der |
| // Format-Angabe f"ur die Zahl |
| while( nPos>=0 && (sStrg.GetChar( nPos )<ASCII_0 || sStrg.GetChar( nPos )>ASCII_9) ) |
| nPos--; |
| // muss ggf. noch Platz f"ur eine weitere (f"uhrende) Ziffer |
| // geschaffen werden ? |
| if( nPos==-1 ) |
| { |
| ShiftString( sStrg,0 ); |
| // f"uhrende 1 einf"ugen: z.B. 99.99 f"ur 0.0 |
| sStrg.SetChar( 0, '1' ); |
| bOverflow = sal_True; |
| } |
| else |
| { |
| // ist die zu rundende Position eine Ziffer ? |
| sal_Unicode c2 = sStrg.GetChar( nPos ); |
| if( c2 >= ASCII_0 && c2 <= ASCII_9 ) |
| { |
| // muss eine 9 gerundet werden? Falls: Ja --> rekursiver Aufruf |
| if( c2 == ASCII_9 ) |
| { |
| sStrg.SetChar( nPos, '0' ); |
| StrRoundDigit( sStrg,nPos-1,bOverflow ); |
| } |
| else |
| sStrg.SetChar( nPos, c2+1 ); |
| } |
| else |
| { |
| // --> Nein, d.h. Platz f"ur Ziffer schaffen: z.B. -99.99 f"ur #0.0 |
| // da gerundet wird MUSS es immer eine g"ultige Position |
| // nPos+1 geben ! |
| ShiftString( sStrg,nPos+1 ); |
| // f"uhrende 1 einf"ugen |
| sStrg.SetChar( nPos+1, '1' ); |
| bOverflow = sal_True; |
| } |
| } |
| } |
| |
| // rundet in einem String die Ziffer an der angegebenen Stelle |
| void SbxBasicFormater::StrRoundDigit( String& sStrg, short nPos ) |
| { |
| sal_Bool bOverflow; |
| |
| StrRoundDigit( sStrg,nPos,bOverflow ); |
| } |
| |
| // parse den Formatstring von der "ubergebenen Position zur"uck |
| // und l"osche ggf. "uberf"ussige 0en, z.B. 4.50 in 0.0# |
| void SbxBasicFormater::ParseBack( String& sStrg, const String& sFormatStrg, |
| short nFormatPos ) |
| { |
| // WICHTIG: nFormatPos kann auch negativ sein, in diesem Fall Aufruf ignorieren |
| for( short i=nFormatPos; |
| i>0 && sFormatStrg.GetChar( i ) == '#' && sStrg.GetChar( (sStrg.Len()-1) ) == '0'; |
| i-- ) |
| { sStrg.Erase( sStrg.Len()-1 ); } |
| } |
| |
| #ifdef _with_sprintf |
| |
| /* |
| Bemerkung: |
| Zahl wird mit maximaler (sinnvollen) Genauigkeit in einen String |
| umgewandelt (mit sprintf()), dieser String wird dann im Schleifen- |
| Durchlauf nach der entsprechenden Ziffer durchsucht. |
| */ |
| // initialisiert die Daten der Klasse um einen Scan-Durchlauf durchzuf"uhren |
| void SbxBasicFormater::InitScan( double _dNum ) |
| { |
| char sBuffer[ MAX_DOUBLE_BUFFER_LENGTH ]; |
| |
| dNum = _dNum; |
| InitExp( get_number_of_digits( dNum ) ); |
| // maximal 15 Nachkomma-Stellen, Format-Beispiel: -1.234000000000000E-001 |
| /*int nCount =*/ sprintf( sBuffer,"%+22.15lE",dNum ); |
| sSciNumStrg.AssignAscii( sBuffer ); |
| } |
| |
| void SbxBasicFormater::InitExp( double _dNewExp ) |
| { |
| char sBuffer[ MAX_DOUBLE_BUFFER_LENGTH ]; |
| // bestimme den Exponenten (kann immer GENAU durch int dargestellt werden) |
| nNumExp = (short)_dNewExp; |
| // und dessen String |
| /*int nCount =*/ sprintf( sBuffer,"%+i",nNumExp ); |
| sNumExpStrg.AssignAscii( sBuffer ); |
| // bestimme die Anzahl der Stellen im Exponenten |
| nExpExp = (short)get_number_of_digits( (double)nNumExp ); |
| } |
| |
| // bestimmt die Ziffer an der angegebenen Stelle (gedacht zur Anwendung im |
| // Scan-Durchlauf) |
| short SbxBasicFormater::GetDigitAtPosScan( short nPos, sal_Bool& bFoundFirstDigit ) |
| { |
| // Versuch eine gr"ossere Ziffer zu lesen, |
| // z.B. Stelle 4 in 1.234, |
| // oder eine Ziffer ausserhalb der Aufl"osung der |
| // Zahl (double) zu lesen (z.B. max. 15 Stellen). |
| if( nPos>nNumExp || abs(nNumExp-nPos)>MAX_NO_OF_DIGITS ) |
| return _NO_DIGIT; |
| // bestimme den Index der Stelle in dem Number-String: |
| // "uberlese das Vorzeichen |
| sal_uInt16 no = 1; |
| // falls notwendig den Dezimal-Punkt "uberlesen: |
| if( nPos<nNumExp ) |
| no++; |
| no += nNumExp-nPos; |
| // Abfrage der ersten (g"ultigen) Ziffer der Zahl --> Flag setzen |
| if( nPos==nNumExp ) |
| bFoundFirstDigit = sal_True; |
| return (short)(sSciNumStrg.GetChar( no ) - ASCII_0); |
| } |
| |
| short SbxBasicFormater::GetDigitAtPosExpScan( short nPos, sal_Bool& bFoundFirstDigit ) |
| { |
| // ist die abgefragte Stelle zu gross f"ur den Exponenten ? |
| if( nPos>nExpExp ) |
| return -1; |
| |
| // bestimme den Index der Stelle in dem Number-String: |
| // "uberlese das Vorzeichen |
| sal_uInt16 no = 1; |
| no += nExpExp-nPos; |
| // Abfrage der ersten (g"ultigen) Ziffer der Zahl --> Flag setzen |
| if( nPos==nExpExp ) |
| bFoundFirstDigit = sal_True; |
| return (short)(sNumExpStrg.GetChar( no ) - ASCII_0); |
| } |
| |
| // es kann ein Wert f"ur den Exponent angegeben werden, da ggf. die |
| // Zahl ggf. NICHT normiert (z.B. 1.2345e-03) dargestellt werden soll, |
| // sondern eventuell 123.345e-3 ! |
| short SbxBasicFormater::GetDigitAtPosExpScan( double dNewExponent, short nPos, |
| sal_Bool& bFoundFirstDigit ) |
| { |
| // neuer Exponent wurde "ubergeben, aktualisiere |
| // die tempor"aren Klassen-Variablen |
| InitExp( dNewExponent ); |
| // und jetzt die Stelle bestimmen |
| return GetDigitAtPosExpScan( nPos,bFoundFirstDigit ); |
| } |
| |
| #else |
| |
| /* Probleme mit der folgenden Methode: |
| |
| TODO: ggf einen 'intelligenten' Peek-Parser um Rundungsfehler bei |
| double-Zahlen herauszufinden ? z.B. f"ur 0.00115 #.#e-000 |
| |
| Problem mit: format( 0.3345 , "0.000" ) |
| Problem mit: format( 0.00115 , "0.0000" ) |
| |
| */ |
| // liefert die Ziffer an der angegebenen '10er System'-Position, |
| // d.h. positive nPos f"ur Stellen vor dem Komma und negative |
| // f"ur Stellen nach dem Komma. |
| // nPos==0 bedeutet erste Stelle vor dem Komma, also 10^0. |
| // liefert 0..9 f"ur g"ultige Ziffern und -1 f"ur nicht vorhanden, |
| // d.h. falls die "ubergebene Zahl zu klein ist |
| // (z.B. Stelle 5 bei dNumber=123). |
| // Weiter wird in dNextNumber die um die f"uhrenden Stellen |
| // (bis nPos) gek"urzte Zahl zur"uckgeliefert, z.B. |
| // GetDigitAtPos( 3434.565 , 2 , dNewNumber ) --> dNewNumber = 434.565 |
| // dies kann f"ur Schleifenabarbeitung g"unstiger sein, d.h. |
| // die Zahlen immer von der gr"ossten Stelle abarbeiten/scanen. |
| // In bFoundFirstDigit wird ggf. ein Flag gesetzt wenn eine Ziffer |
| // gefunden wurde, dies wird dazu verwendet um 'Fehler' beim Parsen 202 |
| // zu vermeiden, die |
| // |
| // ACHTUNG: anscheinend gibt es manchmal noch Probleme mit Rundungs-Fehlern! |
| short SbxBasicFormater::GetDigitAtPos( double dNumber, short nPos, |
| double& dNextNumber, sal_Bool& bFoundFirstDigit ) |
| // ACHTUNG: nPos kann auch negativ werden, f"ur Stellen nach dem Dezimal-Punkt |
| { |
| double dTemp = dNumber; |
| double dDigit,dPos; |
| short nMaxDigit; |
| |
| // erst mal aus der Zahl eine positive Zahl machen: |
| dNumber = fabs( dNumber ); |
| dPos = (double)nPos; |
| |
| // "uberpr"ufe ob Zahl zu klein f"ur angegebene Stelle ist |
| nMaxDigit = (short)get_number_of_digits( dNumber ); |
| // f"uhrende Ziffern 'l"oschen' |
| // Bem.: Fehler nur bei Zahlen gr"osser 0, d.h. bei Ziffern vor dem |
| // Dezimal-Punkt |
| if( nMaxDigit<nPos && !bFoundFirstDigit && nPos>=0 ) |
| return _NO_DIGIT; |
| // Ziffer gefunden, setze Flag: |
| bFoundFirstDigit = sal_True; |
| for( short i=nMaxDigit; i>=nPos; i-- ) |
| { |
| double dI = (double)i; |
| double dTemp1 = pow( 10.0,dI ); |
| // pr"apariere nun die gesuchte Ziffer: |
| dDigit = floor( pow( 10.0,log10( fabs( dNumber ) )-dI ) ); |
| dNumber -= dTemp1 * dDigit; |
| } |
| // Zuweisung f"ur optimierte Schleifen-Durchl"aufe |
| dNextNumber = dNumber; |
| // und zum Schluss noch die float-Rundungsungenauigkeiten heraus filtern |
| return RoundDigit( dDigit ); |
| } |
| |
| // rundet eine double-Zahl zwischen 0 und 9 auf die genaue |
| // Integer-Zahl, z.B. 2.8 -> 3 und 2.2 -> 2 |
| short SbxBasicFormater::RoundDigit( double dNumber ) |
| { |
| // ist der Wertebereich g"ultig ? |
| if( dNumber<0.0 || dNumber>10.0 ) |
| return -1; |
| short nTempHigh = (short)(dNumber+0.5); // ggf. floor( ) |
| return nTempHigh; |
| } |
| |
| #endif |
| |
| // kopiert den entsprechenden Teil des Format-Strings, falls vorhanden, |
| // und liefert diesen zur"uck. |
| // Somit wird ein neuer String erzeugt, der vom Aufrufer wieder freigegeben |
| // werden muss |
| String SbxBasicFormater::GetPosFormatString( const String& sFormatStrg, sal_Bool & bFound ) |
| { |
| bFound = sal_False; // default... |
| sal_uInt16 nPos = sFormatStrg.Search( FORMAT_SEPARATOR ); |
| |
| if( nPos!=STRING_NOTFOUND ) |
| { |
| bFound = sal_True; |
| // der Format-String f"ur die positiven Zahlen ist alles |
| // vor dem ersten ';' |
| return sFormatStrg.Copy( 0,nPos ); |
| } |
| // kein ; gefunden, liefere Leerstring |
| String aRetStr; |
| aRetStr.AssignAscii( EMPTYFORMATSTRING ); |
| return aRetStr; |
| } |
| |
| // siehe auch GetPosFormatString() |
| String SbxBasicFormater::GetNegFormatString( const String& sFormatStrg, sal_Bool & bFound ) |
| { |
| bFound = sal_False; // default... |
| sal_uInt16 nPos = sFormatStrg.Search( FORMAT_SEPARATOR ); |
| |
| if( nPos!=STRING_NOTFOUND ) |
| { |
| // der Format-String f"ur die negative Zahlen ist alles |
| // zwischen dem ersten und dem zweiten ';'. |
| // Daher: hole erst mal alles nach dem ersten ';' |
| String sTempStrg = sFormatStrg.Copy( nPos+1 ); |
| // und suche darin ggf. ein weiteres ';' |
| nPos = sTempStrg.Search( FORMAT_SEPARATOR ); |
| bFound = sal_True; |
| if( nPos==STRING_NOTFOUND ) |
| // keins gefunden, liefere alles... |
| return sTempStrg; |
| else |
| // ansonsten den String zwischen den beiden ';' liefern |
| return sTempStrg.Copy( 0,nPos ); |
| } |
| String aRetStr; |
| aRetStr.AssignAscii( EMPTYFORMATSTRING ); |
| return aRetStr; |
| } |
| |
| // siehe auch GetPosFormatString() |
| String SbxBasicFormater::Get0FormatString( const String& sFormatStrg, sal_Bool & bFound ) |
| { |
| bFound = sal_False; // default... |
| sal_uInt16 nPos = sFormatStrg.Search( FORMAT_SEPARATOR ); |
| |
| if( nPos!=STRING_NOTFOUND ) |
| { |
| // der Format-String f"ur die Null ist alles |
| // was nach dem zweiten ';' kommt. |
| // Daher: hole erst mal alles nach dem ersten ';' |
| String sTempStrg = sFormatStrg.Copy( nPos+1 ); |
| // und suche darin ggf. ein weiteres ';' |
| nPos = sTempStrg.Search( FORMAT_SEPARATOR ); |
| if( nPos!=STRING_NOTFOUND ) |
| { |
| bFound = sal_True; |
| sTempStrg = sTempStrg.Copy( nPos+1 ); |
| nPos = sTempStrg.Search( FORMAT_SEPARATOR ); |
| if( nPos==STRING_NOTFOUND ) |
| // keins gefunden, liefere alles... |
| return sTempStrg; |
| else |
| return sTempStrg.Copy( 0,nPos ); |
| } |
| } |
| // kein ; gefunden, liefere Leerstring |
| String aRetStr; |
| aRetStr.AssignAscii( EMPTYFORMATSTRING ); |
| return aRetStr; |
| } |
| |
| // siehe auch GetPosFormatString() |
| String SbxBasicFormater::GetNullFormatString( const String& sFormatStrg, sal_Bool & bFound ) |
| { |
| bFound = sal_False; // default... |
| sal_uInt16 nPos = sFormatStrg.Search( FORMAT_SEPARATOR ); |
| |
| if( nPos!=STRING_NOTFOUND ) |
| { |
| // der Format-String f"ur die Null ist alles |
| // was nach dem dritten ';' kommt. |
| // Daher: hole erst mal alles nach dem ersten ';' |
| String sTempStrg = sFormatStrg.Copy( nPos+1 ); |
| // und suche darin ggf. ein weiteres ';' |
| nPos = sTempStrg.Search( FORMAT_SEPARATOR ); |
| if( nPos!=STRING_NOTFOUND ) |
| { |
| // und suche nun nach dem dritten ';' |
| sTempStrg = sTempStrg.Copy( nPos+1 ); |
| nPos = sTempStrg.Search( FORMAT_SEPARATOR ); |
| if( nPos!=STRING_NOTFOUND ) |
| { |
| bFound = sal_True; |
| return sTempStrg.Copy( nPos+1 ); |
| } |
| } |
| } |
| // kein ; gefunden, liefere Leerstring |
| String aRetStr; |
| aRetStr.AssignAscii( EMPTYFORMATSTRING ); |
| return aRetStr; |
| } |
| |
| // analysiert den Format-String, liefert Wert <> 0 falls ein Fehler |
| // aufgetreten ist |
| short SbxBasicFormater::AnalyseFormatString( const String& sFormatStrg, |
| short& nNoOfDigitsLeft, short& nNoOfDigitsRight, |
| short& nNoOfOptionalDigitsLeft, |
| short& nNoOfExponentDigits, short& nNoOfOptionalExponentDigits, |
| sal_Bool& bPercent, sal_Bool& bCurrency, sal_Bool& bScientific, |
| sal_Bool& bGenerateThousandSeparator, |
| short& nMultipleThousandSeparators ) |
| { |
| sal_uInt16 nLen; |
| short nState = 0; |
| |
| nLen = sFormatStrg.Len(); |
| // initialisiere alle Z"ahler und Flags |
| nNoOfDigitsLeft = 0; |
| nNoOfDigitsRight = 0; |
| nNoOfOptionalDigitsLeft = 0; |
| nNoOfExponentDigits = 0; |
| nNoOfOptionalExponentDigits = 0; |
| bPercent = sal_False; |
| bCurrency = sal_False; |
| bScientific = sal_False; |
| // ab 11.7.97: sobald ein Komma in dem Format String gefunden wird, |
| // werden alle 3 Zehnerpotenzen markiert (d.h. tausender, milionen, ...) |
| // bisher wurde nur an den gesetzten Position ein Tausender-Separator |
| // ausgegeben oder wenn ein @ im Format-String stand. |
| // Dies war ein Missverstaendnis der VB Kompatiblitaet. |
| bGenerateThousandSeparator = sFormatStrg.Search( ',' ) != STRING_NOTFOUND; |
| nMultipleThousandSeparators = 0; |
| // und untersuche den Format-String nach den gew"unschten Informationen |
| for( sal_uInt16 i=0; i<nLen; i++ ) |
| { |
| sal_Unicode c = sFormatStrg.GetChar( i ); |
| switch( c ) { |
| case '#': |
| case '0': |
| if( nState==0 ) |
| { |
| nNoOfDigitsLeft++; |
| // TODO hier ggf. bessere Fehler-"Uberpr"ufung der Mantisse auf g"ultige Syntax (siehe Grammatik) |
| // ACHTUNG: 'undefiniertes' Verhalten falls # und 0 |
| // gemischt werden !!! |
| // BEMERKUNG: eigentlich sind #-Platzhalter bei Scientific |
| // Darstellung vor dem Dezimal-Punkt sinnlos ! |
| if( c=='#' ) |
| nNoOfOptionalDigitsLeft++; |
| } |
| else if( nState==1 ) |
| nNoOfDigitsRight++; |
| else if( nState==-1 ) // suche 0 im Exponent |
| { |
| if( c=='#' ) // # schaltet den Zustand weiter |
| { |
| nNoOfOptionalExponentDigits++; |
| nState = -2; |
| } |
| nNoOfExponentDigits++; |
| } |
| else if( nState==-2 ) // suche # im Exponent |
| { |
| if( c=='0' ) |
| // ERROR: 0 nach # im Exponent ist NICHT erlaubt !! |
| return -4; |
| nNoOfOptionalExponentDigits++; |
| nNoOfExponentDigits++; |
| } |
| break; |
| case '.': |
| nState++; |
| if( nState>1 ) |
| return -1; // ERROR: zu viele Dezimal-Punkte |
| break; |
| case '%': |
| bPercent = sal_True; |
| /* old: |
| bPercent++; |
| if( bPercent>1 ) |
| return -2; // ERROR: zu viele Prozent-Zeichen |
| */ |
| break; |
| case '(': |
| bCurrency = sal_True; |
| break; |
| case ',': |
| { |
| sal_Unicode ch = sFormatStrg.GetChar( i+1 ); |
| // vorl"aufig wird NUR auf zwei aufeinanderfolgede |
| // Zeichen gepr"uft |
| if( ch!=0 && (ch==',' || ch=='.') ) |
| nMultipleThousandSeparators++; |
| } break; |
| case 'e': |
| case 'E': |
| // #i13821 not when no digits before |
| if( nNoOfDigitsLeft > 0 || nNoOfDigitsRight > 0 ) |
| { |
| nState = -1; // breche jetzt das Z"ahlen der Stellen ab |
| bScientific = sal_True; |
| } |
| /* old: |
| bScientific++; |
| if( bScientific>1 ) |
| return -3; // ERROR: zu viele Exponent-Zeichen |
| */ |
| break; |
| // EIGENES Kommando-Zeichen, das die Erzeugung der |
| // Tausender-Trennzeichen einschaltet |
| case '\\': |
| // Ignore next char |
| i++; |
| break; |
| case CREATE_1000SEP_CHAR: |
| bGenerateThousandSeparator = sal_True; |
| break; |
| } |
| } |
| return 0; |
| } |
| |
| // das Flag bCreateSign zeigt an, dass bei der Mantisse ein Vorzeichen |
| // erzeugt werden soll |
| void SbxBasicFormater::ScanFormatString( double dNumber, |
| const String& sFormatStrg, String& sReturnStrg, |
| sal_Bool bCreateSign ) |
| { |
| short /*nErr,*/nNoOfDigitsLeft,nNoOfDigitsRight,nNoOfOptionalDigitsLeft, |
| nNoOfExponentDigits,nNoOfOptionalExponentDigits, |
| nMultipleThousandSeparators; |
| sal_Bool bPercent,bCurrency,bScientific,bGenerateThousandSeparator; |
| |
| // Initialisiere den Return-String |
| sReturnStrg = String(); |
| |
| // analysiere den Format-String, d.h. bestimme folgende Werte: |
| /* |
| - Anzahl der Ziffern vor dem Komma |
| - Anzahl der Ziffern nach dem Komma |
| - optionale Ziffern vor dem Komma |
| - Anzahl der Ziffern im Exponent |
| - optionale Ziffern im Exponent |
| - Prozent-Zeichen gefunden ? |
| - () f"ur negatives Vorzeichen ? |
| - Exponetial-Schreibweise ? |
| - sollen Tausender-Separatoren erzeugt werden ? |
| - wird ein Prozent-Zeichen gefunden ? --> dNumber *= 100.0; |
| - gibt es aufeinanderfolgende Tausender-Trennzeichen ? |
| ,, oder ,. --> dNumber /= 1000.0; |
| - sonstige Fehler ? mehrfache Dezimalpunkte, E's, etc. |
| --> Fehler werden zur Zeit einfach ignoriert |
| */ |
| /*nErr =*/ AnalyseFormatString( sFormatStrg,nNoOfDigitsLeft,nNoOfDigitsRight, |
| nNoOfOptionalDigitsLeft,nNoOfExponentDigits, |
| nNoOfOptionalExponentDigits, |
| bPercent,bCurrency,bScientific,bGenerateThousandSeparator, |
| nMultipleThousandSeparators ); |
| /* es werden alle Fehler ignoriert, wie in Visual-Basic |
| if( nErr!=0 ) |
| { |
| char sBuffer[512]; |
| |
| //sprintf( sBuffer,"bad format-string >%s< err=%i",sFormatStrg,nErr ); |
| strcpy( sBuffer,"bad format-string" ); |
| ShowError( sBuffer ); |
| } |
| else |
| */ |
| { |
| // Spezialbehandlung f"ur Spezialzeichen |
| if( bPercent ) |
| dNumber *= 100.0; |
| // TODO: diese Vorgabe (,, oder ,.) ist NICHT Visual-Basic kompatibel ! |
| // Frage: soll das hier stehen bleiben (Anforderungen) ? |
| if( nMultipleThousandSeparators ) |
| dNumber /= 1000.0; |
| |
| // einige Arbeits-Variablen |
| double dExponent; |
| short i,nLen; |
| short nState,nDigitPos,nExponentPos,nMaxDigit,nMaxExponentDigit; |
| sal_Bool bFirstDigit,bFirstExponentDigit,bFoundFirstDigit, |
| bIsNegative,bZeroSpaceOn, bSignHappend,bDigitPosNegative; |
| |
| // Initialisierung der Arbeits-Variablen |
| bSignHappend = sal_False; |
| bFoundFirstDigit = sal_False; |
| bIsNegative = dNumber<0.0; |
| nLen = sFormatStrg.Len(); |
| dExponent = get_number_of_digits( dNumber ); |
| nExponentPos = 0; |
| nMaxExponentDigit = 0; |
| nMaxDigit = (short)dExponent; |
| bDigitPosNegative = false; |
| if( bScientific ) |
| { |
| //if( nNoOfOptionalDigitsLeft>0 ) |
| // ShowError( "# in scientific-format in front of the decimal-point has no effect" ); |
| // beim Exponent ggf. "uberz"ahlige Stellen vor dem Komma abziehen |
| dExponent = dExponent - (double)(nNoOfDigitsLeft-1); |
| nDigitPos = nMaxDigit; |
| nMaxExponentDigit = (short)get_number_of_digits( dExponent ); |
| nExponentPos = nNoOfExponentDigits-1 - nNoOfOptionalExponentDigits; |
| } |
| else |
| { |
| nDigitPos = nNoOfDigitsLeft-1; // Z"ahlweise f"angt bei 0 an, 10^0 |
| // hier ben"otigt man keine Exponent-Daten ! |
| bDigitPosNegative = (nDigitPos < 0); |
| } |
| bFirstDigit = sal_True; |
| bFirstExponentDigit = sal_True; |
| nState = 0; // 0 --> Mantisse; 1 --> Exponent |
| bZeroSpaceOn = 0; |
| |
| |
| #ifdef _with_sprintf |
| InitScan( dNumber ); |
| #endif |
| // scanne jetzt den Format-String: |
| sal_Unicode cForce = 0; |
| for( i=0; i<nLen; i++ ) |
| { |
| sal_Unicode c; |
| if( cForce ) |
| { |
| c = cForce; |
| cForce = 0; |
| } |
| else |
| { |
| c = sFormatStrg.GetChar( i ); |
| } |
| switch( c ) { |
| case '0': |
| case '#': |
| if( nState==0 ) |
| { |
| // Behandlung der Mantisse |
| if( bFirstDigit ) |
| { |
| //org:bFirstDigit = sal_False; |
| // ggf. Vorzeichen erzeugen |
| // Bem.: bei bCurrency soll das negative |
| // Vorzeichen durch () angezeigt werden |
| if( bIsNegative && !bCreateSign/*!bCurrency*/ && !bSignHappend ) |
| { |
| // nur einmal ein Vorzeichen ausgeben |
| bSignHappend = sal_True; |
| StrAppendChar( sReturnStrg,'-' ); |
| } |
| // hier jetzt "uberz"ahlige Stellen ausgeben, |
| // d.h. vom Format-String nicht erfasste Stellen |
| if( nMaxDigit>nDigitPos ) |
| { |
| for( short j=nMaxDigit; j>nDigitPos; j-- ) |
| { |
| short nTempDigit; |
| #ifdef _with_sprintf |
| AppendDigit( sReturnStrg,nTempDigit = GetDigitAtPosScan( j,bFoundFirstDigit ) ); |
| #else |
| AppendDigit( sReturnStrg,nTempDigit = GetDigitAtPos( dNumber,j,dNumber,bFoundFirstDigit ) ); |
| #endif |
| // wurde wirklich eine Ziffer eingefuegt ? |
| if( nTempDigit!=_NO_DIGIT ) |
| // jetzt wurde wirklich eine Ziffer ausgegeben, Flag setzen |
| bFirstDigit = sal_False; |
| // muss ggf. ein Tausender-Trennzeichen erzeugt werden? |
| if( bGenerateThousandSeparator && ( c=='0' || nMaxDigit>=nDigitPos ) && j>0 && (j % 3 == 0) ) |
| StrAppendChar( sReturnStrg,cThousandSep ); |
| } |
| } |
| } |
| // muss f"ur eine leere Stelle eventuell eine 0 ausgegeben werden ? |
| if( nMaxDigit<nDigitPos && ( c=='0' || bZeroSpaceOn ) ) |
| { |
| AppendDigit( sReturnStrg,0 ); // Ja |
| // jetzt wurde wirklich eine Ziffer ausgegeben, Flag setzen |
| bFirstDigit = sal_False; |
| bZeroSpaceOn = 1; |
| // BEM.: bei Visual-Basic schaltet die erste 0 f"ur alle |
| // nachfolgenden # (bis zum Dezimal-Punkt) die 0 ein, |
| // dieses Verhalten wird hier mit dem Flag simmuliert. |
| // muss ggf. ein Tausender-Trennzeichen erzeugt werden? |
| if( bGenerateThousandSeparator && ( c=='0' || nMaxDigit>=nDigitPos ) && nDigitPos>0 && (nDigitPos % 3 == 0) ) |
| StrAppendChar( sReturnStrg,cThousandSep ); |
| } |
| else |
| { |
| short nTempDigit; |
| #ifdef _with_sprintf |
| AppendDigit( sReturnStrg,nTempDigit = GetDigitAtPosScan( nDigitPos,bFoundFirstDigit ) ); |
| #else |
| AppendDigit( sReturnStrg,nTempDigit = GetDigitAtPos( dNumber,nDigitPos,dNumber,bFoundFirstDigit ) ); |
| #endif |
| // wurde wirklich eine Ziffer eingefuegt ? |
| if( nTempDigit!=_NO_DIGIT ) |
| // jetzt wurde wirklich eine Ziffer ausgegeben, Flag setzen |
| bFirstDigit = sal_False; |
| // muss ggf. ein Tausender-Trennzeichen erzeugt werden? |
| if( bGenerateThousandSeparator && ( c=='0' || nMaxDigit>=nDigitPos ) && nDigitPos>0 && (nDigitPos % 3 == 0) ) |
| StrAppendChar( sReturnStrg,cThousandSep ); |
| } |
| // und Position aktualisieren |
| nDigitPos--; |
| } |
| else |
| { |
| // Behandlung des Exponenten |
| if( bFirstExponentDigit ) |
| { |
| // Vorzeichen wurde schon bei e/E ausgegeben |
| bFirstExponentDigit = sal_False; |
| if( nMaxExponentDigit>nExponentPos ) |
| // hier jetzt "uberz"ahlige Stellen ausgeben, |
| // d.h. vom Format-String nicht erfasste Stellen |
| { |
| for( short j=nMaxExponentDigit; j>nExponentPos; j-- ) |
| { |
| #ifdef _with_sprintf |
| AppendDigit( sReturnStrg,GetDigitAtPosExpScan( dExponent,j,bFoundFirstDigit ) ); |
| #else |
| AppendDigit( sReturnStrg,GetDigitAtPos( dExponent,j,dExponent,bFoundFirstDigit ) ); |
| #endif |
| } |
| } |
| } |
| // muss f"ur eine leere Stelle eventuell eine 0 ausgegeben werden ? |
| if( nMaxExponentDigit<nExponentPos && c=='0' ) |
| AppendDigit( sReturnStrg,0 ); // Ja |
| else |
| #ifdef _with_sprintf |
| AppendDigit( sReturnStrg,GetDigitAtPosExpScan( dExponent,nExponentPos,bFoundFirstDigit ) ); |
| #else |
| AppendDigit( sReturnStrg,GetDigitAtPos( dExponent,nExponentPos,dExponent,bFoundFirstDigit ) ); |
| #endif |
| nExponentPos--; |
| } |
| break; |
| case '.': |
| if( bDigitPosNegative ) // #i13821: If no digits before . |
| { |
| bDigitPosNegative = false; |
| nDigitPos = 0; |
| cForce = '#'; |
| i-=2; |
| break; |
| } |
| // gebe Komma aus |
| StrAppendChar( sReturnStrg,cDecPoint ); |
| break; |
| case '%': |
| // ggf. "uberf"ussige 0en l"oschen, z.B. 4.500e4 in 0.0##e-00 |
| ParseBack( sReturnStrg,sFormatStrg,i-1 ); |
| // gebe Prozent-Zeichen aus |
| sReturnStrg.Insert('%'); |
| break; |
| case 'e': |
| case 'E': |
| // muss Mantisse noch gerundet werden, bevor der Exponent angezeigt wird ? |
| { |
| // gibt es ueberhaupt eine Mantisse ? |
| if( bFirstDigit ) |
| { |
| // anscheinend nicht, d.h. ungueltiger Format String, z.B. E000.00 |
| // d.h. ignoriere diese e bzw. E Zeichen |
| // ggf. einen Fehler (wie Visual Basic) ausgeben ? |
| |
| // #i13821: VB 6 behaviour |
| StrAppendChar( sReturnStrg,c ); |
| break; |
| } |
| |
| sal_Bool bOverflow = sal_False; |
| #ifdef _with_sprintf |
| short nNextDigit = GetDigitAtPosScan( nDigitPos,bFoundFirstDigit ); |
| #else |
| short nNextDigit = GetDigitAtPos( dNumber,nDigitPos,dNumber,bFoundFirstDigit ); |
| #endif |
| if( nNextDigit>=5 ) |
| StrRoundDigit( sReturnStrg,sReturnStrg.Len()-1,bOverflow ); |
| if( bOverflow ) |
| { |
| // es wurde eine f"uhrende 9 gerundet, d.h. |
| // verschiebe den Dezimal-Punkt um eine Stelle nach links |
| LeftShiftDecimalPoint( sReturnStrg ); |
| // und l"osche die letzte Ziffer, diese wird |
| // duch die f"uhrende 1 ersetzt: |
| sReturnStrg.SetChar( sReturnStrg.Len()-1 , 0 ); |
| // der Exponent muss um 1 erh"oht werden, |
| // da der Dezimalpunkt verschoben wurde |
| dExponent += 1.0; |
| } |
| // ggf. "uberf"ussige 0en l"oschen, z.B. 4.500e4 in 0.0##e-00 |
| ParseBack( sReturnStrg,sFormatStrg,i-1 ); |
| } |
| // "andere Zustand des Scanners |
| nState++; |
| // gebe Exponent-Zeichen aus |
| StrAppendChar( sReturnStrg,c ); |
| // i++; // MANIPULATION der Schleifen-Variable ! |
| c = sFormatStrg.GetChar( ++i ); |
| // und gebe Vorzeichen / Exponent aus |
| if( c!=0 ) |
| { |
| if( c=='-' ) |
| { |
| // falls Exponent < 0 gebe - aus |
| if( dExponent<0.0 ) |
| StrAppendChar( sReturnStrg,'-' ); |
| } |
| else if( c=='+' ) |
| { |
| // gebe auf jeden Fall das Vorzeichen des Exponenten aus ! |
| if( dExponent<0.0 ) |
| StrAppendChar( sReturnStrg,'-' ); |
| else |
| StrAppendChar( sReturnStrg,'+' ); |
| } |
| //else |
| // ShowError( "operator e/E did not find + or -" ); |
| } |
| //else |
| // ShowError( "operator e/E ended with 0" ); |
| break; |
| case ',': |
| // ACHTUNG: nur falls Zahl bisher ausgegeben wurde |
| // das Zeichen ausgeben |
| ////--> Siehe Kommentar vom 11.7. in AnalyseFormatString() |
| ////if( !bFirstDigit ) |
| //// // gebe Tausender-Trennzeichen aus |
| //// StrAppendChar( sReturnStrg,cThousandSep ); |
| break; |
| case ';': |
| break; |
| case '(': |
| case ')': |
| // ggf. "uberf"ussige 0en l"oschen, z.B. 4.500e4 in 0.0##e-00 |
| ParseBack( sReturnStrg,sFormatStrg,i-1 ); |
| if( bIsNegative ) |
| StrAppendChar( sReturnStrg,c ); |
| break; |
| case '$': |
| // den String fuer die Waehrung dranhengen: |
| sReturnStrg += sCurrencyStrg; |
| break; |
| case ' ': |
| case '-': |
| case '+': |
| // ggf. "uberf"ussige 0en l"oschen, z.B. 4.500e4 in 0.0##e-00 |
| ParseBack( sReturnStrg,sFormatStrg,i-1 ); |
| // gebe das jeweilige Zeichen direkt aus |
| StrAppendChar( sReturnStrg,c ); |
| break; |
| case '\\': |
| // ggf. "uberf"ussige 0en l"oschen, z.B. 4.500e4 in 0.0##e-00 |
| // falls Sonderzeichen am Ende oder mitten in |
| // Format-String vorkommen |
| ParseBack( sReturnStrg,sFormatStrg,i-1 ); |
| // Sonderzeichen gefunden, gebe N"ACHSTES |
| // Zeichen direkt aus (falls es existiert) |
| // i++; |
| c = sFormatStrg.GetChar( ++i ); |
| if( c!=0 ) |
| StrAppendChar( sReturnStrg,c ); |
| //else |
| // ShowError( "operator \\ ended with 0" ); |
| break; |
| case CREATE_1000SEP_CHAR: |
| // hier ignorieren, Aktion wurde schon in |
| // AnalyseFormatString durchgef"uhrt |
| break; |
| default: |
| // auch die Zeichen und Ziffern ausgeben (wie in Visual-Basic) |
| if( ( c>='a' && c<='z' ) || |
| ( c>='A' && c<='Z' ) || |
| ( c>='1' && c<='9' ) ) |
| StrAppendChar( sReturnStrg,c ); |
| // else |
| // ignorieren ! |
| // ehemals: ShowError( "bad character in format-string" ); |
| } |
| } |
| // Format-String wurde vollst"andig gescanned, |
| // muss die letzte Stelle nun gerundet werden ? |
| // Dies hier ist jedoch NUR notwendig, falls das |
| // Zahlenformat NICHT Scientific-Format ist ! |
| if( !bScientific ) |
| { |
| #ifdef _with_sprintf |
| short nNextDigit = GetDigitAtPosScan( nDigitPos,bFoundFirstDigit ); |
| #else |
| short nNextDigit = GetDigitAtPos( dNumber,nDigitPos,dNumber,bFoundFirstDigit ); |
| #endif |
| if( nNextDigit>=5 ) |
| StrRoundDigit( sReturnStrg,sReturnStrg.Len()-1 ); |
| } |
| // und ganz zum Schluss: |
| // ggf. "uberf"ussige 0en l"oschen, z.B. 4.500e4 in 0.0##e-00#, |
| // ABER nur Stellen nach dem Dezimal-Punkt k"onnen gel"oscht werden |
| if( nNoOfDigitsRight>0 ) |
| ParseBack( sReturnStrg,sFormatStrg,sFormatStrg.Len()-1 ); |
| } |
| } |
| |
| String SbxBasicFormater::BasicFormatNull( String sFormatStrg ) |
| { |
| sal_Bool bNullFormatFound; |
| String sNullFormatStrg = GetNullFormatString( sFormatStrg,bNullFormatFound ); |
| |
| if( bNullFormatFound ) |
| return sNullFormatStrg; |
| String aRetStr; |
| aRetStr.AssignAscii( "null" ); |
| return aRetStr; |
| } |
| |
| String SbxBasicFormater::BasicFormat( double dNumber, String sFormatStrg ) |
| { |
| sal_Bool bPosFormatFound,bNegFormatFound,b0FormatFound; |
| |
| // analysiere Format-String auf vordefinierte Formate: |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_GENERALNUMBER ) ) |
| sFormatStrg.AssignAscii( GENERALNUMBER_FORMAT ); |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_CURRENCY ) ) |
| sFormatStrg = sCurrencyFormatStrg; // old: CURRENCY_FORMAT; |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_FIXED ) ) |
| sFormatStrg.AssignAscii( FIXED_FORMAT ); |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_STANDARD ) ) |
| sFormatStrg.AssignAscii( STANDARD_FORMAT ); |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_PERCENT ) ) |
| sFormatStrg.AssignAscii( PERCENT_FORMAT ); |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_SCIENTIFIC ) ) |
| sFormatStrg.AssignAscii( SCIENTIFIC_FORMAT ); |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_YESNO ) ) |
| return ( dNumber==0.0 ) ? sNoStrg : sYesStrg ; |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_TRUEFALSE ) ) |
| return ( dNumber==0.0 ) ? sFalseStrg : sTrueStrg ; |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_ONOFF ) ) |
| return ( dNumber==0.0 ) ? sOffStrg : sOnStrg ; |
| |
| // analysiere Format-String auf ';', d.h. Format-Strings f"ur |
| // positive-, negative- und 0-Werte |
| String sPosFormatStrg = GetPosFormatString( sFormatStrg, bPosFormatFound ); |
| String sNegFormatStrg = GetNegFormatString( sFormatStrg, bNegFormatFound ); |
| String s0FormatStrg = Get0FormatString( sFormatStrg, b0FormatFound ); |
| //String sNullFormatStrg = GetNullFormatString( sFormatStrg, bNullFormatFound ); |
| |
| String sReturnStrg; |
| String sTempStrg; |
| |
| if( dNumber==0.0 ) |
| { |
| sTempStrg = sFormatStrg; |
| if( b0FormatFound ) |
| { |
| // wurde ggf. Leer-String uebergeben ? |
| if( s0FormatStrg.Len() == 0 && bPosFormatFound ) |
| // --> Ja, dann verwende String fuer positive Werte |
| sTempStrg = sPosFormatStrg; |
| else |
| sTempStrg = s0FormatStrg; |
| } |
| else if( bPosFormatFound ) |
| { |
| // verwende String fuer positive Werte |
| sTempStrg = sPosFormatStrg; |
| } |
| ScanFormatString( dNumber, sTempStrg, sReturnStrg,/*bCreateSign=*/sal_False ); |
| } |
| else |
| { |
| if( dNumber<0.0 ) |
| { |
| if( bNegFormatFound ) |
| { |
| // wurde ggf. Leer-String uebergeben ? |
| if( sNegFormatStrg.Len() == 0 && bPosFormatFound ) |
| { |
| // --> Ja, dann verwende String fuer positive Werte |
| // und setzte Minus-Zeichen davor ! |
| sTempStrg = String::CreateFromAscii("-"); |
| sTempStrg += sPosFormatStrg; |
| } |
| else |
| sTempStrg = sNegFormatStrg; |
| } |
| else |
| sTempStrg = sFormatStrg; |
| // falls KEIN Format-String speziell f"ur negative Werte angegeben |
| // wurde, so soll das Vorzeichen ausgegeben werden |
| ScanFormatString( dNumber, sTempStrg, sReturnStrg,/*bCreateSign=*/bNegFormatFound/*sNegFormatStrg!=EMPTYFORMATSTRING*/ ); |
| } |
| else // if( dNumber>0.0 ) |
| { |
| ScanFormatString( dNumber, |
| (/*sPosFormatStrg!=EMPTYFORMATSTRING*/bPosFormatFound ? sPosFormatStrg : sFormatStrg), |
| sReturnStrg,/*bCreateSign=*/sal_False ); |
| } |
| } |
| return sReturnStrg; |
| } |
| |
| sal_Bool SbxBasicFormater::isBasicFormat( String sFormatStrg ) |
| { |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_GENERALNUMBER ) ) |
| return sal_True; |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_CURRENCY ) ) |
| return sal_True; |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_FIXED ) ) |
| return sal_True; |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_STANDARD ) ) |
| return sal_True; |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_PERCENT ) ) |
| return sal_True; |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_SCIENTIFIC ) ) |
| return sal_True; |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_YESNO ) ) |
| return sal_True; |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_TRUEFALSE ) ) |
| return sal_True; |
| if( sFormatStrg.EqualsIgnoreCaseAscii( BASICFORMAT_ONOFF ) ) |
| return sal_True; |
| return sal_False; |
| } |
| |