new ODF numbered list parameter loext:num-list-format
Instead of style:num-prefix and style:num-suffix new list format is much more flexible for storing list multilevel numberings. Now it is possible to have not just prefix/suffix but any random separators between levels, arbitrary levels order, etc. Internal LO format for list format is changed: instead of placeholders like %1, %2, etc we right now use %1%, %2%... Reason: for ODT documents, having more than 9 levels there is ambiguity in "%10": it is "%1" followed by "0" suffix, or "%10"? Aux changes: * removed zero width space hack: since format string is always defined this hack is interfering with standard list numbers printing (see changes in ooxmlexport14.cxx, ww8export3.cxx tests) * changed cross-references values to lists: they are now including full list label string: previously this was bit self-contradictory (see changes in odfexport.cxx and check_cross_references.py tests) Change-Id: I9696cc4846375c5f6222539aeaadbca5ae58ce27 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117156 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
This commit is contained in:
committed by
Thorsten Behrens
parent
99ef46fdb2
commit
aa5c6d1275
@@ -314,14 +314,8 @@ IMPL_LINK_NOARG(SvxSingleNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
|
||||
{
|
||||
SvxNumberFormat aFmt(pActNum->GetLevel(i));
|
||||
aFmt.SetNumberingType(eNewType);
|
||||
if(cLocalPrefix == ' ')
|
||||
aFmt.SetPrefix( "" );
|
||||
else
|
||||
aFmt.SetPrefix(_pSet->sPrefix);
|
||||
if(cLocalSuffix == ' ')
|
||||
aFmt.SetSuffix( "" );
|
||||
else
|
||||
aFmt.SetSuffix(_pSet->sSuffix);
|
||||
aFmt.SetListFormat(cLocalPrefix == ' ' ? "" : _pSet->sPrefix,
|
||||
cLocalSuffix == ' ' ? "" : _pSet->sSuffix, i);
|
||||
aFmt.SetCharFormatName("");
|
||||
aFmt.SetBulletRelSize(100);
|
||||
pActNum->SetLevel(i, aFmt);
|
||||
@@ -459,8 +453,7 @@ IMPL_LINK_NOARG(SvxBulletPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
|
||||
SvxNumberFormat aFmt(pActNum->GetLevel(i));
|
||||
aFmt.SetNumberingType( SVX_NUM_CHAR_SPECIAL );
|
||||
// #i93908# clear suffix for bullet lists
|
||||
aFmt.SetPrefix( OUString() );
|
||||
aFmt.SetSuffix( OUString() );
|
||||
aFmt.SetListFormat("", "", i);
|
||||
aFmt.SetBulletFont(&rActBulletFont);
|
||||
aFmt.SetBulletChar(cChar );
|
||||
aFmt.SetCharFormatName(sBulletCharFormatName);
|
||||
@@ -652,8 +645,7 @@ IMPL_LINK_NOARG(SvxNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
|
||||
if(aFmt.GetNumberingType() == SVX_NUM_CHAR_SPECIAL)
|
||||
{
|
||||
// #i93908# clear suffix for bullet lists
|
||||
aFmt.SetPrefix(OUString());
|
||||
aFmt.SetSuffix(OUString());
|
||||
aFmt.SetListFormat("", "", i);
|
||||
if( !pLevelSettings->sBulletFont.isEmpty() &&
|
||||
pLevelSettings->sBulletFont != rActBulletFont.GetFamilyName())
|
||||
{
|
||||
@@ -702,8 +694,7 @@ IMPL_LINK_NOARG(SvxNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
|
||||
aFmt.SetCharFormatName(sNumCharFmtName);
|
||||
aFmt.SetBulletRelSize(100);
|
||||
// #i93908#
|
||||
aFmt.SetPrefix(pLevelSettings->sPrefix);
|
||||
aFmt.SetSuffix(pLevelSettings->sSuffix);
|
||||
aFmt.SetListFormat(pLevelSettings->sPrefix, pLevelSettings->sSuffix, i);
|
||||
}
|
||||
pActNum->SetLevel(i, aFmt);
|
||||
}
|
||||
@@ -885,8 +876,7 @@ IMPL_LINK_NOARG(SvxBitmapPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
|
||||
{
|
||||
SvxNumberFormat aFmt(pActNum->GetLevel(i));
|
||||
aFmt.SetNumberingType(SVX_NUM_BITMAP);
|
||||
aFmt.SetPrefix( "" );
|
||||
aFmt.SetSuffix( "" );
|
||||
aFmt.SetListFormat("", "", i);
|
||||
aFmt.SetCharFormatName( "" );
|
||||
|
||||
Graphic aGraphic;
|
||||
@@ -1644,8 +1634,7 @@ IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox,
|
||||
{
|
||||
bBmp |= nullptr != aNumFmt.GetBrush();
|
||||
aNumFmt.SetIncludeUpperLevels( 0 );
|
||||
aNumFmt.SetSuffix( "" );
|
||||
aNumFmt.SetPrefix( "" );
|
||||
aNumFmt.SetListFormat("", "", i);
|
||||
if(!bBmp)
|
||||
aNumFmt.SetGraphic("");
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
@@ -1655,8 +1644,7 @@ IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox,
|
||||
else if( SVX_NUM_CHAR_SPECIAL == nNumberingType )
|
||||
{
|
||||
aNumFmt.SetIncludeUpperLevels( 0 );
|
||||
aNumFmt.SetSuffix( "" );
|
||||
aNumFmt.SetPrefix( "" );
|
||||
aNumFmt.SetListFormat("", "", i);
|
||||
if( !aNumFmt.GetBulletFont() )
|
||||
aNumFmt.SetBulletFont(&aActBulletFont);
|
||||
if( !aNumFmt.GetBulletChar() )
|
||||
@@ -1671,8 +1659,8 @@ IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox,
|
||||
}
|
||||
else
|
||||
{
|
||||
aNumFmt.SetPrefix( m_xPrefixED->get_text() );
|
||||
aNumFmt.SetSuffix( m_xSuffixED->get_text() );
|
||||
aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
|
||||
|
||||
SwitchNumberType(SHOW_NUMBERING);
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
CheckForStartValue_Impl(nNumberingType);
|
||||
@@ -2098,8 +2086,7 @@ IMPL_LINK(SvxNumOptionsTabPage, SpinModifyHdl_Impl, weld::SpinButton&, rSpinButt
|
||||
|
||||
void SvxNumOptionsTabPage::EditModifyHdl_Impl(const weld::Entry* pEdit)
|
||||
{
|
||||
bool bPrefix = pEdit == m_xPrefixED.get();
|
||||
bool bSuffix = pEdit == m_xSuffixED.get();
|
||||
bool bPrefixSuffix = (pEdit == m_xPrefixED.get())|| (pEdit == m_xSuffixED.get());
|
||||
bool bStart = pEdit == m_xStartED.get();
|
||||
sal_uInt16 nMask = 1;
|
||||
for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
@@ -2107,10 +2094,8 @@ void SvxNumOptionsTabPage::EditModifyHdl_Impl(const weld::Entry* pEdit)
|
||||
if(nActNumLvl & nMask)
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
|
||||
if(bPrefix)
|
||||
aNumFmt.SetPrefix(m_xPrefixED->get_text());
|
||||
else if(bSuffix)
|
||||
aNumFmt.SetSuffix(m_xSuffixED->get_text());
|
||||
if (bPrefixSuffix)
|
||||
aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
|
||||
else if(bStart)
|
||||
aNumFmt.SetStart(m_xStartED->get_value());
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
|
||||
@@ -560,6 +560,55 @@ OUString SvxNumberFormat::CreateRomanString( sal_Int32 nNo, bool bUpper )
|
||||
return sRet.makeStringAndClear();
|
||||
}
|
||||
|
||||
void SvxNumberFormat::SetListFormat(const OUString& rPrefix, const OUString& rSuffix, int nLevel)
|
||||
{
|
||||
sPrefix = rPrefix;
|
||||
sSuffix = rSuffix;
|
||||
|
||||
// Generate list format
|
||||
sListFormat = std::make_optional(sPrefix);
|
||||
|
||||
for (int i = 1; i <= nInclUpperLevels; i++)
|
||||
{
|
||||
int nLevelId = nLevel - nInclUpperLevels + i;
|
||||
if (nLevelId < 0)
|
||||
// There can be cases with curent level 1, but request to show 10 upper levels. Trim it
|
||||
continue;
|
||||
|
||||
*sListFormat += "%";
|
||||
*sListFormat += OUString::number(nLevelId + 1);
|
||||
*sListFormat += "%";
|
||||
if (i != nInclUpperLevels)
|
||||
*sListFormat += "."; // Default separator for older ODT
|
||||
}
|
||||
|
||||
*sListFormat += sSuffix;
|
||||
}
|
||||
|
||||
void SvxNumberFormat::SetListFormat(std::optional<OUString> oSet)
|
||||
{
|
||||
sPrefix.clear();
|
||||
sSuffix.clear();
|
||||
|
||||
if (!oSet.has_value())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sListFormat = oSet;
|
||||
|
||||
// For backward compatibility and UI we should create prefix/suffix also
|
||||
sal_Int32 nFirstReplacement = sListFormat->indexOf('%');
|
||||
sal_Int32 nLastReplacement = sListFormat->lastIndexOf('%') + 1;
|
||||
if (nFirstReplacement > 0)
|
||||
// Everything before first '%' will be prefix
|
||||
sPrefix = sListFormat->copy(0, nFirstReplacement);
|
||||
if (nLastReplacement >= 0 && nLastReplacement < sListFormat->getLength())
|
||||
// Everything beyond last '%' is a suffix
|
||||
sSuffix = sListFormat->copy(nLastReplacement);
|
||||
}
|
||||
|
||||
|
||||
OUString SvxNumberFormat::GetCharFormatName()const
|
||||
{
|
||||
return sCharStyleName;
|
||||
|
||||
@@ -171,7 +171,9 @@ public:
|
||||
const OUString& GetPrefix() const { return sPrefix;}
|
||||
void SetSuffix(const OUString& rSet) { sSuffix = rSet;}
|
||||
const OUString& GetSuffix() const { return sSuffix;}
|
||||
void SetListFormat(std::optional<OUString> oSet = std::nullopt) { sListFormat = oSet; }
|
||||
// Based on prefix and suffix ininialize them (for backward compatibility) and generate listformat string
|
||||
void SetListFormat(const OUString& rPrefix, const OUString& rSuffix, int nLevel);
|
||||
void SetListFormat(std::optional<OUString> oSet = std::nullopt);
|
||||
bool HasListFormat() const { return sListFormat.has_value(); }
|
||||
const OUString& GetListFormat() const { return *sListFormat; }
|
||||
|
||||
|
||||
@@ -1370,6 +1370,7 @@ namespace xmloff::token {
|
||||
XML_NULL_YEAR,
|
||||
XML_NUM_FORMAT,
|
||||
XML_NUM_LETTER_SYNC,
|
||||
XML_NUM_LIST_FORMAT,
|
||||
XML_NUM_PREFIX,
|
||||
XML_NUM_SUFFIX,
|
||||
XML_NUMALIGN,
|
||||
|
||||
@@ -41,10 +41,14 @@ published service NumberingLevel
|
||||
[property] short ParentNumbering;
|
||||
|
||||
/** This prefix is inserted in front of the numbering symbol(s).
|
||||
|
||||
@deprecated as of LibreOffice 7.2, use ListFormat instead
|
||||
*/
|
||||
[property] string Prefix;
|
||||
|
||||
/** This suffix is inserted after the numbering symbol(s).
|
||||
|
||||
@deprecated as of LibreOffice 7.2, use ListFormat instead
|
||||
*/
|
||||
[property] string Suffix;
|
||||
|
||||
@@ -81,6 +85,23 @@ published service NumberingLevel
|
||||
@since LibreOffice 6.1
|
||||
*/
|
||||
[optional, property] com::sun::star::awt::XBitmap GraphicBitmap;
|
||||
|
||||
/** Format string used to generate actual numbering.
|
||||
|
||||
It contains placeholders (like %1%, %2%, etc) where corresponding
|
||||
level numberings are inserted.
|
||||
|
||||
This is more flexible way to provide multilevel numbering with
|
||||
complex format string. This property is a replacement for
|
||||
Prefix and Suffix: if ListFormat is provided, they are not used
|
||||
anymore.
|
||||
|
||||
Example: ListFormat "(%1% %2%.%3%)" can be resolved to numbering
|
||||
in actual multilevel list like "(4 1.3)".
|
||||
|
||||
@since LibreOffice 7.2
|
||||
*/
|
||||
[optional, property] string ListFormat;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -2660,4 +2660,13 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
|
||||
</rng:optional>
|
||||
</rng:define>
|
||||
|
||||
<!-- https://issues.oasis-open.org/browse/OFFICE-4108 -->
|
||||
<rng:define name="common-num-format-prefix-suffix-attlist" combine="interleave">
|
||||
<rng:optional>
|
||||
<rng:attribute name="loext:num-list-format">
|
||||
<rng:ref name="string"/>
|
||||
</rng:attribute>
|
||||
</rng:optional>
|
||||
</rng:define>
|
||||
|
||||
</rng:grammar>
|
||||
|
||||
@@ -716,8 +716,7 @@ IMPL_LINK(SvxBulletAndPositionDlg, NumberTypeSelectHdl_Impl, weld::ComboBox&, rB
|
||||
{
|
||||
bBmp |= nullptr != aNumFmt.GetBrush();
|
||||
aNumFmt.SetIncludeUpperLevels(0);
|
||||
aNumFmt.SetSuffix("");
|
||||
aNumFmt.SetPrefix("");
|
||||
aNumFmt.SetListFormat("", "", i);
|
||||
if (!bBmp)
|
||||
aNumFmt.SetGraphic("");
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
@@ -726,8 +725,7 @@ IMPL_LINK(SvxBulletAndPositionDlg, NumberTypeSelectHdl_Impl, weld::ComboBox&, rB
|
||||
else if (SVX_NUM_CHAR_SPECIAL == nNumberingType)
|
||||
{
|
||||
aNumFmt.SetIncludeUpperLevels(0);
|
||||
aNumFmt.SetSuffix("");
|
||||
aNumFmt.SetPrefix("");
|
||||
aNumFmt.SetListFormat("", "", i);
|
||||
if (!aNumFmt.GetBulletFont())
|
||||
aNumFmt.SetBulletFont(&aActBulletFont);
|
||||
if (!aNumFmt.GetBulletChar())
|
||||
@@ -738,8 +736,7 @@ IMPL_LINK(SvxBulletAndPositionDlg, NumberTypeSelectHdl_Impl, weld::ComboBox&, rB
|
||||
}
|
||||
else
|
||||
{
|
||||
aNumFmt.SetPrefix(m_xPrefixED->get_text());
|
||||
aNumFmt.SetSuffix(m_xSuffixED->get_text());
|
||||
aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
|
||||
SwitchNumberType(SHOW_NUMBERING);
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
CheckForStartValue_Impl(nNumberingType);
|
||||
@@ -1233,8 +1230,7 @@ IMPL_LINK(SvxBulletAndPositionDlg, RelativeHdl_Impl, weld::Toggleable&, rBox, vo
|
||||
|
||||
void SvxBulletAndPositionDlg::EditModifyHdl_Impl(const weld::Entry* pEdit)
|
||||
{
|
||||
bool bPrefix = pEdit == m_xPrefixED.get();
|
||||
bool bSuffix = pEdit == m_xSuffixED.get();
|
||||
bool bPrefixOrSuffix = (pEdit == m_xPrefixED.get()) || (pEdit == m_xSuffixED.get());
|
||||
bool bStart = pEdit == m_xStartED.get();
|
||||
sal_uInt16 nMask = 1;
|
||||
for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
|
||||
@@ -1242,10 +1238,8 @@ void SvxBulletAndPositionDlg::EditModifyHdl_Impl(const weld::Entry* pEdit)
|
||||
if (nActNumLvl & nMask)
|
||||
{
|
||||
SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
|
||||
if (bPrefix)
|
||||
aNumFmt.SetPrefix(m_xPrefixED->get_text());
|
||||
else if (bSuffix)
|
||||
aNumFmt.SetSuffix(m_xSuffixED->get_text());
|
||||
if (bPrefixOrSuffix)
|
||||
aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
|
||||
else if (bStart)
|
||||
aNumFmt.SetStart(m_xStartED->get_value());
|
||||
pActNum->SetLevel(i, aNumFmt);
|
||||
|
||||
@@ -340,8 +340,7 @@ void BulletsTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt1
|
||||
aFmt.SetBulletFont(&rActBulletFont);
|
||||
aFmt.SetBulletChar(cChar);
|
||||
aFmt.SetCharFormatName(sBulletCharFormatName);
|
||||
aFmt.SetPrefix( "" );
|
||||
aFmt.SetSuffix( "" );
|
||||
aFmt.SetListFormat( "" );
|
||||
if (isResetSize) aFmt.SetBulletRelSize(45);
|
||||
aNum.SetLevel(i, aFmt);
|
||||
}
|
||||
@@ -524,9 +523,7 @@ void NumberingTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uIn
|
||||
SvxNumberFormat aFmt(aNum.GetLevel(i));
|
||||
if (eNewType!=aFmt.GetNumberingType()) isResetSize=true;
|
||||
aFmt.SetNumberingType(eNewType);
|
||||
aFmt.SetPrefix(_pSet->pNumSetting->sPrefix);
|
||||
aFmt.SetSuffix(_pSet->pNumSetting->sSuffix);
|
||||
|
||||
aFmt.SetListFormat(_pSet->pNumSetting->sPrefix, _pSet->pNumSetting->sSuffix, i);
|
||||
aFmt.SetCharFormatName(sNumCharFmtName);
|
||||
if (isResetSize) aFmt.SetBulletRelSize(100);
|
||||
aNum.SetLevel(i, aFmt);
|
||||
@@ -875,8 +872,7 @@ void OutlineTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt1
|
||||
aFmt.SetFirstLineIndent(pLevelSettings->nNumAlignAt);
|
||||
aFmt.SetIndentAt(pLevelSettings->nNumIndentAt);
|
||||
}
|
||||
aFmt.SetPrefix(pLevelSettings->sPrefix);
|
||||
aFmt.SetSuffix(pLevelSettings->sSuffix);
|
||||
aFmt.SetListFormat(pLevelSettings->sPrefix, pLevelSettings->sSuffix, i);
|
||||
aNum.SetLevel(i, aFmt);
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -2697,7 +2697,7 @@ DECLARE_ODFEXPORT_TEST(testReferenceLanguage, "referencelanguage.odt")
|
||||
OUString const aFieldTexts[] = { "A 2", "Az Isten", "Az 50-esek",
|
||||
"A 2018-asok", "Az egyebek", "A fejezetek",
|
||||
u"Az „Őseinket...”", "a 2",
|
||||
"Az v", "az 1", "Az e", "az 1",
|
||||
"Az v.", "az 1", "Az e)", "az 1",
|
||||
"Az (5)", "az 1", "A 2", "az 1" };
|
||||
uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
|
||||
// update "A (4)" to "Az (5)"
|
||||
|
||||
@@ -50,6 +50,72 @@ DECLARE_ODFEXPORT_TEST(testTdf137199, "tdf137199.docx")
|
||||
CPPUNIT_ASSERT_EQUAL(OUString("HELLO2WORLD!"), getProperty<OUString>(getParagraph(4), "ListLabelString"));
|
||||
}
|
||||
|
||||
DECLARE_ODFEXPORT_TEST(testListFormatDocx, "listformat.docx")
|
||||
{
|
||||
// Ensure in resulting ODT we also have not just prefix/suffux, but custom delimiters
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(">1<"), getProperty<OUString>(getParagraph(1), "ListLabelString"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(">>1/1<<"), getProperty<OUString>(getParagraph(2), "ListLabelString"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(">>1/1/1<<"), getProperty<OUString>(getParagraph(3), "ListLabelString"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(">>1/1/2<<"), getProperty<OUString>(getParagraph(4), "ListLabelString"));
|
||||
|
||||
// Check also that in numbering styles we have num-list-format defined
|
||||
xmlDocUniquePtr pXmlDoc = parseExport("styles.xml");
|
||||
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/"
|
||||
"text:list-level-style-number[@text:level='1']", "num-list-format", ">%1%<");
|
||||
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/"
|
||||
"text:list-level-style-number[@text:level='2']", "num-list-format", ">>%1%/%2%<<");
|
||||
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/"
|
||||
"text:list-level-style-number[@text:level='3']", "num-list-format", ">>%1%/%2%/%3%<<");
|
||||
|
||||
// But for compatibility there are still prefix/suffix
|
||||
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/"
|
||||
"text:list-level-style-number[@text:level='1']", "num-prefix", ">");
|
||||
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/"
|
||||
"text:list-level-style-number[@text:level='1']", "num-suffix", "<");
|
||||
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/"
|
||||
"text:list-level-style-number[@text:level='2']", "num-prefix", ">>");
|
||||
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/"
|
||||
"text:list-level-style-number[@text:level='2']", "num-suffix", "<<");
|
||||
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/"
|
||||
"text:list-level-style-number[@text:level='3']", "num-prefix", ">>");
|
||||
assertXPath(pXmlDoc, "/office:document-styles/office:styles/text:list-style[@style:name='WWNum1']/"
|
||||
"text:list-level-style-number[@text:level='3']", "num-suffix", "<<");
|
||||
}
|
||||
|
||||
DECLARE_ODFEXPORT_TEST(testListFormatOdt, "listformat.odt")
|
||||
{
|
||||
// Ensure in resulting ODT we also have not just prefix/suffux, but custom delimiters
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(">1<"), getProperty<OUString>(getParagraph(1), "ListLabelString"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(">>1.1<<"), getProperty<OUString>(getParagraph(2), "ListLabelString"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(">>1.1.1<<"), getProperty<OUString>(getParagraph(3), "ListLabelString"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(">>1.1.2<<"), getProperty<OUString>(getParagraph(4), "ListLabelString"));
|
||||
|
||||
if (xmlDocUniquePtr pXmlDoc = parseExport("content.xml"))
|
||||
{
|
||||
// Check how conversion from prefix/suffix to list format did work
|
||||
assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/"
|
||||
"text:list-level-style-number[@text:level='1']", "num-list-format", ">%1%<");
|
||||
assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/"
|
||||
"text:list-level-style-number[@text:level='2']", "num-list-format", ">>%1%.%2%<<");
|
||||
assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/"
|
||||
"text:list-level-style-number[@text:level='3']", "num-list-format", ">>%1%.%2%.%3%<<");
|
||||
|
||||
// But for compatibility there are still prefix/suffix as they were before
|
||||
assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/"
|
||||
"text:list-level-style-number[@text:level='1']", "num-prefix", ">");
|
||||
assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/"
|
||||
"text:list-level-style-number[@text:level='1']", "num-suffix", "<");
|
||||
assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/"
|
||||
"text:list-level-style-number[@text:level='2']", "num-prefix", ">>");
|
||||
assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/"
|
||||
"text:list-level-style-number[@text:level='2']", "num-suffix", "<<");
|
||||
assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/"
|
||||
"text:list-level-style-number[@text:level='3']", "num-prefix", ">>");
|
||||
assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/text:list-style[@style:name='L1']/"
|
||||
"text:list-level-style-number[@text:level='3']", "num-suffix", "<<");
|
||||
}
|
||||
}
|
||||
|
||||
// This test started in LO 7.2. Use the odfexport.cxx if you intend to backport to 7.1.
|
||||
|
||||
CPPUNIT_PLUGIN_IMPLEMENT();
|
||||
|
||||
@@ -1070,12 +1070,12 @@ DECLARE_OOXMLEXPORT_TEST(testTdf120394, "tdf120394.docx")
|
||||
{
|
||||
uno::Reference<beans::XPropertySet> xPara(getParagraph(2), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), getProperty<sal_Int16>(xPara, "NumberingLevel"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(CHAR_ZWSP), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
}
|
||||
{
|
||||
uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), getProperty<sal_Int16>(xPara, "NumberingLevel"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(CHAR_ZWSP), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
}
|
||||
{
|
||||
uno::Reference<beans::XPropertySet> xPara(getParagraph(5), uno::UNO_QUERY);
|
||||
@@ -1090,7 +1090,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf133605, "tdf133605.docx")
|
||||
{
|
||||
uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), getProperty<sal_Int16>(xPara, "NumberingLevel"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(CHAR_ZWSP), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
}
|
||||
{
|
||||
uno::Reference<beans::XPropertySet> xPara(getParagraph(4), uno::UNO_QUERY);
|
||||
@@ -1116,7 +1116,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf133605_2, "tdf133605_2.docx")
|
||||
{
|
||||
uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), getProperty<sal_Int16>(xPara, "NumberingLevel"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(CHAR_ZWSP), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
}
|
||||
{
|
||||
uno::Reference<beans::XPropertySet> xPara(getParagraph(4), uno::UNO_QUERY);
|
||||
|
||||
@@ -672,7 +672,7 @@ DECLARE_RTFEXPORT_TEST(testFdo66682, "fdo66682.rtf")
|
||||
aListFormat = rProp.Value.get<OUString>();
|
||||
}
|
||||
// Suffix was '\0' instead of ' '.
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(" %1 "), aListFormat);
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(" %1% "), aListFormat);
|
||||
}
|
||||
|
||||
DECLARE_RTFEXPORT_TEST(testParaShadow, "para-shadow.rtf")
|
||||
|
||||
@@ -387,19 +387,11 @@ DECLARE_WW8EXPORT_TEST(testTdf119232_startEvenPage, "tdf119232_startEvenPage.doc
|
||||
|
||||
DECLARE_WW8EXPORT_TEST(testTdf104805, "tdf104805.doc")
|
||||
{
|
||||
uno::Reference<beans::XPropertySet> xPropertySet(getStyles("NumberingStyles")->getByName("WW8Num1"), uno::UNO_QUERY);
|
||||
uno::Reference<container::XIndexAccess> xLevels(xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY);
|
||||
uno::Sequence<beans::PropertyValue> aNumberingRule;
|
||||
xLevels->getByIndex(1) >>= aNumberingRule; // 2nd level
|
||||
for (const auto& rPair : std::as_const(aNumberingRule))
|
||||
{
|
||||
if (rPair.Name == "Prefix")
|
||||
// This was "." instead of empty, so the second paragraph was
|
||||
// rendered as ".1" instead of "1.".
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(), rPair.Value.get<OUString>());
|
||||
else if (rPair.Name == "Suffix")
|
||||
CPPUNIT_ASSERT_EQUAL(OUString("."), rPair.Value.get<OUString>());
|
||||
}
|
||||
// Prefix was "." instead of empty, so the second paragraph was
|
||||
// rendered as ".1" instead of "1.".
|
||||
// Unittest modified due to Prefix/Suffix support obsolete
|
||||
uno::Reference<beans::XPropertySet> xPara(getParagraph(2), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
}
|
||||
|
||||
DECLARE_WW8EXPORT_TEST(testTdf104334, "tdf104334.doc")
|
||||
|
||||
@@ -881,12 +881,12 @@ DECLARE_WW8EXPORT_TEST(testTdf120394, "tdf120394.doc")
|
||||
{
|
||||
uno::Reference<beans::XPropertySet> xPara(getParagraph(5), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), getProperty<sal_Int16>(xPara, "NumberingLevel"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(CHAR_ZWSP), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
}
|
||||
{
|
||||
uno::Reference<beans::XPropertySet> xPara(getParagraph(8), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2), getProperty<sal_Int16>(xPara, "NumberingLevel"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(CHAR_ZWSP), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
}
|
||||
{
|
||||
uno::Reference<beans::XPropertySet> xPara(getParagraph(9), uno::UNO_QUERY);
|
||||
@@ -896,7 +896,7 @@ DECLARE_WW8EXPORT_TEST(testTdf120394, "tdf120394.doc")
|
||||
{
|
||||
uno::Reference<beans::XPropertySet> xPara(getParagraph(10), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2), getProperty<sal_Int16>(xPara, "NumberingLevel"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(CHAR_ZWSP), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,15 +89,16 @@ class CheckCrossReferences(unittest.TestCase):
|
||||
FieldResult1 = "*i*"
|
||||
FieldResult2 = "+b+*i*"
|
||||
FieldResult3 = "-1-+b+*i*"
|
||||
FieldResult4 = "1"
|
||||
FieldResult5 = "1"
|
||||
FieldResult6 = "A.1"
|
||||
FieldResult7 = "2(a)"
|
||||
FieldResult8 = "2(b)"
|
||||
FieldResult9 = "2"
|
||||
FieldResult10 = "1(a)"
|
||||
FieldResult4 = "1."
|
||||
FieldResult5 = "1."
|
||||
FieldResult6 = "A.1."
|
||||
FieldResult7 = " 2.(a)"
|
||||
FieldResult8 = " 2.(b)"
|
||||
FieldResult9 = " 2."
|
||||
FieldResult10 = " 1.(a)"
|
||||
FieldResult11 = "(b)"
|
||||
FieldResult12 = "(a)"
|
||||
FieldResult13 = " 1."
|
||||
|
||||
# variables for current field
|
||||
xField = self.getNextField()
|
||||
@@ -155,9 +156,9 @@ class CheckCrossReferences(unittest.TestCase):
|
||||
|
||||
xField = self.getNextField()
|
||||
xProps = self.getFieldProps(xField)
|
||||
self.checkField(xField, xProps, NUMBER, FieldResult4)
|
||||
self.checkField(xField, xProps, NUMBER_NO_CONTEXT, FieldResult4)
|
||||
self.checkField(xField, xProps, NUMBER_FULL_CONTEXT, FieldResult4)
|
||||
self.checkField(xField, xProps, NUMBER, FieldResult13)
|
||||
self.checkField(xField, xProps, NUMBER_NO_CONTEXT, FieldResult13)
|
||||
self.checkField(xField, xProps, NUMBER_FULL_CONTEXT, FieldResult13)
|
||||
|
||||
xField = self.getNextField()
|
||||
xProps = self.getFieldProps(xField)
|
||||
|
||||
@@ -388,8 +388,8 @@ SwNumRule::SwNumRule( const OUString& rNm,
|
||||
pFormat->SetStart( 1 );
|
||||
pFormat->SetAbsLSpace( lNumberIndent + SwNumRule::GetNumIndent( n ) );
|
||||
pFormat->SetFirstLineOffset( lNumberFirstLineOffset );
|
||||
pFormat->SetSuffix( "." );
|
||||
pFormat->SetBulletChar( numfunc::GetBulletChar(n));
|
||||
pFormat->SetListFormat("%" + OUString::number(n + 1) + "%.");
|
||||
pFormat->SetBulletChar(numfunc::GetBulletChar(n));
|
||||
SwNumRule::saBaseFormats[ NUM_RULE ][ n ] = pFormat;
|
||||
}
|
||||
// position-and-space mode LABEL_ALIGNMENT
|
||||
@@ -411,7 +411,7 @@ SwNumRule::SwNumRule( const OUString& rNm,
|
||||
pFormat->SetListtabPos( cIndentAt[ n ] );
|
||||
pFormat->SetFirstLineIndent( cFirstLineIndent );
|
||||
pFormat->SetIndentAt( cIndentAt[ n ] );
|
||||
pFormat->SetSuffix( "." );
|
||||
pFormat->SetListFormat( "%" + OUString::number(n + 1) + "%.");
|
||||
pFormat->SetBulletChar( numfunc::GetBulletChar(n));
|
||||
SwNumRule::saLabelAlignmentBaseFormats[ NUM_RULE ][ n ] = pFormat;
|
||||
}
|
||||
@@ -682,18 +682,12 @@ OUString SwNumRule::MakeNumString( const SwNumberTree::tNumberVector & rNumVecto
|
||||
else
|
||||
sReplacement = "0"; // all 0 level are a 0
|
||||
|
||||
OUString sFind("%" + OUString::number(i + 1));
|
||||
OUString sFind("%" + OUString::number(i + 1) + "%");
|
||||
sal_Int32 nPosition = sLevelFormat.indexOf(sFind);
|
||||
if (nPosition >= 0)
|
||||
sLevelFormat = sLevelFormat.replaceAt(nPosition, sFind.getLength(), sReplacement);
|
||||
}
|
||||
|
||||
// As a fallback: caller code expects nonempty string as a result.
|
||||
// But if we have empty string (and had no errors before) this is valid result.
|
||||
// So use classical hack with zero-width-space as a string filling.
|
||||
if (sLevelFormat.isEmpty())
|
||||
sLevelFormat = OUStringChar(CHAR_ZWSP);
|
||||
|
||||
aStr = sLevelFormat;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -496,7 +496,7 @@ void MSWordExportBase::NumberingLevel(
|
||||
sal_Int32 nFnd = sNumStr.indexOf(sSrch);
|
||||
if (-1 != nFnd)
|
||||
{
|
||||
*pLvlPos = static_cast<sal_uInt8>(nFnd + rFormat.GetPrefix().getLength() + 1);
|
||||
*pLvlPos = static_cast<sal_uInt8>(nFnd + 1);
|
||||
++pLvlPos;
|
||||
sNumStr = sNumStr.replaceAt(nFnd, 1, OUString(static_cast<char>(i)));
|
||||
}
|
||||
|
||||
@@ -939,7 +939,7 @@ bool WW8ListManager::ReadLVL(SwNumFormat& rNumFormat, std::unique_ptr<SfxItemSet
|
||||
}
|
||||
else
|
||||
{
|
||||
// Replace symbols at aOfsNumsXCH offsets to %1, %2 as supported by DOCX and LO
|
||||
// Replace symbols at aOfsNumsXCH offsets to %1%, %2% as supported by LO
|
||||
OUString sListFormat = sNumString;
|
||||
if (sListFormat.getLength())
|
||||
{
|
||||
@@ -957,7 +957,7 @@ bool WW8ListManager::ReadLVL(SwNumFormat& rNumFormat, std::unique_ptr<SfxItemSet
|
||||
}
|
||||
sal_uInt8 nReplacement = sListFormat[nOffset] + 1;
|
||||
|
||||
OUString sReplacement("%" + OUString::number(nReplacement));
|
||||
OUString sReplacement("%" + OUString::number(nReplacement) + "%");
|
||||
sListFormat = sListFormat.replaceAt(nOffset, 1, sReplacement);
|
||||
|
||||
// We need also update an offset, since we are replacing one symbol by at least two
|
||||
|
||||
@@ -648,9 +648,7 @@ IMPL_LINK_NOARG(SwOutlineSettingsTabPage, DelimModify, weld::Entry&, void)
|
||||
if(nActLevel & nMask)
|
||||
{
|
||||
SwNumFormat aNumFormat(pNumRule->Get(i));
|
||||
aNumFormat.SetPrefix( m_xPrefixED->get_text() );
|
||||
aNumFormat.SetSuffix( m_xSuffixED->get_text() );
|
||||
aNumFormat.SetListFormat(); // clear custom format
|
||||
aNumFormat.SetListFormat( m_xPrefixED->get_text(), m_xSuffixED->get_text(), i );
|
||||
pNumRule->Set(i, aNumFormat);
|
||||
}
|
||||
nMask <<= 1;
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <comphelper/sequence.hxx>
|
||||
#include <comphelper/propertyvalue.hxx>
|
||||
#include <comphelper/string.hxx>
|
||||
#include <regex>
|
||||
|
||||
using namespace com::sun::star;
|
||||
|
||||
@@ -676,18 +677,19 @@ void ListsManager::lcl_attribute( Id nName, Value& rVal )
|
||||
{
|
||||
case NS_ooxml::LN_CT_LevelText_val:
|
||||
{
|
||||
//this strings contains the definition of the level
|
||||
//the level number is marked as %n
|
||||
//these numbers can be mixed randomly together with separators pre- and suffixes
|
||||
//the Writer supports only a number of upper levels to show, separators is always a dot
|
||||
//and each level can have a prefix and a suffix
|
||||
if(pCurrentLvl)
|
||||
{
|
||||
//if the BulletChar is a soft-hyphen (0xad)
|
||||
//replace it with a hard-hyphen (0x2d)
|
||||
//-> this fixes missing hyphen export in PDF etc.
|
||||
// see tdf#101626
|
||||
pCurrentLvl->SetBulletChar( rVal.getString().replace( 0xad, 0x2d ) );
|
||||
std::string sLevelText = rVal.getString().replace(0xad, 0x2d).toUtf8().getStr();
|
||||
|
||||
// DOCX level-text contains levels definition in format "%1.%2.%3"
|
||||
// we need to convert it to LO internal representation: "%1%.%2%.%3%"
|
||||
std::regex aTokenRegex("(%\\d)");
|
||||
sLevelText = std::regex_replace(sLevelText, aTokenRegex, "$1%");
|
||||
pCurrentLvl->SetBulletChar( OUString::fromUtf8(sLevelText) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1376,6 +1376,7 @@ namespace xmloff::token {
|
||||
TOKEN( "null-year", XML_NULL_YEAR ),
|
||||
TOKEN( "num-format", XML_NUM_FORMAT ),
|
||||
TOKEN( "num-letter-sync", XML_NUM_LETTER_SYNC ),
|
||||
TOKEN( "num-list-format", XML_NUM_LIST_FORMAT ),
|
||||
TOKEN( "num-prefix", XML_NUM_PREFIX ),
|
||||
TOKEN( "num-suffix", XML_NUM_SUFFIX ),
|
||||
TOKEN( "numalign", XML_NUMALIGN ),
|
||||
|
||||
@@ -82,7 +82,7 @@ void SvxXMLNumRuleExport::exportLevelStyle( sal_Int32 nLevel,
|
||||
sal_Int16 eType = NumberingType::CHAR_SPECIAL;
|
||||
|
||||
sal_Int16 eAdjust = HoriOrientation::LEFT;
|
||||
OUString sPrefix, sSuffix;
|
||||
OUString sPrefix, sSuffix, sListFormat;
|
||||
OUString sTextStyleName;
|
||||
bool bHasColor = false;
|
||||
sal_Int32 nColor = 0;
|
||||
@@ -123,20 +123,7 @@ void SvxXMLNumRuleExport::exportLevelStyle( sal_Int32 nLevel,
|
||||
}
|
||||
else if (rProp.Name == "ListFormat")
|
||||
{
|
||||
OUString sListFormat;
|
||||
rProp.Value >>= sListFormat;
|
||||
|
||||
// Since we have no support for entire format string it should be converted
|
||||
// to prefix and suffix. Of course, it is not so flexible as format string,
|
||||
// but it is the only option
|
||||
sal_Int32 nFirstReplacement = sListFormat.indexOf('%');
|
||||
sal_Int32 nLastReplacement = sListFormat.lastIndexOf('%') + 1;
|
||||
if (nFirstReplacement > 0)
|
||||
// Everything before first '%' will be prefix
|
||||
sPrefix = sListFormat.copy(0, nFirstReplacement);
|
||||
if (nLastReplacement >= 0 && nLastReplacement < sListFormat.getLength() -1 )
|
||||
// Everything beyond last '%' (+1 for follow up id) is a suffix
|
||||
sSuffix = sListFormat.copy(nLastReplacement + 1);
|
||||
}
|
||||
else if (rProp.Name == "BulletChar")
|
||||
{
|
||||
@@ -269,6 +256,15 @@ void SvxXMLNumRuleExport::exportLevelStyle( sal_Int32 nLevel,
|
||||
GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_STYLE_NAME,
|
||||
GetExport().EncodeStyleName( sTextStyleName ) );
|
||||
}
|
||||
if (!sListFormat.isEmpty())
|
||||
{
|
||||
if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
|
||||
{
|
||||
// Write only in extended mode: in ODF 1.3 we write only prefix/suffix,
|
||||
// no list format yet available. Praying we did not lost some formatting.
|
||||
GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, XML_NUM_LIST_FORMAT, sListFormat);
|
||||
}
|
||||
}
|
||||
if (!sPrefix.isEmpty())
|
||||
{
|
||||
GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NUM_PREFIX,
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
#include <xmloff/maptype.hxx>
|
||||
|
||||
#include <xmloff/xmlnumi.hxx>
|
||||
#include <optional>
|
||||
|
||||
using namespace ::com::sun::star;
|
||||
using namespace ::com::sun::star::uno;
|
||||
@@ -114,6 +115,8 @@ class SvxXMLListLevelStyleContext_Impl : public SvXMLImportContext
|
||||
|
||||
OUString sPrefix;
|
||||
OUString sSuffix;
|
||||
std::optional<OUString> sListFormat; // It is optional to distinguish empty format string
|
||||
// from not existing format string in old docs
|
||||
OUString sTextStyleName;
|
||||
OUString sNumFormat;
|
||||
OUString sNumLetterSync;
|
||||
@@ -298,6 +301,10 @@ SvxXMLListLevelStyleContext_Impl::SvxXMLListLevelStyleContext_Impl(
|
||||
case XML_ELEMENT(STYLE, XML_NUM_SUFFIX):
|
||||
sSuffix = aIter.toString();
|
||||
break;
|
||||
case XML_ELEMENT(STYLE, XML_NUM_LIST_FORMAT):
|
||||
case XML_ELEMENT(LO_EXT, XML_NUM_LIST_FORMAT):
|
||||
sListFormat = std::make_optional(aIter.toString());
|
||||
break;
|
||||
case XML_ELEMENT(STYLE, XML_NUM_LETTER_SYNC):
|
||||
if( bNum )
|
||||
sNumLetterSync = aIter.toString();
|
||||
@@ -392,12 +399,32 @@ Sequence<beans::PropertyValue> SvxXMLListLevelStyleContext_Impl::GetProperties()
|
||||
}
|
||||
}
|
||||
|
||||
if (!sListFormat.has_value())
|
||||
{
|
||||
// This is older document: it has no list format, but can probably contain prefix and/or suffix
|
||||
// Generate list format string, based on this
|
||||
sListFormat = std::make_optional(sPrefix);
|
||||
|
||||
for (int i = 1; i <= nNumDisplayLevels; i++)
|
||||
{
|
||||
*sListFormat += "%";
|
||||
*sListFormat += OUString::number(nLevel - nNumDisplayLevels + i + 1);
|
||||
*sListFormat += "%";
|
||||
if (i != nNumDisplayLevels)
|
||||
*sListFormat += "."; // Default separator for older ODT
|
||||
}
|
||||
|
||||
*sListFormat += sSuffix;
|
||||
}
|
||||
|
||||
aProperties.push_back(comphelper::makePropertyValue("NumberingType", eType));
|
||||
|
||||
aProperties.push_back(comphelper::makePropertyValue("Prefix", sPrefix));
|
||||
|
||||
aProperties.push_back(comphelper::makePropertyValue("Suffix", sSuffix));
|
||||
|
||||
aProperties.push_back(comphelper::makePropertyValue("ListFormat", *sListFormat));
|
||||
|
||||
aProperties.push_back(comphelper::makePropertyValue("Adjust", eAdjust));
|
||||
|
||||
sal_Int32 nLeftMargin = nSpaceBefore + nMinLabelWidth;
|
||||
|
||||
@@ -1283,6 +1283,7 @@ null-date
|
||||
null-year
|
||||
num-format
|
||||
num-letter-sync
|
||||
num-list-format
|
||||
num-prefix
|
||||
num-suffix
|
||||
numalign
|
||||
|
||||
Reference in New Issue
Block a user