[Libreoffice-commits] core.git: include/xmloff offapi/com sw/inc sw/qa sw/source xmloff/inc xmloff/source

László Németh nemeth at numbertext.org
Fri Feb 2 08:07:13 UTC 2018


 include/xmloff/xmltoken.hxx                         |    3 
 offapi/com/sun/star/text/textfield/GetReference.idl |   13 +
 sw/inc/reffld.hxx                                   |    3 
 sw/inc/strings.hrc                                  |    3 
 sw/inc/unoprnms.hxx                                 |    1 
 sw/qa/extras/uiwriter/uiwriter.cxx                  |   12 -
 sw/source/core/fields/reffld.cxx                    |  173 +++++++++++++++++++-
 sw/source/core/unocore/unofield.cxx                 |    1 
 sw/source/core/unocore/unomap.cxx                   |    1 
 sw/source/filter/ww8/ww8par5.cxx                    |    8 
 sw/source/ui/fldui/fldref.cxx                       |   58 ++++++
 sw/source/uibase/fldui/fldmgr.cxx                   |   16 +
 xmloff/inc/txtflde.hxx                              |    1 
 xmloff/inc/txtfldi.hxx                              |    2 
 xmloff/source/core/xmltoken.cxx                     |    2 
 xmloff/source/text/txtflde.cxx                      |   22 ++
 xmloff/source/text/txtfldi.cxx                      |    4 
 xmloff/source/text/txtimp.cxx                       |    4 
 18 files changed, 311 insertions(+), 16 deletions(-)

New commits:
commit 1037e3759bf178b52d16c12a811717f94ab9950a
Author: László Németh <nemeth at numbertext.org>
Date:   Wed Jan 31 16:35:05 2018 +0100

    tdf#115319 references with Hungarian articles
    
    Add new alternative reference formats, stored by
    the proposed text:reference-language attribute.
    
    This is an implementation of the ODF improvement draft
    published in the bug report.
    
    Note: choose Hungarian locale setting to show the
    new "Article a/az + Page" etc. reference formats
    in dialog window "Fields".
    
    Change-Id: I210d4b9a3e821fb4e45e24643bad9c70b867c89d
    Reviewed-on: https://gerrit.libreoffice.org/48944
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 175187ae6897..531c81889742 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -3300,6 +3300,9 @@ namespace xmloff { namespace token {
         XML_ZEROS_DENOMINATOR_DIGITS,
         XML_INTEGER_FRACTION_DELIMITER,
 
+        // tdf#115319
+        XML_REFERENCE_LANGUAGE,
+
         XML_TOKEN_END
     };
 
diff --git a/offapi/com/sun/star/text/textfield/GetReference.idl b/offapi/com/sun/star/text/textfield/GetReference.idl
index 110d13c95d26..f561053c8bd9 100644
--- a/offapi/com/sun/star/text/textfield/GetReference.idl
+++ b/offapi/com/sun/star/text/textfield/GetReference.idl
@@ -54,6 +54,19 @@ published service GetReference
         @see com::sun::star::text::Footnote
      */
     [property] short SequenceNumber;
+    /** contains the language id of the alternative language-dependent references.
+        <p> Alternative language-dependent forms of reference types. </p>
+
+        @since LibreOffice 6.1
+
+        <p> The current set of supported languages is:
+        <ul>
+            <li>hu : Hungarian, reference with lowercase article "a" or "az"</li>
+            <li>Hu : Hungarian, reference with uppercase article "A" or "Az"</li>
+        </ul>
+        </p>
+     */
+    [optional, property] string ReferenceFieldLanguage;
 };
 
 
diff --git a/sw/inc/reffld.hxx b/sw/inc/reffld.hxx
index cbc19e181798..8a9987b9ab87 100644
--- a/sw/inc/reffld.hxx
+++ b/sw/inc/reffld.hxx
@@ -82,6 +82,7 @@ class SW_DLLPUBLIC SwGetRefField : public SwField
 {
 private:
     OUString sSetRefName;
+    OUString sSetReferenceLanguage;
     OUString sText;
     sal_uInt16 nSubType;
     sal_uInt16 nSeqNo;
@@ -95,7 +96,7 @@ private:
                           const sal_uInt32 nRefNumFormat );
 
 public:
