diff options
Diffstat (limited to 'svtools/source/numbers/zforlist.cxx')
-rw-r--r-- | svtools/source/numbers/zforlist.cxx | 3657 |
1 files changed, 3657 insertions, 0 deletions
diff --git a/svtools/source/numbers/zforlist.cxx b/svtools/source/numbers/zforlist.cxx new file mode 100644 index 000000000000..262a5572dde2 --- /dev/null +++ b/svtools/source/numbers/zforlist.cxx @@ -0,0 +1,3657 @@ +/************************************************************************* + * + * $RCSfile: zforlist.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:59:03 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#pragma hdrstop + +#include <math.h> + +#ifndef _DEBUG_HXX //autogen +#include <tools/debug.hxx> +#endif +#ifndef _INTN_HXX //autogen +#include <tools/intn.hxx> +#endif +#ifndef _SOUND_HXX //autogen +#include <vcl/sound.hxx> +#endif +#ifndef _SYSTEM_HXX //autogen +#include <vcl/system.hxx> +#endif +#ifndef _SV_SVAPP_HXX //autogen +#include <vcl/svapp.hxx> +#endif +#ifndef _SV_SETTINGS_HXX //autogen +#include <vcl/settings.hxx> +#endif +#ifndef _UNOTOOLS_CHARCLASS_HXX +#include <unotools/charclass.hxx> +#endif +#ifndef _ISOLANG_HXX +#include <tools/isolang.hxx> +#endif + +#define _SVSTDARR_USHORTS +#include "svstdarr.hxx" + +#define _ZFORLIST_CXX +#include "zforlist.hxx" +#undef _ZFORLIST_CXX + +#include "zforscan.hxx" +#include "zforfind.hxx" +#include "zformat.hxx" +#include "numhead.hxx" + + + // Konstanten fuer Typoffsets pro Land/Sprache (CL) +#define ZF_STANDARD 0 +#define ZF_STANDARD_PERCENT 10 +#define ZF_STANDARD_CURRENCY 20 +#define ZF_STANDARD_DATE 30 +#define ZF_STANDARD_TIME 40 +#define ZF_STANDARD_DATETIME 50 +#define ZF_STANDARD_SCIENTIFIC 60 +#define ZF_STANDARD_FRACTION 70 +#define ZF_STANDARD_NEWEXTENDED 75 +#define ZF_STANDARD_NEWEXTENDEDMAX SV_MAX_ANZ_STANDARD_FORMATE-2 // 98 +#define ZF_STANDARD_LOGICAL SV_MAX_ANZ_STANDARD_FORMATE-1 // 99 +#define ZF_STANDARD_TEXT SV_MAX_ANZ_STANDARD_FORMATE // 100 + +// Sprache, die am International gesetzt wird, wenn eine unbekannte Sprache +// (von einem anderen System) geladen wird. Darf nicht SYSTEM sein, weil +// "DM" aus deutschen Einstellungen sonst als Datum erkannt wird (#53155#). + +#define UNKNOWN_SUBSTITUTE LANGUAGE_ENGLISH_US + +static BOOL bIndexTableInitialized = FALSE; +static ULONG __FAR_DATA theIndexTable[NF_INDEX_TABLE_ENTRIES]; + +BOOL SvNumberFormatter::bCurrencyTableInitialized = FALSE; +NfCurrencyTable SvNumberFormatter::theCurrencyTable; +USHORT SvNumberFormatter::nSystemCurrencyPosition = 0; +SV_IMPL_PTRARR( NfCurrencyTable, NfCurrencyEntry* ); +const USHORT nCurrencyTableEuroPosition = 1; +SV_IMPL_PTRARR( NfWSStringsDtor, XubString* ); + +// ob das BankSymbol immer am Ende ist (1 $;-1 $) oder sprachabhaengig +#define NF_BANKSYMBOL_FIX_POSITION 1 + +/***********************Funktionen SvNumberFormatter**************************/ + +SvNumberFormatter::SvNumberFormatter(LanguageType eLnge) +{ +//! if (eLnge == LANGUAGE_SYSTEM) // Sprache Systemn uebersteuern +//! eLnge = System::GetLanguage(); + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = LANGUAGE_ENGLISH_US; + SysLnge = eLnge; + ActLnge = eLnge; + eEvalDateFormat = NF_EVALDATEFORMAT_INTL; + nDefaultCurrencyFormat = NUMBERFORMAT_ENTRY_NOT_FOUND; + if ( !International::IsFormatAvailable( eLnge ) ) + eLnge = UNKNOWN_SUBSTITUTE; + pIntl = new International( eLnge ); + String aLanguage, aCountry, aVariant; + ConvertLanguageToIsoNames( International::GetRealLanguage( eLnge ), aLanguage, aCountry ); + pCharClass = new CharClass( ::com::sun::star::lang::Locale( aLanguage, aCountry, aVariant ) ); + pStringScanner = new ImpSvNumberInputScan( this ); + pFormatScanner = new ImpSvNumberformatScan( this ); + pFormatTable = NULL; + ImpGenerateFormats(0); // 0 .. 999 fuer SystemEinst. + MaxCLOffset = 0; + pMergeTable = new SvULONGTable; + bNoZero = FALSE; + pColorLink = NULL; +} + +SvNumberFormatter::~SvNumberFormatter() +{ + SvNumberformat* pEntry = aFTable.First(); + while (pEntry) + { + delete pEntry; + pEntry = aFTable.Next(); + } + delete pCharClass; + delete pIntl; + delete pStringScanner; + delete pFormatScanner; + ClearMergeTable(); + delete pMergeTable; +} + +Color* SvNumberFormatter::GetUserDefColor(USHORT nIndex) +{ + if( pColorLink && pColorLink->IsSet() ) + return (Color*) ( pColorLink->Call( (void*) &nIndex )); + else + return NULL; +} + +void SvNumberFormatter::ChangeNullDate(USHORT nDay, + USHORT nMonth, + USHORT nYear) +{ + pFormatScanner->ChangeNullDate(nDay, nMonth, nYear); + pStringScanner->ChangeNullDate(nDay, nMonth, nYear); +} + +Date* SvNumberFormatter::GetNullDate() +{ + return pFormatScanner->GetNullDate(); +} + +void SvNumberFormatter::ChangeStandardPrec(short nPrec) +{ + pFormatScanner->ChangeStandardPrec(nPrec); +} + +short SvNumberFormatter::GetStandardPrec() +{ + return pFormatScanner->GetStandardPrec(); +} + +void SvNumberFormatter::ImpChangeSysCL(LanguageType eLnge) +{ +//! if (eLnge == LANGUAGE_SYSTEM) // Sprache Systemn uebersteuern +//! eLnge = System::GetLanguage(); + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = LANGUAGE_ENGLISH_US; + if (eLnge != SysLnge) + { + SysLnge = eLnge; + ChangeIntl(eLnge); + SvNumberformat* pEntry = aFTable.First(); + while (pEntry) // alte Formate loeschen + { + pEntry = (SvNumberformat*) aFTable.Remove(aFTable.GetCurKey()); + delete pEntry; + pEntry = (SvNumberformat*) aFTable.First(); + } + ImpGenerateFormats(0); // wieder neue Standardformate + } +} + +void SvNumberFormatter::ChangeIntl(LanguageType eLnge) +{ +//! if (eLnge == LANGUAGE_SYSTEM) // Sprache Systemn uebersteuern +//! eLnge = System::GetLanguage(); + if (ActLnge != eLnge) + { + delete pIntl; + ActLnge = eLnge; + if ( !International::IsFormatAvailable( eLnge ) ) + eLnge = UNKNOWN_SUBSTITUTE; + pIntl = new International( eLnge ); + + String aLanguage, aCountry, aVariant; + ConvertLanguageToIsoNames( International::GetRealLanguage( eLnge ), aLanguage, aCountry ); + pCharClass->setLocale( ::com::sun::star::lang::Locale( aLanguage, aCountry, aVariant ) ); + + pFormatScanner->ChangeIntl(); + pStringScanner->ChangeIntl(); + } +} + +BOOL SvNumberFormatter::IsTextFormat(ULONG F_Index) const +{ + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(F_Index); + if (!pFormat) + return FALSE; + else + return pFormat->IsTextFormat(); +} + +BOOL SvNumberFormatter::HasTextFormat(ULONG F_Index) const +{ + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(F_Index); + if (!pFormat) + return FALSE; + else + return pFormat->HasTextFormat(); +} + +BOOL SvNumberFormatter::PutEntry(XubString& rString, + xub_StrLen& nCheckPos, + short& nType, + ULONG& nKey, // Formatnummer + LanguageType eLnge) +{ + nKey = 0; + if (rString.Len() == 0) // keinen Leerstring + { + nCheckPos = 1; // -> Fehler + return FALSE; + } + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = SysLnge; + + ChangeIntl(eLnge); // ggfs. austauschen + LanguageType eLge = eLnge; // Umgehung const fuer ConvertMode + BOOL bCheck = FALSE; + SvNumberformat* p_Entry = new SvNumberformat(rString, + pFormatScanner, + pStringScanner, + nCheckPos, + eLge); + if (nCheckPos == 0) // Format ok + { // Typvergleich: + short eCheckType = p_Entry->GetType(); + if ( eCheckType != NUMBERFORMAT_UNDEFINED) + { + p_Entry->SetType(eCheckType | NUMBERFORMAT_DEFINED); + nType = eCheckType; + } + else + { + p_Entry->SetType(NUMBERFORMAT_DEFINED); + nType = NUMBERFORMAT_DEFINED; + } + ULONG CLOffset = ImpGenerateCL(eLge); // ggfs. neu Standard- + // formate anlegen + nKey = ImpIsEntry(p_Entry->GetFormatstring(),CLOffset, eLge); + if (nKey != NUMBERFORMAT_ENTRY_NOT_FOUND) // schon vorhanden + delete p_Entry; + else + { + bCheck = TRUE; + SvNumberformat* pStdFormat = + (SvNumberformat*) aFTable.Get(CLOffset + ZF_STANDARD); + ULONG nPos = CLOffset + pStdFormat->GetLastInsertKey(); +// ULONG nPos = ImpGetLastCLEntryKey(CLOffset, eLge); + if (nPos - CLOffset >= SV_COUNTRY_LANGUAGE_OFFSET) + { +#ifndef DOS + Sound::Beep(); +#endif + DBG_ERROR("SvNumberFormatter:: Zu viele Formate pro CL"); + delete p_Entry; + } + else if (!aFTable.Insert(nPos+1,p_Entry)) + delete p_Entry; + else + { + nKey = nPos+1; + pStdFormat->SetLastInsertKey((USHORT) (nKey-CLOffset)); + } + } + } + else + delete p_Entry; + return bCheck; +} + +BOOL SvNumberFormatter::PutandConvertEntry(XubString& rString, + xub_StrLen& nCheckPos, + short& nType, + ULONG& nKey, + LanguageType eLnge, + LanguageType eNewLnge) +{ + BOOL bRes; +//! if (eNewLnge == LANGUAGE_SYSTEM) // Sprache Systemn uebersteuern +//! eNewLnge = System::GetLanguage(); + if (eNewLnge == LANGUAGE_DONTKNOW) + eNewLnge = LANGUAGE_ENGLISH_US; + + pFormatScanner->SetConvertMode(eLnge, eNewLnge); + bRes = PutEntry(rString, nCheckPos, nType, nKey, eLnge); + pFormatScanner->SetConvertMode(FALSE); + return bRes; +} + +void SvNumberFormatter::DeleteEntry(ULONG nKey) +{ + SvNumberformat* pEntry = aFTable.Remove(nKey); + delete pEntry; +} + +void SvNumberFormatter::PrepareSave() +{ + SvNumberformat* pFormat = aFTable.First(); + while (pFormat) + { + pFormat->SetUsed(FALSE); + pFormat = aFTable.Next(); + } +} + +void SvNumberFormatter::SetFormatUsed(ULONG nFIndex) +{ + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(nFIndex); + if (pFormat) + pFormat->SetUsed(TRUE); +} + +BOOL SvNumberFormatter::Load( SvStream& rStream ) +{ + LanguageType eSysLang = System::GetLanguage(); + SvNumberFormatter* pConverter = NULL; + + ImpSvNumMultipleReadHeader aHdr( rStream ); + USHORT nVersion; + rStream >> nVersion; + SvNumberformat* pEntry; + ULONG nPos; + LanguageType eSaveSysLang, eLoadSysLang; + USHORT nSysOnStore, eLge, eDummy; // Dummy fuer kompatibles Format + rStream >> nSysOnStore >> eLge; // Systemeinstellung aus + // Dokument + eSaveSysLang = (nVersion < SV_NUMBERFORMATTER_VERSION_SYSTORE ? + LANGUAGE_SYSTEM : (LanguageType) nSysOnStore); + LanguageType eLnge = (LanguageType) eLge; + ImpChangeSysCL(eLnge); + + rStream >> nPos; + while (nPos != NUMBERFORMAT_ENTRY_NOT_FOUND) + { + rStream >> eDummy >> eLge; + eLnge = (LanguageType) eLge; + ImpGenerateCL(eLnge); // ggfs. neue Standardformate anlegen + + ULONG nOffset = nPos % SV_COUNTRY_LANGUAGE_OFFSET; // relativIndex + BOOL bUserDefined = (nOffset > SV_MAX_ANZ_STANDARD_FORMATE); + //! HACK! ER 29.07.97 15:15 + // SaveLang wurde bei SYSTEM nicht gespeichert sondern war auch SYSTEM, + // erst ab 364i Unterscheidung moeglich + BOOL bConversionHack; + if ( eLnge == LANGUAGE_SYSTEM ) + { + if ( nVersion < SV_NUMBERFORMATTER_VERSION_SYSTORE ) + { + bConversionHack = bUserDefined; + eLoadSysLang = eSaveSysLang; + } + else + { + bConversionHack = FALSE; + eLoadSysLang = eSysLang; + } + } + else + { + bConversionHack = FALSE; + eLoadSysLang = eSaveSysLang; + } + + pEntry = new SvNumberformat(*pFormatScanner, eLnge); + if ( bConversionHack ) + { // SYSTEM + // nVersion < SV_NUMBERFORMATTER_VERSION_SYSTORE + // nVersion < SV_NUMBERFORMATTER_VERSION_KEYWORDS + if ( !pConverter ) + pConverter = new SvNumberFormatter( eSysLang ); + NfHackConversion eHackConversion = pEntry->Load( + rStream, aHdr, pConverter, *pStringScanner ); + switch ( eHackConversion ) + { + case NF_CONVERT_GERMAN_ENGLISH : + pEntry->ConvertLanguage( *pConverter, + LANGUAGE_ENGLISH_US, eSysLang, TRUE ); + break; + case NF_CONVERT_ENGLISH_GERMAN : + switch ( eSysLang ) + { + case LANGUAGE_GERMAN: + case LANGUAGE_GERMAN_SWISS: + case LANGUAGE_GERMAN_AUSTRIAN: + case LANGUAGE_GERMAN_LUXEMBOURG: + case LANGUAGE_GERMAN_LIECHTENSTEIN: + // alles beim alten + break; + default: + pEntry->ConvertLanguage( *pConverter, + LANGUAGE_GERMAN, eSysLang, TRUE ); + } + break; + } + + } + else + { + pEntry->Load( rStream, aHdr, NULL, *pStringScanner ); + if ( !bUserDefined ) + bUserDefined = (pEntry->GetNewStandardDefined() > SV_NUMBERFORMATTER_VERSION); + if ( bUserDefined ) + { + if ( eSaveSysLang != eLoadSysLang ) + { // SYSTEM verschieden + if ( !pConverter ) + pConverter = new SvNumberFormatter( eSysLang ); + if ( nVersion < SV_NUMBERFORMATTER_VERSION_KEYWORDS ) + { + switch ( eSaveSysLang ) + { + case LANGUAGE_GERMAN: + case LANGUAGE_GERMAN_SWISS: + case LANGUAGE_GERMAN_AUSTRIAN: + case LANGUAGE_GERMAN_LUXEMBOURG: + case LANGUAGE_GERMAN_LIECHTENSTEIN: + // alles beim alten + pEntry->ConvertLanguage( *pConverter, + eSaveSysLang, eLoadSysLang, TRUE ); + break; + default: + // alte english nach neuem anderen + pEntry->ConvertLanguage( *pConverter, + LANGUAGE_ENGLISH_US, eLoadSysLang, TRUE ); + } + } + else + pEntry->ConvertLanguage( *pConverter, + eSaveSysLang, eLoadSysLang, TRUE ); + } + else + { // nicht SYSTEM oder gleiches SYSTEM + if ( nVersion < SV_NUMBERFORMATTER_VERSION_KEYWORDS ) + { + LanguageType eLoadLang; + BOOL bSystem; + if ( eLnge == LANGUAGE_SYSTEM ) + { + eLoadLang = eSysLang; + bSystem = TRUE; + } + else + { + eLoadLang = eLnge; + bSystem = FALSE; + } + switch ( eLoadLang ) + { + case LANGUAGE_GERMAN: + case LANGUAGE_GERMAN_SWISS: + case LANGUAGE_GERMAN_AUSTRIAN: + case LANGUAGE_GERMAN_LUXEMBOURG: + case LANGUAGE_GERMAN_LIECHTENSTEIN: + // alles beim alten + break; + default: + // alte english nach neuem anderen + if ( !pConverter ) + pConverter = new SvNumberFormatter( eSysLang ); + pEntry->ConvertLanguage( *pConverter, + LANGUAGE_ENGLISH_US, eLoadLang, bSystem ); + } + } + } + } + } + if ( nOffset == 0 ) // StandardFormat + { + SvNumberformat* pEnt = aFTable.Get(nPos); + if (pEnt) + pEnt->SetLastInsertKey(pEntry->GetLastInsertKey()); + } + if (!aFTable.Insert(nPos, pEntry)) + delete pEntry; + rStream >> nPos; + } + + // ab SV_NUMBERFORMATTER_VERSION_YEAR2000 + if ( nVersion >= SV_NUMBERFORMATTER_VERSION_YEAR2000 ) + { + aHdr.StartEntry(); + if ( aHdr.BytesLeft() >= sizeof(UINT16) ) + { + UINT16 nY2k; + rStream >> nY2k; + if ( nVersion < SV_NUMBERFORMATTER_VERSION_TWODIGITYEAR && nY2k < 100 ) + nY2k += 1901; // war vor src513e: 29, jetzt: 1930 + SetYear2000( nY2k ); + } + aHdr.EndEntry(); + } + + if ( pConverter ) + delete pConverter; + if (rStream.GetError()) + return FALSE; + else + return TRUE; +} + +BOOL SvNumberFormatter::Save( SvStream& rStream ) const +{ + ImpSvNumMultipleWriteHeader aHdr( rStream ); + // ab 364i wird gespeichert was SYSTEM wirklich war, vorher hart LANGUAGE_SYSTEM + rStream << (USHORT) SV_NUMBERFORMATTER_VERSION; + rStream << (USHORT) System::GetLanguage() << (USHORT) SysLnge; + SvNumberFormatTable* pTable = (SvNumberFormatTable*) &aFTable; + SvNumberformat* pEntry = (SvNumberformat*) pTable->First(); + while (pEntry) + { + // Gespeichert werden alle markierten, benutzerdefinierten Formate und + // jeweils das Standardformat zu allen angewaehlten CL-Kombinationen + // sowie NewStandardDefined + if ( pEntry->GetUsed() || (pEntry->GetType() & NUMBERFORMAT_DEFINED) || + pEntry->GetNewStandardDefined() || + (pTable->GetCurKey() % SV_COUNTRY_LANGUAGE_OFFSET == 0) ) + { + rStream << pTable->GetCurKey() + << (USHORT) LANGUAGE_SYSTEM + << (USHORT) pEntry->GetLanguage(); + pEntry->Save(rStream, aHdr); + } + pEntry = (SvNumberformat*) pTable->Next(); + } + rStream << NUMBERFORMAT_ENTRY_NOT_FOUND; // EndeKennung + + // ab SV_NUMBERFORMATTER_VERSION_YEAR2000 + aHdr.StartEntry(); + rStream << (UINT16) GetYear2000(); + aHdr.EndEntry(); + + if (rStream.GetError()) + return FALSE; + else + return TRUE; +} + +// static +void SvNumberFormatter::SkipNumberFormatterInStream( SvStream& rStream ) +{ + ImpSvNumMultipleReadHeader::Skip( rStream ); +} + +void SvNumberFormatter::GetUsedLanguages( SvUShorts& rList ) +{ + rList.Remove( 0, rList.Count() ); + + ULONG nOffset = 0; + while (nOffset <= MaxCLOffset) + { + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(nOffset); + if (pFormat) + rList.Insert( pFormat->GetLanguage(), rList.Count() ); + nOffset += SV_COUNTRY_LANGUAGE_OFFSET; + } +} + +XubString SvNumberFormatter::GetKeyword( LanguageType eLnge, USHORT nIndex ) +{ + ChangeIntl(eLnge); + const String* pTable = pFormatScanner->GetKeyword(); + if ( pTable && nIndex < NF_KEYWORD_ENTRIES_COUNT ) + return pTable[nIndex]; + + DBG_ERROR("GetKeyword: invalid index"); + return XubString(); +} + +ULONG SvNumberFormatter::ImpGetCLOffset(LanguageType eLnge) const +{ + SvNumberformat* pFormat; + ULONG nOffset = 0; + while (nOffset <= MaxCLOffset) + { + pFormat = (SvNumberformat*) aFTable.Get(nOffset); + if (pFormat && pFormat->GetLanguage() == eLnge) + return nOffset; + nOffset += SV_COUNTRY_LANGUAGE_OFFSET; + } + return nOffset; +} + +ULONG SvNumberFormatter::ImpIsEntry(const XubString& rString, + ULONG nCLOffset, + LanguageType eLnge) +{ +#ifndef NF_COMMENT_IN_FORMATSTRING +#error NF_COMMENT_IN_FORMATSTRING not defined (zformat.hxx) +#endif +#if NF_COMMENT_IN_FORMATSTRING + XubString aStr( rString ); + SvNumberformat::EraseComment( aStr ); +#endif + ULONG res = NUMBERFORMAT_ENTRY_NOT_FOUND; + SvNumberformat* pEntry; + pEntry = (SvNumberformat*) aFTable.Seek(nCLOffset); + while ( res == NUMBERFORMAT_ENTRY_NOT_FOUND && + pEntry && pEntry->GetLanguage() == eLnge ) + { +#if NF_COMMENT_IN_FORMATSTRING + if ( pEntry->GetComment().Len() ) + { + XubString aFormat( pEntry->GetFormatstring() ); + SvNumberformat::EraseComment( aFormat ); + if ( aStr == aFormat ) + res = aFTable.GetCurKey(); + else + pEntry = (SvNumberformat*) aFTable.Next(); + } + else + { + if ( aStr == pEntry->GetFormatstring() ) + res = aFTable.GetCurKey(); + else + pEntry = (SvNumberformat*) aFTable.Next(); + } +#else + if ( rString == pEntry->GetFormatstring() ) + res = aFTable.GetCurKey(); + else + pEntry = (SvNumberformat*) aFTable.Next(); +#endif + } + return res; +} + +/* +ULONG SvNumberFormatter::ImpGetLastCLEntryKey(ULONG nCLOffset, + LanguageType eLnge) +{ + // Diese Funktion ist ueberfluesssig geworden 3.3.95 + ULONG res = 0; + SvNumberformat* pEntry; + pEntry = (SvNumberformat*) aFTable.Seek(nCLOffset); + while (pEntry && pEntry->GetLanguage() == eLnge) + { + res = aFTable.GetCurKey(); + pEntry = (SvNumberformat*) aFTable.Next(); + } + if (res < nCLOffset + SV_MAX_ANZ_STANDARD_FORMATE) // nie bei den Standard- + res = nCLOffset + SV_MAX_ANZ_STANDARD_FORMATE; // formaten + return res; +} +*/ + +SvNumberFormatTable& SvNumberFormatter::GetFirstEntryTable( + short& eType, + ULONG& FIndex, + LanguageType& rLnge) +{ + short eTypetmp = eType; + if (eType == NUMBERFORMAT_ALL) // Leere Zelle oder don't care + rLnge = SysLnge; + else + { + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(FIndex); + if (!pFormat) + { +// DBG_ERROR("SvNumberFormatter:: Unbekanntes altes Zahlformat (1)"); + rLnge = SysLnge; + eType = NUMBERFORMAT_ALL; + eTypetmp = eType; + } + else + { + rLnge = pFormat->GetLanguage(); + eType = pFormat->GetType()&~NUMBERFORMAT_DEFINED; + if (eType == 0) + { + eType = NUMBERFORMAT_DEFINED; + eTypetmp = eType; + } + else if (eType == NUMBERFORMAT_DATETIME) + { + eTypetmp = eType; + eType = NUMBERFORMAT_DATE; + } + else + eTypetmp = eType; + } + } + ChangeIntl(rLnge); + return GetEntryTable(eTypetmp, FIndex, rLnge); +} + +ULONG SvNumberFormatter::ImpGenerateCL(LanguageType eLnge) +{ + ChangeIntl(eLnge); + ULONG CLOffset = ImpGetCLOffset(ActLnge); + if (CLOffset > MaxCLOffset) // CL noch nicht da + { + MaxCLOffset += SV_COUNTRY_LANGUAGE_OFFSET; + ImpGenerateFormats(MaxCLOffset); + CLOffset = MaxCLOffset; + } + return CLOffset; +} + +SvNumberFormatTable& SvNumberFormatter::ChangeCL(short eType, + ULONG& FIndex, + LanguageType eLnge) +{ + ImpGenerateCL(eLnge); + return GetEntryTable(eType, FIndex, ActLnge); +} + +SvNumberFormatTable& SvNumberFormatter::GetEntryTable( + short eType, + ULONG& FIndex, + LanguageType eLnge) +{ + delete pFormatTable; + pFormatTable = new SvNumberFormatTable; // neuer Table + ChangeIntl(eLnge); + ULONG CLOffset = ImpGetCLOffset(ActLnge); + SvNumberformat* pEntry; + pEntry = (SvNumberformat*) aFTable.Seek(CLOffset); + + if (eType == NUMBERFORMAT_ALL) + { + while (pEntry && pEntry->GetLanguage() == ActLnge) + { + pFormatTable->Insert(aFTable.GetCurKey(),pEntry); // einhaengen + pEntry = (SvNumberformat*) aFTable.Next(); + } + } + else + { + while (pEntry && pEntry->GetLanguage() == ActLnge) + { + if ((pEntry->GetType()) & eType) // von diesem Typ + pFormatTable->Insert(aFTable.GetCurKey(),pEntry);// einhaengen + pEntry = (SvNumberformat*) aFTable.Next(); + } + } + pEntry = aFTable.Get(FIndex); + if (!pEntry || !(pEntry->GetType() & eType) // irgendeine Veraenderung + || pEntry->GetLanguage() != ActLnge ) // => StandardForm. + if (pFormatTable->Count() > 0) // aber nicht leer + FIndex = GetStandardFormat(eType, ActLnge); + return *pFormatTable; +} + +BOOL SvNumberFormatter::IsNumberFormat(const XubString& sString, + ULONG& F_Index, + double& fOutNumber) +{ + short FType; + const SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(F_Index); + if (!pFormat) + { +// DBG_ERROR("SvNumberFormatter:: Unbekanntes altes Zahlformat (2)"); + ChangeIntl(SysLnge); + FType = NUMBERFORMAT_NUMBER; + } + else + { + FType = pFormat->GetType() &~NUMBERFORMAT_DEFINED; + if (FType == 0) + FType = NUMBERFORMAT_DEFINED; + ChangeIntl(pFormat->GetLanguage()); + } + BOOL res; + short RType = FType; + // Ergebnistyp + // ohne def-Kennung + if (RType == NUMBERFORMAT_TEXT) // Zahlzelle ->Stringz. + res = FALSE; + else + res = pStringScanner->IsNumberFormat(sString, RType, fOutNumber, pFormat); + + if (res && !IsCompatible(FType, RType)) // unpassender Typ + { + switch ( RType ) + { + case NUMBERFORMAT_TIME : + { + if ( pStringScanner->GetDecPos() ) + { // 100stel Sekunden + if ( pStringScanner->GetAnzNums() > 3 || fOutNumber < 0.0 ) + F_Index = GetFormatIndex( NF_TIME_HH_MMSS00, ActLnge ); + else + F_Index = GetFormatIndex( NF_TIME_MMSS00, ActLnge ); + } + else if ( fOutNumber >= 1.0 || fOutNumber < 0.0 ) + F_Index = GetFormatIndex( NF_TIME_HH_MMSS, ActLnge ); + else + F_Index = GetStandardFormat( RType, ActLnge ); + } + break; + default: + F_Index = GetStandardFormat( RType, ActLnge ); + } + } + return res; +} + +BOOL SvNumberFormatter::IsCompatible(short eOldType, + short eNewType) +{ + if (eOldType == eNewType) + return TRUE; + else if (eOldType == NUMBERFORMAT_DEFINED) + return TRUE; + else + { + switch (eNewType) + { + case NUMBERFORMAT_NUMBER: + { + switch (eOldType) + { + case NUMBERFORMAT_PERCENT: + case NUMBERFORMAT_CURRENCY: + case NUMBERFORMAT_SCIENTIFIC: + case NUMBERFORMAT_FRACTION: +// case NUMBERFORMAT_LOGICAL: + case NUMBERFORMAT_DEFINED: + return TRUE; + default: + return FALSE; + } + } + break; + case NUMBERFORMAT_DATE: + { + switch (eOldType) + { + case NUMBERFORMAT_DATETIME: + return TRUE; + default: + return FALSE; + } + } + break; + case NUMBERFORMAT_TIME: + { + switch (eOldType) + { + case NUMBERFORMAT_DATETIME: + return TRUE; + default: + return FALSE; + } + } + break; + case NUMBERFORMAT_DATETIME: + { + switch (eOldType) + { + case NUMBERFORMAT_TIME: + case NUMBERFORMAT_DATE: + return TRUE; + default: + return FALSE; + } + } + break; + default: + return FALSE; + } + return FALSE; + } +} + +ULONG SvNumberFormatter::GetStandardFormat( short eType, LanguageType eLnge ) +{ + ULONG CLOffset = ImpGenerateCL(eLnge); + switch(eType) + { + case NUMBERFORMAT_DATE : return CLOffset + ZF_STANDARD_DATE; + case NUMBERFORMAT_TIME : return CLOffset + ZF_STANDARD_TIME+1; + case NUMBERFORMAT_DATETIME : return CLOffset + ZF_STANDARD_DATETIME; + case NUMBERFORMAT_CURRENCY : + { + if ( eLnge == LANGUAGE_SYSTEM ) + return ImpGetDefaultSystemCurrencyFormat(); + else + return CLOffset + ZF_STANDARD_CURRENCY+3; + } + case NUMBERFORMAT_PERCENT : return CLOffset + ZF_STANDARD_PERCENT+1; + case NUMBERFORMAT_SCIENTIFIC: return CLOffset + ZF_STANDARD_SCIENTIFIC; + case NUMBERFORMAT_FRACTION : return CLOffset + ZF_STANDARD_FRACTION; + case NUMBERFORMAT_LOGICAL : return CLOffset + ZF_STANDARD_LOGICAL; + case NUMBERFORMAT_TEXT : return CLOffset + ZF_STANDARD_TEXT; + case NUMBERFORMAT_ALL : + case NUMBERFORMAT_DEFINED : + case NUMBERFORMAT_NUMBER : + case NUMBERFORMAT_UNDEFINED : + default : return CLOffset + ZF_STANDARD; + } +} + +BOOL SvNumberFormatter::IsSpecialStandardFormat( ULONG nFIndex, + LanguageType eLnge ) +{ + return + nFIndex == GetFormatIndex( NF_TIME_MMSS00, eLnge ) || + nFIndex == GetFormatIndex( NF_TIME_HH_MMSS00, eLnge ) || + nFIndex == GetFormatIndex( NF_TIME_HH_MMSS, eLnge ) + ; +} + +ULONG SvNumberFormatter::GetStandardFormat( ULONG nFIndex, short eType, + LanguageType eLnge ) +{ + if ( IsSpecialStandardFormat( nFIndex, eLnge ) ) + return nFIndex; + else + return GetStandardFormat( eType, eLnge ); +} + +ULONG SvNumberFormatter::GetStandardFormat( double fNumber, ULONG nFIndex, + short eType, LanguageType eLnge ) +{ + if ( IsSpecialStandardFormat( nFIndex, eLnge ) ) + return nFIndex; + + switch( eType ) + { + case NUMBERFORMAT_TIME : + { + BOOL bSign; + if ( fNumber < 0.0 ) + { + bSign = TRUE; + fNumber = -fNumber; + } + else + bSign = FALSE; + double fSeconds = fNumber * 86400; + if ( floor( fSeconds + 0.5 ) * 100 != floor( fSeconds * 100 + 0.5 ) ) + { // mit 100stel Sekunden + if ( bSign || fSeconds >= 3600 ) + return GetFormatIndex( NF_TIME_HH_MMSS00, eLnge ); + else + return GetFormatIndex( NF_TIME_MMSS00, eLnge ); + } + else + { + if ( bSign || fNumber >= 1.0 ) + return GetFormatIndex( NF_TIME_HH_MMSS, eLnge ); + else + return GetStandardFormat( eType, eLnge ); + } + } + break; + default: + return GetStandardFormat( eType, eLnge ); + } +} + +void SvNumberFormatter::GetInputLineString(const double& fOutNumber, + ULONG nFIndex, + XubString& sOutString) +{ + SvNumberformat* pFormat; + short nOldPrec; + Color* pColor; + pFormat = (SvNumberformat*) aFTable.Get(nFIndex); + if (!pFormat) + pFormat = aFTable.Get(ZF_STANDARD); + LanguageType eLang = pFormat->GetLanguage(); + ChangeIntl( eLang ); + short eType = pFormat->GetType() & ~NUMBERFORMAT_DEFINED; + if (eType == 0) + eType = NUMBERFORMAT_DEFINED; + nOldPrec = -1; + if (eType == NUMBERFORMAT_NUMBER || eType == NUMBERFORMAT_PERCENT + || eType == NUMBERFORMAT_CURRENCY + || eType == NUMBERFORMAT_SCIENTIFIC + || eType == NUMBERFORMAT_FRACTION) + { + if (eType != NUMBERFORMAT_PERCENT) // spaeter Sonderbehandlung % + eType = NUMBERFORMAT_NUMBER; + nOldPrec = pFormatScanner->GetStandardPrec(); + ChangeStandardPrec(300); // Merkwert + } + ULONG nKey = nFIndex; + switch ( eType ) + { // #61619# immer vierstelliges Jahr editieren + case NUMBERFORMAT_DATE : + nKey = GetFormatIndex( NF_DATE_SYS_DDMMYYYY, eLang ); + break; + case NUMBERFORMAT_DATETIME : + nKey = GetFormatIndex( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, eLang ); + break; + default: + nKey = GetStandardFormat( fOutNumber, nFIndex, eType, eLang ); + } + if ( nKey != nFIndex ) + pFormat = (SvNumberformat*) aFTable.Get( nKey ); + if (pFormat) + { + if ( eType == NUMBERFORMAT_TIME && pFormat->GetFormatPrecision() ) + { + nOldPrec = pFormatScanner->GetStandardPrec(); + ChangeStandardPrec(300); // Merkwert + } + pFormat->GetOutputString(fOutNumber, sOutString, &pColor); + } + if (nOldPrec != -1) + ChangeStandardPrec(nOldPrec); +} + +void SvNumberFormatter::GetOutputString(const double& fOutNumber, + ULONG nFIndex, + XubString& sOutString, + Color** ppColor) +{ + if (bNoZero && fOutNumber == 0.0) + { + sOutString.Erase(); + return; + } + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(nFIndex); + if (!pFormat) + pFormat = aFTable.Get(ZF_STANDARD); + ChangeIntl(pFormat->GetLanguage()); + pFormat->GetOutputString(fOutNumber, sOutString, ppColor); +} + +void SvNumberFormatter::GetOutputString(XubString& sString, + ULONG nFIndex, + XubString& sOutString, + Color** ppColor) +{ + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(nFIndex); + if (!pFormat) + pFormat = aFTable.Get(ZF_STANDARD_TEXT); + if (!pFormat->IsTextFormat() && !pFormat->HasTextFormat()) + { + *ppColor = NULL; + sOutString = sString; + } + else + { + ChangeIntl(pFormat->GetLanguage()); + pFormat->GetOutputString(sString, sOutString, ppColor); + } +} + +BOOL SvNumberFormatter::GetPreviewString(const XubString& sFormatString, + double fPreviewNumber, + XubString& sOutString, + Color** ppColor, + LanguageType eLnge) +{ + if (sFormatString.Len() == 0) // keinen Leerstring + return FALSE; + + xub_StrLen nCheckPos; + ULONG nKey; + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = SysLnge; + ChangeIntl(eLnge); // ggfs. austauschen + eLnge = ActLnge; + XubString sTmpString = sFormatString; + SvNumberformat* p_Entry = new SvNumberformat(sTmpString, + pFormatScanner, + pStringScanner, + nCheckPos, + eLnge); + if (nCheckPos == 0) // String ok + { + ULONG CLOffset = ImpGenerateCL(eLnge); // ggfs. neu Standard- + // formate anlegen + nKey = ImpIsEntry(p_Entry->GetFormatstring(),CLOffset, eLnge); + if (nKey != NUMBERFORMAT_ENTRY_NOT_FOUND) // schon vorhanden + GetOutputString(fPreviewNumber,nKey,sOutString,ppColor); + else + p_Entry->GetOutputString(fPreviewNumber,sOutString, ppColor); + delete p_Entry; + return TRUE; + } + else + { + delete p_Entry; + return FALSE; + } +} + +BOOL SvNumberFormatter::GetPreviewStringGuess( const XubString& sFormatString, + double fPreviewNumber, + XubString& sOutString, + Color** ppColor, + LanguageType eLnge ) +{ + if (sFormatString.Len() == 0) // keinen Leerstring + return FALSE; + + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = SysLnge; + + ChangeIntl( eLnge ); + eLnge = ActLnge; + BOOL bEnglish = (eLnge == LANGUAGE_ENGLISH_US); + + String aFormatStringUpper( pCharClass->upper( sFormatString ) ); + ULONG nCLOffset = ImpGenerateCL( eLnge ); + ULONG nKey = ImpIsEntry( aFormatStringUpper, nCLOffset, eLnge ); + if ( nKey != NUMBERFORMAT_ENTRY_NOT_FOUND ) + { // Zielformat vorhanden + GetOutputString( fPreviewNumber, nKey, sOutString, ppColor ); + return TRUE; + } + + SvNumberformat *pEntry = NULL; + xub_StrLen nCheckPos; + XubString sTmpString; + + if ( bEnglish ) + { + sTmpString = sFormatString; + pEntry = new SvNumberformat( sTmpString, pFormatScanner, + pStringScanner, nCheckPos, eLnge ); + } + else + { + nCLOffset = ImpGenerateCL( LANGUAGE_ENGLISH_US ); + nKey = ImpIsEntry( aFormatStringUpper, nCLOffset, LANGUAGE_ENGLISH_US ); + BOOL bEnglishFormat = (nKey != NUMBERFORMAT_ENTRY_NOT_FOUND); + + // try english --> other bzw. english nach other konvertieren + LanguageType eFormatLang = LANGUAGE_ENGLISH_US; + pFormatScanner->SetConvertMode( LANGUAGE_ENGLISH_US, eLnge ); + sTmpString = sFormatString; + pEntry = new SvNumberformat( sTmpString, pFormatScanner, + pStringScanner, nCheckPos, eFormatLang ); + pFormatScanner->SetConvertMode( FALSE ); + ChangeIntl( eLnge ); + + if ( !bEnglishFormat ) + { + if ( nCheckPos > 0 || pIntl->CompareEqual( sFormatString, + pEntry->GetFormatstring(), INTN_COMPARE_IGNORECASE ) ) + { // other Format + delete pEntry; + sTmpString = sFormatString; + pEntry = new SvNumberformat( sTmpString, pFormatScanner, + pStringScanner, nCheckPos, eLnge ); + } + else + { // verify english + xub_StrLen nCheckPos2; + // try other --> english + eFormatLang = eLnge; + pFormatScanner->SetConvertMode( eLnge, LANGUAGE_ENGLISH_US ); + sTmpString = sFormatString; + SvNumberformat* pEntry2 = new SvNumberformat( sTmpString, pFormatScanner, + pStringScanner, nCheckPos2, eFormatLang ); + pFormatScanner->SetConvertMode( FALSE ); + ChangeIntl( eLnge ); + if ( nCheckPos2 == 0 && !pIntl->CompareEqual( sFormatString, + pEntry2->GetFormatstring(), INTN_COMPARE_IGNORECASE ) ) + { // other Format + delete pEntry; + sTmpString = sFormatString; + pEntry = new SvNumberformat( sTmpString, pFormatScanner, + pStringScanner, nCheckPos, eLnge ); + } + delete pEntry2; + } + } + } + + if (nCheckPos == 0) // String ok + { + ImpGenerateCL( eLnge ); // ggfs. neu Standardformate anlegen + pEntry->GetOutputString( fPreviewNumber, sOutString, ppColor ); + delete pEntry; + return TRUE; + } + delete pEntry; + return FALSE; +} + +ULONG SvNumberFormatter::TestNewString(const XubString& sFormatString, + LanguageType eLnge) +{ + if (sFormatString.Len() == 0) // keinen Leerstring + return NUMBERFORMAT_ENTRY_NOT_FOUND; + + xub_StrLen nCheckPos; + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = SysLnge; + ChangeIntl(eLnge); // ggfs. austauschen + eLnge = ActLnge; + ULONG nRes; + BOOL bCheck = FALSE; + XubString sTmpString = sFormatString; + SvNumberformat* pEntry = new SvNumberformat(sTmpString, + pFormatScanner, + pStringScanner, + nCheckPos, + eLnge); + if (nCheckPos == 0) // String ok + { + ULONG CLOffset = ImpGenerateCL(eLnge); // ggfs. neu Standard- + // formate anlegen + nRes = ImpIsEntry(pEntry->GetFormatstring(),CLOffset, eLnge); + // schon vorhanden ? + } + else + nRes = NUMBERFORMAT_ENTRY_NOT_FOUND; + delete pEntry; + return nRes; +} + +SvNumberformat* SvNumberFormatter::ImpInsertFormat(XubString& sStr, + BOOL bStandard, + ULONG nPos) +{ + xub_StrLen nCheckPos = 0; + SvNumberformat* pFormat = new SvNumberformat(sStr, + pFormatScanner, + pStringScanner, + nCheckPos, + ActLnge); + if (!pFormat || nCheckPos > 0) + { + DBG_ERROR + ("SvNumberFormatter:: Unbekanntes oder falsches Zahlformat"); + delete pFormat; + return NULL;; + } + if (bStandard) + pFormat->SetStandard(); + if (!aFTable.Insert(nPos, pFormat)) + { + delete pFormat; + return NULL; + } + return pFormat; +} + +SvNumberformat* SvNumberFormatter::ImpInsertNewStandardFormat( XubString& sStr, + ULONG nPos, USHORT nVersion ) +{ + SvNumberformat* pNewFormat = ImpInsertFormat( sStr, FALSE, nPos ); + if (pNewFormat) + pNewFormat->SetNewStandardDefined( nVersion ); + // damit es gespeichert, richtig angezeigt und von alten Versionen konvertiert wird +#ifndef PRODUCT + else + { + ByteString aErr( "New standard format not inserted: " ); + aErr += ByteString( sStr, RTL_TEXTENCODING_UTF8 ); + DBG_ERRORFILE( aErr.GetBuffer() ); + } +#endif + return pNewFormat; +} + +void SvNumberFormatter::GetFormatSpecialInfo(ULONG nFormat, + BOOL& bThousand, + BOOL& IsRed, + USHORT& nPrecision, + USHORT& nAnzLeading) + +{ + SvNumberformat* pFormat = aFTable.Get(nFormat); + if (pFormat) + pFormat->GetFormatSpecialInfo(bThousand, IsRed, + nPrecision, nAnzLeading); + else + { + bThousand = FALSE; + IsRed = FALSE; + nPrecision = pFormatScanner->GetStandardPrec(); + nAnzLeading = 0; + } +} + +USHORT SvNumberFormatter::GetFormatPrecision( ULONG nFormat ) const +{ + SvNumberformat* pFormat = aFTable.Get( nFormat ); + if ( pFormat ) + return pFormat->GetFormatPrecision(); + else + return pFormatScanner->GetStandardPrec(); +} + + +ULONG SvNumberFormatter::GetFormatSpecialInfo( const XubString& rFormatString, + BOOL& bThousand, BOOL& IsRed, USHORT& nPrecision, + USHORT& nAnzLeading, LanguageType eLnge ) + +{ + xub_StrLen nCheckPos = 0; + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = SysLnge; + ChangeIntl(eLnge); // ggfs. austauschen + eLnge = ActLnge; + XubString aTmpStr( rFormatString ); + SvNumberformat* pFormat = new SvNumberformat( aTmpStr, + pFormatScanner, pStringScanner, nCheckPos, eLnge ); + if ( nCheckPos == 0 ) + pFormat->GetFormatSpecialInfo( bThousand, IsRed, nPrecision, nAnzLeading ); + else + { + bThousand = FALSE; + IsRed = FALSE; + nPrecision = pFormatScanner->GetStandardPrec(); + nAnzLeading = 0; + } + delete pFormat; + return nCheckPos; +} + + +inline ULONG SetIndexTable( NfIndexTableOffset nTabOff, ULONG nIndOff ) +{ + if ( !bIndexTableInitialized ) + { + DBG_ASSERT( theIndexTable[nTabOff] == NUMBERFORMAT_ENTRY_NOT_FOUND, + "SetIndexTable: theIndexTable[nTabOff] bereits belegt" ); + theIndexTable[nTabOff] = nIndOff; + } + return nIndOff; +} + + +void SvNumberFormatter::ImpGenerateFormats(ULONG CLOffset) +{ + if ( !bIndexTableInitialized ) + { + for ( USHORT j=0; j<NF_INDEX_TABLE_ENTRIES; j++ ) + { + theIndexTable[j] = NUMBERFORMAT_ENTRY_NOT_FOUND; + } + } + BOOL bOldConvertMode = pFormatScanner->GetConvertMode(); + if (bOldConvertMode) // fuer diese Funktion + pFormatScanner->SetConvertMode(FALSE); // ausschalten + xub_StrLen nCheckPos = 0; // Eintrag fuer Standard, Text + // und logisch direkt erzeugen + SvNumberformat* pNewFormat = NULL; + XubString aSystem( RTL_CONSTASCII_USTRINGPARAM( "System" ) ); // Kommentar + XubString aDefSystem( RTL_CONSTASCII_USTRINGPARAM( "def/System" ) ); // Kommentar + // Zaehler fuer zusaetzliche Standardformate, die nicht in die ersten 10 + // einer Kategorie passen, insgesamt nochmal ca. 20 + // Bei jedem ImpInsertNewStandardformat hochzaehlen, neue Formate + // hinten anhaengen, nicht einfuegen! + USHORT nNewExtended = ZF_STANDARD_NEWEXTENDED; + + SvNumberformat* pStandard = new SvNumberformat( + pFormatScanner->GetStandardName(), + pFormatScanner, pStringScanner, + nCheckPos, ActLnge); + pStandard->SetType(NUMBERFORMAT_NUMBER); + pStandard->SetStandard(); + if ( !aFTable.Insert( + CLOffset + SetIndexTable( NF_NUMBER_STANDARD, ZF_STANDARD ), + pStandard)) + delete pStandard; + else + pStandard->SetLastInsertKey(SV_MAX_ANZ_STANDARD_FORMATE); + SvNumberformat* pLogical = new SvNumberformat( + pFormatScanner->GetBooleanString(), + pFormatScanner, pStringScanner, + nCheckPos, ActLnge); + pLogical->SetType(NUMBERFORMAT_LOGICAL); + pLogical->SetStandard(); + if ( !aFTable.Insert( + CLOffset + SetIndexTable( NF_BOOLEAN, ZF_STANDARD_LOGICAL ), + pLogical)) + delete pLogical; + + XubString aWSString = '@'; + SvNumberformat* pText = new SvNumberformat(aWSString, + pFormatScanner, pStringScanner, + nCheckPos, ActLnge); + pText->SetType(NUMBERFORMAT_TEXT); + pText->SetStandard(); + if ( !aFTable.Insert( + CLOffset + SetIndexTable( NF_TEXT, ZF_STANDARD_TEXT ), + pText)) + delete pText; + + xub_Unicode cDecSep = pIntl->GetNumDecimalSep(); + xub_Unicode cThousandSep = pIntl->GetNumThousandSep(); + // Zahl: + XubString s0 = '0'; // 0 + ImpInsertFormat(s0,FALSE, + CLOffset + SetIndexTable( NF_NUMBER_INT, ZF_STANDARD+1 )); + XubString s1( RTL_CONSTASCII_USTRINGPARAM( "000" ) ); // 0,00 + s1.Insert(cDecSep,1); + ImpInsertFormat(s1,FALSE, + CLOffset + SetIndexTable( NF_NUMBER_DEC2, ZF_STANDARD+2 )); + XubString s2( RTL_CONSTASCII_USTRINGPARAM( "###0" ) ); // #.##0 + s2.Insert(cThousandSep,1); + ImpInsertFormat(s2,FALSE, + CLOffset + SetIndexTable( NF_NUMBER_1000INT, ZF_STANDARD+3 )); + XubString s3( RTL_CONSTASCII_USTRINGPARAM( "###000" ) ); // #.##0,00 + s3.Insert(cThousandSep,1); + s3.Insert(cDecSep,5); + ImpInsertFormat(s3,FALSE, + CLOffset + SetIndexTable( NF_NUMBER_1000DEC2, ZF_STANDARD+4 )); + // ab Version 6 + XubString sNumSystem; // #.##0,00 System + if ( pIntl->IsNumLeadingZero() ) + sNumSystem = '0'; + if ( pIntl->IsNumThousandSep() ) + { + if ( pIntl->IsNumLeadingZero() ) + sNumSystem.Insert( XubString::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "###" ) ), 0 ); + else + sNumSystem.Insert( XubString::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "####" ) ), 0 ); + sNumSystem.Insert( cThousandSep, 1 ); + } + USHORT nNumDigits = pIntl->GetNumDigits(); + if ( nNumDigits ) + { + sNumSystem += cDecSep; + for ( USHORT j=0; j<nNumDigits; j++ ) + { + sNumSystem += '0'; + } + } + pNewFormat = ImpInsertNewStandardFormat( sNumSystem, + CLOffset + SetIndexTable( NF_NUMBER_SYSTEM, ZF_STANDARD+5 ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aSystem ); + + // Prozent: + XubString s4( RTL_CONSTASCII_USTRINGPARAM( "0%" ) ); // 0% + ImpInsertFormat(s4,FALSE, + CLOffset + SetIndexTable( NF_PERCENT_INT, ZF_STANDARD_PERCENT )); + XubString s5( RTL_CONSTASCII_USTRINGPARAM( "000%" ) ); // 0,00% + s5.Insert(cDecSep,1); + ImpInsertFormat(s5,TRUE, + CLOffset + SetIndexTable( NF_PERCENT_DEC2, ZF_STANDARD_PERCENT+1 )); + + // Waehrung: (keine Standardoption also kein TRUE bei ImpInsertFormat) + + XubString aRed( '[' ); + aRed += pFormatScanner->GetRedString(); + aRed += ']'; + + XubString sCurrFlat1( RTL_CONSTASCII_USTRINGPARAM( "###0" ) ); // #.##0 DM + sCurrFlat1.Insert(cThousandSep,1); + XubString sCurrFlat2( sCurrFlat1 ); // #.##0,00 DM + XubString sCurrFlat3( sCurrFlat1 ); // #.##0,-- DM + // Anzahl Nachkommastellen in Waehrung + USHORT nCurrDigits = pIntl->GetCurrDigits(); + if ( nCurrDigits ) + { + sCurrFlat2 += cDecSep; + sCurrFlat3 += cDecSep; + sCurrFlat2.Expand( sCurrFlat2.Len() + nCurrDigits, '0' ); + sCurrFlat3.Expand( sCurrFlat3.Len() + nCurrDigits, '-' ); + } + + XubString s6 = sCurrFlat1; // #.##0 DM + ImpGetPosCurrFormat(s6); + XubString s7 = sCurrFlat2; // #.##0,00 DM + ImpGetPosCurrFormat(s7); + XubString sDash = sCurrFlat3; // #.##0,-- DM + ImpGetPosCurrFormat(sDash); + XubString sNegStr1 = sCurrFlat1; // -#.##0 DM + ImpGetNegCurrFormat(sNegStr1); + XubString sNegStr2 = sCurrFlat2; // -#.##0,00 DM + ImpGetNegCurrFormat(sNegStr2); + XubString sNegStr3 = sCurrFlat3; // -#.##0,-- DM + ImpGetNegCurrFormat(sNegStr3); + s6 += ';'; + XubString s8 = s6; + s6 += sNegStr1; + s8 += aRed; + s8 += sNegStr1; + s7 += ';'; + XubString s9 = s7; + s7 += sNegStr2; + s9 += aRed; + s9 += sNegStr2; + sDash += ';'; + XubString sDashed = sDash; + sDash += sNegStr3; + sDashed += aRed; + sDashed += sNegStr3; + ImpInsertFormat(s6,FALSE, + CLOffset + SetIndexTable( NF_CURRENCY_1000INT, ZF_STANDARD_CURRENCY )); + ImpInsertFormat(s7,FALSE, + CLOffset + SetIndexTable( NF_CURRENCY_1000DEC2, ZF_STANDARD_CURRENCY+1 )); + // Muss immer 1 hinter + // Standard sein + // fuer Funktion DM()!! + ImpInsertFormat(s8,FALSE, + CLOffset + SetIndexTable( NF_CURRENCY_1000INT_RED, ZF_STANDARD_CURRENCY+2 )); + ImpInsertFormat(s9,FALSE, + CLOffset + SetIndexTable( NF_CURRENCY_1000DEC2_RED, ZF_STANDARD_CURRENCY+3 )); + + // ab Version 3 dazu + XubString s28 = sCurrFlat2; // #.##0,00 DEM +#if NF_BANKSYMBOL_FIX_POSITION + s28.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " CCC" ) ); +#else + XubString s28n( sCurrFlat2 ), aCCC( RTL_CONSTASCII_USTRINGPARAM( "CCC" ) ); + USHORT nPosiForm = NfCurrencyEntry::GetEffectivePositiveFormat( + pIntl->GetCurrPositiveFormat(), pIntl->GetCurrPositiveFormat(), TRUE ); + USHORT nNegaForm = NfCurrencyEntry::GetEffectiveNegativeFormat( + pIntl->GetCurrNegativeFormat(), pIntl->GetCurrNegativeFormat(), TRUE ); + NfCurrencyEntry::CompletePositiveFormatString( s28, aCCC, nPosiForm ); + NfCurrencyEntry::CompleteNegativeFormatString( s28n, aCCC, nNegaForm ); + s28 += ';'; + s28 += s28n; +#endif + pNewFormat = ImpInsertFormat(s28,FALSE, + CLOffset + SetIndexTable( NF_CURRENCY_1000DEC2_CCC, ZF_STANDARD_CURRENCY+4 )); + if ( pNewFormat ) + pNewFormat->SetUsed(TRUE); // damit es gespeichert wird + + // ab Version 6 dazu: #.##0,-- DM + ImpInsertNewStandardFormat( sDashed, + CLOffset + SetIndexTable( NF_CURRENCY_1000DEC2_DASHED, ZF_STANDARD_CURRENCY+5 ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + +#if 0 // erDEBUG + { // ab SV_NUMBERFORMATTER_VERSION_NEW_CURR EURo und letztes Format testen + NfWSStringsDtor aArr; + USHORT j, nDefault; + const NfCurrencyTable& rTable = GetTheCurrencyTable(); + const NfCurrencyEntry* pCurr = rTable.GetObject( nCurrencyTableEuroPosition ); + GetCurrencyFormatStrings( aArr, *pCurr, FALSE ); + GetCurrencyFormatStrings( aArr, *pCurr, TRUE ); + for ( j=0; j<aArr.Count(); j++ ) + { + ULONG nCheck, nKey; + short nType; + PutEntry( *aArr.GetObject(j), nCheck, nType, nKey, ActLnge ); + } + aArr.Remove( 0, aArr.Count() ); + pCurr = rTable.GetObject( rTable.Count()-1 ); +// GetCurrencyFormatStrings( aArr, *pCurr, FALSE ); + GetCurrencyFormatStrings( aArr, *pCurr, TRUE ); + for ( j=0; j<aArr.Count(); j++ ) + { + ULONG nCheck, nKey; + short nType; + PutEntry( *aArr.GetObject(j), nCheck, nType, nKey, ActLnge ); + } + } +#endif + + // Datum: + XubString s10; + ImpGetDateFormat(s10); // TT.MM.JJ kurzes Systemdatum + pNewFormat = ImpInsertFormat(s10,TRUE, + CLOffset + SetIndexTable( NF_DATE_SYSTEM_SHORT, ZF_STANDARD_DATE )); + if ( pNewFormat ) + pNewFormat->SetComment( aSystem ); + + const XubString* pKeyword = pFormatScanner->GetKeyword(); + xub_Unicode cDateSep = pIntl->GetDateSep(); + xub_Unicode cTimeSep = pIntl->GetTimeSep(); + + XubString s11 = pKeyword[NF_KEY_NN]; // NN TT.MMM JJ + s11 += ' '; + s11 += pKeyword[NF_KEY_TT]; + s11 += cDateSep; + s11 += pKeyword[NF_KEY_MMM]; + s11 += ' '; + s11 += pKeyword[NF_KEY_JJ]; + ImpInsertFormat(s11,FALSE, + CLOffset + SetIndexTable( NF_DATE_DEF_NNDDMMMYY, ZF_STANDARD_DATE+1 )); + + XubString s12; // MM.JJ + XubString s13; // TT.MMM + XubString sFullDate; // TT.MM.JJJJ + XubString sDDMMYY; // TT.MM.JJ + switch(pIntl->GetDateFormat()) + { + case DMY: + { + s12 = pKeyword[NF_KEY_MM]; // MM.JJ + s12 += cDateSep; + s12 += pKeyword[NF_KEY_JJ]; + s13 = pKeyword[NF_KEY_TT]; // TT.MMM + s13 += cDateSep; + s13 += pKeyword[NF_KEY_MMM]; + sFullDate = pKeyword[NF_KEY_TT]; // TT + sFullDate += cDateSep; + sFullDate += pKeyword[NF_KEY_MM]; // MM + sFullDate += cDateSep; + sDDMMYY = sFullDate; + sFullDate += pKeyword[NF_KEY_JJJJ]; // JJJJ + sDDMMYY += pKeyword[NF_KEY_JJ]; // JJ + } + break; + case YMD: + { + s12 = pKeyword[NF_KEY_JJ]; // JJ.MM + s12 += cDateSep; + s12 += pKeyword[NF_KEY_MM]; + s13 = pKeyword[NF_KEY_MMM]; // MMM TT + s13 += ' '; + s13 += pKeyword[NF_KEY_TT]; + sFullDate = pKeyword[NF_KEY_JJJJ]; // JJJJ + sDDMMYY = pKeyword[NF_KEY_JJ]; // JJ + XubString aTmp( cDateSep ); + aTmp += pKeyword[NF_KEY_MM]; // MM + aTmp += cDateSep; + aTmp += pKeyword[NF_KEY_TT]; // TT + sFullDate += aTmp; + sDDMMYY += aTmp; + + } + break; + case MDY: + default: + { + s12 = pKeyword[NF_KEY_MM]; // MM.JJ + s12 += cDateSep; + s12 += pKeyword[NF_KEY_JJ]; + s13 = pKeyword[NF_KEY_MMM]; // MMM TT + s13 += ' '; + s13 += pKeyword[NF_KEY_TT]; + sFullDate = pKeyword[NF_KEY_MM]; // MM + sFullDate += cDateSep; + sFullDate += pKeyword[NF_KEY_TT]; // TT + sFullDate += cDateSep; + sDDMMYY = sFullDate; + sFullDate += pKeyword[NF_KEY_JJJJ]; // JJJJ + sDDMMYY += pKeyword[NF_KEY_JJ]; // JJ + } + break; + } + pNewFormat = ImpInsertFormat(s12,FALSE, + CLOffset + SetIndexTable( NF_DATE_SYS_MMYY, ZF_STANDARD_DATE+2 )); + if ( pNewFormat ) + pNewFormat->SetComment( aDefSystem ); + + ImpInsertFormat(s13,FALSE, + CLOffset + SetIndexTable( NF_DATE_SYS_DDMMM, ZF_STANDARD_DATE+3 )); + + XubString s14 = pKeyword[NF_KEY_MMMM]; // MMMM + ImpInsertFormat(s14,FALSE, + CLOffset + SetIndexTable( NF_DATE_MMMM, ZF_STANDARD_DATE+4 )); + + XubString s15 = pKeyword[NF_KEY_QQ]; // QQ JJ + s15 += ' '; + s15 += pKeyword[NF_KEY_JJ]; + ImpInsertFormat(s15,FALSE, + CLOffset + SetIndexTable( NF_DATE_QQJJ, ZF_STANDARD_DATE+5 )); + + // ab Version 2 dazu, war TT.MM.[JJ]JJ jetzt (v6) TT.MM.JJJJ + pNewFormat = ImpInsertFormat(sFullDate,FALSE, + CLOffset + SetIndexTable( NF_DATE_SYS_DDMMYYYY, ZF_STANDARD_DATE+6 )); + if ( pNewFormat ) + { + pNewFormat->SetUsed(TRUE); // damit es gespeichert wird + pNewFormat->SetComment( aDefSystem ); + } + + // ab Version 6 dazu + pNewFormat = ImpInsertNewStandardFormat( sDDMMYY, + CLOffset + SetIndexTable( NF_DATE_SYS_DDMMYY, ZF_STANDARD_DATE+7 ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aDefSystem ); + // lange Wochentage: statt "NNN, " steht "NNNN" Code wg. Kompatibilitaet + // langes Systemdatum wie eingestellt + XubString sLongDate; + ImpGetLongDateFormat( sLongDate ); // NNN, T. MMMM JJJJ System + pNewFormat = ImpInsertNewStandardFormat( sLongDate, + CLOffset + SetIndexTable( NF_DATE_SYSTEM_LONG, ZF_STANDARD_DATE+8 ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aSystem ); + // harte aber systemabhaengige lange Datumformate + sLongDate.Erase(); + ImpGetLongDateFormat( sLongDate, -1, 1, 1, 1 ); // T. MMM JJ def/System + pNewFormat = ImpInsertNewStandardFormat( sLongDate, + CLOffset + SetIndexTable( NF_DATE_SYS_DMMMYY, ZF_STANDARD_DATE+9 ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aDefSystem ); + //! leider hat das Templin'sche Erbe nur 10 Standardformate pro Kategorie + //! vorgesehen, weitere wuerden ZF_STANDARD_TIME ueberschreiben :-(( + sLongDate.Erase(); + ImpGetLongDateFormat( sLongDate, -1, 1, 1, 2 ); // T. MMM JJJJ def/System + pNewFormat = ImpInsertNewStandardFormat( sLongDate, + CLOffset + SetIndexTable( NF_DATE_SYS_DMMMYYYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aDefSystem ); + sLongDate.Erase(); + ImpGetLongDateFormat( sLongDate, -1, 1, 2, 2 ); // T. MMMM JJJJ def/System + pNewFormat = ImpInsertNewStandardFormat( sLongDate, + CLOffset + SetIndexTable( NF_DATE_SYS_DMMMMYYYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aDefSystem ); + sLongDate.Erase(); + ImpGetLongDateFormat( sLongDate, 1, 1, 1, 1 ); // NN, T. MMM JJ def/System + pNewFormat = ImpInsertNewStandardFormat( sLongDate, + CLOffset + SetIndexTable( NF_DATE_SYS_NNDMMMYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aDefSystem ); + sLongDate.Erase(); + ImpGetLongDateFormat( sLongDate, 1, 1, 2, 2 ); // NN, T. MMMM JJJJ def/System + pNewFormat = ImpInsertNewStandardFormat( sLongDate, + CLOffset + SetIndexTable( NF_DATE_SYS_NNDMMMMYYYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aDefSystem ); + sLongDate.Erase(); + ImpGetLongDateFormat( sLongDate, 2, 1, 2, 2 ); // NNN, T. MMMM JJJJ def/System + pNewFormat = ImpInsertNewStandardFormat( sLongDate, + CLOffset + SetIndexTable( NF_DATE_SYS_NNNNDMMMMYYYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aDefSystem ); + + XubString aDIN( RTL_CONSTASCII_USTRINGPARAM( "DIN 5008 (EN 28601)" ) ); + XubString sDinTMMMJJJJ; // DIN: T. MMM. JJJJ + sDinTMMMJJJJ += pKeyword[NF_KEY_T]; + sDinTMMMJJJJ += '.'; + sDinTMMMJJJJ += ' '; + sDinTMMMJJJJ += pKeyword[NF_KEY_MMM]; + sDinTMMMJJJJ += '.'; + sDinTMMMJJJJ += ' '; + sDinTMMMJJJJ += pKeyword[NF_KEY_JJJJ]; + pNewFormat = ImpInsertNewStandardFormat( sDinTMMMJJJJ, + CLOffset + SetIndexTable( NF_DATE_DIN_DMMMYYYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aDIN ); + + XubString sDinTMMMMJJJJ; // DIN: T. MMMM JJJJ + sDinTMMMMJJJJ += pKeyword[NF_KEY_T]; + sDinTMMMMJJJJ += '.'; + sDinTMMMMJJJJ += ' '; + sDinTMMMMJJJJ += pKeyword[NF_KEY_MMMM]; + sDinTMMMMJJJJ += ' '; + sDinTMMMMJJJJ += pKeyword[NF_KEY_JJJJ]; + pNewFormat = ImpInsertNewStandardFormat( sDinTMMMMJJJJ, + CLOffset + SetIndexTable( NF_DATE_DIN_DMMMMYYYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aDIN ); + + XubString sDinMMTT; // DIN: MM-TT + sDinMMTT += pKeyword[NF_KEY_MM]; + sDinMMTT += '-'; + sDinMMTT += pKeyword[NF_KEY_TT]; + pNewFormat = ImpInsertNewStandardFormat( sDinMMTT, + CLOffset + SetIndexTable( NF_DATE_DIN_MMDD, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aDIN ); + + XubString sDinJJMMTT = sDinMMTT; // DIN: JJ-MM-TT + sDinJJMMTT.Insert( '-', 0 ); + sDinJJMMTT.Insert( pKeyword[NF_KEY_JJ], 0 ); + pNewFormat = ImpInsertNewStandardFormat( sDinJJMMTT, + CLOffset + SetIndexTable( NF_DATE_DIN_YYMMDD, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aDIN ); + + XubString sDinJJJJMMTT = sDinMMTT; // DIN: JJJJ-MM-TT + sDinJJJJMMTT.Insert( '-', 0 ); + sDinJJJJMMTT.Insert( pKeyword[NF_KEY_JJJJ], 0 ); + pNewFormat = ImpInsertNewStandardFormat( sDinJJJJMMTT, + CLOffset + SetIndexTable( NF_DATE_DIN_YYYYMMDD, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + if ( pNewFormat ) + pNewFormat->SetComment( aDIN ); + + // Uhrzeit: + XubString s16 = pKeyword[NF_KEY_HH]; // HH:MM + s16 += cTimeSep; + s16 += pKeyword[NF_KEY_MMI]; + ImpInsertFormat(s16,FALSE, + CLOffset + SetIndexTable( NF_TIME_HHMM, ZF_STANDARD_TIME )); + XubString sFullTime = s16; // HH:MM:SS + sFullTime += cTimeSep; + sFullTime += pKeyword[NF_KEY_SS]; + ImpInsertFormat(sFullTime,TRUE, + CLOffset + SetIndexTable( NF_TIME_HHMMSS, ZF_STANDARD_TIME+1 )); + XubString s18 = s16; // HH:MM AM/PM + s18 += ' '; + s18 += pKeyword[NF_KEY_AMPM]; + ImpInsertFormat(s18,FALSE, + CLOffset + SetIndexTable( NF_TIME_HHMMAMPM, ZF_STANDARD_TIME+2 )); + XubString s19 = sFullTime; // HH:MM:SS AM/PM + s19 += ' '; + s19 += pKeyword[NF_KEY_AMPM]; + ImpInsertFormat(s19,FALSE, + CLOffset + SetIndexTable( NF_TIME_HHMMSSAMPM, ZF_STANDARD_TIME+3 )); + XubString s20 = sFullTime; // [HH]:MM:SS + s20.Insert('[',0); + s20.Insert(']',3); + ImpInsertFormat(s20,FALSE, + CLOffset + SetIndexTable( NF_TIME_HH_MMSS, ZF_STANDARD_TIME+4 )); + XubString s21 = pKeyword[NF_KEY_MMI]; // MM:SS,00 + s21 += cTimeSep; + s21 += pKeyword[NF_KEY_SS]; + s21 += cDecSep; + s21 += '0'; + s21 += '0'; + ImpInsertFormat(s21,FALSE, + CLOffset + SetIndexTable( NF_TIME_MMSS00, ZF_STANDARD_TIME+5 )); + XubString s29 = s20; // [HH]:MM:SS,00 + s29 += cDecSep; + s29 += '0'; + s29 += '0'; + ImpInsertNewStandardFormat( s29, + CLOffset + SetIndexTable( NF_TIME_HH_MMSS00, ZF_STANDARD_TIME+6 ), + SV_NUMBERFORMATTER_VERSION_NF_TIME_HH_MMSS00 ); + + // Datum u. Uhrzeit: + XubString s22 = s10; // TT.MM.JJ HH:MM + s22 += ' '; + s22 += s16; + ImpInsertFormat(s22,TRUE, + CLOffset + SetIndexTable( NF_DATETIME_SYSTEM_SHORT_HHMM, ZF_STANDARD_DATETIME )); + XubString sFullDateTime = sFullDate; // TT.MM.JJJJ HH:MM:SS + sFullDateTime += ' '; + sFullDateTime += sFullTime; + ImpInsertNewStandardFormat( sFullDateTime, + CLOffset + SetIndexTable( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, ZF_STANDARD_DATETIME+1 ), + SV_NUMBERFORMATTER_VERSION_NF_DATETIME_SYS_DDMMYYYY_HHMMSS ); + + // Wissenschaft: + XubString s23( RTL_CONSTASCII_USTRINGPARAM( "000E+000" ) ); // 0,00E+000 + s23.Insert(cDecSep,1); + ImpInsertFormat(s23,TRUE, + CLOffset + SetIndexTable( NF_SCIENTIFIC_000E000, ZF_STANDARD_SCIENTIFIC )); + XubString s24( RTL_CONSTASCII_USTRINGPARAM( "000E+00" ) ); // 0,00E+00 + s24.Insert(cDecSep,1); + ImpInsertFormat(s24,FALSE, + CLOffset + SetIndexTable( NF_SCIENTIFIC_000E00, ZF_STANDARD_SCIENTIFIC+1 )); + + // Bruch: (keine Standardopt.) + XubString s25( RTL_CONSTASCII_USTRINGPARAM( "# ?/?" ) ); // # ?/? + ImpInsertFormat(s25,FALSE, + CLOffset + SetIndexTable( NF_FRACTION_1, ZF_STANDARD_FRACTION )); + // "??/" wird vom Compiler als Trigraph fuer '\' interpretiert! + XubString s26( RTL_CONSTASCII_USTRINGPARAM( "# ?\?/?\?" ) ); // # ??/?? + ImpInsertFormat(s26,FALSE, + CLOffset + SetIndexTable( NF_FRACTION_2, ZF_STANDARD_FRACTION+1 )); + + XubString sWeekOfYear( pKeyword[NF_KEY_WW] ); + pNewFormat = ImpInsertNewStandardFormat( sWeekOfYear, + CLOffset + SetIndexTable( NF_DATE_WW, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NF_DATE_WW ); + + bIndexTableInitialized = TRUE; + if (bOldConvertMode) // jetzt wieder + pFormatScanner->SetConvertMode(TRUE); // einschalten + DBG_ASSERT( nNewExtended <= ZF_STANDARD_NEWEXTENDEDMAX, + "Ueberlauf der nNewExtended Standardformate" ); +} + +void SvNumberFormatter::ImpGetDateFormat(XubString& sDateStr) +{ + const XubString* pKeyword = pFormatScanner->GetKeyword(); + xub_Unicode cDateSep = pIntl->GetDateSep(); + switch (pIntl->GetDateFormat()) + { + case MDY: + { + if (pIntl->IsDateMonthLeadingZero()) + sDateStr += pKeyword[NF_KEY_MM]; + else + sDateStr += pKeyword[NF_KEY_M]; + sDateStr += cDateSep; + if (pIntl->IsDateDayLeadingZero()) + sDateStr += pKeyword[NF_KEY_TT]; + else + sDateStr += pKeyword[NF_KEY_T]; + sDateStr += cDateSep; + if (pIntl->IsDateCentury()) + sDateStr += pKeyword[NF_KEY_JJJJ]; + else + sDateStr += pKeyword[NF_KEY_JJ]; + } + break; + case DMY: + { + if (pIntl->IsDateDayLeadingZero()) + sDateStr += pKeyword[NF_KEY_TT]; + else + sDateStr += pKeyword[NF_KEY_T]; + sDateStr += cDateSep; + if (pIntl->IsDateMonthLeadingZero()) + sDateStr += pKeyword[NF_KEY_MM]; + else + sDateStr += pKeyword[NF_KEY_M]; + sDateStr += cDateSep; + if (pIntl->IsDateCentury()) + sDateStr += pKeyword[NF_KEY_JJJJ]; + else + sDateStr += pKeyword[NF_KEY_JJ]; + } + break; + case YMD: + { + if (pIntl->IsDateCentury()) + sDateStr += pKeyword[NF_KEY_JJJJ]; + else + sDateStr += pKeyword[NF_KEY_JJ]; + sDateStr += cDateSep; + if (pIntl->IsDateMonthLeadingZero()) + sDateStr += pKeyword[NF_KEY_MM]; + else + sDateStr += pKeyword[NF_KEY_M]; + sDateStr += cDateSep; + if (pIntl->IsDateDayLeadingZero()) + sDateStr += pKeyword[NF_KEY_TT]; + else + sDateStr += pKeyword[NF_KEY_T]; + } + break; + default: + break; + } +} + + +void lcl_ImplAddStringMaybeQuoted( String& rDes, const String& rSrc, + CharClass* pChrCls ) +{ + BOOL bQuoted = FALSE; + const xub_StrLen nLen = rSrc.Len(); + xub_StrLen nPos = 0; + while ( nPos < nLen ) + { + if ( !bQuoted && pChrCls->isLetter( rSrc, nPos ) ) + { + rDes += '"'; + bQuoted = TRUE; + } + else if ( bQuoted && !pChrCls->isLetter( rSrc, nPos ) ) + { + rDes += '"'; + bQuoted = FALSE; + } + rDes += rSrc.GetChar( nPos++ ); + } + if ( bQuoted ) + rDes += '"'; +} + + +void SvNumberFormatter::ImpGetLongDateFormat( XubString& sDateStr, + short nShortLongDayOfWeek, + short nShortLongDay, + short nShortLongMonth, + short nShortLongYear ) +{ + const XubString* pKeyword = pFormatScanner->GetKeyword(); + switch ( nShortLongDayOfWeek ) + { + case -1 : + break; + case 0 : + switch ( pIntl->GetLongDateDayOfWeekFormat() ) + { + case DAYOFWEEK_NONE : + break; + case DAYOFWEEK_SHORT : + sDateStr += pKeyword[NF_KEY_NN]; + lcl_ImplAddStringMaybeQuoted( sDateStr, + pIntl->GetLongDateDayOfWeekSep(), pCharClass ); + break; + case DAYOFWEEK_LONG : + sDateStr += pKeyword[NF_KEY_NNNN]; + // NNNN ist leider bereits mit Separator, so wird es in + // aelteren Versionen, die noch kein NNN kennen, korrekt + // dargestellt, nur der Formatstring sieht krank aus.. + break; + default: + DBG_ERRORFILE( "unknown LongDateDayOfWeekFormat" ); + } + break; + case 1 : + sDateStr += pKeyword[NF_KEY_NN]; + lcl_ImplAddStringMaybeQuoted( sDateStr, + pIntl->GetLongDateDayOfWeekSep(), pCharClass ); + break; + case 2 : + sDateStr += pKeyword[NF_KEY_NNNN]; + break; + default: + DBG_ERRORFILE( "unknown nShortLongDayOfWeek" ); + } + switch (pIntl->GetLongDateFormat()) + { + case MDY: + { + switch ( nShortLongMonth ) + { + case -1 : + break; + case 0 : + switch ( pIntl->GetLongDateMonthFormat() ) + { + case MONTH_NORMAL : + sDateStr += pKeyword[NF_KEY_M]; + break; + case MONTH_ZERO : + sDateStr += pKeyword[NF_KEY_MM]; + break; + case MONTH_SHORT : + sDateStr += pKeyword[NF_KEY_MMM]; + break; + case MONTH_LONG : + sDateStr += pKeyword[NF_KEY_MMMM]; + break; + default: + DBG_ERRORFILE( "unknown LongDateMonthFormat" ); + } + break; + case 1 : + sDateStr += pKeyword[NF_KEY_MMM]; + break; + case 2 : + sDateStr += pKeyword[NF_KEY_MMMM]; + break; + default: + DBG_ERRORFILE( "unknown nShortLongMonth" ); + } + if ( nShortLongMonth != -1 ) + lcl_ImplAddStringMaybeQuoted( sDateStr, + pIntl->GetLongDateMonthSep(), pCharClass ); + + switch ( nShortLongDay ) + { + case -1 : + break; + case 0 : + if ( pIntl->IsLongDateDayLeadingZero() ) + sDateStr += pKeyword[NF_KEY_TT]; + else + sDateStr += pKeyword[NF_KEY_T]; + break; + case 1 : + sDateStr += pKeyword[NF_KEY_T]; + break; + case 2 : + sDateStr += pKeyword[NF_KEY_TT]; + break; + default: + DBG_ERRORFILE( "unknown nShortLongDay" ); + } + if ( nShortLongDay != -1 ) + lcl_ImplAddStringMaybeQuoted( sDateStr, + pIntl->GetLongDateDaySep(), pCharClass ); + + switch ( nShortLongYear ) + { + case -1 : + break; + case 0 : + if ( pIntl->IsLongDateCentury() ) + sDateStr += pKeyword[NF_KEY_JJJJ]; + else + sDateStr += pKeyword[NF_KEY_JJ]; + break; + case 1 : + sDateStr += pKeyword[NF_KEY_JJ]; + break; + case 2 : + sDateStr += pKeyword[NF_KEY_JJJJ]; + break; + default: + DBG_ERRORFILE( "unknown nShortLongYear" ); + } + //if ( nShortLongYear != -1 ) + // lcl_ImplAddStringMaybeQuoted( sDateStr, + // pIntl->GetLongDateYearSep(), pCharClass ); + + } + break; + case DMY: + { + switch ( nShortLongDay ) + { + case -1 : + break; + case 0 : + if ( pIntl->IsLongDateDayLeadingZero() ) + sDateStr += pKeyword[NF_KEY_TT]; + else + sDateStr += pKeyword[NF_KEY_T]; + break; + case 1 : + sDateStr += pKeyword[NF_KEY_T]; + break; + case 2 : + sDateStr += pKeyword[NF_KEY_TT]; + break; + default: + DBG_ERRORFILE( "unknown nShortLongDay" ); + } + if ( nShortLongDay != -1 ) + lcl_ImplAddStringMaybeQuoted( sDateStr, + pIntl->GetLongDateDaySep(), pCharClass ); + + switch ( nShortLongMonth ) + { + case -1 : + break; + case 0 : + switch ( pIntl->GetLongDateMonthFormat() ) + { + case MONTH_NORMAL : + sDateStr += pKeyword[NF_KEY_M]; + break; + case MONTH_ZERO : + sDateStr += pKeyword[NF_KEY_MM]; + break; + case MONTH_SHORT : + sDateStr += pKeyword[NF_KEY_MMM]; + break; + case MONTH_LONG : + sDateStr += pKeyword[NF_KEY_MMMM]; + break; + default: + DBG_ERRORFILE( "unknown LongDateMonthFormat" ); + } + break; + case 1 : + sDateStr += pKeyword[NF_KEY_MMM]; + break; + case 2 : + sDateStr += pKeyword[NF_KEY_MMMM]; + break; + default: + DBG_ERRORFILE( "unknown nShortLongMonth" ); + } + if ( nShortLongMonth != -1 ) + lcl_ImplAddStringMaybeQuoted( sDateStr, + pIntl->GetLongDateMonthSep(), pCharClass ); + + switch ( nShortLongYear ) + { + case -1 : + break; + case 0 : + if ( pIntl->IsLongDateCentury() ) + sDateStr += pKeyword[NF_KEY_JJJJ]; + else + sDateStr += pKeyword[NF_KEY_JJ]; + break; + case 1 : + sDateStr += pKeyword[NF_KEY_JJ]; + break; + case 2 : + sDateStr += pKeyword[NF_KEY_JJJJ]; + break; + default: + DBG_ERRORFILE( "unknown nShortLongYear" ); + } + //if ( nShortLongYear != -1 ) + // lcl_ImplAddStringMaybeQuoted( sDateStr, + // pIntl->GetLongDateYearSep(), pCharClass ); + + } + break; + case YMD: + { + switch ( nShortLongYear ) + { + case -1 : + break; + case 0 : + if ( pIntl->IsLongDateCentury() ) + sDateStr += pKeyword[NF_KEY_JJJJ]; + else + sDateStr += pKeyword[NF_KEY_JJ]; + break; + case 1 : + sDateStr += pKeyword[NF_KEY_JJ]; + break; + case 2 : + sDateStr += pKeyword[NF_KEY_JJJJ]; + break; + default: + DBG_ERRORFILE( "unknown nShortLongYear" ); + } + if ( nShortLongYear != -1 ) + lcl_ImplAddStringMaybeQuoted( sDateStr, + pIntl->GetLongDateYearSep(), pCharClass ); + + switch ( nShortLongMonth ) + { + case -1 : + break; + case 0 : + switch ( pIntl->GetLongDateMonthFormat() ) + { + case MONTH_NORMAL : + sDateStr += pKeyword[NF_KEY_M]; + break; + case MONTH_ZERO : + sDateStr += pKeyword[NF_KEY_MM]; + break; + case MONTH_SHORT : + sDateStr += pKeyword[NF_KEY_MMM]; + break; + case MONTH_LONG : + sDateStr += pKeyword[NF_KEY_MMMM]; + break; + default: + DBG_ERRORFILE( "unknown LongDateMonthFormat" ); + } + break; + case 1 : + sDateStr += pKeyword[NF_KEY_MMM]; + break; + case 2 : + sDateStr += pKeyword[NF_KEY_MMMM]; + break; + default: + DBG_ERRORFILE( "unknown nShortLongMonth" ); + } + if ( nShortLongMonth != -1 ) + lcl_ImplAddStringMaybeQuoted( sDateStr, + pIntl->GetLongDateMonthSep(), pCharClass ); + + switch ( nShortLongDay ) + { + case -1 : + break; + case 0 : + if ( pIntl->IsLongDateDayLeadingZero() ) + sDateStr += pKeyword[NF_KEY_TT]; + else + sDateStr += pKeyword[NF_KEY_T]; + break; + case 1 : + sDateStr += pKeyword[NF_KEY_T]; + break; + case 2 : + sDateStr += pKeyword[NF_KEY_TT]; + break; + default: + DBG_ERRORFILE( "unknown nShortLongDay" ); + } + //if ( nShortLongDay != -1 ) + // lcl_ImplAddStringMaybeQuoted( sDateStr, + // pIntl->GetLongDateDaySep(), pCharClass ); + + } + break; + default: + DBG_ERRORFILE( "unknown LongDateFormat" ); + } +} + +void SvNumberFormatter::ImpGetPosCurrFormat(XubString& sPosStr) +{ + NfCurrencyEntry::CompletePositiveFormatString( sPosStr, + pIntl->GetCurrSymbol(), pIntl->GetCurrPositiveFormat() ); +} + +void SvNumberFormatter::ImpGetNegCurrFormat(XubString& sNegStr) +{ + NfCurrencyEntry::CompleteNegativeFormatString( sNegStr, + pIntl->GetCurrSymbol(), pIntl->GetCurrNegativeFormat() ); +} + +void SvNumberFormatter::GenerateFormat(XubString& sString, + ULONG nIndex, + LanguageType eLnge, + BOOL bThousand, + BOOL IsRed, + USHORT nPrecision, + USHORT nAnzLeading) +{ + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = SysLnge; + short eType = GetType(nIndex); + USHORT i; + ImpGenerateCL(eLnge); // ggfs. neu Standard- + // formate anlegen + sString.Erase(); + + if (nAnzLeading == 0) + { + if (!bThousand) + sString += '#'; + else + { + sString += '#'; + sString += pIntl->GetNumThousandSep(); + sString += '#'; + sString += '#'; + sString += '#'; + } + } + else + { + for (i = 0; i < nAnzLeading; i++) + { + if (bThousand && i%3 == 0 && i > 0) + sString.Insert(pIntl->GetNumThousandSep(),0); + sString.Insert('0',0); + } + if (bThousand && nAnzLeading < 4) + { + for (i = nAnzLeading; i < 4; i++) + { + if (bThousand && i%3 == 0) + sString.Insert(pIntl->GetNumThousandSep(),0); + sString.Insert('#',0); + } + } + } + if (nPrecision > 0) + { + sString += pIntl->GetNumDecimalSep(); + for (i = 0; i < nPrecision; i++) + sString += '0'; + } + if (eType == NUMBERFORMAT_PERCENT) + sString += '%'; + else if (eType == NUMBERFORMAT_CURRENCY) + { + XubString sNegStr = sString; + XubString aCurr; + const NfCurrencyEntry* pEntry; + BOOL bBank; + if ( GetNewCurrencySymbolString( nIndex, aCurr, &pEntry, &bBank ) ) + { + if ( pEntry ) + { + USHORT nPosiForm = NfCurrencyEntry::GetEffectivePositiveFormat( + pIntl->GetCurrPositiveFormat(), + pEntry->GetPositiveFormat(), bBank ); + USHORT nNegaForm = NfCurrencyEntry::GetEffectiveNegativeFormat( + pIntl->GetCurrNegativeFormat(), + pEntry->GetNegativeFormat(), bBank ); + pEntry->CompletePositiveFormatString( sString, bBank, + nPosiForm ); + pEntry->CompleteNegativeFormatString( sNegStr, bBank, + nNegaForm ); + } + else + { // wir gehen von einem Banksymbol aus + USHORT nPosiForm = NfCurrencyEntry::GetEffectivePositiveFormat( + pIntl->GetCurrPositiveFormat(), + pIntl->GetCurrPositiveFormat(), TRUE ); + USHORT nNegaForm = NfCurrencyEntry::GetEffectiveNegativeFormat( + pIntl->GetCurrNegativeFormat(), + pIntl->GetCurrNegativeFormat(), TRUE ); + NfCurrencyEntry::CompletePositiveFormatString( sString, aCurr, + nPosiForm ); + NfCurrencyEntry::CompleteNegativeFormatString( sNegStr, aCurr, + nNegaForm ); + } + } + else + { + ImpGetPosCurrFormat(sString); + ImpGetNegCurrFormat(sNegStr); + } + if (IsRed) + { + sString += ';'; + sString += '['; + sString += pFormatScanner->GetRedString(); + sString += ']'; + } + else + sString += ';'; + sString += sNegStr; + } + if (IsRed && eType != NUMBERFORMAT_CURRENCY) + { + XubString sTmpStr = sString; + sTmpStr += ';'; + sTmpStr += '['; + sTmpStr += pFormatScanner->GetRedString(); + sTmpStr += ']'; + sTmpStr += '-'; + sTmpStr +=sString; + sString = sTmpStr; + } +} + +BOOL SvNumberFormatter::IsUserDefined(const XubString& sStr, + LanguageType eLnge) +{ + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = SysLnge; + ULONG CLOffset = ImpGenerateCL(eLnge); // ggfs. neu Standard- + // formate anlegen + eLnge = ActLnge; + ULONG nKey = ImpIsEntry(sStr, CLOffset, eLnge); + if (nKey == NUMBERFORMAT_ENTRY_NOT_FOUND) + return TRUE; + SvNumberformat* pEntry = aFTable.Get(nKey); + if ( pEntry && ((pEntry->GetType() & NUMBERFORMAT_DEFINED) != 0) ) + return TRUE; + return FALSE; +} + +ULONG SvNumberFormatter::GetEntryKey(const XubString& sStr, + LanguageType eLnge) +{ + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = SysLnge; + ULONG CLOffset = ImpGenerateCL(eLnge); // ggfs. neu Standard- + // formate anlegen + return ImpIsEntry(sStr, CLOffset, eLnge); +} + +ULONG SvNumberFormatter::GetStandardIndex(LanguageType eLnge) +{ + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = SysLnge; + return GetStandardFormat(NUMBERFORMAT_NUMBER, eLnge); +} + +short SvNumberFormatter::GetType(ULONG nFIndex) +{ + short eType; + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(nFIndex); + if (!pFormat) + eType = NUMBERFORMAT_UNDEFINED; + else + { + eType = pFormat->GetType() &~NUMBERFORMAT_DEFINED; + if (eType == 0) + eType = NUMBERFORMAT_DEFINED; + } + return eType; +} + +void SvNumberFormatter::ClearMergeTable() +{ + ULONG* pIndex = (ULONG*) pMergeTable->First(); + while (pIndex) + { + delete pIndex; + pIndex = pMergeTable->Next(); + } + pMergeTable->Clear(); +} + +SvULONGTable* SvNumberFormatter::MergeFormatter(SvNumberFormatter& rTable) +{ + ClearMergeTable(); + ULONG nCLOffset, nOldKey, nOffset, nNewKey; + ULONG* pNewIndex; + SvNumberformat* pNewEntry; + SvNumberformat* pFormat = rTable.aFTable.First(); + while (pFormat) + { + nOldKey = rTable.aFTable.GetCurKey(); + nOffset = nOldKey % SV_COUNTRY_LANGUAGE_OFFSET; // relativIndex + if (nOffset == 0) // 1. Format von CL + nCLOffset = ImpGenerateCL(pFormat->GetLanguage()); + + if (nOffset <= SV_MAX_ANZ_STANDARD_FORMATE) // Std.form. + { + nNewKey = nCLOffset + nOffset; + if (!aFTable.Get(nNewKey)) // noch nicht da + { +// pNewEntry = new SvNumberformat(*pFormat); // Copy reicht nicht !!! + pNewEntry = new SvNumberformat( *pFormat, *pFormatScanner ); + if (!aFTable.Insert(nNewKey, pNewEntry)) + delete pNewEntry; + } + if (nNewKey != nOldKey) // neuer Index + { + pNewIndex = new ULONG(nNewKey); + if (!pMergeTable->Insert(nOldKey,pNewIndex)) + delete pNewIndex; + } + } + else // benutzerdef. + { +// pNewEntry = new SvNumberformat(*pFormat); // Copy reicht nicht !!! + pNewEntry = new SvNumberformat( *pFormat, *pFormatScanner ); + nNewKey = ImpIsEntry(pNewEntry->GetFormatstring(), + nCLOffset, + pFormat->GetLanguage()); + if (nNewKey != NUMBERFORMAT_ENTRY_NOT_FOUND) // schon vorhanden + delete pNewEntry; + else + { + SvNumberformat* pStdFormat = + (SvNumberformat*) aFTable.Get(nCLOffset + ZF_STANDARD); + ULONG nPos = nCLOffset + pStdFormat->GetLastInsertKey(); + nNewKey = nPos+1; + if (nPos - nCLOffset >= SV_COUNTRY_LANGUAGE_OFFSET) + { +#ifndef DOS + Sound::Beep(); +#endif + DBG_ERROR( + "SvNumberFormatter:: Zu viele Formate pro CL"); + delete pNewEntry; + } + else if (!aFTable.Insert(nNewKey, pNewEntry)) + delete pNewEntry; + else + pStdFormat->SetLastInsertKey((USHORT) (nNewKey - nCLOffset)); + } + if (nNewKey != nOldKey) // neuer Index + { + pNewIndex = new ULONG(nNewKey); + if (!pMergeTable->Insert(nOldKey,pNewIndex)) + delete pNewIndex; + } + } + pFormat = rTable.aFTable.Next(); + } + return pMergeTable; +} + + +ULONG SvNumberFormatter::GetFormatForLanguageIfBuiltIn( ULONG nFormat, + LanguageType eLnge ) +{ + if ( eLnge == LANGUAGE_DONTKNOW ) + eLnge = SysLnge; + if ( nFormat < SV_COUNTRY_LANGUAGE_OFFSET && eLnge == SysLnge ) + return nFormat; // es bleibt wie es ist + ULONG nOffset = nFormat % SV_COUNTRY_LANGUAGE_OFFSET; // relativIndex + if ( nOffset > SV_MAX_ANZ_STANDARD_FORMATE ) + return nFormat; // kein eingebautes Format + ULONG nCLOffset = ImpGenerateCL(eLnge); // ggbf. generieren + return nCLOffset + nOffset; +} + + +ULONG SvNumberFormatter::GetFormatIndex( NfIndexTableOffset nTabOff, + LanguageType eLnge ) +{ + if ( nTabOff >= NF_INDEX_TABLE_ENTRIES + || theIndexTable[nTabOff] == NUMBERFORMAT_ENTRY_NOT_FOUND ) + return NUMBERFORMAT_ENTRY_NOT_FOUND; + if ( eLnge == LANGUAGE_DONTKNOW ) + eLnge = SysLnge; + ULONG nCLOffset = ImpGenerateCL(eLnge); // ggbf. generieren + return nCLOffset + theIndexTable[nTabOff]; +} + + +NfIndexTableOffset SvNumberFormatter::GetIndexTableOffset( ULONG nFormat ) const +{ + ULONG nOffset = nFormat % SV_COUNTRY_LANGUAGE_OFFSET; // relativIndex + if ( nOffset > SV_MAX_ANZ_STANDARD_FORMATE ) + return NF_INDEX_TABLE_ENTRIES; // kein eingebautes Format + for ( USHORT j = 0; j < NF_INDEX_TABLE_ENTRIES; j++ ) + { + if ( theIndexTable[j] == nOffset ) + return (NfIndexTableOffset) j; + } + return NF_INDEX_TABLE_ENTRIES; // bad luck +} + + +void SvNumberFormatter::SetYear2000( USHORT nVal ) +{ + pStringScanner->SetYear2000( nVal ); +} + + +USHORT SvNumberFormatter::GetYear2000() const +{ + return pStringScanner->GetYear2000(); +} + + +USHORT SvNumberFormatter::ExpandTwoDigitYear( USHORT nYear ) const +{ + if ( nYear < 100 ) + return SvNumberFormatter::ExpandTwoDigitYear( nYear, + pStringScanner->GetYear2000() ); + return nYear; +} + + +// static +USHORT SvNumberFormatter::GetYear2000Default() +{ + return Application::GetSettings().GetMiscSettings().GetTwoDigitYearStart(); +} + + +const NfCurrencyTable& SvNumberFormatter::GetTheCurrencyTable() const +{ + while ( !bCurrencyTableInitialized ) + SvNumberFormatter::ImpInitCurrencyTable(); + return theCurrencyTable; +} + + +const NfCurrencyEntry* SvNumberFormatter::MatchSystemCurrency() const +{ + const NfCurrencyTable& rTable = GetTheCurrencyTable(); + return nSystemCurrencyPosition ? rTable[nSystemCurrencyPosition] : NULL; +} + + +const NfCurrencyEntry& SvNumberFormatter::GetCurrencyEntry( LanguageType eLang ) const +{ + if ( eLang == LANGUAGE_DONTKNOW ) + eLang = SysLnge; + if ( eLang == LANGUAGE_SYSTEM ) + { + const NfCurrencyEntry* pCurr = MatchSystemCurrency(); + return pCurr ? *pCurr : *(GetTheCurrencyTable()[0]); + } + else + { + const NfCurrencyTable& rTable = GetTheCurrencyTable(); + USHORT nCount = rTable.Count(); + const NfCurrencyEntryPtr* ppData = rTable.GetData(); + for ( USHORT j = 0; j < nCount; j++, ppData++ ) + { + if ( (*ppData)->GetLanguage() == eLang ) + return **ppData; + } + return *(rTable[0]); + } +} + + +ULONG SvNumberFormatter::ImpGetDefaultSystemCurrencyFormat() +{ + if ( nDefaultCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND ) + { + xub_StrLen nCheck; + short nType; + NfWSStringsDtor aCurrList; + USHORT nDefault = GetCurrencyFormatStrings( aCurrList, + GetCurrencyEntry( LANGUAGE_SYSTEM ), FALSE ); + DBG_ASSERT( nDefault < aCurrList.Count(), "wo ist das NewCurrency Standard Format?!?" ); + // wenn bereits geladen oder userdefined wird nDefaultCurrencyFormat + // hierbei auf den richtigen Wert gesetzt + PutEntry( *aCurrList.GetObject( nDefault ), nCheck, nType, + nDefaultCurrencyFormat, LANGUAGE_SYSTEM ); + DBG_ASSERT( nCheck == 0, "NewCurrency CheckError" ); + DBG_ASSERT( nDefaultCurrencyFormat != NUMBERFORMAT_ENTRY_NOT_FOUND, + "nDefaultCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND" ); + } + return nDefaultCurrencyFormat; +} + + +BOOL SvNumberFormatter::GetNewCurrencySymbolString( ULONG nFormat, + XubString& rStr, const NfCurrencyEntry** ppEntry /* = NULL */, + BOOL* pBank /* = NULL */ ) const +{ + rStr.Erase(); + if ( ppEntry ) + *ppEntry = NULL; + if ( pBank ) + *pBank = FALSE; + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get( nFormat ); + if ( pFormat ) + { + XubString aSymbol, aExtension; + if ( pFormat->GetNewCurrencySymbol( aSymbol, aExtension ) ) + { + xub_StrLen nExtLen = aExtension.Len(); + if ( ppEntry ) + { + LanguageType eExtLang; + if ( nExtLen ) + { + ByteString aTmp( aExtension, 1, nExtLen-1, gsl_getSystemTextEncoding() ); + char* pEnd; + long nExtLang = strtol( aTmp.GetBuffer(), &pEnd, 16 ); + eExtLang = (LanguageType) ( + (*pEnd || nExtLang == LONG_MIN || nExtLang == LONG_MAX) ? + LANGUAGE_DONTKNOW : nExtLang ); + } + else + eExtLang = LANGUAGE_DONTKNOW; + const NfCurrencyEntry* pFoundEntry = NULL; + BOOL bFoundBank = FALSE; + const NfCurrencyTable& rTable = GetTheCurrencyTable(); + USHORT nCount = rTable.Count(); + const NfCurrencyEntryPtr* ppData = rTable.GetData(); + for ( USHORT j = 0; j < nCount; j++, ppData++ ) + { + LanguageType eLang = (*ppData)->GetLanguage(); + if ( !nExtLen || eLang == eExtLang || + (eLang == LANGUAGE_SYSTEM && eExtLang == LANGUAGE_DONTKNOW) ) + { + BOOL bFound; + if ( (*ppData)->GetSymbol() == aSymbol ) + { + bFound = TRUE; + bFoundBank = FALSE; + } + else if ( (*ppData)->GetBankSymbol() == aSymbol ) + { + bFound = TRUE; + bFoundBank = TRUE; + } + else + bFound = FALSE; + if ( bFound ) + { + if ( pFoundEntry && pFoundEntry != *ppData ) + { + pFoundEntry = NULL; + break; // for, nicht eindeutig + } + if ( j == 0 ) + { // erster Eintrag System + pFoundEntry = MatchSystemCurrency(); + if ( pFoundEntry ) + break; // for, selbst wenn es mehrere + // geben sollte, wird dieser gemeint sein + else + pFoundEntry = *ppData; + } + else + pFoundEntry = *ppData; + } + } + } + if ( pFoundEntry ) + { + *ppEntry = pFoundEntry; + if ( pBank ) + *pBank = bFoundBank; + pFoundEntry->BuildSymbolString( rStr, bFoundBank ); + } + } + if ( !rStr.Len() ) + { // analog zu BuildSymbolString + rStr = '['; + rStr += '$'; + if ( aSymbol.Search( '-' ) != STRING_NOTFOUND || + aSymbol.Search( ']' ) != STRING_NOTFOUND ) + { + rStr += '"'; + rStr += aSymbol; + rStr += '"'; + } + else + rStr += aSymbol; + if ( nExtLen ) + rStr += aExtension; + rStr += ']'; + } + return TRUE; + } + } + return FALSE; +} + + +#ifndef PRODUCT +void lcl_CheckCurrencySymbolPosition( const NfCurrencyEntry& rCurr ) +{ + short nPos = -1; // -1:=unknown, 0:=vorne, 1:=hinten + short nNeg = -1; + switch ( rCurr.GetPositiveFormat() ) + { + case 0: // $1 + nPos = 0; + break; + case 1: // 1$ + nPos = 1; + break; + case 2: // $ 1 + nPos = 0; + break; + case 3: // 1 $ + nPos = 1; + break; + default: + DBG_ERRORFILE("lcl_CheckCurrencySymbolPosition: unknown PositiveFormat"); + break; + } + switch ( rCurr.GetNegativeFormat() ) + { + case 0: // ($1) + nNeg = 0; + break; + case 1: // -$1 + nNeg = 0; + break; + case 2: // $-1 + nNeg = 0; + break; + case 3: // $1- + nNeg = 0; + break; + case 4: // (1$) + nNeg = 1; + break; + case 5: // -1$ + nNeg = 1; + break; + case 6: // 1-$ + nNeg = 1; + break; + case 7: // 1$- + nNeg = 1; + break; + case 8: // -1 $ + nNeg = 1; + break; + case 9: // -$ 1 + nNeg = 0; + break; + case 10: // 1 $- + nNeg = 1; + break; + case 11: // $ -1 + nNeg = 0; + break; + case 12 : // $ 1- + nNeg = 0; + break; + case 13 : // 1- $ + nNeg = 1; + break; + case 14 : // ($ 1) + nNeg = 0; + break; + case 15 : // (1 $) + nNeg = 1; + break; + default: + DBG_ERRORFILE("lcl_CheckCurrencySymbolPosition: unknown NegativeFormat"); + break; + } + if ( nPos >= 0 && nNeg >= 0 && nPos != nNeg ) + { + ByteString aStr( "ER->TH: positions of currency symbols differ\nLanguage: " ); + aStr += ByteString::CreateFromInt32( rCurr.GetLanguage() ); + aStr += " <"; + aStr += ByteString( rCurr.GetSymbol(), RTL_TEXTENCODING_UTF8 ); + aStr += "> positive: "; + aStr += ByteString::CreateFromInt32( rCurr.GetPositiveFormat() ); + aStr += ( nPos ? " (postfix)" : " (prefix)" ); + aStr += ", negative: "; + aStr += ByteString::CreateFromInt32( rCurr.GetNegativeFormat() ); + aStr += ( nNeg ? " (postfix)" : " (prefix)" ); +#if 0 + DBG_ERRORFILE( aStr.GetBuffer() ); +#endif + } +} +#endif + + +// static +void SvNumberFormatter::ImpInitCurrencyTable() +{ + // racing condition moeglich: + // while ( !bCurrencyTableInitialized ) + // ImpInitCurrencyTable(); + static BOOL bInitializing = FALSE; + if ( bCurrencyTableInitialized || bInitializing ) + return ; + bInitializing = TRUE; + + LanguageType eSysLang = System::GetLanguage(); + NfCurrencyEntryPtr pEntry; + USHORT n = International::GetAvailableFormatCount(); + for ( USHORT j = 0; j < n; j++ ) + { + LanguageType eLang = International::GetAvailableFormat( j ); +#ifdef DEBUG + LanguageType eReal = International::GetRealLanguage( eLang ); + LanguageType eNeut = International::GetNeutralLanguage( eLang ); + if ( eReal != eLang ) + BOOL bBreak = TRUE; + if ( eNeut != eLang ) + BOOL bBreak = TRUE; +#endif + International* pIntl = new International( eLang ); + pEntry = new NfCurrencyEntry( *pIntl ); +#ifndef PRODUCT + lcl_CheckCurrencySymbolPosition( *pEntry ); +#endif + theCurrencyTable.Insert( pEntry, j ); + delete pIntl; + if ( !nSystemCurrencyPosition && pEntry->GetLanguage() == eSysLang ) + nSystemCurrencyPosition = j; + } + DBG_ASSERT( theCurrencyTable.Count(), + "SvNumberFormatter::ImpInitCurrencyTable: kein NfCurrencyEntry ?!?" ); + // erster Eintrag ist System + // landesunabhaengigen EURo an zweiter Stelle einfuegen + pEntry = new NfCurrencyEntry; + pEntry->SetEuro(); + theCurrencyTable.Insert( pEntry, nCurrencyTableEuroPosition ); + DBG_ASSERT( theCurrencyTable[0]->GetLanguage() == LANGUAGE_SYSTEM, + "SvNumberFormatter::ImpInitCurrencyTable: erster Eintrag nicht System" ); + DBG_ASSERT( nSystemCurrencyPosition, "Regional Settings Language nicht in TH's Tabellen" ); + if ( nSystemCurrencyPosition ) + { + if ( nSystemCurrencyPosition >= nCurrencyTableEuroPosition ) + nSystemCurrencyPosition++; + if ( theCurrencyTable[nSystemCurrencyPosition]->GetSymbol() != + theCurrencyTable[0]->GetSymbol() ) + { + if ( theCurrencyTable[0]->IsEuro() ) + nSystemCurrencyPosition = nCurrencyTableEuroPosition; + else + nSystemCurrencyPosition = 0; + } + if ( nSystemCurrencyPosition ) + theCurrencyTable[nSystemCurrencyPosition]->ApplyVariableInformation( + *theCurrencyTable[0] ); + } + bCurrencyTableInitialized = TRUE; + bInitializing = FALSE; +} + + +USHORT SvNumberFormatter::GetCurrencyFormatStrings( NfWSStringsDtor& rStrArr, + const NfCurrencyEntry& rCurr, BOOL bBank ) const +{ + USHORT nDefault = 0; + if ( bBank ) + { // nur Bankensymbole + XubString aPositiveBank, aNegativeBank; + rCurr.BuildPositiveFormatString( aPositiveBank, TRUE, *pIntl, 1 ); + rCurr.BuildNegativeFormatString( aNegativeBank, TRUE, *pIntl, 1 ); + + WSStringPtr pFormat1 = new String( aPositiveBank ); + *pFormat1 += ';'; + WSStringPtr pFormat2 = new String( *pFormat1 ); + + XubString aRed( '[' ); + aRed += pFormatScanner->GetRedString(); + aRed += ']'; + + *pFormat2 += aRed; + + *pFormat1 += aNegativeBank; + *pFormat2 += aNegativeBank; + + rStrArr.Insert( pFormat1, rStrArr.Count() ); + rStrArr.Insert( pFormat2, rStrArr.Count() ); + nDefault = rStrArr.Count() - 1; + } + else + { // gemischte Formate wie in SvNumberFormatter::ImpGenerateFormats + // aber keine doppelten, wenn keine Nachkommastellen in Waehrung + XubString aPositive, aNegative, aPositiveNoDec, aNegativeNoDec, + aPositiveDashed, aNegativeDashed; + WSStringPtr pFormat1, pFormat2, pFormat3, pFormat4, pFormat5; + + XubString aRed( '[' ); + aRed += pFormatScanner->GetRedString(); + aRed += ']'; + + rCurr.BuildPositiveFormatString( aPositive, FALSE, *pIntl, 1 ); + rCurr.BuildNegativeFormatString( aNegative, FALSE, *pIntl, 1 ); + if ( rCurr.GetDigits() ) + { + rCurr.BuildPositiveFormatString( aPositiveNoDec, FALSE, *pIntl, 0 ); + rCurr.BuildNegativeFormatString( aNegativeNoDec, FALSE, *pIntl, 0 ); + rCurr.BuildPositiveFormatString( aPositiveDashed, FALSE, *pIntl, 2 ); + rCurr.BuildNegativeFormatString( aNegativeDashed, FALSE, *pIntl, 2 ); + + pFormat1 = new String( aPositiveNoDec ); + *pFormat1 += ';'; + pFormat3 = new String( *pFormat1 ); + pFormat5 = new String( aPositiveDashed ); + *pFormat5 += ';'; + + *pFormat1 += aNegativeNoDec; + + *pFormat3 += aRed; + *pFormat5 += aRed; + + *pFormat3 += aNegativeNoDec; + *pFormat5 += aNegativeDashed; + } + else + { + pFormat1 = NULL; + pFormat3 = NULL; + pFormat5 = NULL; + } + + pFormat2 = new String( aPositive ); + *pFormat2 += ';'; + pFormat4 = new String( *pFormat2 ); + + *pFormat2 += aNegative; + + *pFormat4 += aRed; + *pFormat4 += aNegative; + + if ( pFormat1 ) + rStrArr.Insert( pFormat1, rStrArr.Count() ); + rStrArr.Insert( pFormat2, rStrArr.Count() ); + if ( pFormat3 ) + rStrArr.Insert( pFormat3, rStrArr.Count() ); + rStrArr.Insert( pFormat4, rStrArr.Count() ); + nDefault = rStrArr.Count() - 1; + if ( pFormat5 ) + rStrArr.Insert( pFormat5, rStrArr.Count() ); + } + return nDefault; +} + + +//--- NfCurrencyEntry ---------------------------------------------------- + +NfCurrencyEntry::NfCurrencyEntry() + : eLanguage( LANGUAGE_DONTKNOW ), + nPositiveFormat(3), + nNegativeFormat(8), + nDigits(2), + cZeroChar('0') +{ +} + + +NfCurrencyEntry::NfCurrencyEntry( const International& rIntl ) +{ + aSymbol = rIntl.GetCurrSymbol(); + aBankSymbol = rIntl.GetCurrBankSymbol(); + eLanguage = rIntl.GetLanguage(); + nPositiveFormat = rIntl.GetCurrPositiveFormat(); + nNegativeFormat = rIntl.GetCurrNegativeFormat(); + nDigits = rIntl.GetCurrDigits(); + cZeroChar = rIntl.GetCurrZeroChar(); +} + + +void NfCurrencyEntry::SetEuro() +{ + aSymbol = NfCurrencyEntry::GetEuroSymbol(); + aBankSymbol.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "EUR" ) ); + eLanguage = LANGUAGE_DONTKNOW; + nPositiveFormat = 3; + nNegativeFormat = 8; + nDigits = 2; + cZeroChar = '0'; +} + + +BOOL NfCurrencyEntry::IsEuro() const +{ + if ( aBankSymbol.EqualsAscii( "EUR" ) ) + return TRUE; + XubString aEuro( NfCurrencyEntry::GetEuroSymbol() ); + return aSymbol == aEuro; +} + + +void NfCurrencyEntry::ApplyVariableInformation( const NfCurrencyEntry& r ) +{ + nPositiveFormat = r.nPositiveFormat; + nNegativeFormat = r.nNegativeFormat; + nDigits = r.nDigits; + cZeroChar = r.cZeroChar; +} + + +void NfCurrencyEntry::BuildSymbolString( XubString& rStr, BOOL bBank, + BOOL bWithoutExtension ) const +{ + rStr = '['; + rStr += '$'; + if ( bBank ) + rStr += aBankSymbol; + else + { + if ( aSymbol.Search( '-' ) != STRING_NOTFOUND || aSymbol.Search( ']' ) != STRING_NOTFOUND ) + { + rStr += '"'; + rStr += aSymbol; + rStr += '"'; + } + else + rStr += aSymbol; + if ( !bWithoutExtension && eLanguage != LANGUAGE_DONTKNOW && eLanguage != LANGUAGE_SYSTEM ) + { + rStr += '-'; + rStr += UniString::CreateFromInt32( sal_Int32( eLanguage ), 16 ); + } + } + rStr += ']'; +} + + +void NfCurrencyEntry::Impl_BuildFormatStringNumChars( XubString& rStr, + const International& rIntl, USHORT nDecimalFormat ) const +{ + rStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "###0" ) ); + rStr.Insert( rIntl.GetNumThousandSep(), 1 ); + if ( nDecimalFormat && nDigits ) + { + rStr += rIntl.GetNumDecimalSep(); + rStr.Expand( rStr.Len() + nDigits, (nDecimalFormat == 2 ? '-' : cZeroChar) ); + } +} + + +void NfCurrencyEntry::BuildPositiveFormatString( XubString& rStr, BOOL bBank, + const International& rIntl, USHORT nDecimalFormat ) const +{ + Impl_BuildFormatStringNumChars( rStr, rIntl, nDecimalFormat ); + USHORT nPosiForm = NfCurrencyEntry::GetEffectivePositiveFormat( + rIntl.GetCurrPositiveFormat(), nPositiveFormat, bBank ); + CompletePositiveFormatString( rStr, bBank, nPosiForm ); +} + + +void NfCurrencyEntry::BuildNegativeFormatString( XubString& rStr, BOOL bBank, + const International& rIntl, USHORT nDecimalFormat ) const +{ + Impl_BuildFormatStringNumChars( rStr, rIntl, nDecimalFormat ); + USHORT nNegaForm = NfCurrencyEntry::GetEffectiveNegativeFormat( + rIntl.GetCurrNegativeFormat(), nNegativeFormat, bBank ); + CompleteNegativeFormatString( rStr, bBank, nNegaForm ); +} + + +void NfCurrencyEntry::CompletePositiveFormatString( XubString& rStr, BOOL bBank, + USHORT nPosiForm ) const +{ + XubString aSymStr; + BuildSymbolString( aSymStr, bBank ); + NfCurrencyEntry::CompletePositiveFormatString( rStr, aSymStr, nPosiForm ); +} + + +void NfCurrencyEntry::CompleteNegativeFormatString( XubString& rStr, BOOL bBank, + USHORT nNegaForm ) const +{ + XubString aSymStr; + BuildSymbolString( aSymStr, bBank ); + NfCurrencyEntry::CompleteNegativeFormatString( rStr, aSymStr, nNegaForm ); +} + + +// static +void NfCurrencyEntry::CompletePositiveFormatString( XubString& rStr, + const XubString& rSymStr, USHORT nPositiveFormat ) +{ + switch( nPositiveFormat ) + { + case 0: // $1 + rStr.Insert( rSymStr , 0 ); + break; + case 1: // 1$ + rStr += rSymStr; + break; + case 2: // $ 1 + { + rStr.Insert( ' ', 0 ); + rStr.Insert( rSymStr, 0 ); + } + break; + case 3: // 1 $ + { + rStr += ' '; + rStr += rSymStr; + } + break; + default: + DBG_ERROR("NfCurrencyEntry::CompletePositiveFormatString: unknown option"); + break; + } +} + + +// static +void NfCurrencyEntry::CompleteNegativeFormatString( XubString& rStr, + const XubString& rSymStr, USHORT nNegativeFormat ) +{ + switch( nNegativeFormat ) + { + case 0: // ($1) + { + rStr.Insert( rSymStr, 0); + rStr.Insert('(',0); + rStr += ')'; + } + break; + case 1: // -$1 + { + rStr.Insert( rSymStr, 0); + rStr.Insert('-',0); + } + break; + case 2: // $-1 + { + rStr.Insert('-',0); + rStr.Insert( rSymStr, 0); + } + break; + case 3: // $1- + { + rStr.Insert( rSymStr, 0); + rStr += '-'; + } + break; + case 4: // (1$) + { + rStr.Insert('(',0); + rStr += rSymStr; + rStr += ')'; + } + break; + case 5: // -1$ + { + rStr += rSymStr; + rStr.Insert('-',0); + } + break; + case 6: // 1-$ + { + rStr += '-'; + rStr += rSymStr; + } + break; + case 7: // 1$- + { + rStr += rSymStr; + rStr += '-'; + } + break; + case 8: // -1 $ + { + rStr += ' '; + rStr += rSymStr; + rStr.Insert('-',0); + } + break; + case 9: // -$ 1 + { + rStr.Insert(' ',0); + rStr.Insert( rSymStr, 0); + rStr.Insert('-',0); + } + break; + case 10: // 1 $- + { + rStr += ' '; + rStr += rSymStr; + rStr += '-'; + } + break; + case 11: // $ -1 + { + XubString aTmp( rSymStr ); + aTmp += ' '; + aTmp += '-'; + rStr.Insert( aTmp, 0 ); + } + break; + case 12 : // $ 1- + { + rStr.Insert(' ', 0); + rStr.Insert( rSymStr, 0); + rStr += '-'; + } + break; + case 13 : // 1- $ + { + rStr += '-'; + rStr += ' '; + rStr += rSymStr; + } + break; + case 14 : // ($ 1) + { + rStr.Insert(' ',0); + rStr.Insert( rSymStr, 0); + rStr.Insert('(',0); + rStr += ')'; + } + break; + case 15 : // (1 $) + { + rStr.Insert('(',0); + rStr += ' '; + rStr += rSymStr; + rStr += ')'; + } + break; + default: + DBG_ERROR("NfCurrencyEntry::CompleteNegativeFormatString: unknown option"); + break; + } +} + + +// static +USHORT NfCurrencyEntry::GetEffectivePositiveFormat( USHORT nIntlFormat, + USHORT nCurrFormat, BOOL bBank ) +{ + if ( bBank ) + { +#if NF_BANKSYMBOL_FIX_POSITION + return 3; +#else + switch ( nIntlFormat ) + { + case 0: // $1 + nIntlFormat = 2; // $ 1 + break; + case 1: // 1$ + nIntlFormat = 3; // 1 $ + break; + case 2: // $ 1 + break; + case 3: // 1 $ + break; + } + return nIntlFormat; +#endif + } + else + return nCurrFormat; +} + + +// nur aufrufen, wenn nCurrFormat wirklich mit Klammern ist +USHORT lcl_MergeNegativeParenthesisFormat( USHORT nIntlFormat, USHORT nCurrFormat ) +{ + short nSign = 0; // -1:=Klammer 0:=links, 1:=mitte, 2:=rechts + switch ( nIntlFormat ) + { + case 0: // ($1) + case 4: // (1$) + case 14 : // ($ 1) + case 15 : // (1 $) + return nCurrFormat; + break; + case 1: // -$1 + case 5: // -1$ + case 8: // -1 $ + case 9: // -$ 1 + nSign = 0; + break; + case 2: // $-1 + case 6: // 1-$ + case 11 : // $ -1 + case 13 : // 1- $ + break; + nSign = 1; + case 3: // $1- + case 7: // 1$- + case 10: // 1 $- + case 12 : // $ 1- + nSign = 2; + break; + } + + switch ( nCurrFormat ) + { + case 0: // ($1) + switch ( nSign ) + { + case 0: + return 1; // -$1 + break; + case 1: + return 2; // $-1 + break; + case 2: + return 3; // $1- + break; + } + break; + case 4: // (1$) + switch ( nSign ) + { + case 0: + return 5; // -1$ + break; + case 1: + return 6; // 1-$ + break; + case 2: + return 7; // 1$- + break; + } + break; + case 14 : // ($ 1) + switch ( nSign ) + { + case 0: + return 9; // -$ 1 + break; + case 1: + return 11; // $ -1 + break; + case 2: + return 12; // $ 1- + break; + } + break; + case 15 : // (1 $) + switch ( nSign ) + { + case 0: + return 8; // -1 $ + break; + case 1: + return 13; // 1- $ + break; + case 2: + return 10; // 1 $- + break; + } + break; + } + return nCurrFormat; +} + + +// static +USHORT NfCurrencyEntry::GetEffectiveNegativeFormat( USHORT nIntlFormat, + USHORT nCurrFormat, BOOL bBank ) +{ + if ( bBank ) + { +#if NF_BANKSYMBOL_FIX_POSITION + return 8; +#else + switch ( nIntlFormat ) + { + case 0: // ($1) +// nIntlFormat = 14; // ($ 1) + nIntlFormat = 9; // -$ 1 + break; + case 1: // -$1 + nIntlFormat = 9; // -$ 1 + break; + case 2: // $-1 + nIntlFormat = 11; // $ -1 + break; + case 3: // $1- + nIntlFormat = 12; // $ 1- + break; + case 4: // (1$) +// nIntlFormat = 15; // (1 $) + nIntlFormat = 8; // -1 $ + break; + case 5: // -1$ + nIntlFormat = 8; // -1 $ + break; + case 6: // 1-$ + nIntlFormat = 13; // 1- $ + break; + case 7: // 1$- + nIntlFormat = 10; // 1 $- + break; + case 8: // -1 $ + break; + case 9: // -$ 1 + break; + case 10: // 1 $- + break; + case 11: // $ -1 + break; + case 12 : // $ 1- + break; + case 13 : // 1- $ + break; + case 14 : // ($ 1) +// nIntlFormat = 14; // ($ 1) + nIntlFormat = 9; // -$ 1 + break; + case 15 : // (1 $) +// nIntlFormat = 15; // (1 $) + nIntlFormat = 8; // -1 $ + break; + } +#endif + } + else if ( nIntlFormat != nCurrFormat ) + { + switch ( nCurrFormat ) + { + case 0: // ($1) + nIntlFormat = lcl_MergeNegativeParenthesisFormat( + nIntlFormat, nCurrFormat ); + break; + case 1: // -$1 + nIntlFormat = nCurrFormat; + break; + case 2: // $-1 + nIntlFormat = nCurrFormat; + break; + case 3: // $1- + nIntlFormat = nCurrFormat; + break; + case 4: // (1$) + nIntlFormat = lcl_MergeNegativeParenthesisFormat( + nIntlFormat, nCurrFormat ); + break; + case 5: // -1$ + nIntlFormat = nCurrFormat; + break; + case 6: // 1-$ + nIntlFormat = nCurrFormat; + break; + case 7: // 1$- + nIntlFormat = nCurrFormat; + break; + case 8: // -1 $ + nIntlFormat = nCurrFormat; + break; + case 9: // -$ 1 + nIntlFormat = nCurrFormat; + break; + case 10: // 1 $- + nIntlFormat = nCurrFormat; + break; + case 11: // $ -1 + nIntlFormat = nCurrFormat; + break; + case 12 : // $ 1- + nIntlFormat = nCurrFormat; + break; + case 13 : // 1- $ + nIntlFormat = nCurrFormat; + break; + case 14 : // ($ 1) + nIntlFormat = lcl_MergeNegativeParenthesisFormat( + nIntlFormat, nCurrFormat ); + break; + case 15 : // (1 $) + nIntlFormat = lcl_MergeNegativeParenthesisFormat( + nIntlFormat, nCurrFormat ); + break; + } + } + return nIntlFormat; +} + + +// we only support default encodings here +// static +sal_Char NfCurrencyEntry::GetEuroSymbol( rtl_TextEncoding eTextEncoding ) +{ + switch ( eTextEncoding ) + { + case RTL_TEXTENCODING_MS_1252 : // WNT Ansi + case RTL_TEXTENCODING_ISO_8859_1 : // UNX for use with TrueType fonts + return '\x80'; + break; + case RTL_TEXTENCODING_ISO_8859_15 : // UNX real + return '\xA4'; + break; + case RTL_TEXTENCODING_IBM_850 : // OS2 + return '\xD5'; + break; + case RTL_TEXTENCODING_APPLE_ROMAN : // MAC + return '\xDB'; + break; + default: // default system +#if WNT + return '\x80'; +#elif OS2 + return '\xD5'; +#elif UNX +// return '\xA4'; // #56121# 0xA4 waere korrekt fuer iso-8859-15 + return '\x80'; // aber Windoze-Code fuer die konvertierten TrueType-Fonts +#elif MAC + return '\xDB'; +#else +#error EuroSymbol is what? + return '\x80'; +#endif + } + return '\x80'; +} + + + |