sw/inc/IDocumentSettingAccess.hxx | 1 sw/qa/extras/layout/data/A020-min.rtf | 30 ++++++++++++ sw/qa/extras/layout/layout2.cxx | 49 ++++++++++++++++++++ sw/qa/extras/ooxmlexport/data/fdo74110.docx |binary sw/source/core/doc/DocumentSettingManager.cxx | 12 +++++ sw/source/core/inc/DocumentSettingManager.hxx | 3 - sw/source/core/text/atrstck.cxx | 8 ++- sw/source/core/text/itratr.cxx | 55 ++++++++++++++++++++++- sw/source/core/text/itratr.hxx | 5 ++ sw/source/core/text/porlay.cxx | 19 +++++++ sw/source/core/text/txtfrm.cxx | 17 +++++++ sw/source/filter/ww8/ww8par.cxx | 2 sw/source/filter/xml/xmlimp.cxx | 10 ---- sw/source/uibase/uno/SwXDocumentSettings.cxx | 18 +++++++ sw/source/writerfilter/dmapper/SettingsTable.cxx | 2 sw/source/writerfilter/filter/WriterFilter.cxx | 1 16 files changed, 215 insertions(+), 17 deletions(-)
New commits: commit 7b8cec8322b60673e686660caf875bc71117bbd0 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Tue Sep 24 19:06:55 2024 +0200 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Fri Sep 27 18:09:57 2024 +0200 tdf#162268 sw: ApplyParagraphMarkFormatToEmptyLineAtEndOfParagraph Commit 2b47fae7e3e23ee7c733708500cb0482ad7f8af1 introduced the compatibility setting ApplyTextAttrToEmptyLineAtEndOfParagraph, but that was probably a mistake. What Word is doing there is not applying a text attribute but applying the formatting of the paragraph marker; add a new compatibility setting ApplyParagraphMarkFormatToEmptyLineAtEndOfParagraph to do this. Change SwAttrIter to apply the RES_PARATR_LIST_AUTOFMT formatting when the position behind the last character is reached, and use it to set the height of the last line in SwLineLayout::CalcLine() in case it is empty or contains only spaces/tabs. Frustratingly this requires another change to fdo74110.docx to get rid of some odd font that's applied to the paragraph marker. Also, change SwTextFrame::IsHiddenNow() to take into account paragraph marker formatting; if all characters are hidden but the paragraph marker isn't hidden, the paragraph is still displayed in Word. Change-Id: Icccd3e822ad0301ccbe373b50431c3254f691d6e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173880 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/sw/inc/IDocumentSettingAccess.hxx b/sw/inc/IDocumentSettingAccess.hxx index 53fb5bed5e8f..c386259a2952 100644 --- a/sw/inc/IDocumentSettingAccess.hxx +++ b/sw/inc/IDocumentSettingAccess.hxx @@ -99,6 +99,7 @@ enum class DocumentSettingId // tdf#119908 new paragraph justification JUSTIFY_LINES_WITH_SHRINKING, APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH, + APPLY_PARAGRAPH_MARK_FORMAT_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH, DO_NOT_MIRROR_RTL_DRAW_OBJS, // COMPATIBILITY FLAGS END BROWSE_MODE, diff --git a/sw/qa/extras/layout/data/A020-min.rtf b/sw/qa/extras/layout/data/A020-min.rtf new file mode 100644 index 000000000000..23a1be8eb242 --- /dev/null +++ b/sw/qa/extras/layout/data/A020-min.rtf @@ -0,0 +1,30 @@ +{ tf1deflang1025nsinsicpg1252\uc1deff1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang3079\deflangfe3079 hemelang3079 hemelangfe0 hemelangcs0 +{onttbl{0bidi romancharset0prq2{\*\panose 02020603050405020304}Times New Roman{\*alt Times New Roman};} +{1bidi swisscharset0prq2{\*\panose 020b0604020202020204}Arial{\*alt Arial};} +} +{\*\defchp s22 } +{\*\defpap \ql \li0 i0\sa160\sl259\slmult1\widctlpar\wrapdefaultspalphaspnum aautodjustright in0\lin0\itap0 } + oqfpromote +{\stylesheet{\ql \li0 i0\widctlpar\wrapdefaultaautodjustright in0\lin0\itap0 tlchcs1 f1fs22lang1025 +\ltrchcs0 1s22\lang1031\langfe3079+{\*+{\s34\ql \li0 i0\widctlpar + qc x4536 qr x9072\wrapdefaultaautodjustright in0\lin0\itap0 tlchcs1 f1fs22lang1025 \ltrchcs0 1 s22\lang1031\langfe3079+dditive tlchcs1 f1 \ltrchcs0 1\lang1031\langfe0\langnp1031\langfenp0 \sbasedon10 \slink34 \slocked Kopfzeile Zchn;} +} + +\paperw11907\paperh16840\margl1418\margr1418\margt851\margb851\gutter0\ltrsect +\deftab708\widowctrltnbjenddoc\hyphhotz425 rackmoves0 rackformatting1\donotembedsysfont0 elyonvml0\donotembedlingdata1\grfdocevents0 alidatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0 +\showxmlerrors0 oextrasprl\prcolbl+\jcompressiewkind1iewscale100\pgbrdrhead\pgbrdrfoot olnhtadjtblet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0 + +\ltrpar \sectd \ltrsect\sbknone\linex0\headery709ootery709+ qc x4536 qr x9072\wrapdefaultaautodjustright in0\lin0\itap0 tlchcs1 f1fs22lang1025 \ltrchcs0 1s22\lang1031\langfe3079+\line \line +\par \line \line \line \line }{ tlchcs1 f1 \ltrchcs0 +\par }} + +\pard\plain \ltrpar\ql \li0 i0\widctlpar\wrapdefaultaautodjustright in0\lin0\itap0 tlchcs1 f1fs22lang1025 +\ltrchcs0 1s22\lang1031\langfe3079+\par +} diff --git a/sw/qa/extras/layout/layout2.cxx b/sw/qa/extras/layout/layout2.cxx index 50f2cba4d986..7e54b860b1b9 100644 --- a/sw/qa/extras/layout/layout2.cxx +++ b/sw/qa/extras/layout/layout2.cxx @@ -13,8 +13,10 @@ #include <com/sun/star/text/XTextTable.hpp> #include <com/sun/star/linguistic2/XHyphenator.hpp> #include <com/sun/star/view/XSelectionSupplier.hpp> +#include <com/sun/star/view/XViewSettingsSupplier.hpp> #include <com/sun/star/linguistic2/XSpellChecker1.hpp> +#include <comphelper/propertysequence.hxx> #include <comphelper/scopeguard.hxx> #include <comphelper/sequence.hxx> #include <unotools/syslocaleoptions.hxx> @@ -2203,6 +2205,53 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf137819) CPPUNIT_ASSERT(sTextRightSidePosition.toInt32() < sShapeRightSidePosition.toInt32()); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testParagraphMarkLineHeight) +{ + createSwDoc("A020-min.rtf"); + + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + uno::Reference<view::XViewSettingsSupplier> xViewSettingsSupplier( + xModel->getCurrentController(), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xViewSettings(xViewSettingsSupplier->getViewSettings()); + uno::Any aOldHidden{ xViewSettings->getPropertyValue(u"ShowHiddenCharacters"_ustr) }; + uno::Any aOldNon{ xViewSettings->getPropertyValue(u"ShowNonprintingCharacters"_ustr) }; + comphelper::ScopeGuard g([&] { + xViewSettings->setPropertyValue(u"ShowHiddenCharacters"_ustr, aOldHidden); + xViewSettings->setPropertyValue(u"ShowNonprintingCharacters"_ustr, aOldNon); + }); + + xViewSettings->setPropertyValue(u"ShowHiddenCharacters"_ustr, uno::Any(true)); + xViewSettings->setPropertyValue(u"ShowNonprintingCharacters"_ustr, uno::Any(true)); + + { + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page/header/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr, + "height"_ostr, "184"); + assertXPath(pXmlDoc, "/root/page/header/txt[1]/SwParaPortion/SwLineLayout[2]"_ostr, + "height"_ostr, "184"); + assertXPath(pXmlDoc, "/root/page/header/txt[1]/SwParaPortion/SwLineLayout[3]"_ostr, + "height"_ostr, "184"); + assertXPath(pXmlDoc, "/root/page/header/txt[2]/SwParaPortion/SwLineLayout[1]"_ostr, + "height"_ostr, "184"); + assertXPath(pXmlDoc, "/root/page/header/txt[2]/SwParaPortion/SwLineLayout[2]"_ostr, + "height"_ostr, "184"); + assertXPath(pXmlDoc, "/root/page/header/txt[2]/SwParaPortion/SwLineLayout[3]"_ostr, + "height"_ostr, "184"); + assertXPath(pXmlDoc, "/root/page/header/txt[2]/SwParaPortion/SwLineLayout[4]"_ostr, + "height"_ostr, "184"); + assertXPath(pXmlDoc, "/root/page/header/txt[2]/SwParaPortion/SwLineLayout[5]"_ostr, + "height"_ostr, "253"); + } + + xViewSettings->setPropertyValue(u"ShowNonprintingCharacters"_ustr, uno::Any(false)); + + { + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "/root/page/header/txt[1]/SwParaPortion/SwLineLayout[1]"_ostr, + "height"_ostr, "184"); // FIXME should be 253, but better than 0 + } +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf122014) { createSwDoc("tdf122014.docx"); diff --git a/sw/qa/extras/ooxmlexport/data/fdo74110.docx b/sw/qa/extras/ooxmlexport/data/fdo74110.docx index cda0772c5738..0a3d515e9846 100644 Binary files a/sw/qa/extras/ooxmlexport/data/fdo74110.docx and b/sw/qa/extras/ooxmlexport/data/fdo74110.docx differ diff --git a/sw/source/core/doc/DocumentSettingManager.cxx b/sw/source/core/doc/DocumentSettingManager.cxx index 8015878f2357..26a75dc45628 100644 --- a/sw/source/core/doc/DocumentSettingManager.cxx +++ b/sw/source/core/doc/DocumentSettingManager.cxx @@ -259,6 +259,8 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const case DocumentSettingId::HYPHENATE_URLS: return mbHyphenateURLs; case DocumentSettingId::APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH: return mbApplyTextAttrToEmptyLineAtEndOfParagraph; + case DocumentSettingId::APPLY_PARAGRAPH_MARK_FORMAT_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH: + return mbApplyParagraphMarkFormatToEmptyLineAtEndOfParagraph; case DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES: return mbDoNotBreakWrappedTables; case DocumentSettingId::ALLOW_TEXT_AFTER_FLOATING_TABLE_BREAK: @@ -463,6 +465,11 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo mbApplyTextAttrToEmptyLineAtEndOfParagraph = value; break; + case DocumentSettingId::APPLY_PARAGRAPH_MARK_FORMAT_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH: + mbApplyParagraphMarkFormatToEmptyLineAtEndOfParagraph = value; + break; + + case DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS: mbDoNotMirrorRtlDrawObjs = value; break; @@ -1144,6 +1151,11 @@ void sw::DocumentSettingManager::dumpAsXml(xmlTextWriterPtr pWriter) const BAD_CAST(OString::boolean(mbApplyTextAttrToEmptyLineAtEndOfParagraph).getStr())); (void)xmlTextWriterEndElement(pWriter); + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbApplyParagraphMarkFormatToEmptyLineAtEndOfParagraph")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), + BAD_CAST(OString::boolean(mbApplyParagraphMarkFormatToEmptyLineAtEndOfParagraph).getStr())); + (void)xmlTextWriterEndElement(pWriter); + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbDoNotMirrorRtlDrawObjs")); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::boolean(mbDoNotMirrorRtlDrawObjs).getStr())); diff --git a/sw/source/core/inc/DocumentSettingManager.hxx b/sw/source/core/inc/DocumentSettingManager.hxx index f9e1faf9aacd..9125496cdc17 100644 --- a/sw/source/core/inc/DocumentSettingManager.hxx +++ b/sw/source/core/inc/DocumentSettingManager.hxx @@ -178,7 +178,8 @@ class DocumentSettingManager final : bool mbDoNotBreakWrappedTables = false; bool mbAllowTextAfterFloatingTableBreak = false; bool mbJustifyLinesWithShrinking = false; - bool mbApplyTextAttrToEmptyLineAtEndOfParagraph = true; + bool mbApplyTextAttrToEmptyLineAtEndOfParagraph = false; // this was a mistake + bool mbApplyParagraphMarkFormatToEmptyLineAtEndOfParagraph = false; bool mbDoNotMirrorRtlDrawObjs = false; // If this is on as_char flys wrapping will be handled the same like in Word bool mbNoNumberingShowFollowBy; diff --git a/sw/source/core/text/atrstck.cxx b/sw/source/core/text/atrstck.cxx index 85689a2c82a8..7d2b6afddc7f 100644 --- a/sw/source/core/text/atrstck.cxx +++ b/sw/source/core/text/atrstck.cxx @@ -341,15 +341,19 @@ void SwAttrHandler::PushAndChg( const SwTextAttr& rAttr, SwFont& rFnt ) // they have to be pushed to each stack they belong to if ( RES_TXTATR_INETFMT == rAttr.Which() || RES_TXTATR_CHARFMT == rAttr.Which() || + RES_PARATR_LIST_AUTOFMT == rAttr.Which() || RES_TXTATR_AUTOFMT == rAttr.Which() ) { - const SfxItemSet* pSet = CharFormat::GetItemSet( rAttr.GetAttr() ); + const SfxItemSet* pSet = rAttr.Which() == RES_PARATR_LIST_AUTOFMT + ? rAttr.GetAttr().StaticWhichCast(RES_PARATR_LIST_AUTOFMT).GetStyleHandle().get() + : CharFormat::GetItemSet( rAttr.GetAttr() ); if ( !pSet ) return; + bool const inParent{rAttr.Which() != RES_TXTATR_AUTOFMT && rAttr.Which() != RES_PARATR_LIST_AUTOFMT}; for ( sal_uInt16 i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++) { const SfxPoolItem* pItem; - bool bRet = SfxItemState::SET == pSet->GetItemState( i, rAttr.Which() != RES_TXTATR_AUTOFMT, &pItem ); + bool bRet = SfxItemState::SET == pSet->GetItemState(i, inParent, &pItem); if ( bRet ) { diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx index b002e80610aa..ae38bda0bab3 100644 --- a/sw/source/core/text/itratr.cxx +++ b/sw/source/core/text/itratr.cxx @@ -38,6 +38,7 @@ #include <fmtfld.hxx> #include <doc.hxx> #include <IDocumentLayoutAccess.hxx> +#include <IDocumentSettingAccess.hxx> #include <txatbase.hxx> #include <viewsh.hxx> #include <rootfrm.hxx> @@ -301,7 +302,33 @@ void SwAttrIter::SeekFwd(const sal_Int32 nOldPos, const sal_Int32 nNewPos) if ( pTextAttr->GetAnyEnd() > nNewPos ) Chg( pTextAttr ); m_nStartIndex++; } +} +void SwAttrIter::SeekToEnd() +{ + if (m_pTextNode->GetDoc().getIDocumentSettingAccess().get( + DocumentSettingId::APPLY_PARAGRAPH_MARK_FORMAT_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH)) + { + SfxItemPool & rPool{const_cast<SwAttrPool&>(m_pTextNode->GetDoc().GetAttrPool())}; + SwFormatAutoFormat const& rListAutoFormat{m_pTextNode->GetAttr(RES_PARATR_LIST_AUTOFMT)}; + std::shared_ptr<SfxItemSet> const pSet{rListAutoFormat.GetStyleHandle()}; + if (!pSet) + { + return; + } + if (pSet->HasItem(RES_TXTATR_CHARFMT)) + { + SwFormatCharFormat const& rCharFormat{pSet->Get(RES_TXTATR_CHARFMT)}; + m_pEndCharFormatAttr.reset(new SwTextAttrEnd{ + SfxPoolItemHolder{rPool, &rCharFormat}, -1, -1}); + Chg(m_pEndCharFormatAttr.get()); + } + // note: RES_TXTATR_CHARFMT should be cleared here but it looks like + // SwAttrHandler only looks at RES_CHRATR_* anyway + m_pEndAutoFormatAttr.reset(new SwTextAttrEnd{ + SfxPoolItemHolder{rPool, &rListAutoFormat}, -1, -1}); + Chg(m_pEndAutoFormatAttr.get()); + } } bool SwAttrIter::Seek(TextFrameIndex const nNewPos) @@ -368,7 +395,8 @@ bool SwAttrIter::Seek(TextFrameIndex const nNewPos) m_pMergedPara->mergedText, nullptr, nullptr); } } - if (m_pMergedPara || m_pTextNode->GetpSwpHints()) + // also reset it if the RES_PARATR_LIST_AUTOFMT has been applied! + if (m_pMergedPara || m_pTextNode->GetpSwpHints() || m_pEndAutoFormatAttr) { if( m_pRedline ) m_pRedline->Clear( nullptr ); @@ -376,6 +404,8 @@ bool SwAttrIter::Seek(TextFrameIndex const nNewPos) // reset font to its original state m_aAttrHandler.Reset(); m_aAttrHandler.ResetFont( *m_pFont ); + m_pEndCharFormatAttr.reset(); + m_pEndAutoFormatAttr.reset(); if( m_nPropFont ) m_pFont->SetProportion( m_nPropFont ); @@ -395,6 +425,24 @@ bool SwAttrIter::Seek(TextFrameIndex const nNewPos) } } + bool isToEnd{false}; + if (m_pMergedPara) + { + if (!m_pMergedPara->extents.empty()) + { + auto const& rLast{m_pMergedPara->extents.back()}; + isToEnd = rLast.pNode == newPos.first && rLast.nEnd == newPos.second; + } + else + { + isToEnd = true; + } + } + else + { + isToEnd = newPos.second == m_pTextNode->Len(); + } + if (m_pTextNode->GetpSwpHints()) { if (m_pMergedPara) @@ -424,6 +472,11 @@ bool SwAttrIter::Seek(TextFrameIndex const nNewPos) } } + if (isToEnd && !m_pEndAutoFormatAttr) + { + SeekToEnd(); + } + m_pFont->SetActual( m_pScriptInfo->WhichFont(nNewPos) ); if( m_pRedline ) diff --git a/sw/source/core/text/itratr.hxx b/sw/source/core/text/itratr.hxx index 4ad2c6d04c5f..91b3d4f9200c 100644 --- a/sw/source/core/text/itratr.hxx +++ b/sw/source/core/text/itratr.hxx @@ -21,6 +21,7 @@ #include <o3tl/deleter.hxx> #include "atrhndl.hxx" #include <swfont.hxx> +#include <txatbase.hxx> namespace sw { struct MergedPara; } class SwTextAttr; @@ -33,6 +34,9 @@ class SAL_DLLPUBLIC_RTTI SwAttrIter { friend class SwFontSave; protected: + struct Destr{ void operator()(SwTextAttr *const pAttr) { SwTextAttr::Destroy(pAttr); } }; + ::std::unique_ptr<SwTextAttr, Destr> m_pEndCharFormatAttr; + ::std::unique_ptr<SwTextAttr, Destr> m_pEndAutoFormatAttr; SwAttrHandler m_aAttrHandler; SwViewShell *m_pViewShell; @@ -58,6 +62,7 @@ private: sw::MergedPara const* m_pMergedPara; void SeekFwd(sal_Int32 nOldPos, sal_Int32 nNewPos); + void SeekToEnd(); void SetFnt( SwFont* pNew ) { m_pFont = pNew; } void InitFontAndAttrHandler( SwTextNode const& rPropsNode, SwTextNode const& rTextNode, diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx index 37cb23961cff..f1b36ee1557b 100644 --- a/sw/source/core/text/porlay.cxx +++ b/sw/source/core/text/porlay.cxx @@ -569,9 +569,26 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, SwTextFormatInfo &rInf ) { bHasBlankPortion = true; } + else + { + bHasOnlyBlankPortions = false; + bHasNonBlankPortions = true; + } } - if (bIgnoreBlanksAndTabsForLineHeightCalculation && !bHasNonBlankPortions && + if (!rInf.IsNewLine() + && TextFrameIndex(rInf.GetText().getLength()) <= rInf.GetIdx() + && !bHasNonBlankPortions + && rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess().get( + DocumentSettingId::APPLY_PARAGRAPH_MARK_FORMAT_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH)) + { + // Word: for empty last line, line height is based on paragraph marker + // formatting, ignoring blanks/tabs + rLine.SeekAndChg(rInf); + SetAscent(rInf.GetAscent()); + Height(rInf.GetTextHeight()); + } + else if (bIgnoreBlanksAndTabsForLineHeightCalculation && !bHasNonBlankPortions && (bHasTabPortions || (bHasBlankPortion && (nSpacePortionAscent > 0 || nSpacePortionHeight > 0)))) { //Word increases line height if _only_ spaces and|or tabstops are in a line diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index fbd3a3891fbb..ad813eddfc57 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -25,6 +25,7 @@ #include <editeng/lspcitem.hxx> #include <editeng/lrspitem.hxx> #include <editeng/brushitem.hxx> +#include <editeng/charhiddenitem.hxx> #include <editeng/pgrditem.hxx> #include <comphelper/configuration.hxx> #include <swmodule.hxx> @@ -1540,6 +1541,22 @@ bool SwTextFrame::IsHiddenNow() const bHiddenCharsHidePara = static_cast<SwTextNode const*>(SwFrame::GetDep())->HasHiddenCharAttribute( true ); bHiddenParaField = static_cast<SwTextNode const*>(SwFrame::GetDep())->IsHiddenByParaField(); } + if (bHiddenCharsHidePara && GetDoc().getIDocumentSettingAccess().get( + DocumentSettingId::APPLY_PARAGRAPH_MARK_FORMAT_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH)) + { + // apparently in Word it's always the last para marker that determines hidden? + // even in case when they are merged by delete redline (it's obvious when they are merged by hidden-attribute + SwTextNode const*const pNode{ m_pMergedPara + ? m_pMergedPara->pLastNode + : static_cast<SwTextNode const*>(SwFrame::GetDep()) }; + SwFormatAutoFormat const& rListAutoFormat{pNode->GetAttr(RES_PARATR_LIST_AUTOFMT)}; + std::shared_ptr<SfxItemSet> const pSet{rListAutoFormat.GetStyleHandle()}; + SvxCharHiddenItem const*const pItem{pSet ? pSet->GetItemIfSet(RES_CHRATR_HIDDEN) : nullptr}; + if (!pItem || !pItem->GetValue()) + { + bHiddenCharsHidePara = false; + } + } const SwViewShell* pVsh = getRootFrame()->GetCurrShell(); if ( pVsh && ( bHiddenCharsHidePara || bHiddenParaField ) ) diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index a59c7042968a..6c4b50f2b226 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -1958,7 +1958,7 @@ void SwWW8ImplReader::ImportDop() m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::PROP_LINE_SPACING_SHRINKS_FIRST_LINE, true); m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::CONTINUOUS_ENDNOTES, true); // rely on default for HYPHENATE_URLS=false - // rely on default for APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH=true + m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::APPLY_PARAGRAPH_MARK_FORMAT_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH, true); IDocumentSettingAccess& rIDSA = m_rDoc.getIDocumentSettingAccess(); if (m_xWDop->fDontBreakWrappedTables) diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx index a26a9fc4b863..5132e3a0cac4 100644 --- a/sw/source/filter/xml/xmlimp.cxx +++ b/sw/source/filter/xml/xmlimp.cxx @@ -1312,7 +1312,6 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC bool bCollapseEmptyCellPara = false; bool bAutoFirstLineIndentDisregardLineSpace = false; bool bHyphenateURLs = false; - bool bApplyTextAttrToEmptyLineAtEndOfParagraph = false; bool bDoNotBreakWrappedTables = false; bool bAllowTextAfterFloatingTableBreak = false; bool bDropCapPunctuation = false; @@ -1414,10 +1413,6 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC { bHyphenateURLs = true; } - else if (rValue.Name == "ApplyTextAttrToEmptyLineAtEndOfParagraph") - { - bApplyTextAttrToEmptyLineAtEndOfParagraph = true; - } else if (rValue.Name == "DoNotBreakWrappedTables") { rValue.Value >>= bDoNotBreakWrappedTables; @@ -1599,11 +1594,6 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC xProps->setPropertyValue(u"HyphenateURLs"_ustr, Any(true)); } - if (!bApplyTextAttrToEmptyLineAtEndOfParagraph) - { - xProps->setPropertyValue(u"ApplyTextAttrToEmptyLineAtEndOfParagraph"_ustr, Any(false)); - } - if (bDoNotMirrorRtlDrawObjs) { xProps->setPropertyValue(u"DoNotMirrorRtlDrawObjs"_ustr, Any(true)); diff --git a/sw/source/uibase/uno/SwXDocumentSettings.cxx b/sw/source/uibase/uno/SwXDocumentSettings.cxx index 6baeff0a965a..5c43390f53ef 100644 --- a/sw/source/uibase/uno/SwXDocumentSettings.cxx +++ b/sw/source/uibase/uno/SwXDocumentSettings.cxx @@ -160,6 +160,7 @@ enum SwDocumentSettingsPropertyHandles HANDLE_DROP_CAP_PUNCTUATION, HANDLE_USE_VARIABLE_WIDTH_NBSP, HANDLE_APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH, + HANDLE_APPLY_PARAGRAPH_MARK_FORMAT_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH, HANDLE_DO_NOT_MIRROR_RTL_DRAW_OBJS, HANDLE_PAINT_HELL_OVER_HEADER_FOOTER, HANDLE_MIN_ROW_HEIGHT_INCL_BORDER, @@ -270,6 +271,7 @@ static rtl::Reference<MasterPropertySetInfo> lcl_createSettingsInfo() { u"DropCapPunctuation"_ustr, HANDLE_DROP_CAP_PUNCTUATION, cppu::UnoType<bool>::get(), 0 }, { u"UseVariableWidthNBSP"_ustr, HANDLE_USE_VARIABLE_WIDTH_NBSP, cppu::UnoType<bool>::get(), 0 }, { u"ApplyTextAttrToEmptyLineAtEndOfParagraph"_ustr, HANDLE_APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH, cppu::UnoType<bool>::get(), 0 }, + { u"ApplyParagraphMarkFormatToEmptyLineAtEndOfParagraph"_ustr, HANDLE_APPLY_PARAGRAPH_MARK_FORMAT_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH, cppu::UnoType<bool>::get(), 0 }, { u"DoNotMirrorRtlDrawObjs"_ustr, HANDLE_DO_NOT_MIRROR_RTL_DRAW_OBJS, cppu::UnoType<bool>::get(), 0 }, { u"PaintHellOverHeaderFooter"_ustr, HANDLE_PAINT_HELL_OVER_HEADER_FOOTER, cppu::UnoType<bool>::get(), 0 }, { u"MinRowHeightInclBorder"_ustr, HANDLE_MIN_ROW_HEIGHT_INCL_BORDER, cppu::UnoType<bool>::get(), 0 }, @@ -1094,6 +1096,16 @@ void SwXDocumentSettings::_setSingleValue( const comphelper::PropertyInfo & rInf } } break; + case HANDLE_APPLY_PARAGRAPH_MARK_FORMAT_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH: + { + bool bTmp; + if (rValue >>= bTmp) + { + mpDoc->getIDocumentSettingAccess().set( + DocumentSettingId::APPLY_PARAGRAPH_MARK_FORMAT_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH, bTmp); + } + } + break; case HANDLE_DO_NOT_MIRROR_RTL_DRAW_OBJS: { bool bTmp; @@ -1718,6 +1730,12 @@ void SwXDocumentSettings::_getSingleValue( const comphelper::PropertyInfo & rInf DocumentSettingId::APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH); } break; + case HANDLE_APPLY_PARAGRAPH_MARK_FORMAT_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH: + { + rValue <<= mpDoc->getIDocumentSettingAccess().get( + DocumentSettingId::APPLY_PARAGRAPH_MARK_FORMAT_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH); + } + break; case HANDLE_DO_NOT_MIRROR_RTL_DRAW_OBJS: { rValue <<= mpDoc->getIDocumentSettingAccess().get( diff --git a/sw/source/writerfilter/dmapper/SettingsTable.cxx b/sw/source/writerfilter/dmapper/SettingsTable.cxx index b49a6e013ace..c06c5bd395f7 100644 --- a/sw/source/writerfilter/dmapper/SettingsTable.cxx +++ b/sw/source/writerfilter/dmapper/SettingsTable.cxx @@ -643,6 +643,8 @@ void SettingsTable::ApplyProperties(rtl::Reference<SwXTextDocument> const& xDoc) // Shared between DOCX and RTF, unconditional flags. xDocumentSettings->setPropertyValue(u"TableRowKeep"_ustr, uno::Any(true)); xDocumentSettings->setPropertyValue(u"AddVerticalFrameOffsets"_ustr, uno::Any(true)); + xDocumentSettings->setPropertyValue(u"ApplyParagraphMarkFormatToEmptyLineAtEndOfParagraph"_ustr, + uno::Any(true)); if (GetWordCompatibilityMode() <= 14) { diff --git a/sw/source/writerfilter/filter/WriterFilter.cxx b/sw/source/writerfilter/filter/WriterFilter.cxx index 201e2e1a4ee4..f5a90061c267 100644 --- a/sw/source/writerfilter/filter/WriterFilter.cxx +++ b/sw/source/writerfilter/filter/WriterFilter.cxx @@ -336,7 +336,6 @@ void WriterFilter::setTargetDocument(const uno::Reference<lang::XComponent>& xDo xSettings->setPropertyValue(u"PaintHellOverHeaderFooter"_ustr, uno::Any(true)); // rely on default for HyphenateURLs=false - // rely on default for APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH=true xSettings->setPropertyValue(u"DoNotMirrorRtlDrawObjs"_ustr, uno::Any(true)); xSettings->setPropertyValue(u"ContinuousEndnotes"_ustr, uno::Any(true)); }