-    SwGetRefField( SwGetRefFieldType*, const OUString& rSetRef,
+    SwGetRefField( SwGetRefFieldType*, const OUString& rSetRef, const OUString& rReferenceLanguage,
                     sal_uInt16 nSubType, sal_uInt16 nSeqNo, sal_uLong nFormat );
 
     virtual ~SwGetRefField() override;
diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc
index e1c40138fcbb..427835045393 100644
--- a/sw/inc/strings.hrc
+++ b/sw/inc/strings.hrc
@@ -977,6 +977,9 @@
 #define FMT_REF_NUMBER                          NC_("FMT_REF_NUMBER", "Number")
 #define FMT_REF_NUMBER_NO_CONTEXT               NC_("FMT_REF_NUMBER_NO_CONTEXT", "Number (no context)")
 #define FMT_REF_NUMBER_FULL_CONTEXT             NC_("FMT_REF_NUMBER_FULL_CONTEXT", "Number (full context)")
+
+#define FMT_REF_WITH_LOWERCASE_HU_ARTICLE       NC_("FMT_REF_WITH_LOWERCASE_HU_ARTICLE", "Article a/az + ")
+#define FMT_REF_WITH_UPPERCASE_HU_ARTICLE       NC_("FMT_REF_WITH_UPPERCASE_HU_ARTICLE", "Article A/Az + ")
 /*--------------------------------------------------------------------
     Description: placeholder
  --------------------------------------------------------------------*/
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index cb4e45a131f6..21e68ea83296 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -287,6 +287,7 @@
 #define UNO_NAME_PRINT "Print"
 #define UNO_NAME_REFERENCE_FIELD_PART "ReferenceFieldPart"
 #define UNO_NAME_REFERENCE_FIELD_SOURCE "ReferenceFieldSource"
+#define UNO_NAME_REFERENCE_FIELD_LANGUAGE "ReferenceFieldLanguage"
 #define UNO_NAME_REGISTER_PARAGRAPH_STYLE "RegisterParagraphStyle"
 #define UNO_NAME_SCRIPT_TYPE "ScriptType"
 #define UNO_NAME_SEARCH_ALL "SearchAll"
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index a87abf1d4bff..b2a7aaf44d74 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -2434,14 +2434,14 @@ void SwUiWriterTest::testTdf77342()
     //moving cursor to the starting of document
     pWrtShell->SttDoc();
     //inserting reference field 1
-    SwGetRefField aField1(pRefType, "", REF_FOOTNOTE, sal_uInt16(0), REF_CONTENT);
+    SwGetRefField aField1(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(0), REF_CONTENT);
     pWrtShell->Insert(aField1);
     //inserting second footnote
     pWrtShell->InsertFootnote("");
     pWrtShell->SttDoc();
     pCursor->Move(fnMoveForward);
     //inserting reference field 2
-    SwGetRefField aField2(pRefType, "", REF_FOOTNOTE, sal_uInt16(1), REF_CONTENT);
+    SwGetRefField aField2(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(1), REF_CONTENT);
     pWrtShell->Insert(aField2);
     //inserting third footnote
     pWrtShell->InsertFootnote("");
@@ -2449,7 +2449,7 @@ void SwUiWriterTest::testTdf77342()
     pCursor->Move(fnMoveForward);
     pCursor->Move(fnMoveForward);
     //inserting reference field 3
-    SwGetRefField aField3(pRefType, "", REF_FOOTNOTE, sal_uInt16(2), REF_CONTENT);
+    SwGetRefField aField3(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(2), REF_CONTENT);
     pWrtShell->Insert(aField3);
     //updating the fields
     IDocumentFieldsAccess& rField(pDoc->getIDocumentFieldsAccess());
@@ -2676,7 +2676,7 @@ void SwUiWriterTest::testTdf63553()
     //moving cursor to the starting of document
     pWrtShell->SttDoc();
     //inserting reference field 1
-    SwGetRefField aGetField1(pRefType, "Illustration", REF_SEQUENCEFLD, sal_uInt16(0), REF_CONTENT);
+    SwGetRefField aGetField1(pRefType, "Illustration", "", REF_SEQUENCEFLD, sal_uInt16(0), REF_CONTENT);
     pWrtShell->Insert(aGetField1);
     //now we have ref1-seq1
     //moving the cursor
@@ -2688,7 +2688,7 @@ void SwUiWriterTest::testTdf63553()
     pWrtShell->SttDoc();
     pCursor->Move(fnMoveForward);
     //inserting reference field 2
-    SwGetRefField aGetField2(pRefType, "Illustration", REF_SEQUENCEFLD, sal_uInt16(1), REF_CONTENT);
+    SwGetRefField aGetField2(pRefType, "Illustration", "", REF_SEQUENCEFLD, sal_uInt16(1), REF_CONTENT);
     pWrtShell->Insert(aGetField2);
     //now we have ref1-ref2-seq1-seq2
     //moving the cursor
@@ -2701,7 +2701,7 @@ void SwUiWriterTest::testTdf63553()
     pCursor->Move(fnMoveForward);
     pCursor->Move(fnMoveForward);
     //inserting reference field 3
-    SwGetRefField aGetField3(pRefType, "Illustration", REF_SEQUENCEFLD, sal_uInt16(2), REF_CONTENT);
+    SwGetRefField aGetField3(pRefType, "Illustration", "", REF_SEQUENCEFLD, sal_uInt16(2), REF_CONTENT);
     pWrtShell->Insert(aGetField3);
     //now after insertion we have ref1-ref2-ref3-seq1-seq2-seq3
     //updating the fields
diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx
index c0749e131509..cf7eafe65497 100644
--- a/sw/source/core/fields/reffld.cxx
+++ b/sw/source/core/fields/reffld.cxx
@@ -20,6 +20,7 @@
 #include <com/sun/star/text/ReferenceFieldPart.hpp>
 #include <com/sun/star/text/ReferenceFieldSource.hpp>
 #include <unotools/localedatawrapper.hxx>
+#include <unotools/charclass.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/string.hxx>
 #include <editeng/unolingu.hxx>
@@ -196,12 +197,151 @@ bool IsFrameBehind( const SwTextNode& rMyNd, sal_Int32 nMySttPos,
     return bRefIsLower;
 }
 
+// tdf#115319 create alternative reference formats, if the user asked for it
+// (ReferenceFieldLanguage attribute of the reference field is not empty), and
+// language of the text and ReferenceFieldLanguage are the same.
+// Right now only HUNGARIAN seems to need this (as in the related issue,
+// the reversed caption order in autocaption, solved by #i61007#)
+static void lcl_formatReferenceLanguage( OUString& rRefText,
+                                         bool bClosingParenthesis, LanguageType eLang,
+                                         const OUString& rReferenceLanguage)
+{
+    if (eLang != LANGUAGE_HUNGARIAN || (rReferenceLanguage != "hu" && rReferenceLanguage != "Hu"))
+        return;
+
+    // Add Hungarian definitive article (a/az) before references,
+    // similar to \aref, \apageref etc. of LaTeX Babel package.
+    //
+    // for example:
+    //
+    //     "az 1. oldalon" ("on page 1"), but
+    //     "a 2. oldalon" ("on page 2")
+    //     "a fentebbi", "az alábbi" (above/below)
+    //     "a Lorem", "az Ipsum"
+    //
+    // Support following numberings of EU publications:
+    //
+    // 1., 1a., a), (1), (1a), iii., III., IA.
+    //
+    // (http://publications.europa.eu/code/hu/hu-120700.htm,
+    // http://publications.europa.eu/code/hu/hu-4100600.htm)
+
+    LanguageTag aLanguageTag(eLang);
+    CharClass aCharClass( aLanguageTag );
+    sal_Int32 nLen = rRefText.getLength();
+    sal_Int32 i;
+    // substring of rRefText starting with letter or number
+    OUString sNumbering;
+    // is article "az"?
+    bool bArticleAz = false;
+    // is numbering a number?
+    bool bNum = false;
+
+    // search first member of the numbering (numbers or letters)
+    for (i=0; i<nLen && (sNumbering.isEmpty() ||
+                ((bNum && aCharClass.isDigit(rRefText, i)) ||
+                (!bNum && aCharClass.isLetter(rRefText, i)))); ++i)
+    {
+      // start of numbering within the field text
+      if (sNumbering.isEmpty() && aCharClass.isLetterNumeric(rRefText, i)) {
+          sNumbering = rRefText.copy(i);
+          bNum = aCharClass.isDigit(rRefText, i);
+      }
+    }
+
+    // length of numbering
+    nLen = i - (rRefText.getLength() - sNumbering.getLength());
+
+    if (bNum)
+    {
+        // az 1, 1000, 1000000, 1000000000...
+        // az 5, 50, 500...
+        if ((sNumbering.startsWith("1") && (nLen == 1 || nLen == 4 || nLen == 7 || nLen == 10)) ||
+            sNumbering.startsWith("5"))
+                bArticleAz = true;
+    }
+    else if (nLen == 1 && sNumbering[0] < 128)
+    {
+        // ASCII 1-letter numbering
+        // az a), e), f) ... x)
+        // az i., v. (but, a x.)
+        static OUString sLettersStartingWithVowels = "aefilmnorsuxyAEFILMNORSUXY";
+        if (sLettersStartingWithVowels.indexOf(sNumbering[0]) != -1)
+        {
+            // x),  X) are letters, but x. and X. etc. are Roman numbers
+            if (bClosingParenthesis ||
+                (sNumbering[0] != 'x' && sNumbering[0] != 'X'))
+                    bArticleAz = true;
+        } else if ((sNumbering[0] == 'v' || sNumbering[0] == 'V') && !bClosingParenthesis)
+            // v), V) are letters, but v. and V. are Roman numbers
+            bArticleAz = true;
+    }
+    else
+    {
+        static const sal_Unicode sVowelsWithDiacritic[] = {
+            0x00E1, 0x00C1, 0x00E9, 0x00C9, 0x00ED, 0x00CD,
+            0x00F3, 0x00D3, 0x00F6, 0x00D6, 0x0151, 0x0150,
+            0x00FA, 0x00DA, 0x00FC, 0x00DC, 0x0171, 0x0170, 0 };
+        static OUString sVowels = "aAeEoOuU" + OUString(sVowelsWithDiacritic);
+
+        // handle more than 1-letter long Roman numbers and
+        // their possible combinations with letters:
+        // az IA, a IIB, a IIIC., az Ia, a IIb., a iiic), az LVIII. szonett
+        bool bRomanNumber = false;
+        if (nLen > 1 && (nLen + 1 >= sNumbering.getLength() || sNumbering[nLen] == '.'))
+        {
+            sal_Unicode last = sNumbering[nLen - 1];
+            OUString sNumberingTrim;
+            if ((last >= 'A' && last < 'I') || (last >= 'a' && last < 'i'))
+                sNumberingTrim = sNumbering.copy(0, nLen - 1);
+            else
+                sNumberingTrim = sNumbering.copy(0, nLen);
+            bRomanNumber =
+                sNumberingTrim.replaceAll("i", "").replaceAll("v", "").replaceAll("x", "").replaceAll("l", "").replaceAll("c", "").isEmpty() ||
+                sNumberingTrim.replaceAll("I", "").replaceAll("V", "").replaceAll("X", "").replaceAll("L", "").replaceAll("C", "").isEmpty();
+        }
+
+        if (
+             // Roman number and a letter optionally
+             ( bRomanNumber && (
+                  (sNumbering[0] == 'i' && sNumbering[1] != 'i' && sNumbering[1] != 'v' && sNumbering[1] != 'x') ||
+                  (sNumbering[0] == 'I' && sNumbering[1] != 'I' && sNumbering[1] != 'V' && sNumbering[1] != 'X') ||
+                  (sNumbering[0] == 'v' && sNumbering[1] != 'i') ||
+                  (sNumbering[0] == 'V' && sNumbering[1] != 'I') ||
+                  (sNumbering[0] == 'l' && sNumbering[1] != 'x') ||
+                  (sNumbering[0] == 'L' && sNumbering[1] != 'X')) ) ||
+             // a word starting with vowel (not Roman number)
+             ( !bRomanNumber && sVowels.indexOf(sNumbering[0]) != -1))
+        {
+            bArticleAz = true;
+        }
+    }
+    // not a title text starting already with a definitive article
+    if ( !sNumbering.startsWith("A ") && !sNumbering.startsWith("Az ") &&
+         !sNumbering.startsWith("a ") && !sNumbering.startsWith("az ") )
+    {
+        // lowercase, if rReferenceLanguage == "hu", not "Hu"
+        OUString sArticle;
+
+        if ( rReferenceLanguage == "hu" )
+            sArticle = "a";
+        else
+            sArticle = "A";
+
+        if (bArticleAz)
+            sArticle += "z";
+
+        rRefText = sArticle + " " + rRefText;
+    }
+}
+
 /// get references
 SwGetRefField::SwGetRefField( SwGetRefFieldType* pFieldType,
-                              const OUString& rSetRef, sal_uInt16 nSubTyp,
+                              const OUString& rSetRef, const OUString& rSetReferenceLanguage, sal_uInt16 nSubTyp,
                               sal_uInt16 nSequenceNo, sal_uLong nFormat )
     : SwField( pFieldType, nFormat ),
       sSetRefName( rSetRef ),
+      sSetReferenceLanguage( rSetReferenceLanguage ),
       nSubType( nSubTyp ),
       nSeqNo( nSequenceNo )
 {
@@ -380,6 +520,8 @@ void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr )
                     if( nSeqNo == pFootnoteIdx->GetSeqRefNo() )
                     {
                         sText = pFootnoteIdx->GetFootnote().GetViewNumStr( *pDoc );
+                        if (!sSetReferenceLanguage.isEmpty())
+                            lcl_formatReferenceLanguage(sText, false, GetLanguage(), sSetReferenceLanguage);
                         break;
                     }
                 }
