sw/qa/extras/ooxmlexport/data/tdf120852_readOnlyUnProtected.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport5.cxx | 28 ++++++++++ sw/source/filter/ww8/docxexport.cxx | 23 ++++++-- 3 files changed, 47 insertions(+), 4 deletions(-)
New commits: commit 41dbdc1499f4512941a38e5972d03d26a2397a89 Author: Justin Luth <justin.l...@collabora.com> AuthorDate: Tue Mar 10 22:30:02 2020 +0300 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Tue Mar 31 09:39:33 2020 +0200 related tdf#106843 docxexport: if not enforced, let Writer protect The problem was that sections, etc., could not be protected if the document previously had some kind of protection that was now disabled/not enforced. Docx has a special flag that actually enables the selected protection (forms/track changes/readonly). Even if it isn't enabled, grabbagging keeps the "suggestion" for next time when the user wants to enable protection. "If the value of this element is off, 0, or false, all the WordprocessingML pertaining to document protection is still preserved in the document, but is not enforced." If the user requested some kind of protection in Writer, it should be able to override a grabbag "suggestion" and set a real protection value. Change-Id: I638c6420bfb9a1801187f3e16586d2e18dfacb84 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90322 Tested-by: Jenkins Reviewed-by: Justin Luth <justin_l...@sil.org> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/qa/extras/ooxmlexport/data/tdf120852_readOnlyUnProtected.docx b/sw/qa/extras/ooxmlexport/data/tdf120852_readOnlyUnProtected.docx new file mode 100644 index 000000000000..143799ddb6bd Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf120852_readOnlyUnProtected.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx index 7eb17d725845..a1b7ef6aad3b 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx @@ -124,6 +124,34 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testfdo79008, "fdo79008.docx") parseExport("word/document.xml"); } +DECLARE_OOXMLEXPORT_TEST(testTdf120852_readOnlyUnProtected, "tdf120852_readOnlyUnProtected.docx") +{ + + // Readonly is not enforced, just a suggestion, + // so when a section is protected, the document should enable forms protection. + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + CPPUNIT_ASSERT(!pTextDoc->GetDocShell()->IsSecurityOptOpenReadOnly()); + + uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY_THROW); + uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY_THROW); + const sal_Int32 nLastSection = xSections->getCount() - 1; + uno::Reference<beans::XPropertySet> xSect(xSections->getByIndex(nLastSection), uno::UNO_QUERY_THROW); + if ( !mbExported ) + { + CPPUNIT_ASSERT_MESSAGE("Section is not protected", !getProperty<bool>(xSect, "IsProtected")); + // Enable section protection. The round-trip should have forms protection enabled. + xSect->setPropertyValue("IsProtected", uno::makeAny(true)); + } + else + { + CPPUNIT_ASSERT_MESSAGE("Section is protected", getProperty<bool>(xSect, "IsProtected")); + xmlDocPtr pXmlSettings = parseExport("word/settings.xml"); + assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "edit", "forms"); + assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "enforcement", "true"); + } +} + DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testAuthorPropertySdt, "author-property.docx") { xmlDocPtr pXmlDoc = parseExport("word/document.xml"); diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index 9aa7a8a2a083..ae63a3e13a2c 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -1084,15 +1084,25 @@ void DocxExport::WriteSettings() uno::Reference< beans::XPropertySet > xPropSet( m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW ); bool hasProtectionProperties = false; + bool bWriterWantsToProtect = false; + bool bWriterWantsToProtectForm = false; + bool bWriterWantsToProtectRedline = false; bool bHasRedlineProtectionKey = false; bool bHasDummyRedlineProtectionKey = false; uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); + if ( m_pDoc->getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_FORM) || + m_pSections->DocumentIsProtected() ) + { + bWriterWantsToProtect = bWriterWantsToProtectForm = true; + } if ( xPropSetInfo->hasPropertyByName( "RedlineProtectionKey" ) ) { uno::Sequence<sal_Int8> aKey; xPropSet->getPropertyValue( "RedlineProtectionKey" ) >>= aKey; bHasRedlineProtectionKey = aKey.hasElements(); bHasDummyRedlineProtectionKey = aKey.getLength() == 1 && aKey[0] == 1; + if ( bHasRedlineProtectionKey && !bHasDummyRedlineProtectionKey ) + bWriterWantsToProtect = bWriterWantsToProtectRedline = true; } /* Compatibility Mode (tdf#131304) @@ -1194,7 +1204,6 @@ void DocxExport::WriteSettings() } else if (rProp.Name == "DocumentProtection") { - uno::Sequence< beans::PropertyValue > rAttributeList; rProp.Value >>= rAttributeList; @@ -1202,6 +1211,8 @@ void DocxExport::WriteSettings() { sax_fastparser::FastAttributeList* pAttributeList = sax_fastparser::FastSerializerHelper::createAttrList(); bool bIsProtectionTrackChanges = false; + // if grabbag protection is not enforced, allow Writer protection to override + bool bEnforced = false; for (const auto& rAttribute : std::as_const(rAttributeList)) { static DocxStringTokenMap const aTokens[] = @@ -1225,12 +1236,17 @@ void DocxExport::WriteSettings() pAttributeList->add(FSNS(XML_w, nToken), sValue.toUtf8()); if ( nToken == XML_edit && sValue == "trackedChanges" ) bIsProtectionTrackChanges = true; + else if ( nToken == XML_enforcement ) + bEnforced = sValue.toBoolean(); } } // we have document protection from input DOCX file // and in the case of change tracking protection, we didn't modify it hasProtectionProperties = !bIsProtectionTrackChanges || bHasDummyRedlineProtectionKey; + // use grabbag if still valid/enforced + // or leave as an un-enforced suggestion if Writer doesn't want to set any enforcement + hasProtectionProperties &= bEnforced || !bWriterWantsToProtect; if ( hasProtectionProperties ) { sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList); @@ -1264,8 +1280,7 @@ void DocxExport::WriteSettings() { // Protect form - highest priority // Section-specific write protection - if (m_pDoc->getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_FORM) || - m_pSections->DocumentIsProtected()) + if ( bWriterWantsToProtectForm ) { // we have form protection from Writer or from input ODT file @@ -1274,7 +1289,7 @@ void DocxExport::WriteSettings() FSNS(XML_w, XML_enforcement), "true"); } // Protect Change Tracking - next priority - else if ( bHasRedlineProtectionKey && !bHasDummyRedlineProtectionKey ) + else if ( bWriterWantsToProtectRedline ) { // we have change tracking protection from Writer or from input ODT file _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits