From 1037e3759bf178b52d16c12a811717f94ab9950a Mon Sep 17 00:00:00 2001 From: László Németh Date: Wed, 31 Jan 2018 16:35:05 +0100 Subject: 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 Reviewed-by: Miklos Vajna --- sw/source/core/fields/reffld.cxx | 173 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 171 insertions(+), 2 deletions(-) (limited to 'sw/source/core/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 #include #include +#include #include #include #include @@ -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 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(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(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; -- cgit v1.2.3