@@ -413,6 +555,8 @@ void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr )
                         }
                     }
                     sText = aBuf.makeStringAndClear();
+                    if (!sSetReferenceLanguage.isEmpty())
+                        lcl_formatReferenceLanguage(sText, false, GetLanguage(), sSetReferenceLanguage);
                 }
             }
         }
@@ -436,6 +580,9 @@ void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr )
                     sText = pPage->GetPageDesc()->GetNumType().GetNumStr( nPageNo );
                 else
                     sText = OUString::number(nPageNo);
+
+                if (!sSetReferenceLanguage.isEmpty())
+                    lcl_formatReferenceLanguage(sText, false, GetLanguage(), sSetReferenceLanguage);
             }
         }
         break;
@@ -451,6 +598,10 @@ void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr )
                 aField.SetLevel( MAXLEVEL - 1 );
                 aField.ChangeExpansion( pFrame, pTextNd, true );
                 sText = aField.GetNumber();
+
+                if (!sSetReferenceLanguage.isEmpty())
+                    lcl_formatReferenceLanguage(sText, false, GetLanguage(), sSetReferenceLanguage);
+
             }
         }
         break;
@@ -478,6 +629,9 @@ void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr )
                                     *pTextNd, nNumStart )
                         ? aLocaleData.getAboveWord()
                         : aLocaleData.getBelowWord();
