/* -*- 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 .
*/
sal_uInt32 SvXMLNumImpData::GetKeyForName( std::u16string_view rName )
{ for (constauto& rObj : m_NameEntries)
{ if (rObj.aName == rName) return rObj.nKey; // found
} return NUMBERFORMAT_ENTRY_NOT_FOUND;
}
void SvXMLNumImpData::AddKey( sal_uInt32 nKey, const OUString& rName, bool bRemoveAfterUse )
{ if ( bRemoveAfterUse )
{ // if there is already an entry for this key without the bRemoveAfterUse flag, // clear the flag for this entry, too
for (constauto& rObj : m_NameEntries)
{ if (rObj.nKey == nKey && !rObj.bRemoveAfterUse)
{
bRemoveAfterUse = false; // clear flag for new entry break;
}
}
} else
{ // call SetUsed to clear the bRemoveAfterUse flag for other entries for this key
SetUsed( nKey );
}
void SvXMLNumImpData::SetUsed( sal_uInt32 nKey )
{ for (auto& rObj : m_NameEntries)
{ if (rObj.nKey == nKey)
{
rObj.bRemoveAfterUse = false; // used -> don't remove
// continue searching - there may be several entries for the same key // (with different names), the format must not be deleted if any one of // them is used
}
}
}
void SvXMLNumImpData::RemoveVolatileFormats()
{ // remove temporary (volatile) formats from NumberFormatter // called at the end of each import (styles and content), so volatile formats // from styles can't be used in content
if ( !pFormatter ) return;
for (constauto& rObj : m_NameEntries)
{ if (rObj.bRemoveAfterUse )
{ const SvNumberformat* pFormat = pFormatter->GetEntry(rObj.nKey); if (pFormat && (pFormat->GetType() & SvNumFormatType::DEFINED))
pFormatter->DeleteEntry(rObj.nKey);
}
}
}
// Treat space equal to non-breaking space separator. const sal_Unicode cNBSP = 0x00A0;
sal_Unicode cTS; if ( ( nFormatType == SvXMLStylesTokens::NUMBER_STYLE ||
nFormatType == SvXMLStylesTokens::CURRENCY_STYLE ||
nFormatType == SvXMLStylesTokens::PERCENTAGE_STYLE ) &&
(cChar == (cTS = rParent.GetLocaleData().getNumThousandSep()[0]) ||
(cChar == ' ' && cTS == cNBSP)) )
{ // #i22394# Extra occurrences of thousands separator must be quoted, so they // aren't mis-interpreted as display-factor. // This must be limited to the format types that can contain a number element, // because the same character can be a date separator that should not be quoted // in date formats.
returnfalse; // force quotes
}
// see ImpSvNumberformatScan::Next_Symbol
// All format types except BOOLEAN may contain minus sign or delimiter. if ( cChar == '-' ) return nFormatType != SvXMLStylesTokens::BOOLEAN_STYLE;
// percent sign must be used without quotes for percentage styles only if ( nFormatType == SvXMLStylesTokens::PERCENTAGE_STYLE && cChar == '%' ) returntrue;
// don't put quotes around single parentheses (often used for negative numbers) if ( ( nFormatType == SvXMLStylesTokens::NUMBER_STYLE ||
nFormatType == SvXMLStylesTokens::CURRENCY_STYLE ||
nFormatType == SvXMLStylesTokens::PERCENTAGE_STYLE ) &&
( cChar == '(' || cChar == ')' ) ) returntrue;
if (nFormatType != SvXMLStylesTokens::BOOLEAN_STYLE &&
((nLength == 1 && lcl_ValidChar( rContent[0], rParent)) ||
(nLength == 2 &&
((rContent[0] == ' ' && rContent[1] == '-') ||
(rContent[1] == ' ' && lcl_ValidChar( rContent[0], rParent))))))
{ // Don't quote single separator characters like space or percent, // or separator characters followed by space (used in date formats). // Or space followed by minus (used in currency formats) that would // lead to almost duplicated formats with built-in formats just with // the difference of quotes.
bQuote = false;
} elseif ( nFormatType == SvXMLStylesTokens::PERCENTAGE_STYLE && nLength > 1 )
{ // the percent character in percentage styles must be left out of quoting // (one occurrence is enough even if there are several percent characters in the string)
sal_Int32 nPos = rContent.indexOf( '%' ); if ( nPos >= 0 )
{ if ( nPos + 1 < nLength )
{ if ( nPos + 2 == nLength && lcl_ValidChar( rContent[nPos + 1], rParent ) )
{ // single character that doesn't need quoting
} else
{ // quote text behind percent character
rContent.insert( nPos + 1, '"' );
rContent.append( '"' );
}
} if ( nPos > 0 )
{ if ( nPos == 1 && lcl_ValidChar( rContent[0], rParent ) )
{ // single character that doesn't need quoting
} else
{ // quote text before percent character
rContent.insert( nPos, '"' );
rContent.insert( 0, '"' );
}
}
bQuote = false;
} // else: normal quoting (below)
}
if ( !bQuote ) return;
// #i55469# quotes in the string itself have to be escaped bool bEscape = ( rContent.indexOf( '"' ) >= 0 ); if ( bEscape )
{ // A quote is turned into "\"" - a quote to end quoted text, an escaped quote, // and a quote to resume quoting.
OUString aInsert( u"\"\\\""_ustr );
namespace { void lcl_InsertBlankWidthChars( std::u16string_view rBlankWidthString, OUStringBuffer& rContent )
{
sal_Int32 nShiftPosition = 1; // rContent starts with a quote const size_t nLenBlank = rBlankWidthString.size(); for ( size_t i = 0 ; i < nLenBlank ; i++ )
{
sal_Unicode nChar = rBlankWidthString[ i ];
OUString aBlanks;
SvNumberformat::InsertBlanks( aBlanks, 0, nChar );
sal_Int32 nPositionContent = 0; if ( ++i < nLenBlank )
{
sal_Int32 nNext = rBlankWidthString.find( '_', i ); if ( static_cast<sal_Int32>( i ) < nNext )
{
nPositionContent = o3tl::toInt32( rBlankWidthString.substr( i, nNext - i ) );
i = nNext;
} else
nPositionContent = o3tl::toInt32( rBlankWidthString.substr( i ) );
}
nPositionContent += nShiftPosition; if ( nPositionContent >= 0 )
{
rContent.remove( nPositionContent, aBlanks.getLength() ); if ( nPositionContent >= 1 && rContent[ nPositionContent-1 ] == '\"' )
{
nPositionContent--;
rContent.insert( nPositionContent, nChar );
rContent.insert( nPositionContent, '_' );
} else
{
rContent.insert( nPositionContent, '\"' );
rContent.insert( nPositionContent, nChar );
rContent.insert( nPositionContent, "\"_" );
nShiftPosition += 2;
} // rContent length was modified: remove blanks, add "_x"
nShiftPosition += 2 - aBlanks.getLength();
}
} // remove empty string at the end of rContent if ( std::u16string_view( rContent ).substr( rContent.getLength() - 2 ) == u"\"\"" )
{
sal_Int32 nLen = rContent.getLength(); if ( nLen >= 3 && rContent[ nLen-3 ] != '\\' )
rContent.truncate( nLen - 2 );
}
}
}
void SvXMLNumFmtElementContext::AddEmbeddedElement( sal_Int32 nFormatPos, std::u16string_view rContentEmbedded, std::u16string_view rBlankWidthString )
{ if ( rContentEmbedded.empty() ) return;
OUStringBuffer aContentEmbedded( rContentEmbedded ); // #107805# always quote embedded strings - even space would otherwise // be recognized as thousands separator in French.
aContentEmbedded.insert( 0, '"' );
aContentEmbedded.append( '"' ); if ( !rBlankWidthString.empty() )
lcl_InsertBlankWidthChars( rBlankWidthString, aContentEmbedded );
auto iterPair = aNumInfo.m_EmbeddedElements.emplace( nFormatPos, aContentEmbedded.toString() ); if (!iterPair.second)
{ // there's already an element at this position - append text to existing element if ( iterPair.first->second.endsWith( "\"" ) && aContentEmbedded[ 0 ] == '"' )
{ // remove double quote
iterPair.first->second = OUString::Concat( iterPair.first->second.subView( 0, iterPair.first->second.getLength() - 1 ) )
+ aContentEmbedded.subView( 1, aContentEmbedded.getLength() - 1 );
} else
iterPair.first->second += aContentEmbedded;
}
}
void SvXMLNumFmtElementContext::endFastElement(sal_Int32 )
{ bool bEffLong = bLong; switch (nType)
{ case SvXMLStyleTokens::Text: if ( rParent.HasLongDoW() &&
std::u16string_view(aContent) == rParent.GetLocaleData().getLongDateDayOfWeekSep() )
{ // skip separator constant after long day of week // (NF_KEY_NNNN contains the separator)
if ( rParent.ReplaceNfKeyword( NF_KEY_NNN, NF_KEY_NNNN ) )
{
aContent.truncate();
}
rParent.SetHasLongDoW( false ); // only once
} if ( !aContent.isEmpty() )
{
lcl_EnquoteIfNecessary( aContent, rParent ); if ( !sBlankWidthString.isEmpty() )
{
lcl_InsertBlankWidthChars( sBlankWidthString, aContent );
sBlankWidthString = "";
}
rParent.AddToCode( aContent );
aContent.setLength(0);
} else
{ // Quoted empty text may be significant to separate.
aContent.append("\"\"");
rParent.AddToCode( aContent );
aContent.setLength(0);
rParent.SetHasTrailingEmptyText(true); // *after* AddToCode()
} break;
case SvXMLStyleTokens::Number:
rParent.AddNumber( aNumInfo ); break;
case SvXMLStyleTokens::CurrencySymbol:
rParent.AddCurrency( aContent.makeStringAndClear(), nElementLang ); break;
case SvXMLStyleTokens::TextContent:
rParent.AddToCode( '@'); break; case SvXMLStyleTokens::FillCharacter: if ( !aContent.isEmpty() )
{
rParent.AddToCode( '*' );
rParent.AddToCode( aContent[0] );
} break; case SvXMLStyleTokens::Boolean:
rParent.AddNfKeyword( NF_KEY_BOOLEAN ); break;
case SvXMLStyleTokens::Day:
rParent.UpdateCalendar( sCalendar ); //! I18N doesn't provide SYSTEM or extended date information yet
rParent.AddNfKeyword(
sal::static_int_cast< sal_uInt16 >(
bEffLong ? NF_KEY_DD : NF_KEY_D ) ); break; case SvXMLStyleTokens::Month:
rParent.UpdateCalendar( sCalendar ); //! I18N doesn't provide SYSTEM or extended date information yet
rParent.AddNfKeyword(
sal::static_int_cast< sal_uInt16 >(
bTextual
? ( bEffLong ? NF_KEY_MMMM : NF_KEY_MMM )
: ( bEffLong ? NF_KEY_MM : NF_KEY_M ) ) ); break; case SvXMLStyleTokens::Year: //! I18N doesn't provide SYSTEM or extended date information yet
{ // Y after G (era) is replaced by E for a secondary calendar. // Do not replace for default calendar. // Also replace Y by E if we're switching to the secondary // calendar of a locale if it is known to implicitly use E.
rParent.UpdateCalendar( sCalendar); const SvXMLNumFormatContext::ImplicitCalendar eCal = rParent.GetImplicitCalendarState(); if (eCal == SvXMLNumFormatContext::ImplicitCalendar::SECONDARY
|| eCal == SvXMLNumFormatContext::ImplicitCalendar::SECONDARY_FROM_OTHER)
{
rParent.AddNfKeyword(
sal::static_int_cast< sal_uInt16 >(
bEffLong ? NF_KEY_EEC : NF_KEY_EC ) );
} else
{
rParent.AddNfKeyword(
sal::static_int_cast< sal_uInt16 >(
bEffLong ? NF_KEY_YYYY : NF_KEY_YY ) );
}
} break; case SvXMLStyleTokens::Era:
rParent.UpdateCalendar( sCalendar ); //! I18N doesn't provide SYSTEM or extended date information yet
rParent.AddNfKeyword(
sal::static_int_cast< sal_uInt16 >(
bEffLong ? NF_KEY_GGG : NF_KEY_G ) ); // HasEra flag is set break; case SvXMLStyleTokens::DayOfWeek: //! I18N doesn't provide SYSTEM or extended date information yet
{ // Implicit secondary calendar uses A keyword, default and // explicit calendar N keyword.
rParent.UpdateCalendar( sCalendar); const SvXMLNumFormatContext::ImplicitCalendar eCal = rParent.GetImplicitCalendarState(); if (eCal == SvXMLNumFormatContext::ImplicitCalendar::SECONDARY
|| eCal == SvXMLNumFormatContext::ImplicitCalendar::SECONDARY_FROM_OTHER)
{
rParent.AddNfKeyword(
sal::static_int_cast< sal_uInt16 >(
bEffLong ? NF_KEY_AAAA : NF_KEY_AAA ) );
} else
{
rParent.AddNfKeyword(
sal::static_int_cast< sal_uInt16 >(
bEffLong ? NF_KEY_NNNN : NF_KEY_NN ) );
}
} break; case SvXMLStyleTokens::WeekOfYear:
rParent.UpdateCalendar( sCalendar );
rParent.AddNfKeyword( NF_KEY_WW ); break; case SvXMLStyleTokens::Quarter:
rParent.UpdateCalendar( sCalendar );
rParent.AddNfKeyword(
sal::static_int_cast< sal_uInt16 >(
bEffLong ? NF_KEY_QQ : NF_KEY_Q ) ); break; case SvXMLStyleTokens::Hours:
rParent.AddNfKeyword(
sal::static_int_cast< sal_uInt16 >(
bEffLong ? NF_KEY_HH : NF_KEY_H ) ); break; case SvXMLStyleTokens::AmPm: //! short/long?
rParent.AddNfKeyword( NF_KEY_AMPM ); break; case SvXMLStyleTokens::Minutes:
rParent.AddNfKeyword(
sal::static_int_cast< sal_uInt16 >(
bEffLong ? NF_KEY_MMI : NF_KEY_MI ) ); break; case SvXMLStyleTokens::Seconds:
rParent.AddNfKeyword(
sal::static_int_cast< sal_uInt16 >(
bEffLong ? NF_KEY_SS : NF_KEY_S ) ); if ( aNumInfo.nDecimals > 0 )
{ // manually add the decimal places
rParent.AddToCode(rParent.GetLocaleData().getNumDecimalSep()); for (sal_Int32 i=0; i<aNumInfo.nDecimals; i++)
{
rParent.AddToCode( '0');
}
} break;
case SvXMLStyleTokens::Fraction:
{ if ( aNumInfo.nInteger >= 0 )
{ // add integer part only if min-integer-digits attribute is there
aNumInfo.nDecimals = 0;
rParent.AddNumber( aNumInfo ); // number without decimals
OUStringBuffer sIntegerFractionDelimiter(aNumInfo.aIntegerFractionDelimiter);
lcl_EnquoteIfNecessary( sIntegerFractionDelimiter, rParent );
rParent.AddToCode( sIntegerFractionDelimiter ); // default is ' '
}
//! build string and add at once
sal_Int32 i; for (i=aNumInfo.nMaxNumerDigits; i > 0; i--)
{ if ( i > aNumInfo.nMinNumerDigits )
rParent.AddToCode( '#' ); elseif ( i > aNumInfo.nZerosNumerDigits )
rParent.AddToCode( '?' ); else
rParent.AddToCode( '0' );
}
rParent.AddToCode( '/' ); if ( aNumInfo.nFracDenominator > 0 )
{
rParent.AddToCode( OUString::number( aNumInfo.nFracDenominator ) );
} else
{ for (i=aNumInfo.nMaxDenomDigits; i > 0 ; i--)
{ if ( i > aNumInfo.nMinDenomDigits )
rParent.AddToCode( '#' ); elseif ( i > aNumInfo.nZerosDenomDigits )
rParent.AddToCode( '?' ); else
rParent.AddToCode( '0' );
}
}
} break;
case SvXMLStyleTokens::ScientificNumber:
{ // exponential interval for engineering notation if( !aNumInfo.bGrouping && aNumInfo.nExpInterval > aNumInfo.nInteger )
{ for (sal_Int32 i=aNumInfo.nInteger; i<aNumInfo.nExpInterval; i++)
{
rParent.AddToCode( '#' );
}
}
rParent.AddNumber( aNumInfo ); // number and exponent
} break;
default:
assert(false && "invalid element ID");
}
}
switch (nElement)
{ case XML_ELEMENT(LO_EXT, XML_TEXT): case XML_ELEMENT(NUMBER, XML_TEXT):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::Text, xAttrList ); break; case XML_ELEMENT(LO_EXT, XML_FILL_CHARACTER): case XML_ELEMENT(NUMBER, XML_FILL_CHARACTER):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::FillCharacter, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_NUMBER):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::Number, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_SCIENTIFIC_NUMBER):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::ScientificNumber, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_FRACTION):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::Fraction, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_CURRENCY_SYMBOL):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::CurrencySymbol, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_DAY):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::Day, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_MONTH):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::Month, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_YEAR):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::Year, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_ERA):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::Era, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_DAY_OF_WEEK):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::DayOfWeek, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_WEEK_OF_YEAR):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::WeekOfYear, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_QUARTER):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::Quarter, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_HOURS):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::Hours, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_AM_PM):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::AmPm, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_MINUTES):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::Minutes, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_SECONDS):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::Seconds, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_BOOLEAN):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::Boolean, xAttrList ); break; case XML_ELEMENT(NUMBER, XML_TEXT_CONTENT):
pContext = new SvXMLNumFmtElementContext( GetImport(), nElement,
*this, SvXMLStyleTokens::TextContent, xAttrList ); break;
case XML_ELEMENT(STYLE, XML_TEXT_PROPERTIES):
pContext = new SvXMLNumFmtPropContext( GetImport(), nElement,
*this, xAttrList ); break; case XML_ELEMENT(STYLE, XML_MAP):
{ // SvXMLNumFmtMapContext::EndElement adds to aMyConditions, // so there's no need for an extra flag
pContext = new SvXMLNumFmtMapContext( GetImport(), nElement,
*this, xAttrList );
} break;
}
if( !pContext )
{
SAL_WARN("xmloff.core", "No context for unknown-element " << SvXMLImport::getPrefixAndNameFromToken(nElement));
pContext = new SvXMLImportContext(GetImport());
}
return pContext;
}
sal_Int32 SvXMLNumFormatContext::GetKey()
{ if (m_nKey > -1)
{ if (m_bRemoveAfterUse)
{ // format is used -> don't remove
m_bRemoveAfterUse = false; if (m_pData)
m_pData->SetUsed(m_nKey);
// Add to import's list of keys now - CreateAndInsert didn't add // the style if bRemoveAfterUse was set.
GetImport().AddNumberStyle( m_nKey, GetName() );
} return m_nKey;
} else
{ // reset bRemoveAfterUse before CreateAndInsert, so AddKey is called without bRemoveAfterUse set
m_bRemoveAfterUse = false;
CreateAndInsert(true); return m_nKey;
}
}
sal_Int32 SvXMLNumFormatContext::PrivateGetKey(std::vector<SvXMLNumFormatContext*>& rCreateStack)
{ // used for map elements in CreateAndInsert - don't reset bRemoveAfterUse flag
sal_Int32 SvXMLNumFormatContext::CreateAndInsert(SvNumberFormatter* pFormatter, std::vector<SvXMLNumFormatContext*>& rCreateStack)
{ if (!pFormatter)
{
OSL_FAIL("no number formatter"); return -1;
}
rCreateStack.push_back(this);
sal_uInt32 nIndex = NUMBERFORMAT_ENTRY_NOT_FOUND;
for (size_t i = 0; i < m_aMyConditions.size(); i++)
{
SvXMLNumFormatContext* pStyle = const_cast<SvXMLNumFormatContext*>( static_cast<const SvXMLNumFormatContext *>(m_pStyles->FindStyleChildContext(
XmlStyleFamily::DATA_STYLE, m_aMyConditions[i].sMapName))); if (std::find(rCreateStack.begin(), rCreateStack.end(), pStyle) != rCreateStack.end())
{
SAL_INFO("xmloff.style", "invalid style:map references containing style");
pStyle = nullptr;
} if (pStyle)
{ if (pStyle->PrivateGetKey(rCreateStack) > -1) // don't reset pStyle's bRemoveAfterUse flag
AddCondition(i);
}
}
sal_Int32 nBufLen; if ( m_aFormatCode.isEmpty() )
{ // insert empty format as empty string (with quotes) // #93901# this check has to be done before inserting the conditions
m_aFormatCode.append("\"\""); // ""
} elseif (m_bHasTrailingEmptyText && (nBufLen = m_aFormatCode.getLength()) >= 3)
{ // Remove a trailing empty text. Earlier this may had been written to // file, like in "General;General" written with elements for // 'General"";General""' (whyever); when reading, empty text was // ignored, which it isn't anymore, so get rid of those. if (m_aFormatCode[nBufLen-1] == '"' && m_aFormatCode[nBufLen-2] == '"')
m_aFormatCode.truncate( nBufLen - 2);
}
if ( m_bAutoDec ) // automatic decimal places
{ // #99391# adjust only if the format contains no text elements, no conditions // and no color definition (detected by the '[' at the start)
if ( m_nType == SvXMLStylesTokens::NUMBER_STYLE && !m_bHasExtraText &&
m_aMyConditions.empty() && sFormat.toChar() != '[' )
nIndex = pFormatter->GetStandardIndex( m_nFormatLang );
} if ( m_bAutoInt ) // automatic integer digits
{ //! only if two decimal places was set?
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.