forked from amazingfate/loongoffice
tdf#90258 Toggle Thousand Separator with Engineering Notation
If scientific format is selected, "Thousands separator" option is almost useless. It could be replaced by "Engineering Notation". Rebase of https://gerrit.libreoffice.org/15152 Update with more robust tests. Change-Id: Ie2b88b1f149fce26c32a43ace623cf1f45f38e6e Reviewed-on: https://gerrit.libreoffice.org/15606 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com>
This commit is contained in:
committed by
Eike Rathke
parent
a5a17610d5
commit
f630f9598f
@ -60,6 +60,16 @@ String RID_SVXSTR_AUTO_ENTRY
|
||||
Text [ en-US ] = "Automatic";
|
||||
};
|
||||
|
||||
String RID_SVXSTR_THOUSAND_SEP
|
||||
{
|
||||
Text [ en-US ] = "Thousands separator";
|
||||
};
|
||||
|
||||
String RID_SVXSTR_ENGINEERING
|
||||
{
|
||||
Text [ en-US ] = "Engineering notation";
|
||||
};
|
||||
|
||||
String RID_SVXSTR_EDIT_GRAPHIC
|
||||
{
|
||||
Text [ en-US ] = "Link" ;
|
||||
|
||||
@ -440,6 +440,9 @@
|
||||
#define RID_SVXSTR_PERSONA_MUSIC (RID_SVX_START + 1288)
|
||||
#define RID_SVXSTR_PERSONA_NATURE (RID_SVX_START + 1289)
|
||||
|
||||
#define RID_SVXSTR_THOUSAND_SEP (RID_SVX_START + 1290)
|
||||
#define RID_SVXSTR_ENGINEERING (RID_SVX_START + 1291)
|
||||
|
||||
#define RID_SVXPAGE_OPENCL (RID_SVX_START + 254)
|
||||
|
||||
#endif
|
||||
|
||||
@ -130,6 +130,8 @@ private:
|
||||
short nFixedCategory;
|
||||
|
||||
OUString sAutomaticEntry;
|
||||
OUString sThousandSeparator;
|
||||
OUString sEngineeringNotation;
|
||||
|
||||
VclPtr<vcl::Window> pLastActivWindow;
|
||||
|
||||
@ -138,6 +140,7 @@ private:
|
||||
void FillFormatListBox_Impl( std::vector<OUString>& rEntries );
|
||||
void UpdateOptions_Impl( bool bCheckCatChange );
|
||||
void UpdateFormatListBox_Impl( bool bCat, bool bUpdateEdit );
|
||||
void UpdateThousandEngineeringText();
|
||||
void Obstructing();
|
||||
void EnableBySourceFormat_Impl();
|
||||
void SetCategory( sal_uInt16 nPos );
|
||||
|
||||
@ -243,6 +243,8 @@ SvxNumberFormatTabPage::SvxNumberFormatTabPage(vcl::Window* pParent,
|
||||
, pNumFmtShell(NULL)
|
||||
, nInitFormat(ULONG_MAX)
|
||||
, sAutomaticEntry(CUI_RES(RID_SVXSTR_AUTO_ENTRY))
|
||||
, sThousandSeparator(CUI_RES(RID_SVXSTR_THOUSAND_SEP))
|
||||
, sEngineeringNotation(CUI_RES(RID_SVXSTR_ENGINEERING))
|
||||
, pLastActivWindow(NULL)
|
||||
{
|
||||
get(m_pFtCategory, "categoryft");
|
||||
@ -355,6 +357,7 @@ void SvxNumberFormatTabPage::Init_Impl()
|
||||
m_pIbAdd->SetClickHdl( HDL( ClickHdl_Impl ) );
|
||||
m_pIbRemove->SetClickHdl( HDL( ClickHdl_Impl ) );
|
||||
m_pIbInfo->SetClickHdl( HDL( ClickHdl_Impl ) );
|
||||
UpdateThousandEngineeringText();
|
||||
|
||||
aLink = LINK( this, SvxNumberFormatTabPage, LostFocusHdl_Impl);
|
||||
|
||||
@ -907,7 +910,7 @@ void SvxNumberFormatTabPage::FillFormatListBox_Impl( std::vector<OUString>& rEnt
|
||||
|
||||
void SvxNumberFormatTabPage::UpdateOptions_Impl( bool bCheckCatChange /*= sal_False*/ )
|
||||
{
|
||||
OUString theFormat = m_pEdFormat->GetText();
|
||||
OUString theFormat = m_pEdFormat->GetText();
|
||||
sal_Int32 nCurCategory = m_pLbCategory->GetSelectEntryPos();
|
||||
sal_uInt16 nCategory = static_cast<sal_uInt16>(nCurCategory);
|
||||
sal_uInt16 nDecimals = 0;
|
||||
@ -965,10 +968,18 @@ void SvxNumberFormatTabPage::UpdateOptions_Impl( bool bCheckCatChange /*= sal_Fa
|
||||
|
||||
switch ( nCategory )
|
||||
{
|
||||
case CAT_SCIENTIFIC: // bThousand is for Engineering notation
|
||||
{
|
||||
sal_uInt16 nIntDigits = pNumFmtShell->GetFormatIntegerDigits(theFormat);
|
||||
if ( (nIntDigits > 0) && (nIntDigits % 3 == 0) )
|
||||
bThousand = true;
|
||||
else
|
||||
bThousand = false;
|
||||
}
|
||||
// fallthru
|
||||
case CAT_NUMBER:
|
||||
case CAT_PERCENT:
|
||||
case CAT_CURRENCY:
|
||||
case CAT_SCIENTIFIC:
|
||||
m_pFtOptions->Enable();
|
||||
m_pFtDecimals->Enable();
|
||||
m_pEdDecimals->Enable();
|
||||
@ -1002,6 +1013,7 @@ void SvxNumberFormatTabPage::UpdateOptions_Impl( bool bCheckCatChange /*= sal_Fa
|
||||
m_pBtnNegRed->Check( false );
|
||||
m_pBtnThousand->Check( false );
|
||||
}
|
||||
UpdateThousandEngineeringText();
|
||||
}
|
||||
|
||||
|
||||
@ -1112,6 +1124,28 @@ void SvxNumberFormatTabPage::UpdateFormatListBox_Impl
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
#* Method: UpdateThousandEngineeringText
|
||||
#*------------------------------------------------------------------------
|
||||
#*
|
||||
#* Class: SvxNumberFormatTabPage
|
||||
#* Function: Updates the text of Thousands seprator checkbox
|
||||
#* if scientific format "Engineering notation"
|
||||
#* else "Thousands separator"
|
||||
#* Input: ---
|
||||
#* Output: ---
|
||||
#*
|
||||
#************************************************************************/
|
||||
|
||||
void SvxNumberFormatTabPage::UpdateThousandEngineeringText()
|
||||
{
|
||||
if ( m_pLbCategory->GetSelectEntryPos() == CAT_SCIENTIFIC )
|
||||
m_pBtnThousand->SetText(sEngineeringNotation);
|
||||
else
|
||||
m_pBtnThousand->SetText(sThousandSeparator);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
#* Handle: DoubleClickHdl_Impl
|
||||
#*------------------------------------------------------------------------
|
||||
|
||||
@ -529,6 +529,9 @@ public:
|
||||
/// Count of decimals
|
||||
sal_uInt16 GetFormatPrecision( sal_uInt32 nFormat ) const;
|
||||
|
||||
/// Count of integer digits
|
||||
sal_uInt16 GetFormatIntegerDigits( sal_uInt32 nFormat ) const;
|
||||
|
||||
/** Get additional info of a format code string, e.g. for dialog box.
|
||||
Uses a temporary parse, if possible use only if format code is not
|
||||
present in container yet, otherwise ineffective.
|
||||
@ -885,6 +888,9 @@ private:
|
||||
// link to be set at <method>SvtSysLocaleOptions::SetCurrencyChangeLink()</method>
|
||||
DECL_DLLPRIVATE_STATIC_LINK( SvNumberFormatter, CurrencyChangeLink, void* );
|
||||
|
||||
// return position of a special character
|
||||
sal_Int32 ImpPosToken ( const OUStringBuffer & sFormat, sal_Unicode token, sal_Int32 nStartPos = 0 );
|
||||
|
||||
public:
|
||||
|
||||
// own static mutex, may also be used by internal class SvNumberFormatterRegistry_Impl
|
||||
|
||||
@ -231,6 +231,9 @@ public:
|
||||
/// Count of decimal precision
|
||||
sal_uInt16 GetFormatPrecision() const { return NumFor[0].Info().nCntPost; }
|
||||
|
||||
/// Count of integer digits
|
||||
sal_uInt16 GetFormatIntegerDigits() const { return NumFor[0].Info().nCntPre; }
|
||||
|
||||
//! Read/write access on a special sal_uInt16 component, may only be used on the
|
||||
//! standard format 0, 5000, ... and only by the number formatter!
|
||||
sal_uInt16 GetLastInsertKey() const
|
||||
|
||||
@ -128,6 +128,8 @@ public:
|
||||
sal_uInt16& rLeadingZeroes,
|
||||
sal_uInt16& rCatLbPos );
|
||||
|
||||
sal_uInt16 GetFormatIntegerDigits( const OUString& rFormat ) const;
|
||||
|
||||
void MakePreviewString( const OUString& rFormatStr,
|
||||
OUString& rPreviewStr,
|
||||
Color*& rpFontColor );
|
||||
|
||||
@ -1797,6 +1797,15 @@ sal_uInt16 SvNumberFormatter::GetFormatPrecision( sal_uInt32 nFormat ) const
|
||||
return pFormatScanner->GetStandardPrec();
|
||||
}
|
||||
|
||||
sal_uInt16 SvNumberFormatter::GetFormatIntegerDigits( sal_uInt32 nFormat ) const
|
||||
{
|
||||
const SvNumberformat* pFormat = GetFormatEntry( nFormat );
|
||||
if ( pFormat )
|
||||
return pFormat->GetFormatIntegerDigits();
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
sal_Unicode SvNumberFormatter::GetDecSep() const
|
||||
{
|
||||
return GetNumDecimalSep()[0];
|
||||
@ -2590,12 +2599,45 @@ void SvNumberFormatter::ImpGetNegCurrFormat(OUStringBuffer& sNegStr, const OUStr
|
||||
rCurrSymbol, xLocaleData->getCurrNegativeFormat() );
|
||||
}
|
||||
|
||||
sal_Int32 SvNumberFormatter::ImpPosToken ( const OUStringBuffer & sFormat, sal_Unicode token, sal_Int32 nStartPos /* = 0*/ )
|
||||
{
|
||||
sal_Int32 nLength = sFormat.getLength();
|
||||
for ( sal_Int32 i=nStartPos; i<nLength && i>=0 ; i++ )
|
||||
{
|
||||
switch(sFormat[i])
|
||||
{
|
||||
case '\"' : // skip text
|
||||
i = sFormat.indexOf('\"',i+1);
|
||||
break;
|
||||
case '[' : // skip condition
|
||||
i = sFormat.indexOf(']',i+1);
|
||||
break;
|
||||
case '\\' : // skip escaped character
|
||||
i++;
|
||||
break;
|
||||
case ';' :
|
||||
if (token == ';')
|
||||
return i;
|
||||
break;
|
||||
case 'e' :
|
||||
case 'E' :
|
||||
if (token == 'E')
|
||||
return i; // if 'E' is outside "" and [] it must be the 'E' exponent
|
||||
break;
|
||||
default : break;
|
||||
}
|
||||
if ( i<0 )
|
||||
i--;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex,
|
||||
LanguageType eLnge,
|
||||
bool bThousand,
|
||||
bool IsRed,
|
||||
sal_uInt16 nPrecision,
|
||||
sal_uInt16 nAnzLeading)
|
||||
sal_uInt16 nLeadingZeros)
|
||||
{
|
||||
if (eLnge == LANGUAGE_DONTKNOW)
|
||||
{
|
||||
@ -2606,7 +2648,8 @@ OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex,
|
||||
ImpGenerateCL(eLnge); // create new standard formats if necessary
|
||||
|
||||
utl::DigitGroupingIterator aGrouping( xLocaleData->getDigitGrouping());
|
||||
const sal_Int32 nDigitsInFirstGroup = aGrouping.get();
|
||||
// always group of 3 for Engineering notation
|
||||
const sal_Int32 nDigitsInFirstGroup = ( bThousand && (eType == css::util::NumberFormat::SCIENTIFIC) ) ? 3 : aGrouping.get();
|
||||
const OUString& rThSep = GetNumThousandSep();
|
||||
|
||||
SvNumberformat* pFormat = GetFormatEntry( nIndex );
|
||||
@ -2614,20 +2657,27 @@ OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex,
|
||||
OUStringBuffer sString;
|
||||
using comphelper::string::padToLength;
|
||||
|
||||
if (nAnzLeading == 0)
|
||||
if (nLeadingZeros == 0)
|
||||
{
|
||||
if (!bThousand)
|
||||
sString.append('#');
|
||||
else
|
||||
{
|
||||
sString.append('#');
|
||||
sString.append(rThSep);
|
||||
padToLength(sString, sString.getLength() + nDigitsInFirstGroup, '#');
|
||||
if (eType == css::util::NumberFormat::SCIENTIFIC)
|
||||
{ // for scientific, bThousand is used for Engineering notation
|
||||
sString.append("###");
|
||||
}
|
||||
else
|
||||
{
|
||||
sString.append('#');
|
||||
sString.append(rThSep);
|
||||
padToLength(sString, sString.getLength() + nDigitsInFirstGroup, '#');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < nAnzLeading; i++)
|
||||
for (i = 0; i < nLeadingZeros; i++)
|
||||
{
|
||||
if (bThousand && i > 0 && i == aGrouping.getPos())
|
||||
{
|
||||
@ -2636,11 +2686,12 @@ OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex,
|
||||
}
|
||||
sString.insert(0, '0');
|
||||
}
|
||||
if (bThousand && nAnzLeading < nDigitsInFirstGroup + 1)
|
||||
if ( bThousand )
|
||||
{
|
||||
for (i = nAnzLeading; i < nDigitsInFirstGroup + 1; i++)
|
||||
sal_Int32 nDigits = (eType == css::util::NumberFormat::SCIENTIFIC) ? 3*((nLeadingZeros-1)/3 + 1) : nDigitsInFirstGroup + 1;
|
||||
for (i = nLeadingZeros; i < nDigits; i++)
|
||||
{
|
||||
if (bThousand && i % nDigitsInFirstGroup == 0)
|
||||
if ( i % nDigitsInFirstGroup == 0 )
|
||||
sString.insert(0, rThSep);
|
||||
sString.insert(0, '#');
|
||||
}
|
||||
@ -2658,11 +2709,11 @@ OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex,
|
||||
else if (eType == css::util::NumberFormat::SCIENTIFIC)
|
||||
{
|
||||
OUStringBuffer sOldFormatString = pFormat->GetFormatstring();
|
||||
sal_Int32 nIndexE = sOldFormatString.indexOf('E');
|
||||
sal_Int32 nIndexE = ImpPosToken( sOldFormatString, 'E' );
|
||||
if (nIndexE > -1)
|
||||
{
|
||||
sal_Int32 nIndexSep = sOldFormatString.indexOf(';');
|
||||
if (nIndexSep > -1)
|
||||
sal_Int32 nIndexSep = ImpPosToken( sOldFormatString, ';', nIndexE );
|
||||
if (nIndexSep > nIndexE)
|
||||
sString.append( sOldFormatString.copy(nIndexE, nIndexSep - nIndexE) );
|
||||
else
|
||||
sString.append( sOldFormatString.copy(nIndexE) );
|
||||
|
||||
@ -374,6 +374,13 @@ void SvxNumberFormatShell::MakeFormat( OUString& rFormat,
|
||||
}
|
||||
|
||||
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user