+
+            if (!sSetReferenceLanguage.isEmpty())
+                    lcl_formatReferenceLanguage(sText, false, GetLanguage(), sSetReferenceLanguage);
         }
         break;
     // #i81002#
@@ -485,10 +639,19 @@ void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr )
     case REF_NUMBER_NO_CONTEXT:
     case REF_NUMBER_FULL_CONTEXT:
         {
+            // for differentiation of Roman numbers and letters in Hungarian article handling
+            bool bClosingParenthesis = false;
+
             if ( pFieldTextAttr && pFieldTextAttr->GetpTextNode() )
             {
                 sText = MakeRefNumStr( pFieldTextAttr->GetTextNode(), *pTextNd, GetFormat() );
+                if ( !sText.isEmpty() && !sSetReferenceLanguage.isEmpty() )
+                    bClosingParenthesis = pTextNd->GetNumRule()->MakeNumString( *(pTextNd->GetNum()), true).endsWith(")");
             }
+
+            if (!sSetReferenceLanguage.isEmpty())
+                lcl_formatReferenceLanguage(sText, bClosingParenthesis, GetLanguage(), sSetReferenceLanguage);
+
         }
         break;
 
@@ -575,7 +738,7 @@ OUString SwGetRefField::MakeRefNumStr( const SwTextNode& rTextNodeOfField,
 SwField* SwGetRefField::Copy() const
 {
     SwGetRefField* pField = new SwGetRefField( static_cast<SwGetRefFieldType*>(GetTyp()),
-                                                sSetRefName, nSubType,
+                                                sSetRefName, sSetReferenceLanguage, nSubType,
                                                 nSeqNo, GetFormat() );
     pField->sText = sText;
     return pField;
@@ -660,6 +823,9 @@ bool SwGetRefField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
     case FIELD_PROP_PAR3:
         rAny <<= Expand();
         break;
+    case FIELD_PROP_PAR4:
+        rAny <<= sSetReferenceLanguage;
+        break;
     case FIELD_PROP_SHORT1:
         rAny <<= static_cast<sal_Int16>(nSeqNo);
         break;
@@ -732,6 +898,9 @@ bool SwGetRefField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
             SetExpand( sTmpStr );
         }
         break;
+    case FIELD_PROP_PAR4:
+        rAny >>= sSetReferenceLanguage;
+        break;
     case FIELD_PROP_SHORT1:
         {
             sal_Int16 nSetSeq = 0;
diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx
index 5e45a339d1a6..db1cc9b3e378 100644
--- a/sw/source/core/unocore/unofield.cxx
+++ b/sw/source/core/unocore/unofield.cxx
@@ -1469,6 +1469,7 @@ void SAL_CALL SwXTextField::attach(
             SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::GetRef);
             pField = new SwGetRefField(static_cast<SwGetRefFieldType*>(pFieldType),
                         m_pImpl->m_pProps->sPar1,
+                        m_pImpl->m_pProps->sPar4,
                         0,
                         0,
                         0);
diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx
index 51eeee194701..c17964931264 100644
--- a/sw/source/core/unocore/unomap.cxx
+++ b/sw/source/core/unocore/unomap.cxx
@@ -878,6 +878,7 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPropertyMapEntries(s
                     {OUString(UNO_NAME_REFERENCE_FIELD_SOURCE),FIELD_PROP_USHORT2, cppu::UnoType<sal_Int16>::get(),    PROPERTY_NONE,  0},
                     {OUString(UNO_NAME_SEQUENCE_NUMBER),    FIELD_PROP_SHORT1,  cppu::UnoType<sal_Int16>::get(),   PROPERTY_NONE, 0},
                     {OUString(UNO_NAME_SOURCE_NAME),        FIELD_PROP_PAR1,    cppu::UnoType<OUString>::get(),   PROPERTY_NONE, 0},
+                    {OUString(UNO_NAME_REFERENCE_FIELD_LANGUAGE), FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(),  PROPERTY_NONE, 0},
                     COMMON_FLDTYP_PROPERTIES
                     { OUString(), 0, css::uno::Type(), 0, 0 }
                 };
diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx
index 6690c6489300..a1922c0a0566 100644
--- a/sw/source/filter/ww8/ww8par5.cxx
+++ b/sw/source/filter/ww8/ww8par5.cxx
@@ -2062,7 +2062,7 @@ eF_ResT SwWW8ImplReader::Read_F_Ref( WW8FieldDesc*, OUString& rStr )
 
     SwGetRefField aField(
         static_cast<SwGetRefFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )),
-        sBkmName,REF_BOOKMARK,0,eFormat);
+        sBkmName,"",REF_BOOKMARK,0,eFormat);
 
     if (eFormat == REF_CONTENT)
     {
@@ -2117,14 +2117,14 @@ eF_ResT SwWW8ImplReader::Read_F_NoteReference( WW8FieldDesc*, OUString& rStr )
     // set Sequence No of corresponding Foot-/Endnote to Zero
     // (will be corrected in
     SwGetRefField aField( static_cast<SwGetRefFieldType*>(
-        m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )), aBkmName, REF_FOOTNOTE, 0,
+        m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )), aBkmName, "", REF_FOOTNOTE, 0,
         REF_ONLYNUMBER );
     m_xReffingStck->NewAttr(*m_pPaM->GetPoint(), SwFormatField(aField));
     m_xReffingStck->SetAttr(*m_pPaM->GetPoint(), RES_TXTATR_FIELD);
     if (bAboveBelow)
     {
         SwGetRefField aField2( static_cast<SwGetRefFieldType*>(
-            m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )),aBkmName, REF_FOOTNOTE, 0,
+            m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )),aBkmName, "", REF_FOOTNOTE, 0,
             REF_UPDOWN );
         m_xReffingStck->NewAttr(*m_pPaM->GetPoint(), SwFormatField(aField2));
         m_xReffingStck->SetAttr(*m_pPaM->GetPoint(), RES_TXTATR_FIELD);
