diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2020-03-05 15:57:33 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-05-15 10:13:18 +0200 |
commit | d22c0aa1bd6435e84f21f509b014209985c3c83b (patch) | |
tree | dd3104bfddd343e4f294a9be72a3453d40d96e4f | |
parent | sw padded numbering: add DOCX footnote export (diff) | |
download | core-d22c0aa1bd6435e84f21f509b014209985c3c83b.tar.gz core-d22c0aa1bd6435e84f21f509b014209985c3c83b.zip |
sw padded numbering: add DOC footnote filter
Import side: remove the duplication between SwWW8ImplReader::CoreLoad()
and WW8ListManager::ReadLVL(). The CoreLoad() version did not support
reading 0x16 as it did a "& 0xf" on the value before parsing.
Export side: Writer supports footnote numbering type per-document, Word
supports it per-section. So next to the per-document export add a
per-section one, that's what Word actually reads. Similar code was there
already for DOCX.
(cherry picked from commit 5c7d0c5bafd244f1bfb3930e0229f1f3f2371c82)
Conflicts:
sw/source/filter/ww8/ww8par.cxx
Change-Id: Ic94e953cfee4514aabe507a8bcf75445bf05f401
-rw-r--r-- | sw/qa/extras/ww8export/ww8export3.cxx | 33 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtw8num.cxx | 5 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtw8sty.cxx | 8 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8.hxx | 6 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8atr.cxx | 4 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par.cxx | 18 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par.hxx | 2 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par3.cxx | 160 |
8 files changed, 160 insertions, 76 deletions
diff --git a/sw/qa/extras/ww8export/ww8export3.cxx b/sw/qa/extras/ww8export/ww8export3.cxx index 925af30ba55e..84677fb3403c 100644 --- a/sw/qa/extras/ww8export/ww8export3.cxx +++ b/sw/qa/extras/ww8export/ww8export3.cxx @@ -19,6 +19,7 @@ #include <com/sun/star/text/XTextTable.hpp> #include <com/sun/star/text/XTextTablesSupplier.hpp> #include <com/sun/star/text/WritingMode2.hpp> +#include <com/sun/star/text/XTextContentAppend.hpp> class Test : public SwModelTestBase { @@ -51,7 +52,7 @@ DECLARE_WW8EXPORT_TEST(testTdf37778_readonlySection, "tdf37778_readonlySection.d CPPUNIT_ASSERT(drawing::FillStyle_NONE != getProperty<drawing::FillStyle>(xStyle, "FillStyle")); } -DECLARE_ODFEXPORT_TEST(testArabicZeroNumbering, "arabic-zero-numbering.doc") +DECLARE_WW8EXPORT_TEST(testArabicZeroNumbering, "arabic-zero-numbering.doc") { auto xNumberingRules = getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(1), "NumberingRules"); @@ -64,6 +65,36 @@ DECLARE_ODFEXPORT_TEST(testArabicZeroNumbering, "arabic-zero-numbering.doc") aMap["NumberingType"].get<sal_uInt16>()); } +CPPUNIT_TEST_FIXTURE(SwModelTestBase, testArabicZeroNumberingFootnote) +{ + // Create a document, set footnote numbering type to ARABIC_ZERO. + loadURL("private:factory/swriter", nullptr); + uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xFootnoteSettings + = xFootnotesSupplier->getFootnoteSettings(); + sal_uInt16 nNumberingType = style::NumberingType::ARABIC_ZERO; + xFootnoteSettings->setPropertyValue("NumberingType", uno::makeAny(nNumberingType)); + + // Insert a footnote. + uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XTextContent> xFootnote( + xFactory->createInstance("com.sun.star.text.Footnote"), uno::UNO_QUERY); + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XTextContentAppend> xTextContentAppend(xTextDocument->getText(), + uno::UNO_QUERY); + xTextContentAppend->appendTextContent(xFootnote, {}); + + reload("MS Word 97", ""); + xFootnotesSupplier.set(mxComponent, uno::UNO_QUERY); + sal_uInt16 nExpected = style::NumberingType::ARABIC_ZERO; + auto nActual = getProperty<sal_uInt16>(xFootnotesSupplier->getFootnoteSettings(), "NumberingType"); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 64 + // - Actual : 4 + // i.e. the numbering type was ARABIC, not ARABIC_ZERO. + CPPUNIT_ASSERT_EQUAL(nExpected, nActual); +} + DECLARE_WW8EXPORT_TEST(testTdf122429_header, "tdf122429_header.doc") { uno::Reference<container::XNameAccess> pageStyles = getStyles("PageStyles"); diff --git a/sw/source/filter/ww8/wrtw8num.cxx b/sw/source/filter/ww8/wrtw8num.cxx index 7300afca81e9..3864b09bf681 100644 --- a/sw/source/filter/ww8/wrtw8num.cxx +++ b/sw/source/filter/ww8/wrtw8num.cxx @@ -241,6 +241,11 @@ void MSWordExportBase::NumberingDefinitions() } } +/** + * Converts the SVX numbering type to MSONFC. + * + * This is used for paragraph numbering purposes. + */ static sal_uInt8 GetLevelNFC( sal_uInt16 eNumType, const SfxItemSet *pOutSet) { sal_uInt8 nRet = 0; diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx index bfe6483b7f41..d43c96f8f3c8 100644 --- a/sw/source/filter/ww8/wrtw8sty.cxx +++ b/sw/source/filter/ww8/wrtw8sty.cxx @@ -1330,6 +1330,7 @@ void WW8AttributeOutput::StartSection() void WW8AttributeOutput::SectFootnoteEndnotePr() { const SwFootnoteInfo& rInfo = m_rWW8Export.m_pDoc->GetFootnoteInfo(); + const SwEndNoteInfo& rEndNoteInfo = m_rWW8Export.m_pDoc->GetEndNoteInfo(); m_rWW8Export.InsUInt16( NS_sprm::sprmSRncFtn ); switch( rInfo.eNum ) { @@ -1337,6 +1338,13 @@ void WW8AttributeOutput::SectFootnoteEndnotePr() case FTNNUM_CHAPTER: m_rWW8Export.pO->push_back( sal_uInt8/*rncRstSect*/ (1) ); break; default: m_rWW8Export.pO->push_back( sal_uInt8/*rncCont*/ (0) ); break; } + + m_rWW8Export.InsUInt16(NS_sprm::sprmSNfcFtnRef); + sal_uInt8 nId = WW8Export::GetNumId(rInfo.aFormat.GetNumberingType()); + SwWW8Writer::InsUInt16(*m_rWW8Export.pO, nId); + m_rWW8Export.InsUInt16(NS_sprm::sprmSNfcEdnRef); + nId = WW8Export::GetNumId(rEndNoteInfo.aFormat.GetNumberingType()); + SwWW8Writer::InsUInt16(*m_rWW8Export.pO, nId); } void WW8AttributeOutput::SectionFormProtection( bool bProtected ) diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index 45c444c1f0b3..ccfb0a7caed1 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -1144,7 +1144,11 @@ public: void SetHdFtIndex(unsigned int nHdFtIndex) { m_nHdFtIndex = nHdFtIndex; } void IncrementHdFtIndex() { ++m_nHdFtIndex; } - /// Convert the SVX numbering type to id + /** + * Converts the SVX numbering type to MSONFC. + * + * This is used for section, footnote and endnote numbering purposes. + */ static sal_uInt8 GetNumId( sal_uInt16 eNumType ); /// Guess the script (asian/western). diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx index 3b9bff97bde3..18a9da4e8d50 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -740,6 +740,10 @@ sal_uInt8 WW8Export::GetNumId( sal_uInt16 eNumType ) // nothing, WW does the same (undocumented) case SVX_NUM_NUMBER_NONE: nRet = 0xff; break; + case SVX_NUM_ARABIC_ZERO: + // 0x16, msonfcArabicLZ + nRet = 22; + break; } return nRet; } diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index 5839bf219039..22877ca19ea3 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -5119,16 +5119,6 @@ ErrCode SwWW8ImplReader::CoreLoad(WW8Glossary const *pGloss) m_xSBase.reset(new WW8ScannerBase(m_pStrm,m_pTableStream,m_pDataStream, m_xWwFib.get())); - static const SvxNumType eNumTA[16] = - { - SVX_NUM_ARABIC, SVX_NUM_ROMAN_UPPER, SVX_NUM_ROMAN_LOWER, - SVX_NUM_CHARS_UPPER_LETTER_N, SVX_NUM_CHARS_LOWER_LETTER_N, - SVX_NUM_ARABIC, SVX_NUM_ARABIC, SVX_NUM_ARABIC, - SVX_NUM_ARABIC, SVX_NUM_ARABIC, SVX_NUM_ARABIC, - SVX_NUM_ARABIC, SVX_NUM_ARABIC, SVX_NUM_ARABIC, - SVX_NUM_ARABIC, SVX_NUM_ARABIC - }; - if (m_xSBase->AreThereFootnotes()) { static const SwFootnoteNum eNumA[4] = @@ -5140,8 +5130,8 @@ ErrCode SwWW8ImplReader::CoreLoad(WW8Glossary const *pGloss) aInfo.ePos = FTNPOS_PAGE; aInfo.eNum = eNumA[m_xWDop->rncFootnote]; - sal_uInt16 nfcFootnoteRef = m_xWDop->nfcFootnoteRef & 0xF; - aInfo.aFormat.SetNumberingType( eNumTA[nfcFootnoteRef] ); + sal_uInt16 nfcFootnoteRef = m_xWDop->nfcFootnoteRef; + aInfo.aFormat.SetNumberingType(WW8ListManager::GetSvxNumTypeFromMSONFC(nfcFootnoteRef)); if( m_xWDop->nFootnote ) aInfo.nFootnoteOffset = m_xWDop->nFootnote - 1; m_rDoc.SetFootnoteInfo( aInfo ); @@ -5149,8 +5139,8 @@ ErrCode SwWW8ImplReader::CoreLoad(WW8Glossary const *pGloss) if (m_xSBase->AreThereEndnotes()) { SwEndNoteInfo aInfo = m_rDoc.GetEndNoteInfo(); // Same as for Footnote - sal_uInt16 nfcEdnRef = m_xWDop->nfcEdnRef & 0xF; - aInfo.aFormat.SetNumberingType( eNumTA[nfcEdnRef] ); + sal_uInt16 nfcEdnRef = m_xWDop->nfcEdnRef; + aInfo.aFormat.SetNumberingType(WW8ListManager::GetSvxNumTypeFromMSONFC(nfcEdnRef)); if( m_xWDop->nEdn ) aInfo.nFootnoteOffset = m_xWDop->nEdn - 1; m_rDoc.SetEndNoteInfo( aInfo ); diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx index 4221eb3b454c..bdd625364f09 100644 --- a/sw/source/filter/ww8/ww8par.hxx +++ b/sw/source/filter/ww8/ww8par.hxx @@ -156,6 +156,8 @@ public: ~WW8ListManager() COVERITY_NOEXCEPT_FALSE; SwNumRule* GetNumRule(size_t i); size_t GetWW8LSTInfoNum() const{return maLSTInfos.size();} + static SvxNumType GetSvxNumTypeFromMSONFC(sal_uInt16 nMSONFC); + private: wwSprmParser const maSprmParser; SwWW8ImplReader& rReader; diff --git a/sw/source/filter/ww8/ww8par3.cxx b/sw/source/filter/ww8/ww8par3.cxx index f0c1ab4e0c3b..966fb66fb121 100644 --- a/sw/source/filter/ww8/ww8par3.cxx +++ b/sw/source/filter/ww8/ww8par3.cxx @@ -515,6 +515,102 @@ static OUString sanitizeString(const OUString& rString) return rString; } +SvxNumType WW8ListManager::GetSvxNumTypeFromMSONFC(sal_uInt16 nNFC) +{ + SvxNumType nType(SVX_NUM_ARABIC); + + switch (nNFC) + { + case 0: + nType = SVX_NUM_ARABIC; + break; + case 1: + nType = SVX_NUM_ROMAN_UPPER; + break; + case 2: + nType = SVX_NUM_ROMAN_LOWER; + break; + case 3: + nType = SVX_NUM_CHARS_UPPER_LETTER_N; + break; + case 4: + nType = SVX_NUM_CHARS_LOWER_LETTER_N; + break; + case 5: + // actually: ORDINAL + nType = SVX_NUM_ARABIC; + break; + case 22: + // 0x16, msonfcArabicLZ + nType = SVX_NUM_ARABIC_ZERO; + break; + case 23: + nType = SVX_NUM_CHAR_SPECIAL; + + break; + case 255: + nType = SVX_NUM_NUMBER_NONE; + break; + case 14: + case 19: + nType = SVX_NUM_FULL_WIDTH_ARABIC; + break; + case 30: + nType = SVX_NUM_TIAN_GAN_ZH; + break; + case 31: + nType = SVX_NUM_DI_ZI_ZH; + break; + case 35: + case 36: + case 37: + case 11: + case 39: + nType = SVX_NUM_NUMBER_LOWER_ZH; + break; + case 34: + nType = SVX_NUM_NUMBER_UPPER_ZH_TW; + break; + case 38: + nType = SVX_NUM_NUMBER_UPPER_ZH; + break; + case 10: + nType = SVX_NUM_NUMBER_TRADITIONAL_JA; + break; + case 20: + nType = SVX_NUM_AIU_FULLWIDTH_JA; + break; + case 12: + nType = SVX_NUM_AIU_HALFWIDTH_JA; + break; + case 21: + nType = SVX_NUM_IROHA_FULLWIDTH_JA; + break; + case 13: + nType = SVX_NUM_IROHA_HALFWIDTH_JA; + break; + case 24: + nType = SVX_NUM_HANGUL_SYLLABLE_KO; + break; + case 25: + nType = SVX_NUM_HANGUL_JAMO_KO; + break; + case 41: + nType = SVX_NUM_NUMBER_HANGUL_KO; + break; + //case 42: + //case 43: + case 44: + nType = SVX_NUM_NUMBER_UPPER_KO; + break; + default: + nType = SVX_NUM_ARABIC; + break; + } + + return nType; +} + bool WW8ListManager::ReadLVL(SwNumFormat& rNumFormat, std::unique_ptr<SfxItemSet>& rpItemSet, sal_uInt16 nLevelStyle, bool bSetStartNo, std::deque<bool> &rNotReallyThere, sal_uInt16 nLevel, @@ -730,67 +826,11 @@ bool WW8ListManager::ReadLVL(SwNumFormat& rNumFormat, std::unique_ptr<SfxItemSet if( 0 <= aLVL.nStartAt ) nStartNo = static_cast<sal_uInt16>(aLVL.nStartAt); - switch( aLVL.nNFC ) + nType = GetSvxNumTypeFromMSONFC(aLVL.nNFC); + //For i120928,type info + if (bIsPicBullet) { - case 0: - nType = SVX_NUM_ARABIC; - break; - case 1: - nType = SVX_NUM_ROMAN_UPPER; - break; - case 2: - nType = SVX_NUM_ROMAN_LOWER; - break; - case 3: - nType = SVX_NUM_CHARS_UPPER_LETTER_N; - break; - case 4: - nType = SVX_NUM_CHARS_LOWER_LETTER_N; - break; - case 5: - // actually: ORDINAL - nType = SVX_NUM_ARABIC; - break; - case 22: - // 0x16, msonfcArabicLZ - nType = SVX_NUM_ARABIC_ZERO; - break; - case 23: - nType = SVX_NUM_CHAR_SPECIAL; - //For i120928,type info - if (bIsPicBullet) - { - nType = SVX_NUM_BITMAP; - } - - break; - case 255: - nType = SVX_NUM_NUMBER_NONE; - break; - case 14: - case 19:nType = SVX_NUM_FULL_WIDTH_ARABIC; break; - case 30:nType = SVX_NUM_TIAN_GAN_ZH; break; - case 31:nType = SVX_NUM_DI_ZI_ZH; break; - case 35: - case 36: - case 37: - case 11: - case 39:nType = SVX_NUM_NUMBER_LOWER_ZH; break; - case 34:nType = SVX_NUM_NUMBER_UPPER_ZH_TW; break; - case 38:nType = SVX_NUM_NUMBER_UPPER_ZH; break; - case 10:nType = SVX_NUM_NUMBER_TRADITIONAL_JA; break; - case 20:nType = SVX_NUM_AIU_FULLWIDTH_JA; break; - case 12:nType = SVX_NUM_AIU_HALFWIDTH_JA; break; - case 21:nType = SVX_NUM_IROHA_FULLWIDTH_JA; break; - case 13:nType = SVX_NUM_IROHA_HALFWIDTH_JA; break; - case 24:nType = SVX_NUM_HANGUL_SYLLABLE_KO; break; - case 25:nType = SVX_NUM_HANGUL_JAMO_KO; break; - case 41:nType = SVX_NUM_NUMBER_HANGUL_KO; break; - //case 42: - //case 43: - case 44:nType = SVX_NUM_NUMBER_UPPER_KO; break; - default: - nType= SVX_NUM_ARABIC; break; + nType = SVX_NUM_BITMAP; } //If a number level is not going to be used, then record this fact |