[Libreoffice-commits] core.git: cui/source include/svl include/svx svl/source svx/source

Laurent Balland-Poirier laurent.balland-poirier at laposte.net
Wed May 6 03:46:17 PDT 2015


 cui/source/dialogs/cuires.src   |   10 +++++
 cui/source/inc/cuires.hrc       |    3 +
 cui/source/inc/numfmt.hxx       |    3 +
 cui/source/tabpages/numfmt.cxx  |   38 ++++++++++++++++++-
 include/svl/zforlist.hxx        |    6 +++
 include/svl/zformat.hxx         |    3 +
 include/svx/numfmtsh.hxx        |    2 +
 svl/source/numbers/zforlist.cxx |   77 +++++++++++++++++++++++++++++++++-------
 svx/source/items/numfmtsh.cxx   |    7 +++
 9 files changed, 134 insertions(+), 15 deletions(-)

New commits:
commit f630f9598f2e328cbe37aff5af0e93c027a94de5
Author: Laurent Balland-Poirier <laurent.balland-poirier at laposte.net>
Date:   Sun May 3 15:09:20 2015 +0200

    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 at redhat.com>
    Tested-by: Eike Rathke <erack at redhat.com>

diff --git a/cui/source/dialogs/cuires.src b/cui/source/dialogs/cuires.src
index fe97a9c..a738423 100644
--- a/cui/source/dialogs/cuires.src
+++ b/cui/source/dialogs/cuires.src
@@ -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" ;
diff --git a/cui/source/inc/cuires.hrc b/cui/source/inc/cuires.hrc
index a8cf111..d6852c3 100644
--- a/cui/source/inc/cuires.hrc
+++ b/cui/source/inc/cuires.hrc
@@ -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
diff --git a/cui/source/inc/numfmt.hxx b/cui/source/inc/numfmt.hxx
index 65e9f1a..c4413ab 100644
--- a/cui/source/inc/numfmt.hxx
+++ b/cui/source/inc/numfmt.hxx
@@ -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 );
diff --git a/cui/source/tabpages/numfmt.cxx b/cui/source/tabpages/numfmt.cxx
index 352077e..5720e2d 100644
--- a/cui/source/tabpages/numfmt.cxx
+++ b/cui/source/tabpages/numfmt.cxx
@@ -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();
 }
 
 
@@ -1113,6 +1125,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
 #*------------------------------------------------------------------------
 #*
diff --git a/include/svl/zforlist.hxx b/include/svl/zforlist.hxx
index f488801..bc553c0 100644
--- a/include/svl/zforlist.hxx
+++ b/include/svl/zforlist.hxx
@@ -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
diff --git a/include/svl/zformat.hxx b/include/svl/zformat.hxx
index 08415f9..403ba29 100644
--- a/include/svl/zformat.hxx
+++ b/include/svl/zformat.hxx
@@ -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
diff --git a/include/svx/numfmtsh.hxx b/include/svx/numfmtsh.hxx
index 5d97267..a5b7ba4 100644
--- a/include/svx/numfmtsh.hxx
+++ b/include/svx/numfmtsh.hxx
@@ -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 );
diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx
index df271c3..04ee5d5 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -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) );
diff --git a/svx/source/items/numfmtsh.cxx b/svx/source/items/numfmtsh.cxx
index 0a10cba..ceb5dfb 100644
--- a/svx/source/items/numfmtsh.cxx
+++ b/svx/source/items/numfmtsh.cxx
@@ -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,


More information about the Libreoffice-commits mailing list