@@ -2198,7 +2198,7 @@ eF_ResT SwWW8ImplReader::Read_F_PgRef( WW8FieldDesc*, OUString& rStr )
         sPageRefBookmarkName = sName;
     }
     SwGetRefField aField( static_cast<SwGetRefFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )),
-                        sPageRefBookmarkName, REF_BOOKMARK, 0, REF_PAGE );
+                        sPageRefBookmarkName, "", REF_BOOKMARK, 0, REF_PAGE );
     m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) );
 
     return eF_ResT::OK;
diff --git a/sw/source/ui/fldui/fldref.cxx b/sw/source/ui/fldui/fldref.cxx
index 11044773dde1..6bafa43029e3 100644
--- a/sw/source/ui/fldui/fldref.cxx
+++ b/sw/source/ui/fldui/fldref.cxx
@@ -31,6 +31,8 @@
 #include <SwNodeNum.hxx>
 #include <IDocumentMarkAccess.hxx>
 #include <ndtxt.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/syslocaleoptions.hxx>
 
 #include <comphelper/string.hxx>
 
@@ -822,6 +824,8 @@ sal_Int32 SwFieldRefPage::FillFormatLB(sal_uInt16 nTypeId)
         m_pFormatLB->SetEntryData( nPos, reinterpret_cast<void*>(GetFieldMgr().GetFormatId( nTypeId, i )));
     }
     // #i83479#
