diff options
author | Jan-Marek Glogowski <jan-marek.glogowski@extern.cib.de> | 2019-10-22 12:24:43 +0200 |
---|---|---|
committer | Jan-Marek Glogowski <glogow@fbihome.de> | 2019-10-28 14:48:51 +0100 |
commit | a991ad93dcd6807d0eacd11a50c2ae43a2cfb882 (patch) | |
tree | e2ca253f2106438fd18606e188c5a1e28a6bc3d2 /sw | |
parent | e70ccc06094bec12d1947328b98ea040b46d08fc (diff) |
tdf#121441 improve DOCX footnote import
ODF represents footnotes by using a fixed string for the label
(text:note-citation) and a flexible body (text:note-body) for the
representation in the footnote area. The only formatting of the
footnote reference is done by changing the character class assigned
to the anchor (which is the text range of the label in the text).
For most of the setting, the footnote area label just follows the
footnote body character formatting.
OTOH MS Word has no such "restrictions". It handles the label just
as concated, formated text runs with the same style. On top of it,
DOCX completely splits the reference from the footnote area part,
including its own label, which can easily result in completely
different labels for the footnote and the reference, as I happened
to repoduce for my test documents.
At this point it's quite obvious that for any complex footnotes,
LibreOffice won't be able to represent them. IMHO ODF should offer
the same flexibility for the label and the body and allow all the
normal formatting in the label. I'm not sure that getting footnote
area and reference label out of sync is a good idea.
So this patch tries to improve the situation in the current
constraints set by ODF.
1. It imports all runs of the whole custom DOCX footnote label.
2. If any run contains a symbol, switches the font of the whole
label to the referenced symbol font.
3. Completely ignores the label of the footnote area and overrides
the font of the footnote area label with the font of the
reference.
Other problems I found while testing this code:
1. LO edit field correctly gets the font and character set, but
displays empty glyphs. So no real way to edit the label.
2. Normally the font of the footnote area label would follow the
footnote font. This doesn't work anymore when the font is
overridden for the label. Setting the whole font of the label
to Symbol doesn't seem like a good solution either.
3. You can't mix multiple fonts, or even symbols and letters, as
you can just select one font for the label.
4. You can't change the footnote are label font at all and since
it doesn't follow the footnote area anymore, there is basically
no way to change it.
Change-Id: Iafa16936be81e1866c610ebf0f71ab15e74dd059
Reviewed-on: https://gerrit.libreoffice.org/81370
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/fmtftn.hxx | 9 | ||||
-rw-r--r-- | sw/source/core/text/txtftn.cxx | 29 | ||||
-rw-r--r-- | sw/source/core/txtnode/atrftn.cxx | 16 | ||||
-rw-r--r-- | sw/source/core/unocore/unoftn.cxx | 12 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 12 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.hxx | 1 |
6 files changed, 59 insertions, 20 deletions
diff --git a/sw/inc/fmtftn.hxx b/sw/inc/fmtftn.hxx index 44ccc9556c46..247a6c5342b7 100644 --- a/sw/inc/fmtftn.hxx +++ b/sw/inc/fmtftn.hxx @@ -26,9 +26,10 @@ #include "swdllapi.h" #include "calbck.hxx" -namespace com { namespace sun { namespace star { - namespace text { class XFootnote; } -} } } +namespace com { namespace sun { namespace star { namespace text { + class XFootnote; + class XTextRange; +} } } } class SwDoc; class SwTextFootnote; @@ -91,6 +92,8 @@ public: OUString GetViewNumStr(const SwDoc& rDoc, SwRootFrame const* pLayout, bool bInclStrings = false) const; + css::uno::Reference<css::text::XTextRange> getAnchor(SwDoc& rDoc) const; + css::uno::WeakReference<css::text::XFootnote> const& GetXFootnote() const { return m_wXFootnote; } void SetXFootnote(css::uno::Reference<css::text::XFootnote> const& xNote) diff --git a/sw/source/core/text/txtftn.cxx b/sw/source/core/text/txtftn.cxx index 27dfe303d58f..9bc253768349 100644 --- a/sw/source/core/text/txtftn.cxx +++ b/sw/source/core/text/txtftn.cxx @@ -54,6 +54,9 @@ #include <ndindex.hxx> #include <IDocumentSettingAccess.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/awt/CharSet.hpp> + using namespace ::com::sun::star; bool SwTextFrame::IsFootnoteNumFrame_() const @@ -902,7 +905,7 @@ SwFootnotePortion *SwTextFormatter::NewFootnotePortion( SwTextFormatInfo &rInf, rInf.SetFootnoteInside( true ); return pRet; - } +} /** * The portion for the Footnote Numbering in the Footnote Area @@ -929,7 +932,6 @@ SwNumberPortion *SwTextFormatter::NewFootnoteNumPortion( SwTextFormatInfo const pInfo = &pDoc->GetEndNoteInfo(); else pInfo = &pDoc->GetFootnoteInfo(); - const SwAttrSet& rSet = pInfo->GetCharFormat(*pDoc)->GetAttrSet(); const SwAttrSet* pParSet = &rInf.GetCharAttr(); const IDocumentSettingAccess* pIDSA = &pDoc->getIDocumentSettingAccess(); @@ -950,6 +952,29 @@ SwNumberPortion *SwTextFormatter::NewFootnoteNumPortion( SwTextFormatInfo const pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::CJK ); pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::CTL ); + const auto xAnchor = rFootnote.getAnchor(*pDoc); + uno::Reference<beans::XPropertySet> xAnchorProps(xAnchor, uno::UNO_QUERY); + if (xAnchorProps.is()) + { + auto aAny = xAnchorProps->getPropertyValue("CharFontCharSet"); + sal_Int16 eCharSet; + if ((aAny >>= eCharSet) && eCharSet == awt::CharSet::SYMBOL) + { + OUString aFontName; + aAny = xAnchorProps->getPropertyValue("CharFontName"); + if (aAny >>= aFontName) + { + pNumFnt->SetName(aFontName, SwFontScript::Latin); + pNumFnt->SetName(aFontName, SwFontScript::CJK); + pNumFnt->SetName(aFontName, SwFontScript::CTL); + pNumFnt->SetCharSet(RTL_TEXTENCODING_SYMBOL, SwFontScript::Latin); + pNumFnt->SetCharSet(RTL_TEXTENCODING_SYMBOL, SwFontScript::CJK); + pNumFnt->SetCharSet(RTL_TEXTENCODING_SYMBOL, SwFontScript::CTL); + } + } + } + + const SwAttrSet& rSet = pInfo->GetCharFormat(*pDoc)->GetAttrSet(); pNumFnt->SetDiffFnt(&rSet, pIDSA ); pNumFnt->SetVertical( pNumFnt->GetOrientation(), m_pFrame->IsVertical() ); diff --git a/sw/source/core/txtnode/atrftn.cxx b/sw/source/core/txtnode/atrftn.cxx index 832705b4b3be..e9c9709a9ae5 100644 --- a/sw/source/core/txtnode/atrftn.cxx +++ b/sw/source/core/txtnode/atrftn.cxx @@ -37,6 +37,9 @@ #include <section.hxx> #include <calbck.hxx> #include <hints.hxx> +#include <pam.hxx> +#include <vcl/svapp.hxx> +#include <unotextrange.hxx> namespace { /// Get a sorted list of the used footnote reference numbers. @@ -258,6 +261,19 @@ OUString SwFormatFootnote::GetViewNumStr(const SwDoc& rDoc, return sRet; } +uno::Reference<text::XTextRange> SwFormatFootnote::getAnchor(SwDoc& rDoc) const +{ + SolarMutexGuard aGuard; + if (!m_pTextAttr) + return uno::Reference<text::XTextRange>(); + SwPaM aPam(m_pTextAttr->GetTextNode(), m_pTextAttr->GetStart()); + aPam.SetMark(); + ++aPam.GetMark()->nContent; + const uno::Reference<text::XTextRange> xRet = + SwXTextRange::CreateXTextRange(rDoc, *aPam.Start(), aPam.End()); + return xRet; +} + SwTextFootnote::SwTextFootnote( SwFormatFootnote& rAttr, sal_Int32 nStartPos ) : SwTextAttr( rAttr, nStartPos ) , m_pTextNode( nullptr ) diff --git a/sw/source/core/unocore/unoftn.cxx b/sw/source/core/unocore/unoftn.cxx index 50a4bfc0cba1..35d8ffafdc36 100644 --- a/sw/source/core/unocore/unoftn.cxx +++ b/sw/source/core/unocore/unoftn.cxx @@ -27,7 +27,6 @@ #include <cppuhelper/supportsservice.hxx> #include <svl/listener.hxx> #include <osl/mutex.hxx> -#include <vcl/svapp.hxx> #include <unomid.h> #include <unofootnote.hxx> @@ -366,16 +365,7 @@ uno::Reference< text::XTextRange > SAL_CALL SwXFootnote::getAnchor() { SolarMutexGuard aGuard; - - SwFormatFootnote const& rFormat( m_pImpl->GetFootnoteFormatOrThrow() ); - - SwTextFootnote const*const pTextFootnote = rFormat.GetTextFootnote(); - SwPaM aPam( pTextFootnote->GetTextNode(), pTextFootnote->GetStart() ); - aPam.SetMark(); - ++aPam.GetMark()->nContent; - const uno::Reference< text::XTextRange > xRet = - SwXTextRange::CreateXTextRange(*GetDoc(), *aPam.Start(), aPam.End()); - return xRet; + return m_pImpl->GetFootnoteFormatOrThrow().getAnchor(*GetDoc()); } void SAL_CALL SwXFootnote::dispose() diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 9e5c5aad1784..1d01e7978504 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -2680,7 +2680,10 @@ bool DocxAttributeOutput::FootnoteEndnoteRefTag() m_pSerializer->endElementNS( XML_w, XML_rPr ); } - m_pSerializer->singleElementNS(XML_w, m_footnoteEndnoteRefTag); + if (m_footnoteCustomLabel.isEmpty()) + m_pSerializer->singleElementNS(XML_w, m_footnoteEndnoteRefTag); + else + RunText(m_footnoteCustomLabel); m_footnoteEndnoteRefTag = 0; return true; } @@ -7582,12 +7585,12 @@ void DocxAttributeOutput::FootnotesEndnotes( bool bFootnotes ) // footnotes/endnotes themselves for ( const auto& rpItem : rVector ) { + m_footnoteEndnoteRefTag = bFootnotes ? XML_footnoteRef : XML_endnoteRef; + m_footnoteCustomLabel = rpItem->GetNumStr(); + m_pSerializer->startElementNS(XML_w, nItem, FSNS(XML_w, XML_id), OString::number(nIndex)); const SwNodeIndex* pIndex = rpItem->GetTextFootnote()->GetStartNode(); - // tag required at the start of each footnote/endnote - m_footnoteEndnoteRefTag = bFootnotes ? XML_footnoteRef : XML_endnoteRef; - m_rExport.WriteSpecialText( pIndex->GetIndex() + 1, pIndex->GetNode().EndOfSectionIndex(), bFootnotes? TXT_FTN: TXT_EDN ); @@ -9093,6 +9096,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, const FSHelperPtr m_pFootnotesList( new ::docx::FootnotesList() ), m_pEndnotesList( new ::docx::FootnotesList() ), m_footnoteEndnoteRefTag( 0 ), + m_footnoteCustomLabel(), m_pRedlineData( nullptr ), m_nRedlineId( 0 ), m_bOpenedSectPr( false ), diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index d0f92c1f6fc6..2a8a43a76a79 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -750,6 +750,7 @@ private: std::unique_ptr<docx::FootnotesList> m_pFootnotesList; std::unique_ptr<docx::FootnotesList> m_pEndnotesList; int m_footnoteEndnoteRefTag; + OUString m_footnoteCustomLabel; std::unique_ptr< const WW8_SepInfo > m_pSectionInfo; /// Redline data to remember in the text run. |