From 28675af84ae8e2342bd78be3696dc09de6ce5cc5 Mon Sep 17 00:00:00 2001 From: Vojtěch Doležal Date: Sat, 25 Mar 2023 13:01:30 +0100 Subject: tdf#41652: Variable width NBSP Adds a flag that when enabled (opt-in for both old and new documents) changes behaviour of NBSP to not be strictly fixed width. This commit also implements this behaviour such that NBSP has always the width of a standard space (0x20) on the given line. This change is only noticeable when the paragraph is justified. Lastly a tilde or a degree character is now shown in place of NBSP when nonprintable characters are enabled, since the gray field alone is not visible in many circumstances. Change-Id: Iabb30b5930ced62691cc4304f60c5e6dc886ed61 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149576 Tested-by: Jenkins Reviewed-by: Miklos Vajna --- include/unotools/compatibility.hxx | 2 + .../schema/org/openoffice/Office/Compatibility.xcs | 6 + sw/inc/IDocumentSettingAccess.hxx | 4 +- sw/qa/core/text/data/tdf41652_legacy.fodt | 300 ++++++++++++++++++++ .../text/data/tdf41652_variableNBSPdisabled.fodt | 301 +++++++++++++++++++++ .../text/data/tdf41652_variableNBSPenabled.fodt | 301 +++++++++++++++++++++ sw/qa/core/text/text.cxx | 71 +++++ sw/source/core/doc/DocumentSettingManager.cxx | 17 +- sw/source/core/inc/DocumentSettingManager.hxx | 1 + sw/source/core/text/porexp.cxx | 54 +++- sw/source/core/text/portxt.cxx | 10 +- sw/source/filter/xml/xmlimp.cxx | 3 +- sw/source/ui/config/optcomp.cxx | 17 +- sw/source/uibase/uno/SwXDocumentSettings.cxx | 18 +- sw/uiconfig/swriter/ui/optcompatpage.ui | 1 + unotools/source/config/compatibility.cxx | 5 +- 16 files changed, 1096 insertions(+), 15 deletions(-) create mode 100644 sw/qa/core/text/data/tdf41652_legacy.fodt create mode 100644 sw/qa/core/text/data/tdf41652_variableNBSPdisabled.fodt create mode 100644 sw/qa/core/text/data/tdf41652_variableNBSPenabled.fodt diff --git a/include/unotools/compatibility.hxx b/include/unotools/compatibility.hxx index 72017812ab8b..ed7b0f9d52f3 100644 --- a/include/unotools/compatibility.hxx +++ b/include/unotools/compatibility.hxx @@ -60,6 +60,8 @@ class SvtCompatibilityEntry MsWordTrailingBlanks, SubtractFlysAnchoredAtFlys, EmptyDbFieldHidesPara, + UseVariableWidthNBSP, + /// special entry: optcomp.cxx converts the other values to /// integers but not this one because it doesn't have its own /// checkbox, so keep it at the end! diff --git a/officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs b/officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs index 68b369ba09fc..fc0919ae2a3a 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Compatibility.xcs @@ -128,6 +128,12 @@ true + + + Render NBSP as having variable size, instead of having a fixed size + + false + diff --git a/sw/inc/IDocumentSettingAccess.hxx b/sw/inc/IDocumentSettingAccess.hxx index b392b43e378d..c05e5d54df4b 100644 --- a/sw/inc/IDocumentSettingAccess.hxx +++ b/sw/inc/IDocumentSettingAccess.hxx @@ -126,7 +126,9 @@ enum class DocumentSettingId NO_NUMBERING_SHOW_FOLLOWBY, // drop cap punctuation: smaller dashes, bullet, asterisks, quotation marks etc. // by extending the rounding box of the glyph to the baseline - DROP_CAP_PUNCTUATION + DROP_CAP_PUNCTUATION, + // render NBSP as standard-space-width (prettier when justified) + USE_VARIABLE_WIDTH_NBSP, }; /** Provides access to settings of a document diff --git a/sw/qa/core/text/data/tdf41652_legacy.fodt b/sw/qa/core/text/data/tdf41652_legacy.fodt new file mode 100644 index 000000000000..07761f24be72 --- /dev/null +++ b/sw/qa/core/text/data/tdf41652_legacy.fodt @@ -0,0 +1,300 @@ + + + + 2023-03-31T21:00:03.6926293222023-03-31T21:03:03.389379879PT3M8S1LibreOfficeDev/7.6.0.0.alpha0$Linux_X86_64 LibreOffice_project/34216608eb7387c697a92f1d64ea5ca7d26a292f + + + 0 + 0 + 26615 + 15436 + true + false + + + view2 + 16088 + 3962 + 0 + 0 + 26614 + 15434 + 0 + 1 + false + 120 + false + false + false + false + false + false + + + + + true + false + true + false + true + false + false + true + false + 0 + false + true + false + false + false + false + true + false + false + + false + false + true + false + false + true + true + false + false + false + false + false + false + true + false + false + 204352 + false + + true + false + false + 204352 + true + false + false + false + 1 + true + true + false + false + true + false + false + true + true + true + false + true + 0 + + false + true + true + true + + 0 + true + false + false + false + high-resolution + true + true + false + false + true + false + false + false + false + true + + true + false + true + false + + false + false + false + true + false + false + false + false + false + false + false + false + false + false + 0 + true + false + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + + \ No newline at end of file diff --git a/sw/qa/core/text/data/tdf41652_variableNBSPdisabled.fodt b/sw/qa/core/text/data/tdf41652_variableNBSPdisabled.fodt new file mode 100644 index 000000000000..ced23ccf63ea --- /dev/null +++ b/sw/qa/core/text/data/tdf41652_variableNBSPdisabled.fodt @@ -0,0 +1,301 @@ + + + + 2023-03-31T21:00:03.6926293222023-03-31T21:03:03.389379879PT3M8S1LibreOfficeDev/7.6.0.0.alpha0$Linux_X86_64 LibreOffice_project/34216608eb7387c697a92f1d64ea5ca7d26a292f + + + 0 + 0 + 26615 + 15436 + true + false + + + view2 + 18978 + 4935 + 0 + 0 + 26614 + 15434 + 0 + 1 + false + 120 + false + false + false + false + false + false + + + + + true + false + true + false + true + false + false + true + false + 0 + false + true + false + false + false + false + true + false + false + + false + false + true + false + false + true + true + false + false + false + false + false + false + true + false + false + false + 204352 + false + + true + false + false + 204352 + true + false + false + false + 1 + true + true + false + false + true + false + false + true + true + true + false + true + 0 + + false + true + true + true + + 0 + true + false + false + false + high-resolution + true + true + false + false + true + false + false + false + false + true + + true + false + true + false + + false + false + false + true + false + false + false + false + false + false + false + false + false + false + 0 + true + false + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + + \ No newline at end of file diff --git a/sw/qa/core/text/data/tdf41652_variableNBSPenabled.fodt b/sw/qa/core/text/data/tdf41652_variableNBSPenabled.fodt new file mode 100644 index 000000000000..60432ade34f2 --- /dev/null +++ b/sw/qa/core/text/data/tdf41652_variableNBSPenabled.fodt @@ -0,0 +1,301 @@ + + + + 2023-03-31T21:00:03.6926293222023-03-31T21:04:31.905519901PT4M36S2LibreOfficeDev/7.6.0.0.alpha0$Linux_X86_64 LibreOffice_project/34216608eb7387c697a92f1d64ea5ca7d26a292f + + + 0 + 0 + 26615 + 15436 + true + false + + + view2 + 18907 + 3962 + 0 + 0 + 26614 + 15434 + 0 + 1 + false + 120 + false + false + false + false + false + false + + + + + true + false + true + false + true + false + false + true + false + 0 + false + true + false + false + false + false + true + false + false + + false + false + true + false + false + true + true + false + false + false + false + false + false + true + true + false + false + 204352 + false + + true + false + false + 204352 + true + false + false + false + 1 + true + true + false + false + true + false + false + true + true + true + false + true + 0 + + false + true + true + true + + 0 + true + false + false + false + high-resolution + true + true + false + false + true + false + false + false + false + true + + true + false + true + false + + false + false + false + true + false + false + false + false + false + false + false + false + false + false + 0 + true + false + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + + \ No newline at end of file diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx index 9047e5a2160b..d08ff598dd4c 100644 --- a/sw/qa/core/text/text.cxx +++ b/sw/qa/core/text/text.cxx @@ -1186,6 +1186,77 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testNumberPortionNoformat) getXPath(pXmlDoc, "//SwParaPortion/SwLineLayout/SwFieldPortion/SwFont", "color")); } +CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testTdf41652NBSPWidth) +{ + sal_Int32 nSectionAfterNBSPX_legacy_leftAligned; + sal_Int32 nSectionAfterNBSPX_legacy_justified; + sal_Int32 nSectionAfterNBSPX_optionDisabled_leftAligned; + sal_Int32 nSectionAfterNBSPX_optionDisabled_justified; + sal_Int32 nSectionAfterNBSPX_optionEnabled_leftAligned; + sal_Int32 nSectionAfterNBSPX_optionEnabled_justified; + + // Measure the X position of sections after NBSPs in a legacy file (no option value set) + { + createSwDoc("tdf41652_legacy.fodt"); + SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); + SwDocShell* pShell = pTextDoc->GetDocShell(); + std::shared_ptr xMetaFile = pShell->GetPreviewMetaFile(); + MetafileXmlDump aDumper; + xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *xMetaFile); + + nSectionAfterNBSPX_legacy_leftAligned = getXPath(pXmlDoc, "//textarray[3]", "x").toInt32(); + nSectionAfterNBSPX_legacy_justified = getXPath(pXmlDoc, "//textarray[8]", "x").toInt32(); + } + + // Measure the X of sections after NBSPs in a file with the option enabled + { + createSwDoc("tdf41652_variableNBSPdisabled.fodt"); + SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); + SwDocShell* pShell = pTextDoc->GetDocShell(); + std::shared_ptr xMetaFile = pShell->GetPreviewMetaFile(); + MetafileXmlDump aDumper; + xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *xMetaFile); + + nSectionAfterNBSPX_optionDisabled_leftAligned + = getXPath(pXmlDoc, "//textarray[3]", "x").toInt32(); + nSectionAfterNBSPX_optionDisabled_justified + = getXPath(pXmlDoc, "//textarray[8]", "x").toInt32(); + } + + // Measure the X of the sections after NBSPs in a file with the option enabled + { + createSwDoc("tdf41652_variableNBSPenabled.fodt"); + SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); + SwDocShell* pShell = pTextDoc->GetDocShell(); + std::shared_ptr xMetaFile = pShell->GetPreviewMetaFile(); + MetafileXmlDump aDumper; + xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *xMetaFile); + + nSectionAfterNBSPX_optionEnabled_leftAligned + = getXPath(pXmlDoc, "//textarray[3]", "x").toInt32(); + nSectionAfterNBSPX_optionEnabled_justified + = getXPath(pXmlDoc, "//textarray[8]", "x").toInt32(); + } + + // Assert left aligned NBSP for the legacy file is larger than zero + CPPUNIT_ASSERT(nSectionAfterNBSPX_legacy_leftAligned > 0); + // Assert both NBSPs have same width for the legacy file + CPPUNIT_ASSERT_EQUAL(nSectionAfterNBSPX_legacy_leftAligned, + nSectionAfterNBSPX_legacy_justified); + // Assert left aligned NBSP is same width for legacy file as for the disabled file + CPPUNIT_ASSERT_EQUAL(nSectionAfterNBSPX_legacy_leftAligned, + nSectionAfterNBSPX_optionDisabled_leftAligned); + // Assert justified NBSP is same width for legacy file as for the disabled file + CPPUNIT_ASSERT_EQUAL(nSectionAfterNBSPX_legacy_justified, + nSectionAfterNBSPX_optionDisabled_justified); + // Assert left aligned NBSP is same width for the disabled file as for the enabled file + CPPUNIT_ASSERT_EQUAL(nSectionAfterNBSPX_optionDisabled_leftAligned, + nSectionAfterNBSPX_optionEnabled_leftAligned); + // Assert justified NBSP is wider for the enabled file + CPPUNIT_ASSERT(nSectionAfterNBSPX_optionDisabled_justified + < nSectionAfterNBSPX_optionEnabled_justified); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/doc/DocumentSettingManager.cxx b/sw/source/core/doc/DocumentSettingManager.cxx index da04446c1271..412d1a56b686 100644 --- a/sw/source/core/doc/DocumentSettingManager.cxx +++ b/sw/source/core/doc/DocumentSettingManager.cxx @@ -108,7 +108,8 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc &rDoc) mbAutoFirstLineIndentDisregardLineSpace(true), mbWrapAsCharFlysLikeInOOXML(false), mbNoNumberingShowFollowBy(false), - mbDropCapPunctuation(true) + mbDropCapPunctuation(true), + mbUseVariableWidthNBSP(false) // COMPATIBILITY FLAGS END { @@ -137,6 +138,8 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc &rDoc) mbSubtractFlys = aOptions.GetDefault( SvtCompatibilityEntry::Index::SubtractFlysAnchoredAtFlys ); mbEmptyDbFieldHidesPara = aOptions.GetDefault(SvtCompatibilityEntry::Index::EmptyDbFieldHidesPara); + mbUseVariableWidthNBSP + = aOptions.GetDefault(SvtCompatibilityEntry::Index::UseVariableWidthNBSP); } else { @@ -156,6 +159,7 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc &rDoc) mbMsWordCompTrailingBlanks = false; mbSubtractFlys = false; mbEmptyDbFieldHidesPara = true; + mbUseVariableWidthNBSP = false; } // COMPATIBILITY FLAGS END @@ -251,6 +255,7 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const case DocumentSettingId::WRAP_AS_CHAR_FLYS_LIKE_IN_OOXML: return mbWrapAsCharFlysLikeInOOXML; case DocumentSettingId::NO_NUMBERING_SHOW_FOLLOWBY: return mbNoNumberingShowFollowBy; case DocumentSettingId::DROP_CAP_PUNCTUATION: return mbDropCapPunctuation; + case DocumentSettingId::USE_VARIABLE_WIDTH_NBSP: return mbUseVariableWidthNBSP; default: OSL_FAIL("Invalid setting id"); } @@ -445,6 +450,10 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo mbDropCapPunctuation = value; break; + case DocumentSettingId::USE_VARIABLE_WIDTH_NBSP: + mbUseVariableWidthNBSP = value; + break; + // COMPATIBILITY FLAGS END case DocumentSettingId::BROWSE_MODE: //can be used temporary (load/save) when no SwViewShell is available @@ -717,6 +726,7 @@ void sw::DocumentSettingManager::ReplaceCompatibilityOptions(const DocumentSetti mbFrameAutowidthWithMorePara = rSource.mbFrameAutowidthWithMorePara; mbFootnoteInColumnToPageEnd = rSource.mbFootnoteInColumnToPageEnd; mbDropCapPunctuation = rSource.mbDropCapPunctuation; + mbUseVariableWidthNBSP = rSource.mbUseVariableWidthNBSP; } sal_uInt32 sw::DocumentSettingManager::Getn32DummyCompatibilityOptions1() const @@ -1016,6 +1026,11 @@ void sw::DocumentSettingManager::dumpAsXml(xmlTextWriterPtr pWriter) const BAD_CAST(OString::boolean(mbEmptyDbFieldHidesPara).getStr())); (void)xmlTextWriterEndElement(pWriter); + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbUseVariableWidthNBSP")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), + BAD_CAST(OString::boolean(mbUseVariableWidthNBSP).getStr())); + (void)xmlTextWriterEndElement(pWriter); + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbContinuousEndnotes")); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::boolean(mbContinuousEndnotes).getStr())); diff --git a/sw/source/core/inc/DocumentSettingManager.hxx b/sw/source/core/inc/DocumentSettingManager.hxx index 07a12e3f1a6b..a1b1d639173e 100644 --- a/sw/source/core/inc/DocumentSettingManager.hxx +++ b/sw/source/core/inc/DocumentSettingManager.hxx @@ -179,6 +179,7 @@ class DocumentSettingManager final : bool mbWrapAsCharFlysLikeInOOXML; bool mbNoNumberingShowFollowBy; bool mbDropCapPunctuation; // tdf#150200, tdf#150438 + bool mbUseVariableWidthNBSP : 1; // tdf#41652 public: diff --git a/sw/source/core/text/porexp.cxx b/sw/source/core/text/porexp.cxx index f38e7b1f7a8c..9251d9f84171 100644 --- a/sw/source/core/text/porexp.cxx +++ b/sw/source/core/text/porexp.cxx @@ -18,6 +18,7 @@ */ #include +#include #include #include "inftxt.hxx" #include "porexp.hxx" @@ -204,14 +205,57 @@ bool SwBlankPortion::Format( SwTextFormatInfo &rInf ) void SwBlankPortion::Paint( const SwTextPaintInfo &rInf ) const { - if( !m_bMulti ) // No gray background for multiportion brackets - rInf.DrawViewOpt( *this, PortionType::Blank ); - SwExpandPortion::Paint( rInf ); + if (m_cChar == CHAR_HARDBLANK) + { + if (rInf.GetOpt().IsBlank()) + { + // Draw background + rInf.DrawViewOpt(*this, PortionType::Blank); + + // Draw tilde or degree sign + OUString aMarker = (rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess() + .get(DocumentSettingId::USE_VARIABLE_WIDTH_NBSP) + ? u"~" + : u"°"); + + SwPosSize aMarkerSize(rInf.GetTextSize(aMarker)); + Point aPos(rInf.GetPos()); + + std::shared_ptr pPortionRect = std::make_shared(); + rInf.CalcRect(*this, pPortionRect.get()); + aPos.AdjustX((pPortionRect->Width() / 2) - (aMarkerSize.Width() / 2)); + + SwTextPaintInfo aInf(rInf, &aMarker); + aInf.SetPos(aPos); + SwTextPortion aMarkerPor; + aMarkerPor.Width(aMarkerSize.Width()); + aMarkerPor.Height(aMarkerSize.Height()); + aMarkerPor.SetAscent(GetAscent()); + + Color colorBackup = aInf.GetFont()->GetColor(); + aInf.GetFont()->SetColor(NON_PRINTING_CHARACTER_COLOR); + aInf.DrawText(aMarkerPor, TextFrameIndex(aMarker.getLength()), true); + aInf.GetFont()->SetColor(colorBackup); + } + } + else + { + if (!m_bMulti) // No gray background for multiportion brackets + rInf.DrawViewOpt(*this, PortionType::Blank); + + SwExpandPortion::Paint(rInf); + } } -bool SwBlankPortion::GetExpText( const SwTextSizeInfo&, OUString &rText ) const +bool SwBlankPortion::GetExpText( const SwTextSizeInfo& rInf, OUString &rText ) const { - rText = OUString(m_cChar); + if (m_cChar == CHAR_HARDBLANK + && rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess().get( + DocumentSettingId::USE_VARIABLE_WIDTH_NBSP)) + rText = OUString(CH_BLANK); + else + rText = OUString(m_cChar); + return true; } diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx index 0b830419f78c..778a319d2470 100644 --- a/sw/source/core/text/portxt.cxx +++ b/sw/source/core/text/portxt.cxx @@ -590,7 +590,10 @@ TextFrameIndex SwTextPortion::GetSpaceCnt(const SwTextSizeInfo &rInf, if ( InExpGrp() || PortionType::InputField == GetWhichPor() ) { - if( !IsBlankPortion() && !InNumberGrp() && !IsCombinedPortion() ) + if (OUString ExpOut; + (!IsBlankPortion() + || (GetExpText(rInf, ExpOut) && OUStringChar(CH_BLANK) == ExpOut)) + && !InNumberGrp() && !IsCombinedPortion()) { // OnWin() likes to return a blank instead of an empty string from // time to time. We cannot use that here at all, however. @@ -627,7 +630,10 @@ tools::Long SwTextPortion::CalcSpacing( tools::Long nSpaceAdd, const SwTextSizeI if ( InExpGrp() || PortionType::InputField == GetWhichPor() ) { - if( !IsBlankPortion() && !InNumberGrp() && !IsCombinedPortion() ) + if (OUString ExpOut; + (!IsBlankPortion() + || (GetExpText(rInf, ExpOut) && OUStringChar(CH_BLANK) == ExpOut)) + && !InNumberGrp() && !IsCombinedPortion()) { // OnWin() likes to return a blank instead of an empty string from // time to time. We cannot use that here at all, however. diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx index 6ea193f2bc3f..eaf3a6bec72e 100644 --- a/sw/source/filter/xml/xmlimp.cxx +++ b/sw/source/filter/xml/xmlimp.cxx @@ -1263,7 +1263,8 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC "ProtectForm", "MsWordCompTrailingBlanks", "SubtractFlysAnchoredAtFlys", - "EmptyDbFieldHidesPara" + "EmptyDbFieldHidesPara", + "UseVariableWidthNBSP", }; bool bAreUserSettingsFromDocument = officecfg::Office::Common::Load::UserDefinedSettings::get(); diff --git a/sw/source/ui/config/optcomp.cxx b/sw/source/ui/config/optcomp.cxx index 7f6e6bf95141..576ae35bd817 100644 --- a/sw/source/ui/config/optcomp.cxx +++ b/sw/source/ui/config/optcomp.cxx @@ -122,7 +122,8 @@ static sal_uInt32 convertBools2Ulong_Impl bool _bProtectForm, bool _bMsWordCompTrailingBlanks, bool bSubtractFlysAnchoredAtFlys, - bool bEmptyDbFieldHidesPara + bool bEmptyDbFieldHidesPara, + bool bUseVariableWidthNBSP ) { sal_uInt32 nRet = 0; @@ -172,6 +173,9 @@ static sal_uInt32 convertBools2Ulong_Impl nSetBit = nSetBit << 1; if (bEmptyDbFieldHidesPara) nRet |= nSetBit; + nSetBit = nSetBit << 1; + if (bUseVariableWidthNBSP) + nRet |= nSetBit; return nRet; } @@ -241,7 +245,8 @@ void SwCompatibilityOptPage::InitControls( const SfxItemSet& rSet ) rEntry.getValue( SvtCompatibilityEntry::Index::ProtectForm ), rEntry.getValue( SvtCompatibilityEntry::Index::MsWordTrailingBlanks ), rEntry.getValue( SvtCompatibilityEntry::Index::SubtractFlysAnchoredAtFlys ), - rEntry.getValue( SvtCompatibilityEntry::Index::EmptyDbFieldHidesPara ) ); + rEntry.getValue( SvtCompatibilityEntry::Index::EmptyDbFieldHidesPara ), + rEntry.getValue( SvtCompatibilityEntry::Index::UseVariableWidthNBSP ) ); m_xFormattingLB->append(OUString::number(nOptions), sNewEntry); } } @@ -333,7 +338,8 @@ sal_uInt32 SwCompatibilityOptPage::GetDocumentOptions() const rIDocumentSettingAccess.get( DocumentSettingId::PROTECT_FORM ), rIDocumentSettingAccess.get( DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS ), rIDocumentSettingAccess.get( DocumentSettingId::SUBTRACT_FLYS ), - rIDocumentSettingAccess.get( DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA ) ); + rIDocumentSettingAccess.get( DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA ), + rIDocumentSettingAccess.get( DocumentSettingId::USE_VARIABLE_WIDTH_NBSP ) ); } return nRet; } @@ -435,6 +441,11 @@ bool SwCompatibilityOptPage::FillItemSet( SfxItemSet* ) m_pWrtShell->SetEmptyDbFieldHidesPara(bChecked); break; + case SvtCompatibilityEntry::Index::UseVariableWidthNBSP: + m_pWrtShell->GetDoc()->getIDocumentSettingAccess() + .set(DocumentSettingId::USE_VARIABLE_WIDTH_NBSP, bChecked); + break; + default: break; } diff --git a/sw/source/uibase/uno/SwXDocumentSettings.cxx b/sw/source/uibase/uno/SwXDocumentSettings.cxx index 9ce8dda4d5fd..9786964a4282 100644 --- a/sw/source/uibase/uno/SwXDocumentSettings.cxx +++ b/sw/source/uibase/uno/SwXDocumentSettings.cxx @@ -155,7 +155,8 @@ enum SwDocumentSettingsPropertyHandles HANDLE_HYPHENATE_URLS, HANDLE_WORD_LIKE_WRAP_FOR_AS_CHAR_FLYS, HANDLE_NO_NUMBERING_SHOW_FOLLOWBY, - HANDLE_DROP_CAP_PUNCTUATION + HANDLE_DROP_CAP_PUNCTUATION, + HANDLE_USE_VARIABLE_WIDTH_NBSP, }; } @@ -258,6 +259,7 @@ static rtl::Reference lcl_createSettingsInfo() { OUString("WordLikeWrapForAsCharFlys"), HANDLE_WORD_LIKE_WRAP_FOR_AS_CHAR_FLYS, cppu::UnoType::get(), 0 }, { OUString("NoNumberingShowFollowBy"), HANDLE_NO_NUMBERING_SHOW_FOLLOWBY, cppu::UnoType::get(), 0 }, { OUString("DropCapPunctuation"), HANDLE_DROP_CAP_PUNCTUATION, cppu::UnoType::get(), 0 }, + { OUString("UseVariableWidthNBSP"), HANDLE_USE_VARIABLE_WIDTH_NBSP, cppu::UnoType::get(), 0 }, /* * As OS said, we don't have a view when we need to set this, so I have to @@ -1092,6 +1094,14 @@ void SwXDocumentSettings::_setSingleValue( const comphelper::PropertyInfo & rInf DocumentSettingId::DROP_CAP_PUNCTUATION, bTmp); } break; + case HANDLE_USE_VARIABLE_WIDTH_NBSP: + { + bool bTmp; + if (rValue >>= bTmp) + mpDoc->getIDocumentSettingAccess().set( + DocumentSettingId::USE_VARIABLE_WIDTH_NBSP, bTmp); + } + break; default: throw UnknownPropertyException(OUString::number(rInfo.mnHandle)); } @@ -1638,6 +1648,12 @@ void SwXDocumentSettings::_getSingleValue( const comphelper::PropertyInfo & rInf DocumentSettingId::DROP_CAP_PUNCTUATION); } break; + case HANDLE_USE_VARIABLE_WIDTH_NBSP: + { + rValue <<= mpDoc->getIDocumentSettingAccess().get( + DocumentSettingId::USE_VARIABLE_WIDTH_NBSP); + } + break; default: throw UnknownPropertyException(OUString::number(rInfo.mnHandle)); } diff --git a/sw/uiconfig/swriter/ui/optcompatpage.ui b/sw/uiconfig/swriter/ui/optcompatpage.ui index bf325fa1c097..47765ddcd395 100644 --- a/sw/uiconfig/swriter/ui/optcompatpage.ui +++ b/sw/uiconfig/swriter/ui/optcompatpage.ui @@ -236,6 +236,7 @@ Word-compatible trailing blanks Tolerate white lines of PDF page backgrounds for compatibility with old documents Hide paragraphs of database fields (e.g., mail merge) with an empty value + Render non-breaking spaces (NBSP) as standard-space-width (off for fixed size) <User settings> diff --git a/unotools/source/config/compatibility.cxx b/unotools/source/config/compatibility.cxx index 52b0b2e30cbd..0aa5f79c113b 100644 --- a/unotools/source/config/compatibility.cxx +++ b/unotools/source/config/compatibility.cxx @@ -64,6 +64,7 @@ SvtCompatibilityEntry::SvtCompatibilityEntry() setValue( Index::SubtractFlysAnchoredAtFlys, false ); setValue( Index::EmptyDbFieldHidesPara, true ); setValue( Index::AddTableLineSpacing, false ); + setValue( Index::UseVariableWidthNBSP, false ); } OUString SvtCompatibilityEntry::getName( const Index rIdx ) @@ -89,7 +90,9 @@ OUString SvtCompatibilityEntry::getName( const Index rIdx ) "MsWordCompTrailingBlanks", "SubtractFlysAnchoredAtFlys", "EmptyDbFieldHidesPara", - "AddTableLineSpacing", + "UseVariableWidthNBSP", + + "AddTableLineSpacing" // Must be the last one }; /* Size of sPropertyName array not equal size of the SvtCompatibilityEntry::Index enum class */ -- cgit