diff options
-rw-r--r-- | editeng/source/items/numitem.cxx | 8 | ||||
-rw-r--r-- | include/editeng/numitem.hxx | 3 | ||||
-rw-r--r-- | sw/inc/unoprnms.hxx | 1 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/tdf116883.docx | bin | 0 -> 10422 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 5 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport10.cxx | 22 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport12.cxx | 44 | ||||
-rw-r--r-- | sw/qa/extras/rtfexport/rtfexport.cxx | 8 | ||||
-rw-r--r-- | sw/qa/extras/rtfimport/rtfimport.cxx | 156 | ||||
-rw-r--r-- | sw/source/core/doc/number.cxx | 116 | ||||
-rw-r--r-- | sw/source/core/unocore/unosett.cxx | 15 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtw8num.cxx | 8 | ||||
-rw-r--r-- | writerfilter/source/dmapper/NumberingManager.cxx | 73 | ||||
-rw-r--r-- | writerfilter/source/dmapper/NumberingManager.hxx | 5 | ||||
-rw-r--r-- | writerfilter/source/dmapper/PropertyIds.cxx | 1 | ||||
-rw-r--r-- | writerfilter/source/dmapper/PropertyIds.hxx | 1 |
16 files changed, 235 insertions, 231 deletions
diff --git a/editeng/source/items/numitem.cxx b/editeng/source/items/numitem.cxx index 67cf0373cc37..6182ec5189b1 100644 --- a/editeng/source/items/numitem.cxx +++ b/editeng/source/items/numitem.cxx @@ -344,9 +344,10 @@ SvxNumberFormat& SvxNumberFormat::operator=( const SvxNumberFormat& rFormat ) mnListtabPos = rFormat.mnListtabPos; mnFirstLineIndent = rFormat.mnFirstLineIndent; mnIndentAt = rFormat.mnIndentAt; - eVertOrient = rFormat.eVertOrient ; - sPrefix = rFormat.sPrefix ; - sSuffix = rFormat.sSuffix ; + eVertOrient = rFormat.eVertOrient; + sPrefix = rFormat.sPrefix; + sSuffix = rFormat.sSuffix; + sListFormat = rFormat.sListFormat; aGraphicSize = rFormat.aGraphicSize ; nBulletColor = rFormat.nBulletColor ; nBulletRelSize = rFormat.nBulletRelSize; @@ -381,6 +382,7 @@ bool SvxNumberFormat::operator==( const SvxNumberFormat& rFormat) const eVertOrient != rFormat.eVertOrient || sPrefix != rFormat.sPrefix || sSuffix != rFormat.sSuffix || + sListFormat != rFormat.sListFormat || aGraphicSize != rFormat.aGraphicSize || nBulletColor != rFormat.nBulletColor || nBulletRelSize != rFormat.nBulletRelSize || diff --git a/include/editeng/numitem.hxx b/include/editeng/numitem.hxx index 699f82928069..52cb14858c1f 100644 --- a/include/editeng/numitem.hxx +++ b/include/editeng/numitem.hxx @@ -102,6 +102,7 @@ public: private: OUString sPrefix; OUString sSuffix; + OUString sListFormat; // Format string ">%1.%2<" can be used instead of prefix/suffix SvxAdjust eNumAdjust; @@ -166,6 +167,8 @@ public: const OUString& GetPrefix() const { return sPrefix;} void SetSuffix(const OUString& rSet) { sSuffix = rSet;} const OUString& GetSuffix() const { return sSuffix;} + void SetListFormat(const OUString& rSet) { sListFormat = rSet; } + const OUString& GetListFormat() const { return sListFormat; } void SetCharFormatName(const OUString& rSet){ sCharStyleName = rSet; } virtual OUString GetCharFormatName()const; diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx index d324be62bf0a..91780b6530bd 100644 --- a/sw/inc/unoprnms.hxx +++ b/sw/inc/unoprnms.hxx @@ -77,6 +77,7 @@ #define UNO_NAME_ANCHOR_CHAR_STYLE_NAME "AnchorCharStyleName" #define UNO_NAME_SUFFIX "Suffix" #define UNO_NAME_PREFIX "Prefix" +#define UNO_NAME_LIST_FORMAT "ListFormat" #define UNO_NAME_PARENT_NUMBERING "ParentNumbering" #define UNO_NAME_CHAR_FONT_NAME "CharFontName" #define UNO_NAME_CHAR_FONT_STYLE_NAME "CharFontStyleName" diff --git a/sw/qa/extras/ooxmlexport/data/tdf116883.docx b/sw/qa/extras/ooxmlexport/data/tdf116883.docx Binary files differnew file mode 100644 index 000000000000..52a9c42218fa --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/tdf116883.docx diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index e144e6178129..d4a453a27580 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -780,7 +780,10 @@ DECLARE_OOXMLEXPORT_TEST(testNumOverrideLvltext, "num-override-lvltext.docx") { uno::Reference<container::XIndexAccess> xRules = getProperty< uno::Reference<container::XIndexAccess> >(getStyles("NumberingStyles")->getByName("WWNum1"), "NumberingRules"); // This was 1, i.e. the numbering on the second level was "1", not "1.1". - CPPUNIT_ASSERT_EQUAL(sal_Int16(2), comphelper::SequenceAsHashMap(xRules->getByIndex(1))["ParentNumbering"].get<sal_Int16>()); + // Check the praragraph properties, not the list ones, since they can differ due to overrides + uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), getProperty<sal_Int16>(xPara, "NumberingLevel")); + CPPUNIT_ASSERT_EQUAL(OUString("1.1"), getProperty<OUString>(xPara, "ListLabelString")); // The paragraph marker's red font color was inherited by the number portion, this was ff0000. CPPUNIT_ASSERT_EQUAL(OUString("ffffffff"), parseDump("//Special[@nType='PortionType::Number']/SwFont", "color")); diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx index 835947da9dfb..92d7d63aa80d 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx @@ -853,25 +853,11 @@ DECLARE_OOXMLEXPORT_TEST(testTdf65955_2, "tdf65955_2.odt") DECLARE_OOXMLEXPORT_TEST(testChtOutlineNumberingOoxml, "chtoutline.docx") { - const sal_Unicode aExpectedPrefix[2] = { 0x7b2c, 0x0020 }; - const sal_Unicode aExpectedSuffix[2] = { 0x0020, 0x7ae0 }; - uno::Reference< text::XChapterNumberingSupplier > xChapterNumberingSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference< container::XIndexAccess> xLevels(xChapterNumberingSupplier->getChapterNumberingRules()); - uno::Sequence<beans::PropertyValue> aProps; - xLevels->getByIndex(0) >>= aProps; // 1st level - - OUString aSuffix,aPrefix; - for (int i = 0; i < aProps.getLength(); ++i) - { - const beans::PropertyValue& rProp = aProps[i]; + const sal_Unicode aExpectedNumbering[] = { 0x7b2c, ' ', '1', ' ', 0x7ae0 }; - if (rProp.Name == "Suffix") - aSuffix = rProp.Value.get<OUString>(); - if (rProp.Name == "Prefix") - aPrefix = rProp.Value.get<OUString>(); - } - CPPUNIT_ASSERT_EQUAL(OUString(aExpectedPrefix,SAL_N_ELEMENTS(aExpectedPrefix)), aPrefix); - CPPUNIT_ASSERT_EQUAL(OUString(aExpectedSuffix,SAL_N_ELEMENTS(aExpectedSuffix)), aSuffix); + uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(aExpectedNumbering,SAL_N_ELEMENTS(aExpectedNumbering)), + getProperty<OUString>(xPara, "ListLabelString")); } DECLARE_OOXMLEXPORT_TEST(mathtype, "mathtype.docx") diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx index 908faf14e22a..f51804eebd1c 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx @@ -995,6 +995,50 @@ DECLARE_OOXMLEXPORT_TEST(testTdf122594, "tdf122594.docx") CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), nCheck); } +DECLARE_OOXMLEXPORT_TEST(testTdf116883, "tdf116883.docx") +{ + { + uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1>1>"), getProperty<OUString>(xPara, "ListLabelString")); + } + { + uno::Reference<beans::XPropertySet> xPara(getParagraph(2), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1>2>"), getProperty<OUString>(xPara, "ListLabelString")); + } + { + uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1>2>1>1>"), getProperty<OUString>(xPara, "ListLabelString")); + } + { + uno::Reference<beans::XPropertySet> xPara(getParagraph(4), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1>2>2>"), getProperty<OUString>(xPara, "ListLabelString")); + } + { + uno::Reference<beans::XPropertySet> xPara(getParagraph(5), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1>2>3>"), getProperty<OUString>(xPara, "ListLabelString")); + } + { + uno::Reference<beans::XPropertySet> xPara(getParagraph(6), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1>1)"), getProperty<OUString>(xPara, "ListLabelString")); + } + { + uno::Reference<beans::XPropertySet> xPara(getParagraph(7), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1>2)"), getProperty<OUString>(xPara, "ListLabelString")); + } + { + uno::Reference<beans::XPropertySet> xPara(getParagraph(8), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1>2>1<1)"), getProperty<OUString>(xPara, "ListLabelString")); + } + { + uno::Reference<beans::XPropertySet> xPara(getParagraph(9), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1>2.2)"), getProperty<OUString>(xPara, "ListLabelString")); + } + { + uno::Reference<beans::XPropertySet> xPara(getParagraph(10), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1>2.3)"), getProperty<OUString>(xPara, "ListLabelString")); + } +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/rtfexport/rtfexport.cxx b/sw/qa/extras/rtfexport/rtfexport.cxx index cf2cb780bb12..535374da8863 100644 --- a/sw/qa/extras/rtfexport/rtfexport.cxx +++ b/sw/qa/extras/rtfexport/rtfexport.cxx @@ -659,16 +659,16 @@ DECLARE_RTFEXPORT_TEST(testFdo66682, "fdo66682.rtf") uno::Sequence<beans::PropertyValue> aProps; xLevels->getByIndex(0) >>= aProps; // 1st level - OUString aSuffix; + OUString aListFormat; for (int i = 0; i < aProps.getLength(); ++i) { const beans::PropertyValue& rProp = aProps[i]; - if (rProp.Name == "Suffix") - aSuffix = rProp.Value.get<OUString>(); + if (rProp.Name == "ListFormat") + aListFormat = rProp.Value.get<OUString>(); } // Suffix was '\0' instead of ' '. - CPPUNIT_ASSERT_EQUAL(OUString(" "), aSuffix); + CPPUNIT_ASSERT_EQUAL(OUString(" %1 "), aListFormat); } DECLARE_RTFEXPORT_TEST(testParaShadow, "para-shadow.rtf") diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx index a652b354dbe7..3fe90033be59 100644 --- a/sw/qa/extras/rtfimport/rtfimport.cxx +++ b/sw/qa/extras/rtfimport/rtfimport.cxx @@ -141,21 +141,52 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf108943) CPPUNIT_TEST_FIXTURE(Test, testFdo46662) { load(mpTestDocumentPath, "fdo46662.rtf"); - uno::Reference<beans::XPropertySet> xPropertySet( - getStyles("NumberingStyles")->getByName("WWNum3"), uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xLevels( - xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY); - uno::Sequence<beans::PropertyValue> aProps; - xLevels->getByIndex(1) >>= aProps; // 2nd level - for (int i = 0; i < aProps.getLength(); ++i) + OUString listStyle; + { - const beans::PropertyValue& rProp = aProps[i]; + uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), + getProperty<sal_Int16>(xPara, "NumberingLevel")); + CPPUNIT_ASSERT(xPara->getPropertyValue("NumberingStyleName") >>= listStyle); + CPPUNIT_ASSERT(listStyle.startsWith("WWNum")); + CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty<OUString>(xPara, "ListLabelString")); + } + + { + 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(xPara->getPropertyValue("NumberingStyleName") >>= listStyle); + CPPUNIT_ASSERT(listStyle.startsWith("WWNum")); + CPPUNIT_ASSERT_EQUAL(OUString("1.1"), getProperty<OUString>(xPara, "ListLabelString")); + } + + { + uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2), + getProperty<sal_Int16>(xPara, "NumberingLevel")); + CPPUNIT_ASSERT(xPara->getPropertyValue("NumberingStyleName") >>= listStyle); + CPPUNIT_ASSERT(listStyle.startsWith("WWNum")); + CPPUNIT_ASSERT_EQUAL(OUString("1.1.1"), getProperty<OUString>(xPara, "ListLabelString")); + } + + { + uno::Reference<beans::XPropertySet> xPara(getParagraph(4), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(3), + getProperty<sal_Int16>(xPara, "NumberingLevel")); + CPPUNIT_ASSERT(xPara->getPropertyValue("NumberingStyleName") >>= listStyle); + CPPUNIT_ASSERT(listStyle.startsWith("WWNum")); + CPPUNIT_ASSERT_EQUAL(OUString("1.1.1.1"), getProperty<OUString>(xPara, "ListLabelString")); + } - if (rProp.Name == "ParentNumbering") - CPPUNIT_ASSERT_EQUAL(sal_Int16(2), rProp.Value.get<sal_Int16>()); - else if (rProp.Name == "Suffix") - CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rProp.Value.get<OUString>().getLength()); + { + 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(xPara->getPropertyValue("NumberingStyleName") >>= listStyle); + CPPUNIT_ASSERT(listStyle.startsWith("WWNum")); + CPPUNIT_ASSERT_EQUAL(OUString("2"), getProperty<OUString>(xPara, "ListLabelString")); } } @@ -1037,25 +1068,12 @@ CPPUNIT_TEST_FIXTURE(Test, testCp950listleveltext1) { load(mpTestDocumentPath, "cp950listleveltext1.rtf"); // suffix with Chinese only ( most common case generated by MSO2010 TC) - const sal_Unicode aExpectedSuffix[1] - = { 0x3001 }; // This is a dot that is generally used as suffix of Chinese list number - uno::Reference<beans::XPropertySet> xPropertySet( - getStyles("NumberingStyles")->getByName("WWNum3"), uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xLevels( - xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY); - uno::Sequence<beans::PropertyValue> aProps; - xLevels->getByIndex(0) >>= aProps; // 1st level - - OUString aSuffix; - for (int i = 0; i < aProps.getLength(); ++i) - { - const beans::PropertyValue& rProp = aProps[i]; + // This is a dot that is generally used as suffix of Chinese list number + const sal_Unicode aExpectedNumbering[] = { 0x4e00, 0x3001 }; - if (rProp.Name == "Suffix") - aSuffix = rProp.Value.get<OUString>(); - } - // Suffix was '\0' instead of ' '. - CPPUNIT_ASSERT_EQUAL(OUString(aExpectedSuffix, SAL_N_ELEMENTS(aExpectedSuffix)), aSuffix); + uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(aExpectedNumbering, SAL_N_ELEMENTS(aExpectedNumbering)), + getProperty<OUString>(xPara, "ListLabelString")); } // This testcase illustrate leveltext with multibyte strings coded in cp950 ( BIG5 ). @@ -1063,85 +1081,35 @@ CPPUNIT_TEST_FIXTURE(Test, testCp950listleveltext2) { load(mpTestDocumentPath, "cp950listleveltext2.rtf"); // Prefix and suffix with Chinese only ( tweaked from default in MSO2010 TC) - const sal_Unicode aExpectedPrefix[2] = { 0x524d, 0x7f6e }; - const sal_Unicode aExpectedSuffix[3] = { 0x3001, 0x5f8c, 0x7f6e }; + const sal_Unicode aExpectedNumbering[] = { 0x524d, 0x7f6e, 0x7532, 0x3001, 0x5f8c, 0x7f6e }; - uno::Reference<beans::XPropertySet> xPropertySet( - getStyles("NumberingStyles")->getByName("WWNum1"), uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xLevels( - xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY); - uno::Sequence<beans::PropertyValue> aProps; - xLevels->getByIndex(0) >>= aProps; // 1st level - - OUString aSuffix, aPrefix; - for (int i = 0; i < aProps.getLength(); ++i) - { - const beans::PropertyValue& rProp = aProps[i]; - - if (rProp.Name == "Suffix") - aSuffix = rProp.Value.get<OUString>(); - if (rProp.Name == "Prefix") - aPrefix = rProp.Value.get<OUString>(); - } - // Suffix was '\0' instead of ' '. - CPPUNIT_ASSERT_EQUAL(OUString(aExpectedPrefix, SAL_N_ELEMENTS(aExpectedPrefix)), aPrefix); - CPPUNIT_ASSERT_EQUAL(OUString(aExpectedSuffix, SAL_N_ELEMENTS(aExpectedSuffix)), aSuffix); + uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(aExpectedNumbering, SAL_N_ELEMENTS(aExpectedNumbering)), + getProperty<OUString>(xPara, "ListLabelString")); } // This testcase illustrate leveltext with multibyte strings coded in cp950 ( BIG5 ) CPPUNIT_TEST_FIXTURE(Test, testCp950listleveltext3) { load(mpTestDocumentPath, "cp950listleveltext3.rtf"); - // Prefix and suffix that mix Chinese and English ( tweaked from default in MSO2010 TC) - const sal_Unicode aExpectedPrefix[4] = { 0x524d, 0x0061, 0x7f6e, 0x0062 }; - const sal_Unicode aExpectedSuffix[6] = { 0x3001, 0x0063, 0x5f8c, 0x0064, 0x7f6e, 0x0065 }; + // Numbering is a mix Chinese and English ( tweaked from default in MSO2010 TC) + const sal_Unicode aExpectedNumbering[] = { 0x524d, 0x0061, 0x7f6e, 0x0062, 0x7532, 0x3001, + 0x0063, 0x5f8c, 0x0064, 0x7f6e, 0x0065 }; - uno::Reference<beans::XPropertySet> xPropertySet( - getStyles("NumberingStyles")->getByName("WWNum1"), uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xLevels( - xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY); - uno::Sequence<beans::PropertyValue> aProps; - xLevels->getByIndex(0) >>= aProps; // 1st level - - OUString aSuffix, aPrefix; - for (int i = 0; i < aProps.getLength(); ++i) - { - const beans::PropertyValue& rProp = aProps[i]; - - if (rProp.Name == "Suffix") - aSuffix = rProp.Value.get<OUString>(); - if (rProp.Name == "Prefix") - aPrefix = rProp.Value.get<OUString>(); - } - // Suffix was '\0' instead of ' '. - CPPUNIT_ASSERT_EQUAL(OUString(aExpectedPrefix, SAL_N_ELEMENTS(aExpectedPrefix)), aPrefix); - CPPUNIT_ASSERT_EQUAL(OUString(aExpectedSuffix, SAL_N_ELEMENTS(aExpectedSuffix)), aSuffix); + uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(aExpectedNumbering, SAL_N_ELEMENTS(aExpectedNumbering)), + getProperty<OUString>(xPara, "ListLabelString")); } CPPUNIT_TEST_FIXTURE(Test, testChtOutlineNumberingRtf) { load(mpTestDocumentPath, "chtoutline.rtf"); - const sal_Unicode aExpectedPrefix[2] = { 0x7b2c, 0x0020 }; - const sal_Unicode aExpectedSuffix[2] = { 0x0020, 0x7ae0 }; - uno::Reference<text::XChapterNumberingSupplier> xChapterNumberingSupplier(mxComponent, - uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xLevels( - xChapterNumberingSupplier->getChapterNumberingRules()); - uno::Sequence<beans::PropertyValue> aProps; - xLevels->getByIndex(0) >>= aProps; // 1st level - OUString aSuffix, aPrefix; - for (int i = 0; i < aProps.getLength(); ++i) - { - const beans::PropertyValue& rProp = aProps[i]; + const sal_Unicode aExpectedNumbering[] = { 0x7b2c, ' ', '1', ' ', 0x7ae0 }; - if (rProp.Name == "Suffix") - aSuffix = rProp.Value.get<OUString>(); - if (rProp.Name == "Prefix") - aPrefix = rProp.Value.get<OUString>(); - } - CPPUNIT_ASSERT_EQUAL(OUString(aExpectedPrefix, SAL_N_ELEMENTS(aExpectedPrefix)), aPrefix); - CPPUNIT_ASSERT_EQUAL(OUString(aExpectedSuffix, SAL_N_ELEMENTS(aExpectedSuffix)), aSuffix); + uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(aExpectedNumbering, SAL_N_ELEMENTS(aExpectedNumbering)), + getProperty<OUString>(xPara, "ListLabelString")); } CPPUNIT_TEST_FIXTURE(Test, testTdf90046) diff --git a/sw/source/core/doc/number.cxx b/sw/source/core/doc/number.cxx index f57933440278..df3dcf76bfff 100644 --- a/sw/source/core/doc/number.cxx +++ b/sw/source/core/doc/number.cxx @@ -639,64 +639,94 @@ OUString SwNumRule::MakeNumString( const SwNumberTree::tNumberVector & rNumVecto const SwNumFormat& rMyNFormat = Get( static_cast<sal_uInt16>(nLevel) ); { - SwNumberTree::tNumberVector::size_type i = nLevel; + css::lang::Locale aLocale( LanguageTag::convertToLocale(nLang)); - if( !IsContinusNum() && - // - do not include upper levels, if level isn't numbered. - rMyNFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE && - rMyNFormat.GetIncludeUpperLevels() ) // Just the own level? + OUString sLevelFormat = rMyNFormat.GetListFormat(); + if (!sLevelFormat.isEmpty()) { - sal_uInt8 n = rMyNFormat.GetIncludeUpperLevels(); - if( 1 < n ) + // In this case we are ignoring GetIncludeUpperLevels: we put all + // level nubers requested by level format + for (SwNumberTree::tNumberVector::size_type i=0; i <= nLevel; ++i) { - if( i+1 >= n ) - i -= n - 1; + OUString sReplacement; + if (rNumVector[i]) + { + if (bOnlyArabic) + sReplacement = OUString::number(rNumVector[i]); + else + sReplacement = Get(i).GetNumStr(rNumVector[i], aLocale); + } else - i = 0; + sReplacement = "0"; // all 0 level are a 0 + + OUString sFind("%" + OUString::number(i + 1)); + sal_Int32 nPosition = sLevelFormat.indexOf(sFind); + if (nPosition >= 0) + sLevelFormat = sLevelFormat.replaceAt(nPosition, sFind.getLength(), sReplacement); } + aStr = sLevelFormat; } - - css::lang::Locale aLocale( LanguageTag::convertToLocale(nLang)); - - for( ; i <= nLevel; ++i ) + else { - const SwNumFormat& rNFormat = Get( i ); - if( SVX_NUM_NUMBER_NONE == rNFormat.GetNumberingType() ) + // Fallback case: level format is not defined + // So use old way with levels joining by dot "." + SwNumberTree::tNumberVector::size_type i = nLevel; + + if (!IsContinusNum() && + // - do not include upper levels, if level isn't numbered. + rMyNFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE && + rMyNFormat.GetIncludeUpperLevels()) // Just the own level? { - // Should 1.1.1 --> 2. NoNum --> 1..1 or 1.1 ?? - // if( i != rNum.nMyLevel ) - // aStr += "."; - continue; + sal_uInt8 n = rMyNFormat.GetIncludeUpperLevels(); + if (1 < n) + { + if (i + 1 >= n) + i -= n - 1; + else + i = 0; + } } - if( rNumVector[ i ] ) + for (; i <= nLevel; ++i) { - if( bOnlyArabic ) - aStr.append(OUString::number( rNumVector[ i ] )); + const SwNumFormat& rNFormat = Get(i); + if (SVX_NUM_NUMBER_NONE == rNFormat.GetNumberingType()) + { + // Should 1.1.1 --> 2. NoNum --> 1..1 or 1.1 ?? + // if( i != rNum.nMyLevel ) + // aStr += "."; + continue; + } + + if (rNumVector[i]) + { + if (bOnlyArabic) + aStr.append(OUString::number(rNumVector[i])); + else + aStr.append(rNFormat.GetNumStr(rNumVector[i], aLocale)); + } else - aStr.append(rNFormat.GetNumStr( rNumVector[ i ], aLocale )); + aStr.append("0"); // all 0 level are a 0 + if (i != nLevel && !aStr.isEmpty()) + aStr.append("."); } - else - aStr.append("0"); // all 0 level are a 0 - if( i != nLevel && !aStr.isEmpty() ) - aStr.append("."); - } - // The type doesn't have any number, so don't append - // the post-/prefix string - if( bInclStrings && !bOnlyArabic && - SVX_NUM_CHAR_SPECIAL != rMyNFormat.GetNumberingType() && - SVX_NUM_BITMAP != rMyNFormat.GetNumberingType() ) - { - const OUString& sPrefix = rMyNFormat.GetPrefix(); - const OUString& sSuffix = rMyNFormat.GetSuffix(); - - aStr.insert(0, sPrefix); - aStr.append(sSuffix); - if ( pExtremities ) + // The type doesn't have any number, so don't append + // the post-/prefix string + if (bInclStrings && !bOnlyArabic && + SVX_NUM_CHAR_SPECIAL != rMyNFormat.GetNumberingType() && + SVX_NUM_BITMAP != rMyNFormat.GetNumberingType()) { - pExtremities->nPrefixChars = sPrefix.getLength(); - pExtremities->nSuffixChars = sSuffix.getLength(); + const OUString& sPrefix = rMyNFormat.GetPrefix(); + const OUString& sSuffix = rMyNFormat.GetSuffix(); + + aStr.insert(0, sPrefix); + aStr.append(sSuffix); + if (pExtremities) + { + pExtremities->nPrefixChars = sPrefix.getLength(); + pExtremities->nSuffixChars = sSuffix.getLength(); + } } } } diff --git a/sw/source/core/unocore/unosett.cxx b/sw/source/core/unocore/unosett.cxx index c41d13dea3a8..2b3b08e59b9e 100644 --- a/sw/source/core/unocore/unosett.cxx +++ b/sw/source/core/unocore/unosett.cxx @@ -1342,6 +1342,10 @@ uno::Sequence<beans::PropertyValue> SwXNumberingRules::GetPropertiesForNumFormat aUString = rFormat.GetSuffix(); aPropertyValues.push_back(comphelper::makePropertyValue("Suffix", aUString)); + //listformat + aUString = rFormat.GetListFormat(); + aPropertyValues.push_back(comphelper::makePropertyValue("ListFormat", aUString)); + //char style name aUString.clear(); @@ -1581,7 +1585,9 @@ void SwXNumberingRules::SetPropertiesToNumFormat( // these two are accepted but ignored for some reason UNO_NAME_BULLET_REL_SIZE, // 25 UNO_NAME_BULLET_COLOR, // 26 - UNO_NAME_GRAPHIC_URL // 27 + UNO_NAME_GRAPHIC_URL, // 27 + + UNO_NAME_LIST_FORMAT // 28 }; enum { @@ -2035,6 +2041,13 @@ void SwXNumberingRules::SetPropertiesToNumFormat( bWrongArg = true; } break; + case 28: //"ListFormat", + { + OUString uTmp; + pProp->Value >>= uTmp; + aFormat.SetListFormat(uTmp); + } + break; } } if(!bWrongArg && (pSetBrush || pSetSize || pSetVOrient)) diff --git a/sw/source/filter/ww8/wrtw8num.cxx b/sw/source/filter/ww8/wrtw8num.cxx index e665a253ca3e..afe0204a48cd 100644 --- a/sw/source/filter/ww8/wrtw8num.cxx +++ b/sw/source/filter/ww8/wrtw8num.cxx @@ -489,7 +489,13 @@ void MSWordExportBase::NumberingLevel( const vcl::Font* pBulletFont=nullptr; rtl_TextEncoding eChrSet=0; FontFamily eFamily=FAMILY_DECORATIVE; - if (SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType() || + + if (!rRule.Get(nLvl).GetListFormat().isEmpty()) + { + // We have stored list format, use it + sNumStr = rRule.Get(nLvl).GetListFormat(); + } + else if (SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType() || SVX_NUM_BITMAP == rFormat.GetNumberingType()) { sNumStr = OUString(rFormat.GetBulletChar()); diff --git a/writerfilter/source/dmapper/NumberingManager.cxx b/writerfilter/source/dmapper/NumberingManager.cxx index 32dead60a100..eab1ac81ecc7 100644 --- a/writerfilter/source/dmapper/NumberingManager.cxx +++ b/writerfilter/source/dmapper/NumberingManager.cxx @@ -42,6 +42,7 @@ #include <tools/diagnose_ex.h> #include <comphelper/sequence.hxx> #include <comphelper/propertyvalue.hxx> +#include <comphelper/string.hxx> using namespace com::sun::star; @@ -149,55 +150,6 @@ void ListLevel::SetParaStyle( const tools::SvRef< StyleSheetEntry >& pStyle ) && styleId[ RTL_CONSTASCII_LENGTH( "Heading " ) ] <= '9' ); } -sal_Int16 ListLevel::GetParentNumbering( const OUString& sText, sal_Int16 nLevel, - OUString& rPrefix, OUString& rSuffix ) -{ - sal_Int16 nParentNumbering = 1; - - //now parse the text to find %n from %1 to %nLevel+1 - //everything before the first % and the last %x is prefix and suffix - OUString sLevelText( sText ); - sal_Int32 nCurrentIndex = 0; - sal_Int32 nFound = sLevelText.indexOf( '%', nCurrentIndex ); - if( nFound > 0 ) - { - rPrefix = sLevelText.copy( 0, nFound ); - sLevelText = sLevelText.copy( nFound ); - } - sal_Int32 nMinLevel = nLevel; - //now the text should either be empty or start with % - nFound = sLevelText.getLength( ) > 1 ? 0 : -1; - while( nFound >= 0 ) - { - if( sLevelText.getLength() > 1 ) - { - sal_Unicode cLevel = sLevelText[1]; - if( cLevel >= '1' && cLevel <= '9' ) - { - if( cLevel - '1' < nMinLevel ) - nMinLevel = cLevel - '1'; - //remove first char - next char is removed later - sLevelText = sLevelText.copy( 1 ); - } - } - //remove old '%' or number - sLevelText = sLevelText.copy( 1 ); - nCurrentIndex = 0; - nFound = sLevelText.indexOf( '%', nCurrentIndex ); - //remove the text before the next % - if(nFound > 0) - sLevelText = sLevelText.copy( nFound -1 ); - } - if( nMinLevel < nLevel ) - { - nParentNumbering = sal_Int16( nLevel - nMinLevel + 1); - } - - rSuffix = sLevelText; - - return nParentNumbering; -} - uno::Sequence<beans::PropertyValue> ListLevel::GetProperties(bool bDefaults) { uno::Sequence<beans::PropertyValue> aLevelProps = GetLevelProperties(bDefaults); @@ -588,19 +540,11 @@ void ListDef::CreateNumberingRules( DomainMapper& rDMapper, if (pLevel.get() && !pLevel->GetBulletChar().isEmpty()) sText = pLevel->GetBulletChar( ); - OUString sPrefix; - OUString sSuffix; - OUString& rPrefix = sPrefix; - OUString& rSuffix = sSuffix; - sal_Int16 nParentNum = ListLevel::GetParentNumbering( - sText, nLevel, rPrefix, rSuffix ); - - aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_PREFIX), rPrefix)); - if (sText.isEmpty()) { // Empty <w:lvlText>? Then put a Unicode "zero width space" as a suffix, so LabelFollowedBy is still shown, as in Word. // With empty suffix, Writer does not show LabelFollowedBy, either. + OUString sSuffix; auto it = std::find_if(aLvlProps.begin(), aLvlProps.end(), [](const beans::PropertyValue& rValue) { return rValue.Name == "NumberingType"; }); if (it != aLvlProps.end()) { @@ -617,12 +561,19 @@ void ListDef::CreateNumberingRules( DomainMapper& rDMapper, } if (bLabelFollowedBy && nNumberFormat == style::NumberingType::NUMBER_NONE) - rSuffix = OUString(u'\x200B'); + sSuffix = OUString(u'\x200B'); } + aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_SUFFIX), sSuffix)); } + else + { + aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_LIST_FORMAT), sText)); - aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_SUFFIX), rSuffix)); - aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_PARENT_NUMBERING), nParentNum)); + // Total count of replacement holders is determining amount of required parent numbering to include + // TODO: not sure how "%" symbol is escaped. This is not supported yet + sal_Int16 nParentNum = comphelper::string::getTokenCount(sText, '%'); + aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_PARENT_NUMBERING), nParentNum)); + } aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_POSITION_AND_SPACE_MODE), sal_Int16(text::PositionAndSpaceMode::LABEL_ALIGNMENT))); diff --git a/writerfilter/source/dmapper/NumberingManager.hxx b/writerfilter/source/dmapper/NumberingManager.hxx index c0e68d9327a5..3949c3bf7dcd 100644 --- a/writerfilter/source/dmapper/NumberingManager.hxx +++ b/writerfilter/source/dmapper/NumberingManager.hxx @@ -86,11 +86,6 @@ public: bool HasValues() const; // UNO mapping functions - - // rPrefix and rSuffix are out parameters - static sal_Int16 GetParentNumbering( const OUString& sText, sal_Int16 nLevel, - OUString& rPrefix, OUString& rSuffix ); - css::uno::Sequence<css::beans::PropertyValue> GetProperties(bool bDefaults); css::uno::Sequence<css::beans::PropertyValue> GetCharStyleProperties(); diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx index 0d5740e9fa83..6fecf7fe2be4 100644 --- a/writerfilter/source/dmapper/PropertyIds.cxx +++ b/writerfilter/source/dmapper/PropertyIds.cxx @@ -207,6 +207,7 @@ OUString getPropertyName( PropertyIds eId ) case PROP_LEVEL_FOLLOW : sName = "LabelFollowedBy"; break; case PROP_LEVEL_PARAGRAPH_STYLES : sName = "LevelParagraphStyles"; break; case PROP_LEVEL_FORMAT : sName = "LevelFormat"; break; + case PROP_LIST_FORMAT : sName = "ListFormat"; break; case PROP_TOKEN_TYPE : sName = "TokenType"; break; case PROP_TOKEN_HYPERLINK_START : sName = "TokenHyperlinkStart"; break; case PROP_TOKEN_HYPERLINK_END : sName = "TokenHyperlinkEnd"; break; diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx index a1a0c8f851a1..d511fd737238 100644 --- a/writerfilter/source/dmapper/PropertyIds.hxx +++ b/writerfilter/source/dmapper/PropertyIds.hxx @@ -205,6 +205,7 @@ enum PropertyIds ,PROP_LEVEL_FORMAT ,PROP_LEVEL_PARAGRAPH_STYLES ,PROP_LISTTAB_STOP_POSITION + ,PROP_LIST_FORMAT ,PROP_MACRO_NAME ,PROP_NAME ,PROP_NUMBERING_LEVEL |