sw/inc/IDocumentSettingAccess.hxx | 1 + sw/qa/uibase/uno/uno.cxx | 24 ++++++++++++++++++++++++ sw/source/core/doc/DocumentSettingManager.cxx | 10 ++++++++++ sw/source/core/inc/DocumentSettingManager.hxx | 1 + sw/source/filter/xml/xmlexp.cxx | 1 + sw/source/filter/xml/xmlimp.cxx | 10 ++++++++++ sw/source/uibase/uno/SwXDocumentSettings.cxx | 18 ++++++++++++++++++ 7 files changed, 65 insertions(+)
New commits: commit 799767d5670efc7f996892de5dd7d1afdb4a6cce Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Apr 29 10:39:43 2024 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Fri May 3 11:55:12 2024 +0200 tdf#160833 sw: add a DoNotMirrorRtlDrawObjs compat flag The DOCX bugdoc has a circle shape anchored inside an RTL paragraph: this shows up on the right hand side in Word, but on the left hand side in Writer. What happens is that Writer implicitly mirrors draw objects anchored in RTL paragraphs, while Word doesn't do this. Start fixing the problem by adding a new layout compatibility flag that can be used by the DOCX import in the future, to leave the behavior unchanged for new & existing ODT documents. An alternative would be to do something similar to the DOC import's SwWW8ImplReader::MiserableRTLGraphicsHack(), but 1) we don't have the page margins by the time we import the shape and 2) as its name says, it doesn't feel like a clean solution, it's better to handle this difference at a layout level. Change-Id: I2ec067d86c7fbdbe57e4cd9547015fe25a9a56b9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166820 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins (cherry picked from commit c675eaf923cf579670b8ba2f7794b47be7fad39e) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166845 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sw/inc/IDocumentSettingAccess.hxx b/sw/inc/IDocumentSettingAccess.hxx index 0dd9467bdf13..264860b854c4 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, + DO_NOT_MIRROR_RTL_DRAW_OBJS, // COMPATIBILITY FLAGS END BROWSE_MODE, HTML_MODE, diff --git a/sw/qa/uibase/uno/uno.cxx b/sw/qa/uibase/uno/uno.cxx index d38d0bbfc967..3e6d9c93d51c 100644 --- a/sw/qa/uibase/uno/uno.cxx +++ b/sw/qa/uibase/uno/uno.cxx @@ -560,6 +560,30 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testAllowTextAfterFloatingTableBreak) CPPUNIT_ASSERT(bAllowTextAfterFloatingTableBreak); } +CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testDoNotMirrorRtlDrawObjs) +{ + // Given an empty document: + createSwDoc(); + + // When checking the state of the DoNotMirrorRtlDrawObjs compat flag: + uno::Reference<lang::XMultiServiceFactory> xDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xSettings( + xDocument->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY); + bool bDoNotMirrorRtlDrawObjs{}; + // Without the accompanying fix in place, this test would have failed with: + // An uncaught exception of type com.sun.star.beans.UnknownPropertyException + // i.e. the compat flag was not recognized. + xSettings->getPropertyValue("DoNotMirrorRtlDrawObjs") >>= bDoNotMirrorRtlDrawObjs; + // Then make sure it's false by default: + CPPUNIT_ASSERT(!bDoNotMirrorRtlDrawObjs); + + // And when setting DoNotMirrorRtlDrawObjs=true: + xSettings->setPropertyValue("DoNotMirrorRtlDrawObjs", uno::Any(true)); + // Then make sure it gets enabled: + xSettings->getPropertyValue("DoNotMirrorRtlDrawObjs") >>= bDoNotMirrorRtlDrawObjs; + CPPUNIT_ASSERT(bDoNotMirrorRtlDrawObjs); +} + 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 661c001e98c2..14cfa5fd3c24 100644 --- a/sw/source/core/doc/DocumentSettingManager.cxx +++ b/sw/source/core/doc/DocumentSettingManager.cxx @@ -256,6 +256,8 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const return mbDoNotBreakWrappedTables; case DocumentSettingId::ALLOW_TEXT_AFTER_FLOATING_TABLE_BREAK: return mbAllowTextAfterFloatingTableBreak; + case DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS: + return mbDoNotMirrorRtlDrawObjs; case DocumentSettingId::JUSTIFY_LINES_WITH_SHRINKING: return mbJustifyLinesWithShrinking; case DocumentSettingId::NO_NUMBERING_SHOW_FOLLOWBY: return mbNoNumberingShowFollowBy; @@ -450,6 +452,10 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo mbApplyTextAttrToEmptyLineAtEndOfParagraph = value; break; + case DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS: + mbDoNotMirrorRtlDrawObjs = value; + break; + case DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES: mbDoNotBreakWrappedTables = value; break; @@ -1097,12 +1103,16 @@ void sw::DocumentSettingManager::dumpAsXml(xmlTextWriterPtr pWriter) const (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mnImagePreferredDPI")); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(mnImagePreferredDPI).getStr())); + (void)xmlTextWriterEndElement(pWriter); (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbApplyTextAttrToEmptyLineAtEndOfParagraph")); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::boolean(mbApplyTextAttrToEmptyLineAtEndOfParagraph).getStr())); (void)xmlTextWriterEndElement(pWriter); + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbDoNotMirrorRtlDrawObjs")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), + BAD_CAST(OString::boolean(mbDoNotMirrorRtlDrawObjs).getStr())); (void)xmlTextWriterEndElement(pWriter); (void)xmlTextWriterEndElement(pWriter); diff --git a/sw/source/core/inc/DocumentSettingManager.hxx b/sw/source/core/inc/DocumentSettingManager.hxx index a3395a977f7e..6599c9bf2ad0 100644 --- a/sw/source/core/inc/DocumentSettingManager.hxx +++ b/sw/source/core/inc/DocumentSettingManager.hxx @@ -179,6 +179,7 @@ class DocumentSettingManager final : bool mbAllowTextAfterFloatingTableBreak = false; bool mbJustifyLinesWithShrinking = false; bool mbApplyTextAttrToEmptyLineAtEndOfParagraph = true; + bool mbDoNotMirrorRtlDrawObjs = false; // If this is on as_char flys wrapping will be handled the same like in Word bool mbNoNumberingShowFollowBy; bool mbDropCapPunctuation; // tdf#150200, tdf#150438 diff --git a/sw/source/filter/xml/xmlexp.cxx b/sw/source/filter/xml/xmlexp.cxx index 434eb8c07312..fa6f0d1dda9d 100644 --- a/sw/source/filter/xml/xmlexp.cxx +++ b/sw/source/filter/xml/xmlexp.cxx @@ -397,6 +397,7 @@ void SwXMLExport::GetConfigurationSettings( Sequence < PropertyValue >& rProps) static const std::initializer_list<std::u16string_view> vOmitFalseValues = { u"DoNotBreakWrappedTables", u"AllowTextAfterFloatingTableBreak", + u"DoNotMirrorRtlDrawObjs", }; SvXMLUnitConverter::convertPropertySet( rProps, xProps, &vOmitFalseValues ); diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx index 5074a3c4a94d..aa670c8f92af 100644 --- a/sw/source/filter/xml/xmlimp.cxx +++ b/sw/source/filter/xml/xmlimp.cxx @@ -1306,6 +1306,7 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC bool bDoNotBreakWrappedTables = false; bool bAllowTextAfterFloatingTableBreak = false; bool bDropCapPunctuation = false; + bool bDoNotMirrorRtlDrawObjs = false; const PropertyValue* currentDatabaseDataSource = nullptr; const PropertyValue* currentDatabaseCommand = nullptr; @@ -1417,6 +1418,10 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC } else if ( rValue.Name == "DropCapPunctuation" ) bDropCapPunctuation = true; + else if (rValue.Name == "DoNotMirrorRtlDrawObjs") + { + rValue.Value >>= bDoNotMirrorRtlDrawObjs; + } } catch( Exception& ) { @@ -1589,6 +1594,11 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC xProps->setPropertyValue("ApplyTextAttrToEmptyLineAtEndOfParagraph", Any(false)); } + if (bDoNotMirrorRtlDrawObjs) + { + xProps->setPropertyValue("DoNotMirrorRtlDrawObjs", Any(true)); + } + if (bDoNotBreakWrappedTables) { xProps->setPropertyValue("DoNotBreakWrappedTables", Any(true)); diff --git a/sw/source/uibase/uno/SwXDocumentSettings.cxx b/sw/source/uibase/uno/SwXDocumentSettings.cxx index 4c6e85cc6613..3c0a8bbbf2a4 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_DO_NOT_MIRROR_RTL_DRAW_OBJS, }; } @@ -266,6 +267,7 @@ static rtl::Reference<MasterPropertySetInfo> lcl_createSettingsInfo() { 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 }, + { OUString("DoNotMirrorRtlDrawObjs"), HANDLE_DO_NOT_MIRROR_RTL_DRAW_OBJS, cppu::UnoType<bool>::get(), 0 }, /* * As OS said, we don't have a view when we need to set this, so I have to @@ -1086,6 +1088,16 @@ void SwXDocumentSettings::_setSingleValue( const comphelper::PropertyInfo & rInf } } break; + case HANDLE_DO_NOT_MIRROR_RTL_DRAW_OBJS: + { + bool bTmp; + if (rValue >>= bTmp) + { + mpDoc->getIDocumentSettingAccess().set( + DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS, bTmp); + } + } + break; case HANDLE_DO_NOT_BREAK_WRAPPED_TABLES: { bool bTmp; @@ -1674,6 +1686,12 @@ void SwXDocumentSettings::_getSingleValue( const comphelper::PropertyInfo & rInf DocumentSettingId::APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH); } break; + case HANDLE_DO_NOT_MIRROR_RTL_DRAW_OBJS: + { + rValue <<= mpDoc->getIDocumentSettingAccess().get( + DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS); + } + break; case HANDLE_DO_NOT_BREAK_WRAPPED_TABLES: { rValue <<= mpDoc->getIDocumentSettingAccess().get(