diff options
author | Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de> | 2019-10-10 08:13:51 +0200 |
---|---|---|
committer | Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de> | 2019-10-14 08:15:31 +0200 |
commit | 075f20a4b696f9e85d11dc977806e41a49e6de61 (patch) | |
tree | 30827954123e3dd54764c74ccad37302f05b2816 | |
parent | 03ec3b7dd11656c8b64a94efb172e17d97ea662e (diff) |
Add document-level option to lock down content extraction
Setting this option will prevent copying/dragging any content from LO
to another program or even another LO window.
Change-Id: Ifbc032a4fa69ac1a17d4b500f5a30f5399d84ed7
Reviewed-on: https://gerrit.libreoffice.org/80586
Tested-by: Jenkins
Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
23 files changed, 104 insertions, 9 deletions
diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc index d77279cb44d3..6124255f2756 100644 --- a/include/sfx2/sfxsids.hrc +++ b/include/sfx2/sfxsids.hrc @@ -258,6 +258,7 @@ class SvxSearchItem; #define SID_TOOLBAR_MODE (SID_SFX_START + 1728) #define SID_NO_FILE_SYNC (SID_SFX_START + 1729) #define SID_NO_THUMBNAIL (SID_SFX_START + 1730) +#define SID_LOCK_CONTENT_EXTRACTION (SID_SFX_START + 1731) // Used to export a temporary file for preview in Mail Merge Wizard, where saving the data source is // not required for preview, but interferes with not-yet-saved embedded data source for main document. #define SID_NO_EMBEDDED_DS TypedWhichId<SfxBoolItem>(SID_SFX_START + 1731) diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx index d3856243e9f5..fff76219ea3b 100644 --- a/include/sfx2/viewsh.hxx +++ b/include/sfx2/viewsh.hxx @@ -288,6 +288,7 @@ public: void AddRemoveClipboardListener( const css::uno::Reference < css::datatransfer::clipboard::XClipboardListener>&, bool ); css::uno::Reference< css::datatransfer::clipboard::XClipboardNotifier > GetClipboardNotifier() const; + bool isContentExtractionLocked(); SAL_DLLPRIVATE SfxInPlaceClient* GetUIActiveIPClient_Impl() const; SAL_DLLPRIVATE void AddContextMenuInterceptor_Impl( const css::uno::Reference < css::ui::XContextMenuInterceptor >& xInterceptor ); diff --git a/include/unotools/mediadescriptor.hxx b/include/unotools/mediadescriptor.hxx index 6a826ce309ac..b2260b5652ff 100644 --- a/include/unotools/mediadescriptor.hxx +++ b/include/unotools/mediadescriptor.hxx @@ -100,6 +100,7 @@ class UNOTOOLS_DLLPUBLIC MediaDescriptor : public comphelper::SequenceAsHashMap static const OUString& PROP_VIEWONLY(); static const OUString& PROP_DOCUMENTBASEURL(); static const OUString& PROP_SUGGESTEDSAVEASNAME(); + static const OUString& PROP_LOCKCONTENTEXTRACTION(); // interface public: diff --git a/offapi/com/sun/star/document/MediaDescriptor.idl b/offapi/com/sun/star/document/MediaDescriptor.idl index 58e773311875..0a4ba28f611b 100644 --- a/offapi/com/sun/star/document/MediaDescriptor.idl +++ b/offapi/com/sun/star/document/MediaDescriptor.idl @@ -560,6 +560,14 @@ service MediaDescriptor /** specifies the frame containing the document. May be empty. */ [optional,property] com::sun::star::frame::XFrame Frame; + + /** Setting this option will prevent copying/dragging any content anywhere. + The commands 'Copy' and 'Cut' will be disabled; selection clipboard won't work, + and dragging with mouse will also be disabled. + + @since LibreOffice 6.4 + */ + [optional,property] boolean LockContentExtraction; }; diff --git a/offapi/com/sun/star/frame/XModel2.idl b/offapi/com/sun/star/frame/XModel2.idl index 22d1ff9f82ec..c3a8d18a71b6 100644 --- a/offapi/com/sun/star/frame/XModel2.idl +++ b/offapi/com/sun/star/frame/XModel2.idl @@ -142,6 +142,7 @@ interface XModel2 : com::sun::star::frame::XModel <ul> <li>com::sun::star::document::MediaDescriptor::SuggestedSaveAsDir</li> <li>com::sun::star::document::MediaDescriptor::SuggestedSaveAsName</li> + <li>com::sun::star::document::MediaDescriptor::LockContentExtraction</li> </ul> @throws com::sun::star::lang::IllegalArgumentException When trying to set an unsupported property diff --git a/sc/source/ui/drawfunc/drawsh2.cxx b/sc/source/ui/drawfunc/drawsh2.cxx index 4f7c591339bb..a3da77fd7296 100644 --- a/sc/source/ui/drawfunc/drawsh2.cxx +++ b/sc/source/ui/drawfunc/drawsh2.cxx @@ -147,6 +147,12 @@ void ScDrawShell::GetDrawFuncState( SfxItemSet& rSet ) // disable functions rSet.DisableItem( SID_FLIP_VERTICAL ); } + if (pViewData->GetViewShell()->isContentExtractionLocked()) + { + rSet.DisableItem(SID_COPY); + rSet.DisableItem(SID_CUT); + } + const SdrMarkList& rMarkList = pView->GetMarkedObjectList(); const size_t nMarkCount = rMarkList.GetMarkCount(); diff --git a/sc/source/ui/drawfunc/drtxtob.cxx b/sc/source/ui/drawfunc/drtxtob.cxx index 92910b2dea87..17f8321d58e2 100644 --- a/sc/source/ui/drawfunc/drtxtob.cxx +++ b/sc/source/ui/drawfunc/drtxtob.cxx @@ -466,6 +466,12 @@ void ScDrawTextObjectBar::GetState( SfxItemSet& rSet ) if (!bCanDoThesaurus) rSet.DisableItem( SID_THESAURUS ); } + + if (pViewData->GetViewShell()->isContentExtractionLocked()) + { + rSet.DisableItem(SID_COPY); + rSet.DisableItem(SID_CUT); + } } IMPL_LINK( ScDrawTextObjectBar, ClipboardChanged, TransferableDataHelper*, pDataHelper, void ) diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx index 6554b63c6e7f..949c81e47a3d 100644 --- a/sc/source/ui/view/cellsh.cxx +++ b/sc/source/ui/view/cellsh.cxx @@ -211,6 +211,8 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet ) bDisable = false; break; case SID_CUT: // cut + bDisable = !bSimpleArea || GetViewData()->GetViewShell()->isContentExtractionLocked(); + break; case FID_INS_CELL: // insert cells, just simple selection bDisable = (!bSimpleArea); break; @@ -271,6 +273,7 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet ) //! work is to be done once more if ( !(!bEditable && bOnlyNotBecauseOfMatrix) ) bNeedEdit = false; // allowed when protected/ReadOnly + bDisable = GetViewData()->GetViewShell()->isContentExtractionLocked(); break; case SID_AUTOFORMAT: // Autoformat, at least 3x3 selected diff --git a/sc/source/ui/view/editsh.cxx b/sc/source/ui/view/editsh.cxx index 8cda154cd702..6e0b40269d09 100644 --- a/sc/source/ui/view/editsh.cxx +++ b/sc/source/ui/view/editsh.cxx @@ -817,6 +817,14 @@ void ScEditShell::GetState( SfxItemSet& rSet ) case SID_INSERT_FIELD_TITLE: case SID_INSERT_FIELD_DATE_VAR: break; + case SID_COPY: + case SID_CUT: + if (pViewData->GetViewShell()->isContentExtractionLocked()) + { + rSet.DisableItem(SID_COPY); + rSet.DisableItem(SID_CUT); + } + break; } nWhich = aIter.NextWhich(); diff --git a/sd/source/ui/view/drviews7.cxx b/sd/source/ui/view/drviews7.cxx index bb12920ef246..e405a987fc84 100644 --- a/sd/source/ui/view/drviews7.cxx +++ b/sd/source/ui/view/drviews7.cxx @@ -915,7 +915,7 @@ void DrawViewShell::GetMenuState( SfxItemSet &rSet ) if (pOlView) { - if (pOlView->GetSelected().isEmpty()) + if (pOlView->GetSelected().isEmpty() || GetViewShell()->isContentExtractionLocked()) { rSet.DisableItem( SID_CUT ); rSet.DisableItem( SID_COPY ); diff --git a/sd/source/ui/view/drviewsj.cxx b/sd/source/ui/view/drviewsj.cxx index addc54e4fc9f..80882a93394e 100644 --- a/sd/source/ui/view/drviewsj.cxx +++ b/sd/source/ui/view/drviewsj.cxx @@ -503,6 +503,11 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet ) rSet.DisableItem (SID_OBJECT_SHEAR); } + if (GetViewShell()->isContentExtractionLocked()) + { + rSet.DisableItem(SID_COPY); + rSet.DisableItem(SID_CUT); + } } } // end of namespace sd diff --git a/sd/source/ui/view/outlnvsh.cxx b/sd/source/ui/view/outlnvsh.cxx index 53d55b60e46e..0c0ca15a4062 100644 --- a/sd/source/ui/view/outlnvsh.cxx +++ b/sd/source/ui/view/outlnvsh.cxx @@ -884,7 +884,8 @@ void OutlineViewShell::GetMenuState( SfxItemSet &rSet ) } } - if (!pOlView->GetViewByWindow(GetActiveWindow())->HasSelection()) + if (!pOlView->GetViewByWindow(GetActiveWindow())->HasSelection() + || GetViewShell()->isContentExtractionLocked()) { rSet.DisableItem(SID_CUT); rSet.DisableItem(SID_COPY); diff --git a/sfx2/source/appl/appuno.cxx b/sfx2/source/appl/appuno.cxx index 649c18952701..6c70975db7a1 100644 --- a/sfx2/source/appl/appuno.cxx +++ b/sfx2/source/appl/appuno.cxx @@ -169,6 +169,7 @@ static char const sFailOnWarning[] = "FailOnWarning"; static char const sDocumentService[] = "DocumentService"; static char const sFilterProvider[] = "FilterProvider"; static char const sImageFilter[] = "ImageFilter"; +static char const sLockContentExtraction[] = "LockContentExtraction"; static bool isMediaDescriptor( sal_uInt16 nSlotId ) { @@ -845,6 +846,14 @@ void TransformParameters( sal_uInt16 nSlotId, const uno::Sequence<beans::Propert if (bOK) rSet.Put(SfxStringItem(SID_FILTER_PROVIDER, aVal)); } + else if (aName == sLockContentExtraction) + { + bool bVal = false; + bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for LockContentExtraction" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_LOCK_CONTENT_EXTRACTION, bVal ) ); + } #ifdef DBG_UTIL else --nFoundArgs; @@ -1614,6 +1623,11 @@ void TransformItems( sal_uInt16 nSlotId, const SfxItemSet& rSet, uno::Sequence<b pValue[nActProp].Name = sImageFilter; pValue[nActProp++].Value <<= static_cast<const SfxStringItem*>(pItem)->GetValue(); } + if ( rSet.GetItemState( SID_LOCK_CONTENT_EXTRACTION, false, &pItem ) == SfxItemState::SET ) + { + pValue[nActProp].Name = sLockContentExtraction; + pValue[nActProp++].Value <<= static_cast<const SfxBoolItem*>(pItem)->GetValue() ; + } } rArgs = aSequ; diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index cc2aae255542..f4019db6b98d 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -1062,16 +1062,23 @@ void SAL_CALL SfxBaseModel::setArgs(const Sequence<beans::PropertyValue>& aArgs) for (const auto& rArg : aArgs) { OUString sValue; - rArg.Value >>= sValue; + bool bValue; if (rArg.Name == "SuggestedSaveAsName") { + rArg.Value >>= sValue; pMedium->GetItemSet()->Put(SfxStringItem(SID_SUGGESTEDSAVEASNAME, sValue)); } else if (rArg.Name == "SuggestedSaveAsDir") { + rArg.Value >>= sValue; pMedium->GetItemSet()->Put(SfxStringItem(SID_SUGGESTEDSAVEASDIR, sValue)); } + else if (rArg.Name == "LockContentExtraction") + { + rArg.Value >>= bValue; + pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_CONTENT_EXTRACTION, bValue)); + } else { throw lang::IllegalArgumentException("Setting property not supported: " + rArg.Name, diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx index a6f8567f8aac..4866fcabc4bc 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -39,11 +39,13 @@ #include <com/sun/star/embed/XEmbeddedObject.hpp> #include <com/sun/star/container/XContainerQuery.hpp> #include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/frame/XModel.hpp> #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp> #include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp> #include <com/sun/star/view/XRenderable.hpp> +#include <com/sun/star/uno/Reference.hxx> #include <cppuhelper/implbase.hxx> #include <osl/file.hxx> @@ -60,6 +62,7 @@ #include <basic/sbuno.hxx> #include <framework/actiontriggerhelper.hxx> #include <comphelper/lok.hxx> +#include <comphelper/namedvaluecollection.hxx> #include <comphelper/processfactory.hxx> #include <comphelper/sequenceashashmap.hxx> #include <toolkit/helper/vclunohelper.hxx> @@ -1733,6 +1736,15 @@ void SfxViewShell::SetController( SfxBaseController* pController ) pImpl->xClipboardListener = new SfxClipboardChangeListener( this, GetClipboardNotifier() ); } +bool SfxViewShell::isContentExtractionLocked() +{ + Reference<XModel> xModel = GetCurrentDocument(); + if (!xModel.is()) + return false; + comphelper::NamedValueCollection aArgs(xModel->getArgs()); + return aArgs.getOrDefault("LockContentExtraction", false); +} + Reference < XController > SfxViewShell::GetController() const { return pImpl->m_pController.get(); diff --git a/sw/qa/python/check_xmodel.py b/sw/qa/python/check_xmodel.py index c5374c03c350..a71fdf9bc142 100644 --- a/sw/qa/python/check_xmodel.py +++ b/sw/qa/python/check_xmodel.py @@ -32,12 +32,14 @@ class TestXModel(unittest.TestCase): p1 = PropertyValue(Name="SuggestedSaveAsName", Value="prettyFileName") p2 = PropertyValue(Name="SuggestedSaveAsDir", Value="/my/dir") - xDoc.setArgs([p1, p2]) + p3 = PropertyValue(Name="LockContentExtraction", Value=True) + xDoc.setArgs([p1, p2, p3]) # Make sure that all properties are returned with getArgs() args = xDoc.getArgs() self.assertTrue(p1 in args) self.assertTrue(p2 in args) + self.assertTrue(p3 in args) xDoc.close(True) diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx index 20639bacd8bf..67a5d390c2e0 100644 --- a/sw/source/uibase/dochdl/swdtflvr.cxx +++ b/sw/source/uibase/dochdl/swdtflvr.cxx @@ -1108,6 +1108,9 @@ int SwTransferable::PrepareForCopy( bool bIsCut ) int SwTransferable::Copy( bool bIsCut ) { + if (m_pWrtShell->GetView().isContentExtractionLocked()) + return 0; + int nRet = PrepareForCopy( bIsCut ); if ( nRet ) { diff --git a/sw/source/uibase/docvw/edtdd.cxx b/sw/source/uibase/docvw/edtdd.cxx index 2a4fdb2eb9e9..f9488aca1b38 100644 --- a/sw/source/uibase/docvw/edtdd.cxx +++ b/sw/source/uibase/docvw/edtdd.cxx @@ -66,6 +66,9 @@ void SwEditWin::StopDDTimer(SwWrtShell *pSh, const Point &rPt) void SwEditWin::StartDrag( sal_Int8 /*nAction*/, const Point& rPosPixel ) { + if (m_rView.isContentExtractionLocked()) + return; + SwWrtShell &rSh = m_rView.GetWrtShell(); if( rSh.GetDrawView() ) { diff --git a/sw/source/uibase/shells/annotsh.cxx b/sw/source/uibase/shells/annotsh.cxx index 0c5467c16075..e6478adf3292 100644 --- a/sw/source/uibase/shells/annotsh.cxx +++ b/sw/source/uibase/shells/annotsh.cxx @@ -983,13 +983,13 @@ void SwAnnotationShell::StateClpbrd(SfxItemSet &rSet) { case SID_CUT: { - if ( (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()==SwPostItHelper::DELETED) || !pOLV->HasSelection() ) + if (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus() == SwPostItHelper::DELETED) rSet.DisableItem( nWhich ); - break; + [[fallthrough]]; } case SID_COPY: { - if( !pOLV->HasSelection() ) + if (!pOLV->HasSelection() || rView.isContentExtractionLocked()) rSet.DisableItem( nWhich ); break; } diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx index 8da42ad496d4..89f4e3a00824 100644 --- a/sw/source/uibase/shells/basesh.cxx +++ b/sw/source/uibase/shells/basesh.cxx @@ -462,7 +462,7 @@ void SwBaseShell::StateClpbrd(SfxItemSet &rSet) } [[fallthrough]]; case SID_COPY: - if( !bCopy ) + if( !bCopy || GetView().isContentExtractionLocked()) rSet.DisableItem( nWhich ); break; diff --git a/sw/source/uibase/shells/drwtxtex.cxx b/sw/source/uibase/shells/drwtxtex.cxx index c975ecebfbae..702a08a3bedd 100644 --- a/sw/source/uibase/shells/drwtxtex.cxx +++ b/sw/source/uibase/shells/drwtxtex.cxx @@ -1144,7 +1144,7 @@ void SwDrawTextShell::StateClpbrd(SfxItemSet &rSet) { case SID_CUT: case SID_COPY: - if( !bCopy ) + if( !bCopy || GetView().isContentExtractionLocked()) rSet.DisableItem( nWhich ); break; diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx index 06ed752d11a3..57b37a1d7ef6 100644 --- a/sw/source/uibase/shells/textsh1.cxx +++ b/sw/source/uibase/shells/textsh1.cxx @@ -1964,6 +1964,13 @@ void SwTextShell::GetState( SfxItemSet &rSet ) rSet.DisableItem(nWhich); } break; + case SID_COPY: + case SID_CUT: + { + if (GetShell().GetView().isContentExtractionLocked()) + rSet.DisableItem(nWhich); + break; + } } nWhich = aIter.NextWhich(); } diff --git a/unotools/source/misc/mediadescriptor.cxx b/unotools/source/misc/mediadescriptor.cxx index 0d0839f62b18..1da5778ab9fe 100644 --- a/unotools/source/misc/mediadescriptor.cxx +++ b/unotools/source/misc/mediadescriptor.cxx @@ -324,6 +324,12 @@ const OUString& MediaDescriptor::PROP_SUGGESTEDSAVEASNAME() return sProp; } +const OUString& MediaDescriptor::PROP_LOCKCONTENTEXTRACTION() +{ + static const OUString sProp("LockContentExtraction"); + return sProp; +} + MediaDescriptor::MediaDescriptor() : SequenceAsHashMap() { |