+
+    sal_uInt16 nExtraSize( 0 );
     if ( bAddCrossRefFormats )
     {
         sal_uInt16 nFormat = FMT_REF_NUMBER_IDX;
@@ -833,16 +837,66 @@ sal_Int32 SwFieldRefPage::FillFormatLB(sal_uInt16 nTypeId)
         nFormat = FMT_REF_NUMBER_FULL_CONTEXT_IDX;
         nPos = m_pFormatLB->InsertEntry(GetFieldMgr().GetFormatStr( nTypeId, nFormat ));
         m_pFormatLB->SetEntryData( nPos, reinterpret_cast<void*>(GetFieldMgr().GetFormatId( nTypeId, nFormat )));
-        nSize += 3;
+        nExtraSize = 3;
     }
 
+    // extra list items optionally, depending from reference-language
+    SvtSysLocaleOptions aSysLocaleOptions;
+    static const LanguageTag& rLang = aSysLocaleOptions.GetRealLanguageTag();
+
+    if (rLang.getLanguage() == "hu")
+    {
+        for (sal_uInt16 i = 0; i < nSize; i++)
+        {
+            sal_Int32 nPos = m_pFormatLB->InsertEntry(SwResId(FMT_REF_WITH_LOWERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nTypeId, i ));
+            m_pFormatLB->SetEntryData( nPos, reinterpret_cast<void*>(GetFieldMgr().GetFormatId( nTypeId, i + SAL_N_ELEMENTS(FMT_REF_ARY))));
+        }
+        nExtraSize += nSize;
+
+        if ( bAddCrossRefFormats )
+        {
+            sal_uInt16 nFormat = FMT_REF_NUMBER_IDX + SAL_N_ELEMENTS(FMT_REF_ARY);
+            sal_Int32 nPos = m_pFormatLB->InsertEntry(SwResId(FMT_REF_WITH_LOWERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nTypeId, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+            m_pFormatLB->SetEntryData( nPos, reinterpret_cast<void*>(GetFieldMgr().GetFormatId( nTypeId, nFormat )));
+            nFormat = FMT_REF_NUMBER_NO_CONTEXT_IDX + SAL_N_ELEMENTS(FMT_REF_ARY);
+            nPos = m_pFormatLB->InsertEntry(SwResId(FMT_REF_WITH_LOWERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nTypeId, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+            m_pFormatLB->SetEntryData( nPos, reinterpret_cast<void*>(GetFieldMgr().GetFormatId( nTypeId, nFormat )));
+            nFormat = FMT_REF_NUMBER_FULL_CONTEXT_IDX + SAL_N_ELEMENTS(FMT_REF_ARY);
+            nPos = m_pFormatLB->InsertEntry(SwResId(FMT_REF_WITH_LOWERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nTypeId, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+            m_pFormatLB->SetEntryData( nPos, reinterpret_cast<void*>(GetFieldMgr().GetFormatId( nTypeId, nFormat )));
+            nExtraSize += 3;
+        }
+        // uppercase article
+        for (sal_uInt16 i = 0; i < nSize; i++)
+        {
+            sal_Int32 nPos = m_pFormatLB->InsertEntry(SwResId(FMT_REF_WITH_UPPERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nTypeId, i ));
+            m_pFormatLB->SetEntryData( nPos, reinterpret_cast<void*>(GetFieldMgr().GetFormatId( nTypeId, i + 2 * SAL_N_ELEMENTS(FMT_REF_ARY))));
+        }
+        nExtraSize += nSize;
+        if ( bAddCrossRefFormats )
+        {
+            sal_uInt16 nFormat = FMT_REF_NUMBER_IDX + 2 * SAL_N_ELEMENTS(FMT_REF_ARY);
+            sal_Int32 nPos = m_pFormatLB->InsertEntry(SwResId(FMT_REF_WITH_UPPERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nTypeId, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+            m_pFormatLB->SetEntryData( nPos, reinterpret_cast<void*>(GetFieldMgr().GetFormatId( nTypeId, nFormat )));
+            nFormat = FMT_REF_NUMBER_NO_CONTEXT_IDX + 2 * SAL_N_ELEMENTS(FMT_REF_ARY);
+            nPos = m_pFormatLB->InsertEntry(SwResId(FMT_REF_WITH_UPPERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nTypeId, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+            m_pFormatLB->SetEntryData( nPos, reinterpret_cast<void*>(GetFieldMgr().GetFormatId( nTypeId, nFormat )));
+            nFormat = FMT_REF_NUMBER_FULL_CONTEXT_IDX + 2 * SAL_N_ELEMENTS(FMT_REF_ARY);
+            nPos = m_pFormatLB->InsertEntry(SwResId(FMT_REF_WITH_UPPERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nTypeId, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+            m_pFormatLB->SetEntryData( nPos, reinterpret_cast<void*>(GetFieldMgr().GetFormatId( nTypeId, nFormat )));
+            nExtraSize += 3;
+        }
+    }
+
+    nSize += nExtraSize;
+
     // select a certain entry
     if (nSize)
     {
         if (!IsFieldEdit())
             m_pFormatLB->SelectEntry(sOldSel);
         else
-            m_pFormatLB->SelectEntry(SwResId(FMT_REF_ARY[GetCurField()->GetFormat()]));
+            m_pFormatLB->SelectEntry(SwResId(FMT_REF_ARY[GetCurField()->GetFormat() % SAL_N_ELEMENTS(FMT_REF_ARY)]));
 
         if (!m_pFormatLB->GetSelectedEntryCount())
         {
diff --git a/sw/source/uibase/fldui/fldmgr.cxx b/sw/source/uibase/fldui/fldmgr.cxx
index 14bb2d4623a4..1ae000cfabc8 100644
--- a/sw/source/uibase/fldui/fldmgr.cxx
+++ b/sw/source/uibase/fldui/fldmgr.cxx
@@ -1094,7 +1094,21 @@ bool SwFieldMgr::InsertField(
             SwGetRefFieldType* pTyp =
                 static_cast<SwGetRefFieldType*>( pCurShell->GetFieldType(0, SwFieldIds::GetRef) );
             sal_uInt16 nSeqNo = static_cast<sal_uInt16>(rData.m_sPar2.toInt32());
-            pField = new SwGetRefField(pTyp, rData.m_sPar1, nSubType, nSeqNo, nFormatId);
+            OUString sReferenceLanguage;
+            // handle language-variant formats
+            if (nFormatId >= SAL_N_ELEMENTS(FMT_REF_ARY))
+            {
+                LanguageType nLang = GetCurrLanguage();
+                if (nLang == LANGUAGE_HUNGARIAN)
+                {
+                    if (nFormatId >= SAL_N_ELEMENTS(FMT_REF_ARY) * 2)
+                        sReferenceLanguage = "Hu";
+                    else
+                        sReferenceLanguage = "hu";
+                }
+                nFormatId %= SAL_N_ELEMENTS(FMT_REF_ARY);
+            }
+            pField = new SwGetRefField(pTyp, rData.m_sPar1, sReferenceLanguage, nSubType, nSeqNo, nFormatId);
             bExp = true;
             break;
         }
diff --git a/xmloff/inc/txtflde.hxx b/xmloff/inc/txtflde.hxx
index 34c867017762..909da05499ca 100644
--- a/xmloff/inc/txtflde.hxx
+++ b/xmloff/inc/txtflde.hxx
@@ -464,6 +464,7 @@ private:
     const OUString sPropertyPlaceholderType;
     const OUString sPropertyReferenceFieldPart;
     const OUString sPropertyReferenceFieldSource;
+    const OUString sPropertyReferenceFieldLanguage;
     const OUString sPropertyScriptType;
     const OUString sPropertySelectedItem;
     const OUString sPropertySequenceNumber;
diff --git a/xmloff/inc/txtfldi.hxx b/xmloff/inc/txtfldi.hxx
index 5e66297a53d7..350ca6d11e0e 100644
--- a/xmloff/inc/txtfldi.hxx
+++ b/xmloff/inc/txtfldi.hxx
@@ -89,6 +89,7 @@ enum XMLTextFieldAttrTokens
     XML_TOK_TEXTFIELD_CURRENT_VALUE,
 
     XML_TOK_TEXTFIELD_REFERENCE_FORMAT,
+    XML_TOK_TEXTFIELD_REFERENCE_LANGUAGE,
     XML_TOK_TEXTFIELD_REF_NAME,
     XML_TOK_TEXTFIELD_CONNECTION_NAME,
 
@@ -931,6 +932,7 @@ protected:
 class XMLReferenceFieldImportContext : public XMLTextFieldImportContext
 {
     OUString sName;
+    OUString sLanguage;
     sal_uInt16 nElementToken;
     sal_Int16 nSource;
     sal_Int16 nType;
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index f1761339481d..26ca52d0966e 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -3294,6 +3294,8 @@ namespace xmloff { namespace token {
         TOKEN( "zeros-denominator-digits",        XML_ZEROS_DENOMINATOR_DIGITS ),
         TOKEN( "integer-fraction-delimiter",      XML_INTEGER_FRACTION_DELIMITER ),
 
+        // for optional language-dependent reference formats
+        TOKEN( "reference-language",              XML_REFERENCE_LANGUAGE ),
 #if OSL_DEBUG_LEVEL > 0
         { 0, nullptr, nullptr,                       XML_TOKEN_END }
 #else
diff --git a/xmloff/source/text/txtflde.cxx b/xmloff/source/text/txtflde.cxx
index c2d52cf48421..b39772a82e46 100644
--- a/xmloff/source/text/txtflde.cxx
+++ b/xmloff/source/text/txtflde.cxx
@@ -327,6 +327,7 @@ XMLTextFieldExport::XMLTextFieldExport( SvXMLExport& rExp,
     sPropertyPlaceholderType("PlaceHolderType"),
     sPropertyReferenceFieldPart("ReferenceFieldPart"),
     sPropertyReferenceFieldSource("ReferenceFieldSource"),
+    sPropertyReferenceFieldLanguage("ReferenceFieldLanguage"),
     sPropertyScriptType("ScriptType"),
     sPropertySelectedItem("SelectedItem"),
     sPropertySequenceNumber("SequenceNumber"),
@@ -1601,6 +1602,13 @@ void XMLTextFieldExport::ExportFieldHelper(
                       MakeSequenceRefName(
                           GetInt16Property(sPropertySequenceNumber, rPropSet),
                           GetStringProperty(sPropertySourceName, rPropSet) ) );
+        if (xPropSetInfo->hasPropertyByName(sPropertyReferenceFieldLanguage) &&
+            SvtSaveOptions().GetODFDefaultVersion() > SvtSaveOptions::ODFVER_012)
+        {
+            // export text:reference-language attribute, if not empty
+            ProcessString(XML_REFERENCE_LANGUAGE,
+                    GetStringProperty(sPropertyReferenceFieldLanguage, rPropSet), true);
+        }
         ExportElement(
             MapReferenceSource(
                 GetInt16Property(sPropertyReferenceFieldSource, rPropSet)),
@@ -1616,6 +1624,13 @@ void XMLTextFieldExport::ExportFieldHelper(
                       XML_TEMPLATE);
         ProcessString(XML_REF_NAME,
                       GetStringProperty(sPropertySourceName, rPropSet));
+        if (xPropSetInfo->hasPropertyByName(sPropertyReferenceFieldLanguage) &&
+            SvtSaveOptions().GetODFDefaultVersion() > SvtSaveOptions::ODFVER_012)
+        {
+            // export text:reference-language attribute, if not empty
+            ProcessString(XML_REFERENCE_LANGUAGE,
+                      GetStringProperty(sPropertyReferenceFieldLanguage, rPropSet), true);
+        }
         ExportElement(
             MapReferenceSource(GetInt16Property(
                 sPropertyReferenceFieldSource, rPropSet)),
@@ -1634,6 +1649,13 @@ void XMLTextFieldExport::ExportFieldHelper(
         ProcessString(XML_REF_NAME,
                       MakeFootnoteRefName(GetInt16Property(
                           sPropertySequenceNumber, rPropSet)));
+        if (xPropSetInfo->hasPropertyByName(sPropertyReferenceFieldLanguage) &&
+            SvtSaveOptions().GetODFDefaultVersion() > SvtSaveOptions::ODFVER_012)
+        {
+            // export text:reference-language attribute, if not empty
+            ProcessString(XML_REFERENCE_LANGUAGE,
+                      GetStringProperty(sPropertyReferenceFieldLanguage, rPropSet), true);
+        }
         ExportElement(
             MapReferenceSource(GetInt16Property(
                 sPropertyReferenceFieldSource, rPropSet)),
diff --git a/xmloff/source/text/txtfldi.cxx b/xmloff/source/text/txtfldi.cxx
index 963d0ce3fa50..fd20df679564 100644
--- a/xmloff/source/text/txtfldi.cxx
+++ b/xmloff/source/text/txtfldi.cxx
@@ -2626,6 +2626,9 @@ void XMLReferenceFieldImportContext::ProcessAttribute(
 
             break;
         }
+        case XML_TOK_TEXTFIELD_REFERENCE_LANGUAGE:
+            sLanguage = sAttrValue;
+            break;
     }
 
     // bValid: we need proper element type and name
@@ -2639,6 +2642,7 @@ void XMLReferenceFieldImportContext::PrepareField(
 
     xPropertySet->setPropertyValue("ReferenceFieldSource", Any(nSource));
 
+    xPropertySet->setPropertyValue("ReferenceFieldLanguage", Any(sLanguage));
     switch (nElementToken)
     {
         case XML_TOK_TEXT_REFERENCE_REF:
diff --git a/xmloff/source/text/txtimp.cxx b/xmloff/source/text/txtimp.cxx
index 53e8836c846b..c8abe9651736 100644
--- a/xmloff/source/text/txtimp.cxx
+++ b/xmloff/source/text/txtimp.cxx
@@ -482,6 +482,10 @@ static const SvXMLTokenMapEntry aTextFieldAttrTokenMap[] =
                 XML_TOK_TEXTFIELD_CURRENT_VALUE },
     { XML_NAMESPACE_TEXT, XML_TABLE_TYPE, XML_TOK_TEXTFIELD_TABLE_TYPE },
     { XML_NAMESPACE_OFFICE, XML_NAME, XML_TOK_TEXT_NAME },
+    { XML_NAMESPACE_LO_EXT, XML_REFERENCE_LANGUAGE,
+                XML_TOK_TEXTFIELD_REFERENCE_LANGUAGE },
+    { XML_NAMESPACE_TEXT, XML_REFERENCE_LANGUAGE,
+                XML_TOK_TEXTFIELD_REFERENCE_LANGUAGE },
 
     XML_TOKEN_MAP_END
 };


More information about the Libreoffice-commits mailing list