include/xmloff/xmlnumfi.hxx      |   17 +++++++-
 xmloff/source/style/xmlnumfi.cxx |   82 ++++++++++++++++++++++++++++++---------
 2 files changed, 80 insertions(+), 19 deletions(-)

New commits:
commit 010d6d1562f309a2aee728f8e5590385cc6ce8fd
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Tue Mar 16 21:12:29 2021 +0100
Commit:     Eike Rathke <er...@redhat.com>
CommitDate: Sun Mar 21 12:36:02 2021 +0100

    ODF load: suppress calendar modifiers in format codes if possible
    
    ... for switching to/from implicit secondary calendar, like ja-JP
    explicit [~gengou] and [~gregorian] most times are superfluous and
    GE or YYYY are used.
    
    In preparation for https://gerrit.libreoffice.org/c/core/+/108532
    
    Change-Id: I8eb412c0fbba0927741bb305f91eb575b5f1bb13
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112596
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Jenkins

diff --git a/include/xmloff/xmlnumfi.hxx b/include/xmloff/xmlnumfi.hxx
index 1bf6c9228ed6..c863304bc293 100644
--- a/include/xmloff/xmlnumfi.hxx
+++ b/include/xmloff/xmlnumfi.hxx
@@ -115,6 +115,18 @@ struct MyCondition
 
 class XMLOFF_DLLPUBLIC SvXMLNumFormatContext : public SvXMLStyleContext
 {
+public:
+    enum ImplicitCalendar
+    {
+        DEFAULT,
+        SECONDARY,
+        OTHER,
+        DEFAULT_FROM_OTHER,
+        SECONDARY_FROM_OTHER
+    };
+
+private:
+
     SvXMLNumImpData*    pData;
     SvXMLStylesContext*             pStyles;
     std::vector <MyCondition>   aMyConditions;
@@ -124,6 +136,8 @@ class XMLOFF_DLLPUBLIC SvXMLNumFormatContext : public 
SvXMLStyleContext
     OUString       sFormatTitle;
 //  OUString       sMapName;
     OUString       sCalendar;
+    OUString       aImplicitCalendar[2];
+    ImplicitCalendar eImplicitCalendar;
     LanguageType   nFormatLang;
     bool            bAutoOrder;
     bool            bFromSystem;
@@ -178,7 +192,8 @@ public:
     void SetHasLongDoW(bool bSet)               { bHasLongDoW = bSet; }
     bool HasEra() const                         { return bHasEra; }
 
-    void UpdateCalendar( const OUString& rNewCalendar, bool 
bImplicitSecondaryCalendarEC = false );
+    void UpdateCalendar( const OUString& rNewCalendar );
+    ImplicitCalendar GetImplicitCalendarState() const { return 
eImplicitCalendar; }
 
     const LocaleDataWrapper& GetLocaleData() const;
 
diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx
index 734f572608b1..28dbe6574336 100644
--- a/xmloff/source/style/xmlnumfi.cxx
+++ b/xmloff/source/style/xmlnumfi.cxx
@@ -929,25 +929,17 @@ void SvXMLNumFmtElementContext::endFastElement(sal_Int32 )
                 // 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.
-                bool bImplicitEC = (!sCalendar.isEmpty() &&
-                        rParent.GetLocaleData().doesSecondaryCalendarUseEC( 
sCalendar));
-                if (bImplicitEC || (!sCalendar.isEmpty() && rParent.HasEra()
-                            && sCalendar != 
rParent.GetLocaleData().getDefaultCalendar()->Name))
+                rParent.UpdateCalendar( sCalendar);
+                const SvXMLNumFormatContext::ImplicitCalendar eCal = 
rParent.GetImplicitCalendarState();
+                if (eCal == SvXMLNumFormatContext::ImplicitCalendar::SECONDARY
+                        || eCal == 
SvXMLNumFormatContext::ImplicitCalendar::SECONDARY_FROM_OTHER)
                 {
-                    // If E or EE is the first format keyword, passing
-                    // bImplicitEC=true suppresses the superfluous calendar
-                    // modifier for this format. This does not help for
-                    // something like [~cal]DD/MM/EE but so far only YMD order
-                    // is used with such calendars. Live with the modifier if
-                    // other keywords precede this.
-                    rParent.UpdateCalendar( sCalendar, bImplicitEC);
                     rParent.AddNfKeyword(
                             sal::static_int_cast< sal_uInt16 >(
                                 bEffLong ? NF_KEY_EEC : NF_KEY_EC ) );
                 }
                 else
                 {
-                    rParent.UpdateCalendar( sCalendar );
                     rParent.AddNfKeyword(
                             sal::static_int_cast< sal_uInt16 >(
                                 bEffLong ? NF_KEY_YYYY : NF_KEY_YY ) );
@@ -1118,6 +1110,7 @@ SvXMLNumFormatContext::SvXMLNumFormatContext( 
SvXMLImport& rImport,
     aMyConditions(),
     nType( nNewType ),
     nKey(-1),
+    eImplicitCalendar(ImplicitCalendar::DEFAULT),
     nFormatLang( LANGUAGE_SYSTEM ),
     bAutoOrder( false ),
     bFromSystem( false ),
@@ -1254,6 +1247,7 @@ SvXMLNumFormatContext::SvXMLNumFormatContext( 
SvXMLImport& rImport,
     aMyConditions(),
     nType( SvXMLStylesTokens::NUMBER_STYLE ),
     nKey(nTempKey),
+    eImplicitCalendar(ImplicitCalendar::DEFAULT),
     nFormatLang( nLang ),
     bAutoOrder( false ),
     bFromSystem( false ),
@@ -2047,17 +2041,69 @@ void SvXMLNumFormatContext::AddColor( Color const 
nColor )
     }
 }
 
-void SvXMLNumFormatContext::UpdateCalendar( const OUString& rNewCalendar, bool 
bImplicitSecondaryCalendarEC )
+void SvXMLNumFormatContext::UpdateCalendar( const OUString& rNewCalendar )
 {
     if ( rNewCalendar != sCalendar )
     {
-        sCalendar = rNewCalendar;
-        if ( !sCalendar.isEmpty() && !bImplicitSecondaryCalendarEC )
+        if (rNewCalendar.isEmpty() || rNewCalendar == aImplicitCalendar[0])
+        {
+            eImplicitCalendar = (eImplicitCalendar == ImplicitCalendar::OTHER ?
+                    ImplicitCalendar::DEFAULT_FROM_OTHER : 
ImplicitCalendar::DEFAULT);
+        }
+        else if (aImplicitCalendar[0].isEmpty() && rNewCalendar == 
GetLocaleData().getDefaultCalendar()->Name)
+        {
+            eImplicitCalendar = (eImplicitCalendar == ImplicitCalendar::OTHER ?
+                    ImplicitCalendar::DEFAULT_FROM_OTHER : 
ImplicitCalendar::DEFAULT);
+            aImplicitCalendar[0] = rNewCalendar;
+        }
+        else if (rNewCalendar == aImplicitCalendar[1])
+        {
+            eImplicitCalendar = (eImplicitCalendar == ImplicitCalendar::OTHER ?
+                    ImplicitCalendar::SECONDARY_FROM_OTHER : 
ImplicitCalendar::SECONDARY);
+        }
+        else if (aImplicitCalendar[1].isEmpty() && 
GetLocaleData().doesSecondaryCalendarUseEC( rNewCalendar))
+        {
+            eImplicitCalendar = (eImplicitCalendar == ImplicitCalendar::OTHER ?
+                    ImplicitCalendar::SECONDARY_FROM_OTHER : 
ImplicitCalendar::SECONDARY);
+            aImplicitCalendar[1] = rNewCalendar;
+        }
+        else
         {
-            aFormatCode.append( "[~" );            // intro for calendar code
-            aFormatCode.append( sCalendar );
-            aFormatCode.append( ']' );    // end of calendar code
+            eImplicitCalendar = ImplicitCalendar::OTHER;
         }
+
+        if (eImplicitCalendar != ImplicitCalendar::DEFAULT && 
eImplicitCalendar != ImplicitCalendar::SECONDARY)
+        {
+            // A switch from empty default calendar to named default calendar 
or
+            // vice versa is not a switch.
+            bool bSameDefault = false;
+            if (sCalendar.isEmpty() || rNewCalendar.isEmpty())
+            {
+                // As both are not equal, only one can be empty here, the other
+                // can not.
+                const OUString& rDefaultCalendar = 
GetLocaleData().getDefaultCalendar()->Name;
+                // So if one is the named default calendar the other is the
+                // empty default calendar.
+                bSameDefault = (rNewCalendar == rDefaultCalendar || sCalendar 
== rDefaultCalendar);
+            }
+            if (!bSameDefault)
+            {
+                aFormatCode.append( "[~" );   // intro for calendar code
+                if (rNewCalendar.isEmpty())
+                {
+                    // Empty calendar name here means switching to default 
calendar
+                    // from a different calendar. Needs to be explicitly 
stated in
+                    // format code.
+                    aFormatCode.append( 
GetLocaleData().getDefaultCalendar()->Name );
+                }
+                else
+                {
+                    aFormatCode.append( rNewCalendar );
+                }
+                aFormatCode.append( ']' );    // end of calendar code
+            }
+        }
+        sCalendar = rNewCalendar;
     }
 }
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to