tdf#88214 sw: text formatting: adapt empty line at end of para to Word
For an empty line at the end of an empty paragraph, Writer already uses any existing text attribute in the paragraph, see for example testEmptyTrailingSpans. For an empty line at the end of a non-empty paragraph, Writer text formatting uses only paragraph attributes, ignoring any text attributes, whereas the UI will display the attributes from the text attributes (such as font height) if you move the cursor there. Word uses text attributes also in this case, so adapt the inconsistent Writer behaviour: text formatting now uses text attributes too. Apparently this can be achieved by calling SeekAndChgBefore() instead of SeekAndChg(). Add another compat flag "ApplyTextAttrToEmptyLineAtEndOfParagraph" to preserve the formatting of existing ODF documents. Adapt test document fdo74110.docx, it has a line break with "Angsana New" font. Change-Id: I0863d3077e419404194b47110e4ad2bdda3d11c4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165887 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
This commit is contained in:
parent
b523a72fd0
commit
2b47fae7e3
@ -98,6 +98,7 @@ enum class DocumentSettingId
|
||||
ALLOW_TEXT_AFTER_FLOATING_TABLE_BREAK,
|
||||
// tdf#119908 new paragraph justification
|
||||
JUSTIFY_LINES_WITH_SHRINKING,
|
||||
APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH,
|
||||
// COMPATIBILITY FLAGS END
|
||||
BROWSE_MODE,
|
||||
HTML_MODE,
|
||||
|
27
sw/qa/core/text/data/A011-charheight.rtf
Normal file
27
sw/qa/core/text/data/A011-charheight.rtf
Normal file
@ -0,0 +1,27 @@
|
||||
{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch0\stshfloch31506\stshfhich31506\stshfbi31506\deflang3079\deflangfe3079\themelang3079\themelangfe0\themelangcs0
|
||||
{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2Times New Roman{\*\falt Arial};}
|
||||
}
|
||||
{\*\defchp \f0\fs22\lang3079\langfe1033\langfenp1033 }
|
||||
{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1
|
||||
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }
|
||||
\noqfpromote
|
||||
{\stylesheet
|
||||
{\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0
|
||||
\f0\fs23\lang3079\langfe1033\cgrid\langnp3079\langfenp1033 \snext0 \sqformat \spriority0 Normal;}
|
||||
{\s15\ql \li0\ri0\widctlpar\tqc\tx4536\tqr\tx9072\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \f0\fs23\lang3079\langfe1033\cgrid\langnp3079\langfenp1033
|
||||
\sbasedon0 \snext15 \slink16 \sunhideused header;}
|
||||
{\*\cs16 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \slink15 \slocked Kopfzeile Zchn;}
|
||||
}
|
||||
\paperw11906\paperh16838\margl1417\margr1417\margt1417\margb1134\gutter0\ltrsect
|
||||
\deftab708\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0
|
||||
\showxmlerrors1\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1417\dgvorigin1417\dghshow1\dgvshow1
|
||||
\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct
|
||||
\asianbrkrule\newtblstyruls\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0
|
||||
{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0
|
||||
|
||||
\ltrpar \pard\plain \ltrpar\s15\qc \li0\ri0\widctlpar
|
||||
\tqc\tx4536\tqr\tx9072\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \f0\fs23\lang3079\langfe1033\cgrid\langnp3079\langfenp1033 {\rtlch\fcs1 \af0\afs16 \ltrch\fcs0
|
||||
\fs16 \line \line \line
|
||||
\par \line
|
||||
\par }
|
||||
}
|
@ -88,6 +88,24 @@ CPPUNIT_TEST_FIXTURE(Test, testFloattableLegacyWrapEmptyParagraph)
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPageObjs2.size());
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Test, testApplyTextAttrToEmptyLineAtEndOfParagraph)
|
||||
{
|
||||
createSwDoc("A011-charheight.rtf");
|
||||
|
||||
calcLayout();
|
||||
|
||||
SwDoc* pDoc = getSwDoc();
|
||||
SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
|
||||
auto pPage = dynamic_cast<SwPageFrame*>(pLayout->Lower());
|
||||
|
||||
SwContentFrame* pLastPara = pPage->FindLastBodyContent();
|
||||
// wrong was 449 (11.5pt)
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<SwTwips>(368), pLastPara->getFrameArea().Height());
|
||||
SwContentFrame* pFirstPara = pPage->FindFirstBodyContent();
|
||||
// wrong was 817 (11.5pt)
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<SwTwips>(736), pFirstPara->getFrameArea().Height());
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Test, testFlyMinimalWrap)
|
||||
{
|
||||
// Given a document with a first page that has a shape and a table in it (not floating table),
|
||||
|
Binary file not shown.
@ -249,6 +249,8 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const
|
||||
case DocumentSettingId::AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE:
|
||||
return mbAutoFirstLineIndentDisregardLineSpace;
|
||||
case DocumentSettingId::HYPHENATE_URLS: return mbHyphenateURLs;
|
||||
case DocumentSettingId::APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH:
|
||||
return mbApplyTextAttrToEmptyLineAtEndOfParagraph;
|
||||
case DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES:
|
||||
return mbDoNotBreakWrappedTables;
|
||||
case DocumentSettingId::ALLOW_TEXT_AFTER_FLOATING_TABLE_BREAK:
|
||||
@ -443,6 +445,10 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo
|
||||
mbHyphenateURLs = value;
|
||||
break;
|
||||
|
||||
case DocumentSettingId::APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH:
|
||||
mbApplyTextAttrToEmptyLineAtEndOfParagraph = value;
|
||||
break;
|
||||
|
||||
case DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES:
|
||||
mbDoNotBreakWrappedTables = value;
|
||||
break;
|
||||
@ -1091,6 +1097,11 @@ void sw::DocumentSettingManager::dumpAsXml(xmlTextWriterPtr pWriter) const
|
||||
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
|
||||
BAD_CAST(OString::number(mnImagePreferredDPI).getStr()));
|
||||
|
||||
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbApplyTextAttrToEmptyLineAtEndOfParagraph"));
|
||||
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
|
||||
BAD_CAST(OString::boolean(mbApplyTextAttrToEmptyLineAtEndOfParagraph).getStr()));
|
||||
(void)xmlTextWriterEndElement(pWriter);
|
||||
|
||||
(void)xmlTextWriterEndElement(pWriter);
|
||||
|
||||
(void)xmlTextWriterEndElement(pWriter);
|
||||
|
@ -178,6 +178,7 @@ class DocumentSettingManager final :
|
||||
bool mbDoNotBreakWrappedTables = false;
|
||||
bool mbAllowTextAfterFloatingTableBreak = false;
|
||||
bool mbJustifyLinesWithShrinking = false;
|
||||
bool mbApplyTextAttrToEmptyLineAtEndOfParagraph = true;
|
||||
// If this is on as_char flys wrapping will be handled the same like in Word
|
||||
bool mbNoNumberingShowFollowBy;
|
||||
bool mbDropCapPunctuation; // tdf#150200, tdf#150438
|
||||
|
@ -852,6 +852,7 @@ void SwTextFormatter::CalcAscent( SwTextFormatInfo &rInf, SwLinePortion *pPor )
|
||||
|
||||
// In empty lines the attributes are switched on via SeekStart
|
||||
const bool bFirstPor = rInf.GetLineStart() == rInf.GetIdx();
|
||||
|
||||
if ( pPor->IsQuoVadisPortion() )
|
||||
bChg = SeekStartAndChg( rInf, true );
|
||||
else
|
||||
@ -860,10 +861,16 @@ void SwTextFormatter::CalcAscent( SwTextFormatInfo &rInf, SwLinePortion *pPor )
|
||||
{
|
||||
if( !rInf.GetText().isEmpty() )
|
||||
{
|
||||
if ( pPor->GetLen() || !rInf.GetIdx()
|
||||
|| ( m_pCurr != pLast && !pLast->IsFlyPortion() )
|
||||
|| !m_pCurr->IsRest() ) // instead of !rInf.GetRest()
|
||||
if ((rInf.GetIdx() != TextFrameIndex(rInf.GetText().getLength())
|
||||
|| rInf.GetRest() // field continued - not empty
|
||||
|| !GetTextFrame()->GetDoc().getIDocumentSettingAccess().get(
|
||||
DocumentSettingId::APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH))
|
||||
&& (pPor->GetLen() || !rInf.GetIdx()
|
||||
|| (m_pCurr != pLast && !pLast->IsFlyPortion())
|
||||
|| !m_pCurr->IsRest())) // instead of !rInf.GetRest()
|
||||
{
|
||||
bChg = SeekAndChg( rInf );
|
||||
}
|
||||
else
|
||||
bChg = SeekAndChgBefore( rInf );
|
||||
}
|
||||
|
@ -1945,6 +1945,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
|
||||
|
||||
IDocumentSettingAccess& rIDSA = m_rDoc.getIDocumentSettingAccess();
|
||||
if (m_xWDop->fDontBreakWrappedTables)
|
||||
|
@ -1298,6 +1298,7 @@ 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;
|
||||
@ -1398,6 +1399,10 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC
|
||||
{
|
||||
bHyphenateURLs = true;
|
||||
}
|
||||
else if (rValue.Name == "ApplyTextAttrToEmptyLineAtEndOfParagraph")
|
||||
{
|
||||
bApplyTextAttrToEmptyLineAtEndOfParagraph = true;
|
||||
}
|
||||
else if (rValue.Name == "DoNotBreakWrappedTables")
|
||||
{
|
||||
rValue.Value >>= bDoNotBreakWrappedTables;
|
||||
@ -1575,6 +1580,11 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC
|
||||
xProps->setPropertyValue("HyphenateURLs", Any(true));
|
||||
}
|
||||
|
||||
if (!bApplyTextAttrToEmptyLineAtEndOfParagraph)
|
||||
{
|
||||
xProps->setPropertyValue("ApplyTextAttrToEmptyLineAtEndOfParagraph", Any(false));
|
||||
}
|
||||
|
||||
if (bDoNotBreakWrappedTables)
|
||||
{
|
||||
xProps->setPropertyValue("DoNotBreakWrappedTables", Any(true));
|
||||
|
@ -159,6 +159,7 @@ enum SwDocumentSettingsPropertyHandles
|
||||
HANDLE_NO_NUMBERING_SHOW_FOLLOWBY,
|
||||
HANDLE_DROP_CAP_PUNCTUATION,
|
||||
HANDLE_USE_VARIABLE_WIDTH_NBSP,
|
||||
HANDLE_APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH,
|
||||
};
|
||||
|
||||
}
|
||||
@ -264,6 +265,7 @@ static rtl::Reference<MasterPropertySetInfo> lcl_createSettingsInfo()
|
||||
{ OUString("NoNumberingShowFollowBy"), HANDLE_NO_NUMBERING_SHOW_FOLLOWBY, cppu::UnoType<bool>::get(), 0 },
|
||||
{ OUString("DropCapPunctuation"), HANDLE_DROP_CAP_PUNCTUATION, cppu::UnoType<bool>::get(), 0 },
|
||||
{ OUString("UseVariableWidthNBSP"), HANDLE_USE_VARIABLE_WIDTH_NBSP, cppu::UnoType<bool>::get(), 0 },
|
||||
{ OUString("ApplyTextAttrToEmptyLineAtEndOfParagraph"), HANDLE_APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH, cppu::UnoType<bool>::get(), 0 },
|
||||
|
||||
/*
|
||||
* As OS said, we don't have a view when we need to set this, so I have to
|
||||
@ -1074,6 +1076,16 @@ void SwXDocumentSettings::_setSingleValue( const comphelper::PropertyInfo & rInf
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HANDLE_APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH:
|
||||
{
|
||||
bool bTmp;
|
||||
if (rValue >>= bTmp)
|
||||
{
|
||||
mpDoc->getIDocumentSettingAccess().set(
|
||||
DocumentSettingId::APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH, bTmp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HANDLE_DO_NOT_BREAK_WRAPPED_TABLES:
|
||||
{
|
||||
bool bTmp;
|
||||
@ -1656,6 +1668,12 @@ void SwXDocumentSettings::_getSingleValue( const comphelper::PropertyInfo & rInf
|
||||
DocumentSettingId::HYPHENATE_URLS);
|
||||
}
|
||||
break;
|
||||
case HANDLE_APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH:
|
||||
{
|
||||
rValue <<= mpDoc->getIDocumentSettingAccess().get(
|
||||
DocumentSettingId::APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH);
|
||||
}
|
||||
break;
|
||||
case HANDLE_DO_NOT_BREAK_WRAPPED_TABLES:
|
||||
{
|
||||
rValue <<= mpDoc->getIDocumentSettingAccess().get(
|
||||
|
@ -330,6 +330,7 @@ void WriterFilter::setTargetDocument(const uno::Reference<lang::XComponent>& xDo
|
||||
xSettings->setPropertyValue("DisableOffPagePositioning", uno::Any(true));
|
||||
xSettings->setPropertyValue("DropCapPunctuation", uno::Any(true));
|
||||
// rely on default for HyphenateURLs=false
|
||||
// rely on default for APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH=true
|
||||
}
|
||||
|
||||
void WriterFilter::setSourceDocument(const uno::Reference<lang::XComponent>& xDoc)
|
||||
|
Loading…
x
Reference in New Issue
Block a user