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 ...@@ -60,6 +60,16 @@ String RID_SVXSTR_AUTO_ENTRY
Text [ en-US ] = "Automatic"; 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 String RID_SVXSTR_EDIT_GRAPHIC
{ {
Text [ en-US ] = "Link" ; Text [ en-US ] = "Link" ;
......
...@@ -440,6 +440,9 @@ ...@@ -440,6 +440,9 @@
#define RID_SVXSTR_PERSONA_MUSIC (RID_SVX_START + 1288) #define RID_SVXSTR_PERSONA_MUSIC (RID_SVX_START + 1288)
#define RID_SVXSTR_PERSONA_NATURE (RID_SVX_START + 1289) #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) #define RID_SVXPAGE_OPENCL (RID_SVX_START + 254)
#endif #endif
......
...@@ -130,6 +130,8 @@ private: ...@@ -130,6 +130,8 @@ private:
short nFixedCategory; short nFixedCategory;
OUString sAutomaticEntry; OUString sAutomaticEntry;
OUString sThousandSeparator;
OUString sEngineeringNotation;
VclPtr<vcl::Window> pLastActivWindow; VclPtr<vcl::Window> pLastActivWindow;
...@@ -138,6 +140,7 @@ private: ...@@ -138,6 +140,7 @@ private:
void FillFormatListBox_Impl( std::vector<OUString>& rEntries ); void FillFormatListBox_Impl( std::vector<OUString>& rEntries );
void UpdateOptions_Impl( bool bCheckCatChange ); void UpdateOptions_Impl( bool bCheckCatChange );
void UpdateFormatListBox_Impl( bool bCat, bool bUpdateEdit ); void UpdateFormatListBox_Impl( bool bCat, bool bUpdateEdit );
void UpdateThousandEngineeringText();
void Obstructing(); void Obstructing();
void EnableBySourceFormat_Impl(); void EnableBySourceFormat_Impl();
void SetCategory( sal_uInt16 nPos ); void SetCategory( sal_uInt16 nPos );
......
...@@ -243,6 +243,8 @@ SvxNumberFormatTabPage::SvxNumberFormatTabPage(vcl::Window* pParent, ...@@ -243,6 +243,8 @@ SvxNumberFormatTabPage::SvxNumberFormatTabPage(vcl::Window* pParent,
, pNumFmtShell(NULL) , pNumFmtShell(NULL)
, nInitFormat(ULONG_MAX) , nInitFormat(ULONG_MAX)
, sAutomaticEntry(CUI_RES(RID_SVXSTR_AUTO_ENTRY)) , sAutomaticEntry(CUI_RES(RID_SVXSTR_AUTO_ENTRY))
, sThousandSeparator(CUI_RES(RID_SVXSTR_THOUSAND_SEP))
, sEngineeringNotation(CUI_RES(RID_SVXSTR_ENGINEERING))
, pLastActivWindow(NULL) , pLastActivWindow(NULL)
{ {
get(m_pFtCategory, "categoryft"); get(m_pFtCategory, "categoryft");
...@@ -355,6 +357,7 @@ void SvxNumberFormatTabPage::Init_Impl() ...@@ -355,6 +357,7 @@ void SvxNumberFormatTabPage::Init_Impl()
m_pIbAdd->SetClickHdl( HDL( ClickHdl_Impl ) ); m_pIbAdd->SetClickHdl( HDL( ClickHdl_Impl ) );
m_pIbRemove->SetClickHdl( HDL( ClickHdl_Impl ) ); m_pIbRemove->SetClickHdl( HDL( ClickHdl_Impl ) );
m_pIbInfo->SetClickHdl( HDL( ClickHdl_Impl ) ); m_pIbInfo->SetClickHdl( HDL( ClickHdl_Impl ) );
UpdateThousandEngineeringText();
aLink = LINK( this, SvxNumberFormatTabPage, LostFocusHdl_Impl); aLink = LINK( this, SvxNumberFormatTabPage, LostFocusHdl_Impl);
...@@ -907,7 +910,7 @@ void SvxNumberFormatTabPage::FillFormatListBox_Impl( std::vector<OUString>& rEnt ...@@ -907,7 +910,7 @@ void SvxNumberFormatTabPage::FillFormatListBox_Impl( std::vector<OUString>& rEnt
void SvxNumberFormatTabPage::UpdateOptions_Impl( bool bCheckCatChange /*= sal_False*/ ) 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_Int32 nCurCategory = m_pLbCategory->GetSelectEntryPos();
sal_uInt16 nCategory = static_cast<sal_uInt16>(nCurCategory); sal_uInt16 nCategory = static_cast<sal_uInt16>(nCurCategory);
sal_uInt16 nDecimals = 0; sal_uInt16 nDecimals = 0;
...@@ -965,10 +968,18 @@ void SvxNumberFormatTabPage::UpdateOptions_Impl( bool bCheckCatChange /*= sal_Fa ...@@ -965,10 +968,18 @@ void SvxNumberFormatTabPage::UpdateOptions_Impl( bool bCheckCatChange /*= sal_Fa
switch ( nCategory ) 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_NUMBER:
case CAT_PERCENT: case CAT_PERCENT:
case CAT_CURRENCY: case CAT_CURRENCY:
case CAT_SCIENTIFIC:
m_pFtOptions->Enable(); m_pFtOptions->Enable();
m_pFtDecimals->Enable(); m_pFtDecimals->Enable();
m_pEdDecimals->Enable(); m_pEdDecimals->Enable();
...@@ -1002,6 +1013,7 @@ void SvxNumberFormatTabPage::UpdateOptions_Impl( bool bCheckCatChange /*= sal_Fa ...@@ -1002,6 +1013,7 @@ void SvxNumberFormatTabPage::UpdateOptions_Impl( bool bCheckCatChange /*= sal_Fa
m_pBtnNegRed->Check( false ); m_pBtnNegRed->Check( false );
m_pBtnThousand->Check( false ); m_pBtnThousand->Check( false );
} }
UpdateThousandEngineeringText();
} }
...@@ -1112,6 +1124,28 @@ void SvxNumberFormatTabPage::UpdateFormatListBox_Impl ...@@ -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 #* Handle: DoubleClickHdl_Impl
#*------------------------------------------------------------------------ #*------------------------------------------------------------------------
......
...@@ -529,6 +529,9 @@ public: ...@@ -529,6 +529,9 @@ public:
/// Count of decimals /// Count of decimals
sal_uInt16 GetFormatPrecision( sal_uInt32 nFormat ) const; 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. /** 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 Uses a temporary parse, if possible use only if format code is not
present in container yet, otherwise ineffective. present in container yet, otherwise ineffective.
...@@ -885,6 +888,9 @@ private: ...@@ -885,6 +888,9 @@ private:
// link to be set at <method>SvtSysLocaleOptions::SetCurrencyChangeLink()</method> // link to be set at <method>SvtSysLocaleOptions::SetCurrencyChangeLink()</method>
DECL_DLLPRIVATE_STATIC_LINK( SvNumberFormatter, CurrencyChangeLink, void* ); 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: public:
// own static mutex, may also be used by internal class SvNumberFormatterRegistry_Impl // own static mutex, may also be used by internal class SvNumberFormatterRegistry_Impl
......
...@@ -231,6 +231,9 @@ public: ...@@ -231,6 +231,9 @@ public:
/// Count of decimal precision /// Count of decimal precision
sal_uInt16 GetFormatPrecision() const { return NumFor[0].Info().nCntPost; } 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 //! 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! //! standard format 0, 5000, ... and only by the number formatter!
sal_uInt16 GetLastInsertKey() const sal_uInt16 GetLastInsertKey() const
......
...@@ -128,6 +128,8 @@ public: ...@@ -128,6 +128,8 @@ public:
sal_uInt16& rLeadingZeroes, sal_uInt16& rLeadingZeroes,
sal_uInt16& rCatLbPos ); sal_uInt16& rCatLbPos );
sal_uInt16 GetFormatIntegerDigits( const OUString& rFormat ) const;
void MakePreviewString( const OUString& rFormatStr, void MakePreviewString( const OUString& rFormatStr,
OUString& rPreviewStr, OUString& rPreviewStr,
Color*& rpFontColor ); Color*& rpFontColor );
......
...@@ -1797,6 +1797,15 @@ sal_uInt16 SvNumberFormatter::GetFormatPrecision( sal_uInt32 nFormat ) const ...@@ -1797,6 +1797,15 @@ sal_uInt16 SvNumberFormatter::GetFormatPrecision( sal_uInt32 nFormat ) const
return pFormatScanner->GetStandardPrec(); 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 sal_Unicode SvNumberFormatter::GetDecSep() const
{ {
return GetNumDecimalSep()[0]; return GetNumDecimalSep()[0];
...@@ -2590,12 +2599,45 @@ void SvNumberFormatter::ImpGetNegCurrFormat(OUStringBuffer& sNegStr, const OUStr ...@@ -2590,12 +2599,45 @@ void SvNumberFormatter::ImpGetNegCurrFormat(OUStringBuffer& sNegStr, const OUStr
rCurrSymbol, xLocaleData->getCurrNegativeFormat() ); 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, OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex,
LanguageType eLnge, LanguageType eLnge,
bool bThousand, bool bThousand,
bool IsRed, bool IsRed,
sal_uInt16 nPrecision, sal_uInt16 nPrecision,
sal_uInt16 nAnzLeading) sal_uInt16 nLeadingZeros)
{ {
if (eLnge == LANGUAGE_DONTKNOW) if (eLnge == LANGUAGE_DONTKNOW)
{ {
...@@ -2606,7 +2648,8 @@ OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex, ...@@ -2606,7 +2648,8 @@ OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex,
ImpGenerateCL(eLnge); // create new standard formats if necessary ImpGenerateCL(eLnge); // create new standard formats if necessary
utl::DigitGroupingIterator aGrouping( xLocaleData->getDigitGrouping()); 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(); const OUString& rThSep = GetNumThousandSep();
SvNumberformat* pFormat = GetFormatEntry( nIndex ); SvNumberformat* pFormat = GetFormatEntry( nIndex );
...@@ -2614,20 +2657,27 @@ OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex, ...@@ -2614,20 +2657,27 @@ OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex,
OUStringBuffer sString; OUStringBuffer sString;
using comphelper::string::padToLength; using comphelper::string::padToLength;
if (nAnzLeading == 0) if (nLeadingZeros == 0)
{ {
if (!bThousand) if (!bThousand)
sString.append('#'); sString.append('#');
else else
{ {
sString.append('#'); if (eType == css::util::NumberFormat::SCIENTIFIC)
sString.append(rThSep); { // for scientific, bThousand is used for Engineering notation
padToLength(sString, sString.getLength() + nDigitsInFirstGroup, '#'); sString.append("###");
}
else
{
sString.append('#');
sString.append(rThSep);
padToLength(sString, sString.getLength() + nDigitsInFirstGroup, '#');
}
} }
} }
else else
{ {
for (i = 0; i < nAnzLeading; i++) for (i = 0; i < nLeadingZeros; i++)
{ {
if (bThousand && i > 0 && i == aGrouping.getPos()) if (bThousand && i > 0 && i == aGrouping.getPos())
{ {
...@@ -2636,11 +2686,12 @@ OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex, ...@@ -2636,11 +2686,12 @@ OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex,
} }
sString.insert(0, '0'); 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, rThSep);
sString.insert(0, '#'); sString.insert(0, '#');
} }
...@@ -2658,11 +2709,11 @@ OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex, ...@@ -2658,11 +2709,11 @@ OUString SvNumberFormatter::GenerateFormat(sal_uInt32 nIndex,
else if (eType == css::util::NumberFormat::SCIENTIFIC) else if (eType == css::util::NumberFormat::SCIENTIFIC)
{ {
OUStringBuffer sOldFormatString = pFormat->GetFormatstring(); OUStringBuffer sOldFormatString = pFormat->GetFormatstring();
sal_Int32 nIndexE = sOldFormatString.indexOf('E'); sal_Int32 nIndexE = ImpPosToken( sOldFormatString, 'E' );
if (nIndexE > -1) if (nIndexE > -1)
{ {
sal_Int32 nIndexSep = sOldFormatString.indexOf(';'); sal_Int32 nIndexSep = ImpPosToken( sOldFormatString, ';', nIndexE );
if (nIndexSep > -1) if (nIndexSep > nIndexE)
sString.append( sOldFormatString.copy(nIndexE, nIndexSep - nIndexE) ); sString.append( sOldFormatString.copy(nIndexE, nIndexSep - nIndexE) );
else else
sString.append( sOldFormatString.copy(nIndexE) ); sString.append( sOldFormatString.copy(nIndexE) );
......
...@@ -374,6 +374,13 @@ void SvxNumberFormatShell::MakeFormat( OUString& rFormat, ...@@ -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, void SvxNumberFormatShell::GetOptions( const OUString& rFormat,
bool& rThousand, 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