sw/qa/extras/ooxmlexport/data/tdf122201_editUnprotectedText.odt |binary sw/qa/extras/ooxmlexport/ooxmlexport5.cxx | 31 ++++++++ sw/qa/extras/ooxmlexport/ooxmlexport8.cxx | 15 ++++ sw/source/core/crsr/pam.cxx | 12 +++ sw/source/filter/ww8/wrtw8sty.cxx | 4 - writerfilter/source/dmapper/DomainMapper.cxx | 6 + writerfilter/source/dmapper/PropertyIds.cxx | 1 writerfilter/source/dmapper/PropertyIds.hxx | 1 writerfilter/source/dmapper/PropertyMap.cxx | 36 +++++++++- writerfilter/source/dmapper/PropertyMap.hxx | 3 10 files changed, 102 insertions(+), 7 deletions(-)
New commits: commit 50ea5eac2e01cd71184ac86d69a96140938e0630 Author: Serge Krot <serge.k...@cib.de> AuthorDate: Mon Dec 17 17:07:23 2018 +0100 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Fri Jan 18 11:17:28 2019 +0100 sw: DOCX: allow editing of unprotected areas in protected doc Change-Id: I5fb590745b733e2bfb934d946276857b65caf680 Reviewed-on: https://gerrit.libreoffice.org/65278 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de> writerfilter: implement formprot The document properly opens with all sections protected because document protection (forms view) is enabled. However, when that setting was toggled off, all sections wrongly became unprotected, and remained unprotected when round-tripped (including in Word - so loss of configuration). Word does protection differently. It opens up in a forms only mode, but upon enabling editing mode, the individual sections can still be protected. Only when global enforcement is disabled do all sections become editable. So, if global enforcement is enabled, map the section protection to LO native protection. On startup, the sections will all be protected because of the global compatibility flag. If the flag is turned off, then you enter a similar mode to Word's "Edit document" where the sections are still protected. In LO, *each* section's protection must be turned off individually to fully disable enforcement. This patch keeps the same three-step process to fully edit the entire document, but the meanings take on a different form. "Compatability: Protect Form" changes from "enforcement" to "edit document" in concept. BTW, that matches how export works, where PROTECT_FORM is auto-enabled if any sections are protected. Section protection in LO can be disabled through Format - Sections - Write Protection. Patch initially developed to support tdf#120499. It depends on an earlier commit in order to round-trip. Change-Id: I8a2399f79640115d689ae9093792eecef7dbaeec Reviewed-on: https://gerrit.libreoffice.org/61918 Tested-by: Jenkins Reviewed-by: Justin Luth <justin_l...@sil.org> sw mso export: PROTECT_FORM shouldn't force section to protected PROTECT_FORM maps to enforcement = true, not "everything is protected". "The enforcement of this property is determined by the documentProtection element (ยง17.15.1.29), as it is possible to specify protection without turning it on." So, sections should retain their protected on/off status regardless of the value of PROTECT_FORM. My guess was that this was to offset the fact that DOCX import did not import protected status, so this helped to protect the sections that should not be unprotected. A followup patch will address the import side. patch initially developed to support tdf#120499. Change-Id: I8ff6d31711651a4827cbb8520fd68e88273d6799 Reviewed-on: https://gerrit.libreoffice.org/61905 Tested-by: Jenkins Reviewed-by: Justin Luth <justin_l...@sil.org> Reviewed-on: https://gerrit.libreoffice.org/66383 Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de> Tested-by: Thorsten Behrens <thorsten.behr...@cib.de> diff --git a/sw/qa/extras/ooxmlexport/data/tdf122201_editUnprotectedText.odt b/sw/qa/extras/ooxmlexport/data/tdf122201_editUnprotectedText.odt new file mode 100644 index 000000000000..217c8c38a409 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf122201_editUnprotectedText.odt differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx index 0f8e562a0f8a..935c3e458f99 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx @@ -52,6 +52,8 @@ #include <string> #include <config_features.h> +#include <unocrsr.hxx> +#include <ndtxt.hxx> class Test : public SwModelTestBase { @@ -967,6 +969,13 @@ DECLARE_OOXMLEXPORT_TEST(testSectionProtection, "sectionprot.odt") assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "enforcement", "true"); assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "edit", "forms"); } + + uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xSect(xSections->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL_MESSAGE("TextSection is protected", true, getProperty<bool>(xSect, "IsProtected")); + xSect.set(xSections->getByIndex(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Section1 is protected", false, getProperty<bool>(xSect, "IsProtected")); } DECLARE_OOXMLEXPORT_TEST(tdf66398_permissions, "tdf66398_permissions.docx") @@ -996,6 +1005,28 @@ DECLARE_OOXMLEXPORT_TEST(tdf66398_permissions, "tdf66398_permissions.docx") CPPUNIT_ASSERT(xBookmarksByName->hasByName("permission-for-group:267014232:everyone")); } +DECLARE_OOXMLEXPORT_TEST(tdf122201_editUnprotectedText, "tdf122201_editUnprotectedText.odt") +{ + // get the document + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + CPPUNIT_ASSERT(pDoc); + + // get two different nodes + SwNodeIndex aDocEnd(pDoc->GetNodes().GetEndOfContent()); + SwNodeIndex aDocStart(*aDocEnd.GetNode().StartOfSectionNode(), 3); + + // check protected area + SwPaM aPaMPortected(aDocStart); + CPPUNIT_ASSERT(aPaMPortected.HasReadonlySel(false)); + + // check unprotected area + SwPaM aPaMUnprotected(aDocEnd); + CPPUNIT_ASSERT(!aPaMUnprotected.HasReadonlySel(false)); +} + DECLARE_OOXMLEXPORT_TEST(testSectionHeader, "sectionprot.odt") { if (xmlDocPtr pXmlDoc = parseExport("word/document.xml")) diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx index 66e2228fb368..01911229f2e3 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx @@ -19,6 +19,7 @@ #include <swmodeltestbase.hxx> +#include <IDocumentSettingAccess.hxx> #include <com/sun/star/awt/XBitmap.hpp> #include <com/sun/star/awt/FontUnderline.hpp> #include <com/sun/star/awt/FontWeight.hpp> @@ -792,6 +793,20 @@ DECLARE_OOXMLEXPORT_TEST(testFdo53985, "fdo53985.docx") uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xTables->getCount()); // Only 4 tables were imported. + + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + CPPUNIT_ASSERT_MESSAGE("Compatibility: Protect form", pDoc->getIDocumentSettingAccess().get( DocumentSettingId::PROTECT_FORM ) ); + + uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xSections->getCount()); // The first paragraph wasn't counted as a section. + + uno::Reference<beans::XPropertySet> xSect(xSections->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL_MESSAGE("TextSection is protected", true, getProperty<bool>(xSect, "IsProtected")); + xSect.set(xSections->getByIndex(3), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Section3 is protected", false, getProperty<bool>(xSect, "IsProtected")); } DECLARE_OOXMLEXPORT_TEST(testFdo59638, "fdo59638.docx") diff --git a/sw/source/core/crsr/pam.cxx b/sw/source/core/crsr/pam.cxx index f13e24380181..e5c492ce0251 100644 --- a/sw/source/core/crsr/pam.cxx +++ b/sw/source/core/crsr/pam.cxx @@ -601,6 +601,16 @@ bool SwPaM::HasReadonlySel( bool bFormView ) const { bRet = true; } + else + { + const SwSectionNode* pParentSectionNd = pNd->FindSectionNode(); + if ( pParentSectionNd != nullptr + && ( pParentSectionNd->GetSection().IsProtectFlag() + || ( bFormView && !pParentSectionNd->GetSection().IsEditInReadonlyFlag()) ) ) + { + bRet = true; + } + } } if ( !bRet @@ -708,7 +718,7 @@ bool SwPaM::HasReadonlySel( bool bFormView ) const // touches fields, or fully encloses it), then don't disable editing bRet = !( ( !pA || bAtStartA ) && ( !pB || bAtStartB ) ); } - if( !bRet && pDoc->GetDocumentSettingManager().get( DocumentSettingId::PROTECT_FORM ) ) + if( !bRet && pDoc->GetDocumentSettingManager().get( DocumentSettingId::PROTECT_FORM ) && (pA || pB) ) { // Form protection case bRet = ( pA == nullptr ) || ( pB == nullptr ) || bAtStartA || bAtStartB; diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx index 7289bdd8f9d2..4658f5fb64a1 100644 --- a/sw/source/filter/ww8/wrtw8sty.cxx +++ b/sw/source/filter/ww8/wrtw8sty.cxx @@ -1535,9 +1535,7 @@ void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAtt AttrOutput().SectFootnoteEndnotePr(); // forms - bool formProtection = m_pDoc->getIDocumentSettingAccess().get( DocumentSettingId::PROTECT_FORM ); - formProtection |= rSepInfo.IsProtected(); - AttrOutput().SectionFormProtection( formProtection ); + AttrOutput().SectionFormProtection( rSepInfo.IsProtected() ); // line numbers const SwLineNumberInfo& rLnNumInfo = m_pDoc->GetLineNumberInfo(); diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index b14db3d28767..459d67954793 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -2385,7 +2385,11 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) case NS_ooxml::LN_CT_PPrBase_mirrorIndents: // mirrorIndents rContext->Insert(PROP_MIRROR_INDENTS, uno::makeAny( nIntValue != 0 ), true, PARA_GRAB_BAG); break; - case NS_ooxml::LN_EG_SectPrContents_formProt: //section protection, only form editing is enabled - unsupported + case NS_ooxml::LN_EG_SectPrContents_formProt: //section protection + { + if( pSectionContext ) + pSectionContext->Insert( PROP_IS_PROTECTED, uno::makeAny( bool(nIntValue) ) ); + } break; case NS_ooxml::LN_EG_SectPrContents_vAlign: { diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx index f515d5118636..d8b99ada629e 100644 --- a/writerfilter/source/dmapper/PropertyIds.cxx +++ b/writerfilter/source/dmapper/PropertyIds.cxx @@ -234,6 +234,7 @@ OUString getPropertyName( PropertyIds eId ) case PROP_REDLINE_DATE_TIME : sName = "RedlineDateTime"; break; case PROP_REDLINE_TYPE : sName = "RedlineType"; break; case PROP_REDLINE_REVERT_PROPERTIES: sName = "RedlineRevertProperties"; break; + case PROP_IS_PROTECTED : sName = "IsProtected"; break; case PROP_SIZE_PROTECTED : sName = "SizeProtected"; break; case PROP_POSITION_PROTECTED : sName = "PositionProtected"; break; case PROP_OPAQUE : sName = "Opaque"; break; diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx index 6d1d77bd743c..65ab06aa8321 100644 --- a/writerfilter/source/dmapper/PropertyIds.hxx +++ b/writerfilter/source/dmapper/PropertyIds.hxx @@ -217,6 +217,7 @@ enum PropertyIds ,PROP_PARENT_NUMBERING ,PROP_POSITION_AND_SPACE_MODE ,PROP_POSITION_PROTECTED + ,PROP_IS_PROTECTED ,PROP_PREFIX ,PROP_PRINTER_PAPER_TRAY_INDEX ,PROP_REDLINE_AUTHOR diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx index ed7632b2551f..885ee5798660 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -679,6 +679,30 @@ void SectionPropertyMap::DontBalanceTextColumns() } } +void SectionPropertyMap::ApplyProtectionProperties( uno::Reference< beans::XPropertySet >& xSection, DomainMapper_Impl& rDM_Impl ) +{ + try + { + // Word implements section protection differently than LO. + // PROP_IS_PROTECTED only applies if global setting GetProtectForm is enabled. + bool bIsProtected = rDM_Impl.GetSettingsTable()->GetProtectForm(); + if ( bIsProtected ) + { + // If form protection is enabled then section protection is enabled, unless explicitly disabled + if ( isSet(PROP_IS_PROTECTED) ) + getProperty(PROP_IS_PROTECTED)->second >>= bIsProtected; + if ( !xSection.is() ) + xSection = rDM_Impl.appendTextSectionAfter( m_xStartingRange ); + if ( xSection.is() ) + xSection->setPropertyValue( getPropertyName(PROP_IS_PROTECTED), uno::makeAny(bIsProtected) ); + } + } + catch ( uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("writerfilter", "ApplyProtectionProperties failed setting PROP_IS_PROTECTED"); + } +} + uno::Reference< text::XTextColumns > SectionPropertyMap::ApplyColumnProperties( const uno::Reference< beans::XPropertySet >& xColumnContainer, DomainMapper_Impl& rDM_Impl ) { @@ -1326,8 +1350,13 @@ void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl ) //todo: insert a section or access the already inserted section uno::Reference< beans::XPropertySet > xSection = rDM_Impl.appendTextSectionAfter( m_xStartingRange ); - if ( m_nColumnCount > 0 && xSection.is() ) - ApplyColumnProperties( xSection, rDM_Impl ); + if ( xSection.is() ) + { + if ( m_nColumnCount > 0 ) + ApplyColumnProperties( xSection, rDM_Impl ); + + ApplyProtectionProperties( xSection, rDM_Impl ); + } try { @@ -1366,6 +1395,9 @@ void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl ) } else { + uno::Reference< beans::XPropertySet > xSection; + ApplyProtectionProperties( xSection, rDM_Impl ); + //get the properties and create appropriate page styles uno::Reference< beans::XPropertySet > xFollowPageStyle = GetPageStyle( rDM_Impl.GetPageStyles(), rDM_Impl.GetTextFactory(), false ); diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx index 91962a7b0adb..8450715db53e 100644 --- a/writerfilter/source/dmapper/PropertyMap.hxx +++ b/writerfilter/source/dmapper/PropertyMap.hxx @@ -265,6 +265,9 @@ private: void DontBalanceTextColumns(); + /// Check if document is protected. If so, ensure a section exists, and apply its protected value. + void ApplyProtectionProperties( css::uno::Reference< css::beans::XPropertySet >& xSection, DomainMapper_Impl& rDM_Impl ); + css::uno::Reference< css::text::XTextColumns > ApplyColumnProperties( const css::uno::Reference< css::beans::XPropertySet >& xFollowPageStyle, DomainMapper_Impl& rDM_Impl); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits