/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include namespace { double GetDefaultValNum(const SvNumFormatType nType) { switch (nType) { case SvNumFormatType::NUMBER: return fSvxNumValConst[SvxNumValCategory::Standard]; case SvNumFormatType::CURRENCY: return fSvxNumValConst[SvxNumValCategory::Currency]; case SvNumFormatType::PERCENT: return fSvxNumValConst[SvxNumValCategory::Percent]; case SvNumFormatType::DATE: case SvNumFormatType::DATETIME: return fSvxNumValConst[SvxNumValCategory::Date]; case SvNumFormatType::TIME: return fSvxNumValConst[SvxNumValCategory::Time]; case SvNumFormatType::SCIENTIFIC: return fSvxNumValConst[SvxNumValCategory::Scientific]; case SvNumFormatType::FRACTION: return fSvxNumValConst[SvxNumValCategory::Fraction]; case SvNumFormatType::LOGICAL: return fSvxNumValConst[SvxNumValCategory::Boolean]; default: break; } return fSvxNumValConst[SvxNumValCategory::NoValue]; } } SvxNumberFormatShell* SvxNumberFormatShell::Create(SvNumberFormatter* pNumFormatter, sal_uInt32 nFormatKey, SvxNumberValueType eNumValType, const OUString& rNumStr) { return new SvxNumberFormatShell(pNumFormatter, nFormatKey, eNumValType, rNumStr); } SvxNumberFormatShell* SvxNumberFormatShell::Create(SvNumberFormatter* pNumFormatter, sal_uInt32 nFormatKey, SvxNumberValueType eNumValType, double nNumVal, const OUString* pNumStr) { return new SvxNumberFormatShell(pNumFormatter, nFormatKey, eNumValType, nNumVal, pNumStr); } SvxNumberFormatShell::SvxNumberFormatShell(SvNumberFormatter* pNumFormatter, sal_uInt32 nFormatKey, SvxNumberValueType eNumValType, const OUString& rNumStr) : pFormatter(pNumFormatter) , pCurFmtTable(nullptr) , eValType(eNumValType) , bUndoAddList(true) , nCurFormatKey(nFormatKey) , nCurCategory(SvNumFormatType::ALL) , eCurLanguage(LANGUAGE_NONE) , pCurCurrencyEntry(nullptr) , bBankingSymbol(false) , nCurCurrencyEntryPos(sal_uInt16(SELPOS_NONE)) , bUseStarFormat(false) , bIsDefaultValNum(true) { nValNum = 0; switch (eValType) { case SvxNumberValueType::String: aValStr = rNumStr; break; case SvxNumberValueType::Number: if (pFormatter) { nValNum = GetDefaultValNum(pFormatter->GetType(nCurFormatKey)); } [[fallthrough]]; case SvxNumberValueType::Undefined: default: aValStr.clear(); } } SvxNumberFormatShell::SvxNumberFormatShell(SvNumberFormatter* pNumFormatter, sal_uInt32 nFormatKey, SvxNumberValueType eNumValType, double nNumVal, const OUString* pNumStr) : pFormatter(pNumFormatter) , pCurFmtTable(nullptr) , eValType(eNumValType) , bUndoAddList(true) , nCurFormatKey(nFormatKey) , nCurCategory(SvNumFormatType::ALL) , eCurLanguage(LANGUAGE_NONE) , pCurCurrencyEntry(nullptr) , bBankingSymbol(false) , nCurCurrencyEntryPos(sal_uInt16(SELPOS_NONE)) , bUseStarFormat(false) , bIsDefaultValNum(false) { // #50441# When used in Writer, the SvxNumberInfoItem contains the // original string in addition to the value if (pNumStr) aValStr = *pNumStr; switch (eValType) { case SvxNumberValueType::Number: nValNum = nNumVal; break; case SvxNumberValueType::String: case SvxNumberValueType::Undefined: default: nValNum = 0; bIsDefaultValNum = true; } } SvxNumberFormatShell::~SvxNumberFormatShell() { /* * At this point, depending on whether the added user-defined were * validated (ValidateNewEntries()), the add list is removed from * the number formatter again. * * Deleting formats from the formatter happens for Undo reasons * only in the calling instance. */ if (bUndoAddList) { // Added formats are invalid => remove them for (const auto& rItem : aAddList) pFormatter->DeleteEntry(rItem); } } std::vector const& SvxNumberFormatShell::GetUpdateData() const { return aDelList; } void SvxNumberFormatShell::CategoryChanged(sal_uInt16 nCatLbPos, short& rFmtSelPos, std::vector& rFmtEntries) { SvNumFormatType nOldCategory = nCurCategory; PosToCategory_Impl(nCatLbPos, nCurCategory); pCurFmtTable = &(pFormatter->GetEntryTable(nCurCategory, nCurFormatKey, eCurLanguage)); // reinitialize currency if category newly entered if (nCurCategory == SvNumFormatType::CURRENCY && nOldCategory != nCurCategory) pCurCurrencyEntry = nullptr; rFmtSelPos = FillEntryList_Impl(rFmtEntries); } void SvxNumberFormatShell::LanguageChanged(LanguageType eLangType, short& rFmtSelPos, std::vector& rFmtEntries) { eCurLanguage = eLangType; pCurFmtTable = &(pFormatter->ChangeCL(nCurCategory, nCurFormatKey, eCurLanguage)); rFmtSelPos = FillEntryList_Impl(rFmtEntries); } void SvxNumberFormatShell::FormatChanged(sal_uInt16 nFmtLbPos, OUString& rPreviewStr, const Color*& rpFontColor) { if (static_cast(nFmtLbPos) < aCurEntryList.size()) { nCurFormatKey = aCurEntryList[nFmtLbPos]; if (nCurFormatKey != NUMBERFORMAT_ENTRY_NOT_FOUND) { GetPreviewString_Impl(rPreviewStr, rpFontColor); } else if (nCurCategory == SvNumFormatType::CURRENCY) { if (static_cast(nFmtLbPos) < aCurrencyFormatList.size()) { MakePrevStringFromVal(aCurrencyFormatList[nFmtLbPos], rPreviewStr, rpFontColor, nValNum); } } } } bool SvxNumberFormatShell::AddFormat(OUString& rFormat, sal_Int32& rErrPos, sal_uInt16& rCatLbSelPos, short& rFmtSelPos, std::vector& rFmtEntries) { bool bInserted = false; sal_uInt32 nAddKey = pFormatter->GetEntryKey(rFormat, eCurLanguage); if (nAddKey != NUMBERFORMAT_ENTRY_NOT_FOUND) // exists already? { ::std::vector::iterator nAt = GetRemoved_Impl(nAddKey); if (nAt != aDelList.end()) { aDelList.erase(nAt); bInserted = true; } else { OSL_FAIL("duplicate format!"); } } else // new format { sal_Int32 nPos; bInserted = pFormatter->PutEntry(rFormat, nPos, nCurCategory, nAddKey, eCurLanguage); rErrPos = (nPos >= 0) ? nPos : -1; if (bInserted) { // May be sorted under a different locale if LCID was parsed. const SvNumberformat* pEntry = pFormatter->GetEntry(nAddKey); if (pEntry) { LanguageType nLang = pEntry->GetLanguage(); if (eCurLanguage != nLang) { // Current language's list would not show entry, adapt. eCurLanguage = nLang; } } } } if (bInserted) { nCurFormatKey = nAddKey; DBG_ASSERT(GetAdded_Impl(nCurFormatKey) == aAddList.end(), "duplicate format!"); aAddList.push_back(nCurFormatKey); // get current table pCurFmtTable = &(pFormatter->GetEntryTable(nCurCategory, nCurFormatKey, eCurLanguage)); nCurCategory = pFormatter->GetType(nAddKey); CategoryToPos_Impl(nCurCategory, rCatLbSelPos); rFmtSelPos = FillEntryList_Impl(rFmtEntries); } else if (rErrPos != 0) // syntax error { ; } else // insert twice not possible { OSL_FAIL("duplicate format!"); } return bInserted; } void SvxNumberFormatShell::RemoveFormat(const OUString& rFormat, sal_uInt16& rCatLbSelPos, short& rFmtSelPos, std::vector& rFmtEntries) { sal_uInt32 nDelKey = pFormatter->GetEntryKey(rFormat, eCurLanguage); DBG_ASSERT(nDelKey != NUMBERFORMAT_ENTRY_NOT_FOUND, "entry not found!"); DBG_ASSERT(!IsRemoved_Impl(nDelKey), "entry already removed!"); if ((nDelKey == NUMBERFORMAT_ENTRY_NOT_FOUND) || IsRemoved_Impl(nDelKey)) return; aDelList.push_back(nDelKey); ::std::vector::iterator nAt = GetAdded_Impl(nDelKey); if (nAt != aAddList.end()) { aAddList.erase(nAt); } nCurCategory = pFormatter->GetType(nDelKey); pCurFmtTable = &(pFormatter->GetEntryTable(nCurCategory, nCurFormatKey, eCurLanguage)); nCurFormatKey = pFormatter->GetStandardFormat(nCurCategory, eCurLanguage); CategoryToPos_Impl(nCurCategory, rCatLbSelPos); rFmtSelPos = FillEntryList_Impl(rFmtEntries); } void SvxNumberFormatShell::MakeFormat(OUString& rFormat, bool bThousand, bool bNegRed, sal_uInt16 nPrecision, sal_uInt16 nLeadingZeroes, sal_uInt16 nCurrencyPos) { if (aCurrencyFormatList.size() > static_cast(nCurrencyPos)) { sal_Int32 rErrPos = 0; std::vector aFmtEList; sal_uInt32 nFound = pFormatter->TestNewString(aCurrencyFormatList[nCurrencyPos], eCurLanguage); if (nFound == NUMBERFORMAT_ENTRY_NOT_FOUND) { sal_uInt16 rCatLbSelPos = 0; short rFmtSelPos = 0; AddFormat(aCurrencyFormatList[nCurrencyPos], rErrPos, rCatLbSelPos, rFmtSelPos, aFmtEList); } if (rErrPos == 0) { rFormat = pFormatter->GenerateFormat(nCurFormatKey, eCurLanguage, bThousand, bNegRed, nPrecision, nLeadingZeroes); } } else { rFormat = pFormatter->GenerateFormat(nCurFormatKey, eCurLanguage, bThousand, bNegRed, nPrecision, nLeadingZeroes); } } sal_uInt16 SvxNumberFormatShell::GetFormatIntegerDigits(const OUString& rFormat) const { sal_uInt32 nFmtKey = pFormatter->GetEntryKey(rFormat, eCurLanguage); return pFormatter->GetFormatIntegerDigits(nFmtKey); } void SvxNumberFormatShell::GetOptions(const OUString& rFormat, bool& rThousand, bool& rNegRed, sal_uInt16& rPrecision, sal_uInt16& rLeadingZeroes, sal_uInt16& rCatLbPos) { sal_uInt32 nFmtKey = pFormatter->GetEntryKey(rFormat, eCurLanguage); if (nFmtKey != NUMBERFORMAT_ENTRY_NOT_FOUND) { pFormatter->GetFormatSpecialInfo(nFmtKey, rThousand, rNegRed, rPrecision, rLeadingZeroes); CategoryToPos_Impl(pFormatter->GetType(nFmtKey), rCatLbPos); } else { bool bTestBanking = false; sal_uInt16 nPos = FindCurrencyTableEntry(rFormat, bTestBanking); if (IsInTable(nPos, bTestBanking, rFormat) && pFormatter->GetFormatSpecialInfo(rFormat, rThousand, rNegRed, rPrecision, rLeadingZeroes, eCurLanguage) == 0) { rCatLbPos = CAT_CURRENCY; } else rCatLbPos = CAT_USERDEFINED; } } void SvxNumberFormatShell::MakePreviewString(const OUString& rFormatStr, OUString& rPreviewStr, const Color*& rpFontColor) { rpFontColor = nullptr; sal_uInt32 nExistingFormat = pFormatter->GetEntryKey(rFormatStr, eCurLanguage); if (nExistingFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) { // real preview - not implemented in NumberFormatter for text formats pFormatter->GetPreviewString(rFormatStr, nValNum, rPreviewStr, &rpFontColor, eCurLanguage, bUseStarFormat); } else { // format exists // #50441# if a string was set in addition to the value, use it for text formats bool bUseText = (eValType == SvxNumberValueType::String || (!aValStr.isEmpty() && (pFormatter->GetType(nExistingFormat) & SvNumFormatType::TEXT))); if (bUseText) { pFormatter->GetOutputString(aValStr, nExistingFormat, rPreviewStr, &rpFontColor); } else { if (bIsDefaultValNum) nValNum = GetDefaultValNum(pFormatter->GetType(nExistingFormat)); pFormatter->GetOutputString(nValNum, nExistingFormat, rPreviewStr, &rpFontColor, bUseStarFormat); } } } bool SvxNumberFormatShell::IsUserDefined(const OUString& rFmtString) { sal_uInt32 nFound = pFormatter->GetEntryKey(rFmtString, eCurLanguage); bool bFlag = false; if (nFound != NUMBERFORMAT_ENTRY_NOT_FOUND) { bFlag = pFormatter->IsUserDefined(rFmtString, eCurLanguage); if (bFlag) { const SvNumberformat* pNumEntry = pFormatter->GetEntry(nFound); if (pNumEntry != nullptr && pNumEntry->HasNewCurrency()) { bool bTestBanking; sal_uInt16 nPos = FindCurrencyTableEntry(rFmtString, bTestBanking); bFlag = !IsInTable(nPos, bTestBanking, rFmtString); } } } return bFlag; } bool SvxNumberFormatShell::FindEntry(const OUString& rFmtString, sal_uInt32* pAt /* = NULL */) { bool bRes = false; sal_uInt32 nFound = NUMBERFORMAT_ENTRY_NOT_FOUND; // There may be multiple builtin entries with the same format code, first // try if the current key matches. const SvNumberformat* pEntry = pFormatter->GetEntry(nCurFormatKey); if (pEntry && pEntry->GetLanguage() == eCurLanguage && pEntry->GetFormatstring() == rFmtString) nFound = nCurFormatKey; if (nFound == NUMBERFORMAT_ENTRY_NOT_FOUND) // Find the first matching format code. nFound = pFormatter->TestNewString(rFmtString, eCurLanguage); if (nFound == NUMBERFORMAT_ENTRY_NOT_FOUND) { bool bTestBanking = false; sal_uInt16 nPos = FindCurrencyTableEntry(rFmtString, bTestBanking); if (IsInTable(nPos, bTestBanking, rFmtString)) { nFound = NUMBERFORMAT_ENTRY_NEW_CURRENCY; bRes = true; } } else { bRes = !IsRemoved_Impl(nFound); } if (pAt) *pAt = nFound; return bRes; } void SvxNumberFormatShell::GetInitSettings(sal_uInt16& nCatLbPos, LanguageType& rLangType, sal_uInt16& nFmtLbSelPos, std::vector& rFmtEntries, OUString& rPrevString, const Color*& rpPrevColor) { // precondition: number formater found DBG_ASSERT(pFormatter != nullptr, "Number formatter not found!"); short nSelPos = SELPOS_NONE; // special treatment for undefined number format: if ((eValType == SvxNumberValueType::Undefined) && (nCurFormatKey == 0)) PosToCategory_Impl(CAT_ALL, nCurCategory); // category = all else nCurCategory = SvNumFormatType::UNDEFINED; // category = undefined pCurFmtTable = &(pFormatter->GetFirstEntryTable(nCurCategory, nCurFormatKey, eCurLanguage)); CategoryToPos_Impl(nCurCategory, nCatLbPos); rLangType = eCurLanguage; nSelPos = FillEntryList_Impl(rFmtEntries); DBG_ASSERT(nSelPos != SELPOS_NONE, "Leere Formatliste!"); nFmtLbSelPos = (nSelPos != SELPOS_NONE) ? static_cast(nSelPos) : 0; GetPreviewString_Impl(rPrevString, rpPrevColor); } short SvxNumberFormatShell::FillEntryList_Impl(std::vector& rList) { /* Create a current list of format entries. The return value is * the list position of the current format. If the list is empty * or if there is no current format, SELPOS_NONE is delivered. */ short nSelPos = SELPOS_NONE; aCurEntryList.clear(); if (nCurCategory == SvNumFormatType::ALL) { FillEListWithStd_Impl(rList, SvNumFormatType::NUMBER, nSelPos); nSelPos = FillEListWithUsD_Impl(rList, SvNumFormatType::NUMBER, nSelPos); FillEListWithStd_Impl(rList, SvNumFormatType::PERCENT, nSelPos); nSelPos = FillEListWithUsD_Impl(rList, SvNumFormatType::PERCENT, nSelPos); FillEListWithStd_Impl(rList, SvNumFormatType::CURRENCY, nSelPos); // No FillEListWithUsD_Impl() here, user defined currency formats // were already added. FillEListWithStd_Impl(rList, SvNumFormatType::DATE, nSelPos); nSelPos = FillEListWithUsD_Impl(rList, SvNumFormatType::DATE, nSelPos); FillEListWithStd_Impl(rList, SvNumFormatType::TIME, nSelPos); nSelPos = FillEListWithUsD_Impl(rList, SvNumFormatType::TIME, nSelPos); nSelPos = FillEListWithDateTime_Impl(rList, nSelPos, false); nSelPos = FillEListWithUsD_Impl(rList, SvNumFormatType::DATETIME, nSelPos); FillEListWithStd_Impl(rList, SvNumFormatType::SCIENTIFIC, nSelPos); nSelPos = FillEListWithUsD_Impl(rList, SvNumFormatType::SCIENTIFIC, nSelPos); FillEListWithStd_Impl(rList, SvNumFormatType::FRACTION, nSelPos); nSelPos = FillEListWithUsD_Impl(rList, SvNumFormatType::FRACTION, nSelPos); FillEListWithStd_Impl(rList, SvNumFormatType::LOGICAL, nSelPos); nSelPos = FillEListWithUsD_Impl(rList, SvNumFormatType::LOGICAL, nSelPos); FillEListWithStd_Impl(rList, SvNumFormatType::TEXT, nSelPos); nSelPos = FillEListWithUsD_Impl(rList, SvNumFormatType::TEXT, nSelPos); } else { FillEListWithStd_Impl(rList, nCurCategory, nSelPos, true); if (nCurCategory != SvNumFormatType::CURRENCY) nSelPos = FillEListWithUsD_Impl(rList, nCurCategory, nSelPos); if (nCurCategory == SvNumFormatType::DATE || nCurCategory == SvNumFormatType::TIME) nSelPos = FillEListWithDateTime_Impl(rList, nSelPos, true); } return nSelPos; } void SvxNumberFormatShell::FillEListWithStd_Impl(std::vector& rList, SvNumFormatType eCategory, short& nSelPos, bool bSuppressDuplicates) { /* Create a current list of format entries. The return value is * the list position of the current format. If the list is empty * or if there is no current format, SELPOS_NONE is delivered. */ assert(pCurFmtTable != nullptr); aCurrencyFormatList.clear(); NfIndexTableOffset eOffsetStart; NfIndexTableOffset eOffsetEnd; switch (eCategory) { case SvNumFormatType::NUMBER: eOffsetStart = NF_NUMBER_START; eOffsetEnd = NF_NUMBER_END; break; case SvNumFormatType::PERCENT: eOffsetStart = NF_PERCENT_START; eOffsetEnd = NF_PERCENT_END; break; case SvNumFormatType::CURRENCY: // Currency entries are generated and assembled, ignore // bSuppressDuplicates. nSelPos = FillEListWithCurrency_Impl(rList, nSelPos); return; case SvNumFormatType::DATE: eOffsetStart = NF_DATE_START; eOffsetEnd = NF_DATE_END; break; case SvNumFormatType::TIME: eOffsetStart = NF_TIME_START; eOffsetEnd = NF_TIME_END; break; case SvNumFormatType::SCIENTIFIC: eOffsetStart = NF_SCIENTIFIC_START; eOffsetEnd = NF_SCIENTIFIC_END; break; case SvNumFormatType::FRACTION: eOffsetStart = NF_FRACTION_START; eOffsetEnd = NF_FRACTION_END; // Fraction formats are internally generated by the number // formatter and are not supposed to contain duplicates anyway. nSelPos = FillEListWithFormats_Impl(rList, nSelPos, eOffsetStart, eOffsetEnd, false); nSelPos = FillEListWithFormats_Impl(rList, nSelPos, NF_FRACTION_3D, NF_FRACTION_100, false); return; case SvNumFormatType::LOGICAL: eOffsetStart = NF_BOOLEAN; eOffsetEnd = NF_BOOLEAN; break; case SvNumFormatType::TEXT: eOffsetStart = NF_TEXT; eOffsetEnd = NF_TEXT; break; default: return; } nSelPos = FillEListWithFormats_Impl(rList, nSelPos, eOffsetStart, eOffsetEnd, bSuppressDuplicates); } short SvxNumberFormatShell::FillEListWithFormats_Impl(std::vector& rList, short nSelPos, NfIndexTableOffset eOffsetStart, NfIndexTableOffset eOffsetEnd, bool bSuppressDuplicates) { /* Create a current list of format entries. The return value is * the list position of the current format. If the list is empty * or if there is no current format, SELPOS_NONE is delivered. */ for (tools::Long nIndex = eOffsetStart; nIndex <= eOffsetEnd; ++nIndex) { FillEListWithOneFormat_Impl( rList, nSelPos, bSuppressDuplicates, static_cast(nIndex), false); } return nSelPos; } short SvxNumberFormatShell::FillEListWithDateTime_Impl(std::vector& rList, short nSelPos, bool bSuppressDuplicates) { // Append a list of date+time formats. // Add first, so a NF_DATETIME_SYSTEM_SHORT_HHMM may be suppressed in // locales that do not use 2-digit years there and this here is the // default. FillEListWithOneFormat_Impl( rList, nSelPos, bSuppressDuplicates, NF_DATETIME_SYS_DDMMYYYY_HHMM, true); for (tools::Long nIndex = NF_DATETIME_START; nIndex <= NF_DATETIME_END; ++nIndex) { FillEListWithOneFormat_Impl( rList, nSelPos, bSuppressDuplicates, static_cast(nIndex), true); } // Always add the internally generated ISO formats. nSelPos = FillEListWithFormats_Impl(rList, nSelPos, NF_DATETIME_ISO_YYYYMMDD_HHMMSS, NF_DATETIME_ISO_YYYYMMDDTHHMMSS, false); return nSelPos; } void SvxNumberFormatShell::FillEListWithOneFormat_Impl(std::vector& rList, short & nSelPos, bool bSuppressDuplicates, NfIndexTableOffset nOffset, bool bSuppressIsoDateTime) { sal_uInt32 nNFEntry = pFormatter->GetFormatIndex(nOffset, eCurLanguage); const SvNumberformat* pNumEntry = pFormatter->GetEntry(nNFEntry); if (pNumEntry == nullptr) return; SvNumFormatType nMyCat = pNumEntry->GetMaskedType(); sal_uInt16 nMyType; CategoryToPos_Impl(nMyCat, nMyType); OUString aNewFormNInfo = pNumEntry->GetFormatstring(); if (nNFEntry == nCurFormatKey) { nSelPos = (!IsRemoved_Impl(nNFEntry)) ? aCurEntryList.size() : SELPOS_NONE; } // Ugly hack to suppress an ISO date+time format that is the default // date+time format of the locale and identical to the internally generated // one always to be added after/below. const bool bSupIso = bSuppressIsoDateTime && bSuppressDuplicates && (aNewFormNInfo == "YYYY-MM-DD HH:MM:SS" || aNewFormNInfo == "YYYY-MM-DD\"T\"HH:MM:SS"); if (!bSupIso && (!bSuppressDuplicates || IsEssentialFormat_Impl(nMyCat, nNFEntry) || std::find(rList.begin(), rList.end(), aNewFormNInfo) == rList.end())) { rList.push_back(aNewFormNInfo); aCurEntryList.push_back(nNFEntry); } } bool SvxNumberFormatShell::IsEssentialFormat_Impl(SvNumFormatType eType, sal_uInt32 nKey) { if (nKey == nCurFormatKey) return true; const NfIndexTableOffset nIndex = pFormatter->GetIndexTableOffset(nKey); switch (nIndex) { // These are preferred or edit formats. case NF_DATE_SYS_DDMMYYYY: case NF_DATE_ISO_YYYYMMDD: case NF_TIME_HH_MMSS: case NF_TIME_MMSS00: case NF_TIME_HH_MMSS00: case NF_DATETIME_SYS_DDMMYYYY_HHMM: case NF_DATETIME_SYS_DDMMYYYY_HHMMSS: case NF_DATETIME_ISO_YYYYMMDD_HHMMSS: case NF_DATETIME_ISO_YYYYMMDDTHHMMSS: return true; default: break; } return nKey == pFormatter->GetStandardFormat(eType, eCurLanguage); } short SvxNumberFormatShell::FillEListWithCurrency_Impl(std::vector& rList, short nSelPos) { /* Create a current list of format entries. The return value is * the list position of the current format. If the list is empty * or if there is no current format, SELPOS_NONE is delivered. */ DBG_ASSERT(pCurFmtTable != nullptr, "unknown NumberFormat"); const NfCurrencyEntry* pTmpCurrencyEntry; bool bTmpBanking; OUString rSymbol; bool bFlag = pFormatter->GetNewCurrencySymbolString(nCurFormatKey, rSymbol, &pTmpCurrencyEntry, &bTmpBanking); if ((!bFlag && pCurCurrencyEntry == nullptr) || (bFlag && pTmpCurrencyEntry == nullptr && rSymbol.isEmpty()) || (nCurCategory == SvNumFormatType::ALL)) { if (nCurCategory == SvNumFormatType::ALL) FillEListWithUserCurrencys(rList, nSelPos); nSelPos = FillEListWithSysCurrencys(rList, nSelPos); } else { nSelPos = FillEListWithUserCurrencys(rList, nSelPos); } return nSelPos; } short SvxNumberFormatShell::FillEListWithSysCurrencys(std::vector& rList, short nSelPos) { /* Create a current list of format entries. The return value is * the list position of the current format. If the list is empty * or if there is no current format, SELPOS_NONE is delivered. */ sal_uInt16 nMyType; DBG_ASSERT(pCurFmtTable != nullptr, "unknown NumberFormat"); sal_uInt32 nNFEntry; OUString aNewFormNInfo; nCurCurrencyEntryPos = 0; for (tools::Long nIndex = NF_CURRENCY_START; nIndex <= NF_CURRENCY_END; nIndex++) { nNFEntry = pFormatter->GetFormatIndex(static_cast(nIndex), eCurLanguage); if (nCurCategory == SvNumFormatType::ALL && nNFEntry != nCurFormatKey) // Deprecated old currency entries, for ALL add only if used as // current format key. continue; const SvNumberformat* pNumEntry = pFormatter->GetEntry(nNFEntry); if (pNumEntry == nullptr) continue; SvNumFormatType nMyCat = pNumEntry->GetMaskedType(); CategoryToPos_Impl(nMyCat, nMyType); aNewFormNInfo = pNumEntry->GetFormatstring(); if (nNFEntry == nCurFormatKey) { nSelPos = (!IsRemoved_Impl(nNFEntry)) ? aCurEntryList.size() : SELPOS_NONE; } rList.push_back(aNewFormNInfo); aCurEntryList.push_back(nNFEntry); } if (nCurCategory != SvNumFormatType::ALL) { for (const auto& rEntry : *pCurFmtTable) { sal_uInt32 nKey = rEntry.first; const SvNumberformat* pNumEntry = rEntry.second; if (!IsRemoved_Impl(nKey)) { bool bUserNewCurrency = false; if (pNumEntry->HasNewCurrency()) { const NfCurrencyEntry* pTmpCurrencyEntry; bool bTmpBanking; OUString rSymbol; pFormatter->GetNewCurrencySymbolString(nKey, rSymbol, &pTmpCurrencyEntry, &bTmpBanking); bUserNewCurrency = (pTmpCurrencyEntry != nullptr); } if (!bUserNewCurrency && (pNumEntry->GetType() & SvNumFormatType::DEFINED)) { SvNumFormatType nMyCat = pNumEntry->GetMaskedType(); CategoryToPos_Impl(nMyCat, nMyType); aNewFormNInfo = pNumEntry->GetFormatstring(); if (nKey == nCurFormatKey) nSelPos = aCurEntryList.size(); rList.push_back(aNewFormNInfo); aCurEntryList.push_back(nKey); } } } } return nSelPos; } short SvxNumberFormatShell::FillEListWithUserCurrencys(std::vector& rList, short nSelPos) { /* Create a current list of format entries. The return value is * the list position of the current format. If the list is empty * or if there is no current format, SELPOS_NONE is delivered. */ sal_uInt16 nMyType; DBG_ASSERT(pCurFmtTable != nullptr, "unknown NumberFormat"); OUString aNewFormNInfo; const NfCurrencyEntry* pTmpCurrencyEntry; bool bTmpBanking, bAdaptSelPos; OUString rSymbol; OUString rBankSymbol; std::vector aList; std::vector aKeyList; pFormatter->GetNewCurrencySymbolString(nCurFormatKey, rSymbol, &pTmpCurrencyEntry, &bTmpBanking); OUString rShortSymbol; if (pCurCurrencyEntry == nullptr) { // #110398# If no currency format was previously selected (we're not // about to add another currency), try to select the initial currency // format (nCurFormatKey) that was set in FormatChanged() after // matching the format string entered in the dialog. bAdaptSelPos = true; pCurCurrencyEntry = const_cast(pTmpCurrencyEntry); bBankingSymbol = bTmpBanking; nCurCurrencyEntryPos = FindCurrencyFormat(pTmpCurrencyEntry, bTmpBanking); } else { if (pTmpCurrencyEntry == pCurCurrencyEntry) bAdaptSelPos = true; else { bAdaptSelPos = false; pTmpCurrencyEntry = pCurCurrencyEntry; } bTmpBanking = bBankingSymbol; } if (pTmpCurrencyEntry != nullptr) { rSymbol = pTmpCurrencyEntry->BuildSymbolString(false); rBankSymbol = pTmpCurrencyEntry->BuildSymbolString(true); rShortSymbol = pTmpCurrencyEntry->BuildSymbolString(bTmpBanking, true); } for (const auto& rEntry : *pCurFmtTable) { sal_uInt32 nKey = rEntry.first; const SvNumberformat* pNumEntry = rEntry.second; if (!IsRemoved_Impl(nKey)) { if (pNumEntry->GetType() & SvNumFormatType::DEFINED || pNumEntry->IsAdditionalBuiltin()) { SvNumFormatType nMyCat = pNumEntry->GetMaskedType(); CategoryToPos_Impl(nMyCat, nMyType); aNewFormNInfo = pNumEntry->GetFormatstring(); bool bInsFlag = false; if (pNumEntry->HasNewCurrency()) { bInsFlag = true; // merge locale formats into currency selection } else if ((!bTmpBanking && aNewFormNInfo.indexOf(rSymbol) >= 0) || (bTmpBanking && aNewFormNInfo.indexOf(rBankSymbol) >= 0)) { bInsFlag = true; } else if (aNewFormNInfo.indexOf(rShortSymbol) >= 0) { OUString rTstSymbol; const NfCurrencyEntry* pTstCurrencyEntry; bool bTstBanking; pFormatter->GetNewCurrencySymbolString(nKey, rTstSymbol, &pTstCurrencyEntry, &bTstBanking); if (pTmpCurrencyEntry == pTstCurrencyEntry && bTstBanking == bTmpBanking) { bInsFlag = true; } } if (bInsFlag) { aList.push_back(aNewFormNInfo); aKeyList.push_back(nKey); } } } } NfWSStringsDtor aWSStringsDtor; sal_uInt16 nDefault; if (pTmpCurrencyEntry && nCurCategory != SvNumFormatType::ALL) { nDefault = pFormatter->GetCurrencyFormatStrings(aWSStringsDtor, *pTmpCurrencyEntry, bTmpBanking); if (!bTmpBanking) pFormatter->GetCurrencyFormatStrings(aWSStringsDtor, *pTmpCurrencyEntry, true); } else nDefault = 0; if (!bTmpBanking && nCurCategory != SvNumFormatType::ALL) { // append formats for all currencies defined in the current I18N locale const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable(); sal_uInt16 nCurrCount = rCurrencyTable.size(); LanguageType eLang = MsLangId::getRealLanguage(eCurLanguage); for (sal_uInt16 i = 0; i < nCurrCount; ++i) { const NfCurrencyEntry* pCurr = &rCurrencyTable[i]; if (pCurr->GetLanguage() == eLang && pTmpCurrencyEntry != pCurr) { pFormatter->GetCurrencyFormatStrings(aWSStringsDtor, *pCurr, false); pFormatter->GetCurrencyFormatStrings(aWSStringsDtor, *pCurr, true); } } } size_t nOldListCount = rList.size(); for (size_t i = 0, nPos = nOldListCount; i < aWSStringsDtor.size(); ++i) { bool bFlag = true; OUString aInsStr(aWSStringsDtor[i]); size_t j; for (j = 0; j < aList.size(); ++j) { if (aList[j] == aInsStr) { bFlag = false; break; } } if (bFlag) { rList.push_back(aInsStr); aCurEntryList.insert(aCurEntryList.begin() + (nPos++), NUMBERFORMAT_ENTRY_NOT_FOUND); } else { rList.push_back(aList[j]); aList.erase(aList.begin() + j); aCurEntryList.insert(aCurEntryList.begin() + (nPos++), aKeyList[j]); aKeyList.erase(aKeyList.begin() + j); } } for (size_t i = 0; i < aKeyList.size(); ++i) { if (aKeyList[i] != NUMBERFORMAT_ENTRY_NOT_FOUND) { rList.push_back(aList[i]); aCurEntryList.push_back(aKeyList[i]); } } for (size_t i = nOldListCount; i < rList.size(); ++i) { aCurrencyFormatList.push_back(rList[i]); if (nSelPos == SELPOS_NONE && bAdaptSelPos && aCurEntryList[i] == nCurFormatKey) nSelPos = i; } if (nSelPos == SELPOS_NONE && nCurCategory != SvNumFormatType::ALL) nSelPos = nDefault; return nSelPos; } short SvxNumberFormatShell::FillEListWithUsD_Impl(std::vector& rList, SvNumFormatType eCategory, short nSelPos) { /* Create a current list of format entries. The return value is * the list position of the current format. If the list is empty * or if there is no current format, SELPOS_NONE is delivered. */ assert(pCurFmtTable != nullptr); OUString aNewFormNInfo; const bool bCatDefined = (eCategory == SvNumFormatType::DEFINED); const bool bCategoryMatch = (eCategory != SvNumFormatType::ALL && !bCatDefined); for (const auto& rEntry : *pCurFmtTable) { const SvNumberformat* pNumEntry = rEntry.second; if (bCategoryMatch && (pNumEntry->GetMaskedType() & eCategory) != eCategory) continue; // for; type does not match category if not ALL const bool bUserDefined = bool(pNumEntry->GetType() & SvNumFormatType::DEFINED); if (!bUserDefined && bCatDefined) continue; // for; not user defined in DEFINED category if (!(bUserDefined || (!bCatDefined && pNumEntry->IsAdditionalBuiltin()))) continue; // for; does not match criteria at all const sal_uInt32 nKey = rEntry.first; if (!IsRemoved_Impl(nKey)) { aNewFormNInfo = pNumEntry->GetFormatstring(); bool bAdd = true; if (pNumEntry->HasNewCurrency()) { bool bTestBanking; sal_uInt16 nPos = FindCurrencyTableEntry(aNewFormNInfo, bTestBanking); bAdd = !IsInTable(nPos, bTestBanking, aNewFormNInfo); } if (bAdd) { if (nKey == nCurFormatKey) nSelPos = aCurEntryList.size(); rList.push_back(aNewFormNInfo); aCurEntryList.push_back(nKey); } } } return nSelPos; } void SvxNumberFormatShell::GetPreviewString_Impl(OUString& rString, const Color*& rpColor) { rpColor = nullptr; // #50441# if a string was set in addition to the value, use it for text formats bool bUseText = (eValType == SvxNumberValueType::String || (!aValStr.isEmpty() && (pFormatter->GetType(nCurFormatKey) & SvNumFormatType::TEXT))); if (bUseText) { pFormatter->GetOutputString(aValStr, nCurFormatKey, rString, &rpColor); } else { pFormatter->GetOutputString(nValNum, nCurFormatKey, rString, &rpColor, bUseStarFormat); } } ::std::vector::iterator SvxNumberFormatShell::GetRemoved_Impl(size_t nKey) { return ::std::find(aDelList.begin(), aDelList.end(), nKey); } bool SvxNumberFormatShell::IsRemoved_Impl(size_t nKey) { return GetRemoved_Impl(nKey) != aDelList.end(); } ::std::vector::iterator SvxNumberFormatShell::GetAdded_Impl(size_t nKey) { return ::std::find(aAddList.begin(), aAddList.end(), nKey); } // Conversion routines: void SvxNumberFormatShell::PosToCategory_Impl(sal_uInt16 nPos, SvNumFormatType& rCategory) { // map category css::form positions (->resource) switch (nPos) { case CAT_USERDEFINED: rCategory = SvNumFormatType::DEFINED; break; case CAT_NUMBER: rCategory = SvNumFormatType::NUMBER; break; case CAT_PERCENT: rCategory = SvNumFormatType::PERCENT; break; case CAT_CURRENCY: rCategory = SvNumFormatType::CURRENCY; break; case CAT_DATE: rCategory = SvNumFormatType::DATE; break; case CAT_TIME: rCategory = SvNumFormatType::TIME; break; case CAT_SCIENTIFIC: rCategory = SvNumFormatType::SCIENTIFIC; break; case CAT_FRACTION: rCategory = SvNumFormatType::FRACTION; break; case CAT_BOOLEAN: rCategory = SvNumFormatType::LOGICAL; break; case CAT_TEXT: rCategory = SvNumFormatType::TEXT; break; case CAT_ALL: default: rCategory = SvNumFormatType::ALL; break; } } void SvxNumberFormatShell::CategoryToPos_Impl(SvNumFormatType nCategory, sal_uInt16& rPos) { // map category to css::form positions (->resource) switch (nCategory) { case SvNumFormatType::DEFINED: rPos = CAT_USERDEFINED; break; case SvNumFormatType::NUMBER: rPos = CAT_NUMBER; break; case SvNumFormatType::PERCENT: rPos = CAT_PERCENT; break; case SvNumFormatType::CURRENCY: rPos = CAT_CURRENCY; break; case SvNumFormatType::DATETIME: case SvNumFormatType::DATE: rPos = CAT_DATE; break; case SvNumFormatType::TIME: rPos = CAT_TIME; break; case SvNumFormatType::SCIENTIFIC: rPos = CAT_SCIENTIFIC; break; case SvNumFormatType::FRACTION: rPos = CAT_FRACTION; break; case SvNumFormatType::LOGICAL: rPos = CAT_BOOLEAN; break; case SvNumFormatType::TEXT: rPos = CAT_TEXT; break; case SvNumFormatType::ALL: default: rPos = CAT_ALL; } } /* * Function: Formats the number nValue dependent on rFormatStr * and stores the result in rPreviewStr. * Input: FormatString, color, number to format * Output: Output string rPreviewStr */ void SvxNumberFormatShell::MakePrevStringFromVal(const OUString& rFormatStr, OUString& rPreviewStr, const Color*& rpFontColor, double nValue) { rpFontColor = nullptr; pFormatter->GetPreviewString(rFormatStr, nValue, rPreviewStr, &rpFontColor, eCurLanguage); } /* * Function: Returns the comment for a given entry. * Input: Number of the entry * Output: Comment string */ void SvxNumberFormatShell::SetComment4Entry(short nEntry, const OUString& aEntStr) { SvNumberformat* pNumEntry; if (nEntry < 0) return; sal_uInt32 nMyNfEntry = aCurEntryList[nEntry]; pNumEntry = const_cast(pFormatter->GetEntry(nMyNfEntry)); if (pNumEntry != nullptr) pNumEntry->SetComment(aEntStr); } /* * Function: Returns the comment for a given entry. * Input: Number of the entry * Output: Comment string */ OUString SvxNumberFormatShell::GetComment4Entry(short nEntry) { if (nEntry < 0) return OUString(); if (o3tl::make_unsigned(nEntry) < aCurEntryList.size()) { sal_uInt32 nMyNfEntry = aCurEntryList[nEntry]; const SvNumberformat* pNumEntry = pFormatter->GetEntry(nMyNfEntry); if (pNumEntry != nullptr) return pNumEntry->GetComment(); } return OUString(); } /* * Function: Returns the category number for a given entry. * Input: Number of the entry * Output: Category number */ short SvxNumberFormatShell::GetCategory4Entry(short nEntry) const { if (nEntry < 0) return 0; if (o3tl::make_unsigned(nEntry) < aCurEntryList.size()) { sal_uInt32 nMyNfEntry = aCurEntryList[nEntry]; if (nMyNfEntry != NUMBERFORMAT_ENTRY_NOT_FOUND) { const SvNumberformat* pNumEntry = pFormatter->GetEntry(nMyNfEntry); if (pNumEntry != nullptr) { SvNumFormatType nMyCat = pNumEntry->GetMaskedType(); sal_uInt16 nMyType; CategoryToPos_Impl(nMyCat, nMyType); return static_cast(nMyType); } return 0; } else if (!aCurrencyFormatList.empty()) { return CAT_CURRENCY; } } return 0; } /* * Function: Returns the information about whether an entry is user-specific. * Input: Number of the entry * Output: User-specific? */ bool SvxNumberFormatShell::GetUserDefined4Entry(short nEntry) { if (nEntry < 0) return false; if (o3tl::make_unsigned(nEntry) < aCurEntryList.size()) { sal_uInt32 nMyNfEntry = aCurEntryList[nEntry]; const SvNumberformat* pNumEntry = pFormatter->GetEntry(nMyNfEntry); if (pNumEntry != nullptr) { if (pNumEntry->GetType() & SvNumFormatType::DEFINED) { return true; } } } return false; } /* * Function: Returns the format string for a given entry. * Input: Number of the entry * Output: Format string */ OUString SvxNumberFormatShell::GetFormat4Entry(short nEntry) { if (nEntry < 0) return OUString(); if (!aCurrencyFormatList.empty()) { if (aCurrencyFormatList.size() > o3tl::make_unsigned(nEntry)) return aCurrencyFormatList[nEntry]; } else { sal_uInt32 nMyNfEntry = aCurEntryList[nEntry]; const SvNumberformat* pNumEntry = pFormatter->GetEntry(nMyNfEntry); if (pNumEntry != nullptr) return pNumEntry->GetFormatstring(); } return OUString(); } /* * Function: Returns the list number for a given format index. * Input: Number of the entry * Output: Category number */ short SvxNumberFormatShell::GetListPos4Entry( sal_uInt32 nIdx, const OUString& rFmtString ) { short nSelP = SELPOS_NONE; if (nIdx != NUMBERFORMAT_ENTRY_NEW_CURRENCY) { // Check list size against return type limit. if (aCurEntryList.size() <= o3tl::make_unsigned(::std::numeric_limits::max())) { for (size_t i = 0; i < aCurEntryList.size(); ++i) { if (aCurEntryList[i] == nIdx) { nSelP = i; break; } } } else { OSL_FAIL("svx::SvxNumberFormatShell::GetListPos4Entry(), list got too large!"); } } else { // A second list holds the generated currency formats. for (size_t i = 0; i < aCurrencyFormatList.size(); ++i) { if (rFmtString == aCurrencyFormatList[i]) { nSelP = static_cast(i); break; } } } return nSelP; } OUString SvxNumberFormatShell::GetStandardName() const { return pFormatter->GetStandardName(eCurLanguage); } void SvxNumberFormatShell::GetCurrencySymbols(std::vector& rList, sal_uInt16* pPos) { const NfCurrencyEntry* pTmpCurrencyEntry = SvNumberFormatter::MatchSystemCurrency(); bool bFlag = (pTmpCurrencyEntry == nullptr); SvxCurrencyToolBoxControl::GetCurrencySymbols(rList, bFlag, aCurCurrencyList); if (pPos == nullptr) return; const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable(); sal_uInt16 nTableCount = rCurrencyTable.size(); *pPos = 0; size_t nCount = aCurCurrencyList.size(); if (bFlag) { *pPos = 1; nCurCurrencyEntryPos = 1; } else { for (size_t i = 1; i < nCount; i++) { const sal_uInt16 j = aCurCurrencyList[i]; if (j != sal_uInt16(-1) && j < nTableCount && pTmpCurrencyEntry == &rCurrencyTable[j]) { *pPos = static_cast(i); nCurCurrencyEntryPos = static_cast(i); break; } } } } void SvxNumberFormatShell::SetCurrencySymbol(sal_uInt32 nPos) { const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable(); sal_uInt16 nCount = rCurrencyTable.size(); bBankingSymbol = (nPos >= nCount); if (nPos >= aCurCurrencyList.size()) return; sal_uInt16 nCurrencyPos = aCurCurrencyList[nPos]; if (nCurrencyPos != sal_uInt16(-1)) { pCurCurrencyEntry = const_cast(&rCurrencyTable[nCurrencyPos]); nCurCurrencyEntryPos = nPos; } else { pCurCurrencyEntry = nullptr; nCurCurrencyEntryPos = 0; nCurFormatKey = pFormatter->GetFormatIndex(NF_CURRENCY_1000DEC2_RED, eCurLanguage); } } void SvxNumberFormatShell::SetCurCurrencyEntry(NfCurrencyEntry* pCEntry) { pCurCurrencyEntry = pCEntry; } bool SvxNumberFormatShell::IsTmpCurrencyFormat(const OUString& rFmtString) { sal_uInt32 nFound; FindEntry(rFmtString, &nFound); return nFound == NUMBERFORMAT_ENTRY_NEW_CURRENCY; } sal_uInt16 SvxNumberFormatShell::FindCurrencyFormat(const OUString& rFmtString) { const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable(); sal_uInt16 nCount = rCurrencyTable.size(); bool bTestBanking = false; sal_uInt16 nPos = FindCurrencyTableEntry(rFmtString, bTestBanking); if (nPos != sal_uInt16(-1)) { sal_uInt16 nStart = 0; if (bTestBanking && aCurCurrencyList.size() > nPos) { nStart = nCount; } for (size_t j = nStart; j < aCurCurrencyList.size(); j++) { if (aCurCurrencyList[j] == nPos) return j; } } return sal_uInt16(-1); } sal_uInt16 SvxNumberFormatShell::FindCurrencyTableEntry(const OUString& rFmtString, bool& bTestBanking) { sal_uInt16 nPos = sal_uInt16(-1); const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable(); sal_uInt16 nCount = rCurrencyTable.size(); const SvNumberformat* pFormat; OUString aSymbol, aExtension; sal_uInt32 nFound = pFormatter->TestNewString(rFmtString, eCurLanguage); if (nFound != NUMBERFORMAT_ENTRY_NOT_FOUND && ((pFormat = pFormatter->GetEntry(nFound)) != nullptr) && pFormat->GetNewCurrencySymbol(aSymbol, aExtension)) { // eventually match with format locale const NfCurrencyEntry* pTmpCurrencyEntry = SvNumberFormatter::GetCurrencyEntry( bTestBanking, aSymbol, aExtension, pFormat->GetLanguage()); if (pTmpCurrencyEntry) { for (sal_uInt16 i = 0; i < nCount; i++) { if (pTmpCurrencyEntry == &rCurrencyTable[i]) { nPos = i; break; } } } } else { // search symbol string only for (sal_uInt16 i = 0; i < nCount; i++) { const NfCurrencyEntry* pTmpCurrencyEntry = &rCurrencyTable[i]; OUString _aSymbol = pTmpCurrencyEntry->BuildSymbolString(false); OUString aBankSymbol = pTmpCurrencyEntry->BuildSymbolString(true); if (rFmtString.indexOf(_aSymbol) != -1) { bTestBanking = false; nPos = i; break; } else if (rFmtString.indexOf(aBankSymbol) != -1) { bTestBanking = true; nPos = i; break; } } } return nPos; } sal_uInt16 SvxNumberFormatShell::FindCurrencyFormat(const NfCurrencyEntry* pTmpCurrencyEntry, bool bTmpBanking) { const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable(); sal_uInt16 nCount = rCurrencyTable.size(); sal_uInt16 nPos = 0; for (sal_uInt16 i = 0; i < nCount; i++) { if (pTmpCurrencyEntry == &rCurrencyTable[i]) { nPos = i; break; } } sal_uInt16 nStart = 0; if (bTmpBanking && aCurCurrencyList.size() > nPos) { nStart = nCount; } for (size_t j = nStart; j < aCurCurrencyList.size(); j++) { if (aCurCurrencyList[j] == nPos) return j; } return sal_uInt16(-1); } bool SvxNumberFormatShell::IsInTable(sal_uInt16 const nPos, bool const bTmpBanking, OUString const& rFmtString) { bool bFlag = false; if (nPos != sal_uInt16(-1)) { const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable(); if (nPos < rCurrencyTable.size()) { NfWSStringsDtor aWSStringsDtor; pFormatter->GetCurrencyFormatStrings(aWSStringsDtor, rCurrencyTable[nPos], bTmpBanking); for (const OUString& s : aWSStringsDtor) { if (s == rFmtString) { bFlag = true; break; } } } } return bFlag; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */