Kaydet (Commit) f630f959 authored tarafından Laurent Balland-Poirier's avatar Laurent Balland-Poirier Kaydeden (comit) Eike Rathke

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/15606Reviewed-by: 's avatarEike Rathke <erack@redhat.com>
Tested-by: 's avatarEike Rathke <erack@redhat.com>
üst a5a17610
......@@ -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);
......@@ -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
{
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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment