.gitreview | 2 basctl/source/basicide/baside2.cxx | 4 framework/Library_fwk.mk | 2 framework/inc/uielement/FixedImageToolbarController.hxx | 59 ++ framework/inc/uielement/FixedTextToolbarController.hxx | 55 ++ framework/inc/uielement/togglebuttontoolbarcontroller.hxx | 9 framework/inc/uielement/toolbarmerger.hxx | 2 framework/source/uielement/FixedImageToolbarController.cxx | 114 +++++ framework/source/uielement/FixedTextToolbarController.cxx | 98 ++++ framework/source/uielement/togglebuttontoolbarcontroller.cxx | 44 +- framework/source/uielement/toolbarmerger.cxx | 6 include/oox/crypto/DocumentEncryption.hxx | 4 include/sfx2/sfxsids.hrc | 5 include/sfx2/viewsh.hxx | 5 offapi/com/sun/star/document/MediaDescriptor.idl | 34 + offapi/com/sun/star/frame/XModel2.idl | 5 officecfg/registry/schema/org/openoffice/Office/Common.xcs | 1 oox/source/crypto/DocumentEncryption.cxx | 2 package/source/zippackage/ZipPackage.cxx | 20 sc/source/filter/excel/excel.cxx | 196 +++++++++ scripting/Library_protocolhandler.mk | 4 scripting/java/com/sun/star/script/framework/provider/ScriptEditor.java | 61 ++ scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java | 51 +- scripting/java/com/sun/star/script/framework/provider/javascript/ScriptEditorForJavaScript.java | 8 scripting/source/protocolhandler/scripthandler.cxx | 6 sd/source/filter/sdpptwrp.cxx | 207 +++++++++- sfx2/source/appl/appuno.cxx | 90 ++++ sfx2/source/dialog/filedlghelper.cxx | 9 sfx2/source/doc/objserv.cxx | 27 - sfx2/source/doc/objstor.cxx | 8 sfx2/source/doc/sfxbasemodel.cxx | 25 + sfx2/source/view/viewfrm.cxx | 26 - sfx2/source/view/viewsh.cxx | 45 ++ sw/qa/python/check_xmodel.py | 12 sw/source/filter/ww8/wrtww8.cxx | 102 ++++ sw/source/filter/ww8/wrtww8.hxx | 2 sw/source/filter/ww8/ww8par.cxx | 99 ++++ sw/source/filter/ww8/ww8par.hxx | 4 sw/source/uibase/app/docsh.cxx | 8 vcl/source/app/help.cxx | 4 40 files changed, 1356 insertions(+), 109 deletions(-)
New commits: commit 3ccee9931e3f23ddb67025532f4c954b1064eada Author: Thorsten Behrens <thorsten.behr...@cib.de> AuthorDate: Wed Nov 13 03:53:11 2019 +0100 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:53:11 2019 +0100 .gitreview: Update default branch Change-Id: I91659ecd8b176ea80dfcece63dbfce92f24ff857 diff --git a/.gitreview b/.gitreview index 1e6ce73905e8..fd925839a944 100644 --- a/.gitreview +++ b/.gitreview @@ -3,5 +3,5 @@ host=gerrit.libreoffice.org port=29418 project=core defaultremote=logerrit -defaultbranch=libreoffice-6-3 +defaultbranch=feature/cib_contract3756b commit 21da6f089a090e0963431ff79f8005561d78516d Author: Serge Krot <serge.k...@cib.de> AuthorDate: Fri Nov 8 21:14:28 2019 +0100 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:51:45 2019 +0100 Source code clean up: do not clean up EncryptionData during SaveAs Conflicts: package/source/zippackage/ZipPackage.cxx Change-Id: I1213ec55d6dc42f062930467976de45c73152f0b Reviewed-on: https://gerrit.libreoffice.org/82326 Reviewed-by: Serge Krot (CIB) <serge.k...@cib.de> Tested-by: Serge Krot (CIB) <serge.k...@cib.de> diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx index da9ae6751415..78627441b506 100644 --- a/package/source/zippackage/ZipPackage.cxx +++ b/package/source/zippackage/ZipPackage.cxx @@ -1752,27 +1752,9 @@ void SAL_CALL ZipPackage::setPropertyValue( const OUString& aPropertyName, const // this property is only necessary to support raw passwords in storage API; // because of this support the storage has to operate with more than one key dependent on storage generation algorithm; // when this support is removed, the storage will get only one key from outside - uno::Sequence< beans::NamedValue > aKeys; - if ( !( aValue >>= aKeys ) ) + if ( !( aValue >>= m_aStorageEncryptionKeys ) ) throw IllegalArgumentException(THROW_WHERE, uno::Reference< uno::XInterface >(), 2 ); -/* if ( aKeys.hasElements() ) - { - bool bHasSHA256 = false; - bool bHasSHA1 = false; - for ( sal_Int32 nInd = 0; nInd < aKeys.getLength(); nInd++ ) - { - if ( aKeys[nInd].Name == PACKAGE_ENCRYPTIONDATA_SHA256UTF8 ) - bHasSHA256 = true; - if ( aKeys[nInd].Name == PACKAGE_ENCRYPTIONDATA_SHA1UTF8 ) - bHasSHA1 = true; - } - - if ( !bHasSHA256 && !bHasSHA1 ) - throw IllegalArgumentException(THROW_WHERE "Expected keys are not provided!", uno::Reference< uno::XInterface >(), 2 ); - }*/ - - m_aStorageEncryptionKeys = aKeys; m_aEncryptionKey.realloc( 0 ); } else if ( aPropertyName == ENCRYPTION_ALGORITHMS_PROPERTY ) diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx index 2ae3f9c0b03a..c2bb4abbda1d 100644 --- a/sfx2/source/dialog/filedlghelper.cxx +++ b/sfx2/source/dialog/filedlghelper.cxx @@ -1432,8 +1432,13 @@ ErrCode FileDialogHelper_Impl::execute( std::vector<OUString>& rpURLList, // the password will be set in case user decide so rpSet->ClearItem( SID_PASSWORDINTERACTION ); - rpSet->ClearItem( SID_PASSWORD ); - //rpSet->ClearItem( SID_ENCRYPTIONDATA ); + if (rpSet->HasItem( SID_PASSWORD )) + { + // As the SID_ENCRYPTIONDATA and SID_PASSWORD are using for setting password together, we need to clear them both. + // Note: Do not remove SID_ENCRYPTIONDATA without SID_PASSWORD + rpSet->ClearItem( SID_PASSWORD ); + rpSet->ClearItem( SID_ENCRYPTIONDATA ); + } rpSet->ClearItem( SID_RECOMMENDREADONLY ); rpSet->ClearItem( SID_MODIFYPASSWORDINFO ); diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index 3b61915e99ac..a67f0f92bf91 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -786,22 +786,9 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) } - bool bPreselectPassword = false; const SfxStringItem* pOldPasswordItem = SfxItemSet::GetItem<SfxStringItem>(GetMedium()->GetItemSet(), SID_PASSWORD, false); - if (pOldPasswordItem) - { - bPreselectPassword = true; - } - else - { - const SfxUnoAnyItem* pOldEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(GetMedium()->GetItemSet(), SID_ENCRYPTIONDATA, false); - if (pOldEncryptionDataItem) - { - uno::Sequence< beans::NamedValue > aEncryptionData; - pOldEncryptionDataItem->GetValue() >>= aEncryptionData; - - } - } + const SfxUnoAnyItem* pOldEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(GetMedium()->GetItemSet(), SID_ENCRYPTIONDATA, false); + bool bPreselectPassword = (pOldPasswordItem && pOldEncryptionDataItem); uno::Sequence< beans::PropertyValue > aDispatchArgs; if ( rReq.GetArgs() ) diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index 1bcc6edd15b1..1b3f50712d72 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -2780,11 +2780,13 @@ bool SfxObjectShell::PreDoSaveAs_Impl(const OUString& rFileName, const OUString& std::unique_ptr<SfxAllItemSet> pMergedParams(new SfxAllItemSet( *pMedium->GetItemSet() )); // in "SaveAs" title and password will be cleared ( maybe the new itemset contains new values, otherwise they will be empty ) - //pMergedParams->ClearItem( SID_ENCRYPTIONDATA ); - pMergedParams->ClearItem( SID_PASSWORD ); // #i119366# - As the SID_ENCRYPTIONDATA and SID_PASSWORD are using for setting password together, we need to clear them both. // Also, ( maybe the new itemset contains new values, otherwise they will be empty ) -// pMergedParams->ClearItem( SID_ENCRYPTIONDATA ); + if (pMergedParams->HasItem( SID_PASSWORD )) + { + pMergedParams->ClearItem( SID_PASSWORD ); + pMergedParams->ClearItem( SID_ENCRYPTIONDATA ); + } pMergedParams->ClearItem( SID_DOCINFO_TITLE ); pMergedParams->ClearItem( SID_INPUTSTREAM ); commit 53842c9fe655695f1fc691a5a5f61650bb6bc123 Author: Vasily Melenchuk <vasily.melenc...@cib.de> AuthorDate: Fri Nov 8 21:17:10 2019 +0300 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:49:41 2019 +0100 sd: support for DRM encryption during saving to ppt Change-Id: Id82f8b3fa7ea045b00d7d81e2c9ce5e130c8060c diff --git a/sd/source/filter/sdpptwrp.cxx b/sd/source/filter/sdpptwrp.cxx index bb42b9d4bc11..cc418fd7fc5a 100644 --- a/sd/source/filter/sdpptwrp.cxx +++ b/sd/source/filter/sdpptwrp.cxx @@ -219,8 +219,6 @@ bool SdPPTFilter::Export() if( mxModel.is() ) { - tools::SvRef<SotStorage> xStorRef = new SotStorage( mrMedium.GetOutStream(), false ); - #ifdef DISABLE_DYNLOADING ExportPPTPointer PPTExport = ExportPPT; #else @@ -228,7 +226,7 @@ bool SdPPTFilter::Export() SdFilter::GetLibrarySymbol(mrMedium.GetFilter()->GetUserData(), "ExportPPT")); #endif - if( PPTExport && xStorRef.is() ) + if( PPTExport) { sal_uInt32 nCnvrtFlags = 0; const SvtFilterOptions& rFilterOptions = SvtFilterOptions::Get(); @@ -252,8 +250,105 @@ bool SdPPTFilter::Export() aProperty.Value <<= mrMedium.GetBaseURL( true ); aProperties.push_back( aProperty ); - bRet = PPTExport( aProperties, xStorRef, mxModel, mxStatusIndicator, pBas, nCnvrtFlags ); - xStorRef->Commit(); + SvStream * pOutputStrm = mrMedium.GetOutStream(); + + Sequence< NamedValue > aEncryptionData; + Reference< css::packages::XPackageEncryption > xPackageEncryption; + const SfxUnoAnyItem* pEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(mrMedium.GetItemSet(), SID_ENCRYPTIONDATA, false); + std::shared_ptr<SvStream> pMediaStrm; + if (pEncryptionDataItem && (pEncryptionDataItem->GetValue() >>= aEncryptionData)) + { + ::comphelper::SequenceAsHashMap aHashData(aEncryptionData); + OUString sCryptoType = aHashData.getUnpackedValueOrDefault("CryptoType", OUString()); + + if (sCryptoType.getLength()) + { + Reference<XComponentContext> xComponentContext(comphelper::getProcessComponentContext()); + Sequence<Any> aArguments; + xPackageEncryption.set( + xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.oox.crypto." + sCryptoType, aArguments, xComponentContext), UNO_QUERY); + + if (xPackageEncryption.is()) + { + // We have an encryptor. Export document into memory stream and encrypt it later + pMediaStrm.reset(new SvMemoryStream()); + pOutputStrm = pMediaStrm.get(); + + // Temp removal of EncryptionData to avoid password protection triggering + mrMedium.GetItemSet()->ClearItem(SID_ENCRYPTIONDATA); + } + } + } + + tools::SvRef<SotStorage> xStorRef = new SotStorage(pOutputStrm, false); + + if (xStorRef.is()) + { + bRet = PPTExport(aProperties, xStorRef, mxModel, mxStatusIndicator, pBas, nCnvrtFlags); + xStorRef->Commit(); + + if (xPackageEncryption.is()) + { + // Perform DRM encryption + pOutputStrm->Seek(0); + + xPackageEncryption->setupEncryption(aEncryptionData); + + Reference<css::io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(pOutputStrm, false)); + Sequence<NamedValue> aStreams = xPackageEncryption->encrypt(xInputStream); + + tools::SvRef<SotStorage> xEncryptedRootStrg = new SotStorage(mrMedium.GetOutStream(), false); + for (const NamedValue & aStreamData : aStreams) + { + // To avoid long paths split and open substorages recursively + // Splitting paths manually, since comphelper::string::split is trimming special characters like \0x01, \0x09 + SotStorage * pStorage = xEncryptedRootStrg.get(); + OUString sFileName; + sal_Int32 idx = 0; + do + { + OUString sPathElem = aStreamData.Name.getToken(0, L'/', idx); + if (!sPathElem.isEmpty()) + { + if (idx < 0) + { + sFileName = sPathElem; + } + else + { + pStorage = pStorage->OpenSotStorage(sPathElem); + } + } + } while (pStorage && idx >= 0); + + if (!pStorage) + { + bRet = false; + break; + } + + SotStorageStream* pStream = pStorage->OpenSotStream(sFileName); + if (!pStream) + { + bRet = false; + break; + } + Sequence<sal_Int8> aStreamContent; + aStreamData.Value >>= aStreamContent; + size_t nBytesWritten = pStream->WriteBytes(aStreamContent.getArray(), aStreamContent.getLength()); + if (nBytesWritten != aStreamContent.getLength()) + { + bRet = false; + break; + } + } + xEncryptedRootStrg->Commit(); + + // Restore encryption data + mrMedium.GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, makeAny(aEncryptionData))); + } + } } } commit 50ca3b15c2163c1f5ead027d152c872ed83bc8b2 Author: Vasily Melenchuk <vasily.melenc...@cib.de> AuthorDate: Fri Nov 8 21:00:12 2019 +0300 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:49:40 2019 +0100 sd: support of DRM encrypted ppt files reading Change-Id: Ib91538d53ee1f53a3cd14a44d47fd6f6136c0472 diff --git a/sd/source/filter/sdpptwrp.cxx b/sd/source/filter/sdpptwrp.cxx index edc21c482d45..bb42b9d4bc11 100644 --- a/sd/source/filter/sdpptwrp.cxx +++ b/sd/source/filter/sdpptwrp.cxx @@ -23,6 +23,10 @@ #include <svx/svxerr.hxx> #include <unotools/fltrcfg.hxx> #include <sot/storage.hxx> +#include <comphelper/sequenceashashmap.hxx> + +#include <com/sun/star/packages/XPackageEncryption.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> #include <sdpptwrp.hxx> #include <DrawDocShell.hxx> @@ -67,9 +71,101 @@ SdPPTFilter::~SdPPTFilter() delete pBas; // deleting the compressed basic storage } +static void lcl_getListOfStreams(SotStorage * pStorage, comphelper::SequenceAsHashMap& aStreamsData, const OUString& sPrefix) +{ + SvStorageInfoList aElements; + pStorage->FillInfoList(&aElements); + for (const auto & aElement : aElements) + { + OUString sStreamFullName = sPrefix.getLength() ? sPrefix + "/" + aElement.GetName() : aElement.GetName(); + if (aElement.IsStorage()) + { + SotStorage * pSubStorage = pStorage->OpenSotStorage(aElement.GetName(), StreamMode::STD_READ | StreamMode::SHARE_DENYALL); + lcl_getListOfStreams(pSubStorage, aStreamsData, sStreamFullName); + } + else + { + // Read stream + tools::SvRef<SotStorageStream> rStream = pStorage->OpenSotStream(aElement.GetName(), StreamMode::READ | StreamMode::SHARE_DENYALL); + assert(rStream.is()); + + sal_Int32 nStreamSize = rStream->GetSize(); + Sequence< sal_Int8 > oData; + oData.realloc(nStreamSize); + sal_Int32 nReadBytes = rStream->ReadBytes(oData.getArray(), nStreamSize); + assert(nStreamSize == nReadBytes); + aStreamsData[sStreamFullName] <<= oData; + } + } +} + +static tools::SvRef<SotStorage> lcl_DRMDecrypt(SfxMedium& rMedium, tools::SvRef<SotStorage>& rStorage, std::shared_ptr<SvStream>& rNewStorageStrm) +{ + tools::SvRef<SotStorage> aNewStorage; + + // We have DRM encrypted storage. We should try to decrypt it first, if we can + Sequence< Any > aArguments; + Reference<XComponentContext> xComponentContext(comphelper::getProcessComponentContext()); + Reference< css::packages::XPackageEncryption > xPackageEncryption( + xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.oox.crypto.DRMDataSpace", aArguments, xComponentContext), UNO_QUERY); + + if (!xPackageEncryption.is()) + { + // We do not know how to decrypt this + return aNewStorage; + } + + std::vector<OUString> aStreamsList; + comphelper::SequenceAsHashMap aStreamsData; + lcl_getListOfStreams(rStorage.get(), aStreamsData, OUString("")); + + try { + Sequence<NamedValue> aStreams = aStreamsData.getAsConstNamedValueList(); + if (!xPackageEncryption->readEncryptionInfo(aStreams)) + { + // We failed with decryption + return aNewStorage; + } + + tools::SvRef<SotStorageStream> rContentStream = rStorage->OpenSotStream("\011DRMContent", StreamMode::READ | StreamMode::SHARE_DENYALL); + if (!rContentStream.is()) + { + return aNewStorage; + } + + rNewStorageStrm.reset(new SvMemoryStream()); + + Reference<css::io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(rContentStream.get(), false)); + Reference<css::io::XOutputStream > xDecryptedStream(new utl::OSeekableOutputStreamWrapper(*rNewStorageStrm.get())); + + if (!xPackageEncryption->decrypt(xInputStream, xDecryptedStream)) + { + // We failed with decryption + return aNewStorage; + } + + rNewStorageStrm->Seek(0); + + // Further reading is done from new document + aNewStorage = new SotStorage(*rNewStorageStrm); + + // Set the media descriptor data + Sequence<NamedValue> aEncryptionData = xPackageEncryption->createEncryptionData(""); + rMedium.GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, makeAny(aEncryptionData))); + } + catch (const std::exception&) + { + return aNewStorage; + } + + return aNewStorage; +} + bool SdPPTFilter::Import() { bool bRet = false; + std::shared_ptr<SvStream> aDecryptedStorageStrm; tools::SvRef<SotStorage> pStorage = new SotStorage( mrMedium.GetInStream(), false ); if( !pStorage->GetError() ) { @@ -82,6 +178,12 @@ bool SdPPTFilter::Import() xDualStorage = pStorage->OpenSotStorage( sDualStorage, StreamMode::STD_READ ); pStorage = xDualStorage; } + OUString sDRMContent("\011DRMContent"); + if (pStorage->IsContained(sDRMContent)) + { + // Document is DRM encrypted + pStorage = lcl_DRMDecrypt(mrMedium, pStorage, aDecryptedStorageStrm); + } std::unique_ptr<SvStream> pDocStream(pStorage->OpenSotStream( "PowerPoint Document" , StreamMode::STD_READ )); if( pDocStream ) { commit 6ee8512387c4c53e9a3730bd386b1226c6d37bd1 Author: Vasily Melenchuk <vasily.melenc...@cib.de> AuthorDate: Fri Nov 8 18:28:41 2019 +0300 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:49:38 2019 +0100 calc: support for writing DRM encrypted xls files Change-Id: I5faf885cf494becca2838c6493413bcc56e91826 diff --git a/sc/source/filter/excel/excel.cxx b/sc/source/filter/excel/excel.cxx index 56adce29a061..2e4015e34569 100644 --- a/sc/source/filter/excel/excel.cxx +++ b/sc/source/filter/excel/excel.cxx @@ -24,7 +24,7 @@ #include <sot/exchange.hxx> #include <filter/msfilter/classids.hxx> #include <tools/globname.hxx> -#include <com/sun/star/packages/XPAckageEncryption.hpp> +#include <com/sun/star/packages/XPackageEncryption.hpp> #include <com/sun/star/ucb/ContentCreationException.hpp> #include <com/sun/star/uno/XComponentContext.hpp> #include <unotools/streamwrap.hxx> @@ -248,6 +248,36 @@ ErrCode ScFormatFilterPluginImpl::ScImportExcel( SfxMedium& rMedium, ScDocument* static ErrCode lcl_ExportExcelBiff( SfxMedium& rMedium, ScDocument *pDocument, SvStream* pMedStrm, bool bBiff8, rtl_TextEncoding eNach ) { + uno::Reference< packages::XPackageEncryption > xPackageEncryption; + uno::Sequence< beans::NamedValue > aEncryptionData; + const SfxUnoAnyItem* pEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(rMedium.GetItemSet(), SID_ENCRYPTIONDATA, false); + SvStream* pOriginalMediaStrm = pMedStrm; + std::shared_ptr<SvStream> pMediaStrm; + if (pEncryptionDataItem && (pEncryptionDataItem->GetValue() >>= aEncryptionData)) + { + ::comphelper::SequenceAsHashMap aHashData(aEncryptionData); + OUString sCryptoType = aHashData.getUnpackedValueOrDefault("CryptoType", OUString()); + + if (sCryptoType.getLength()) + { + uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext()); + uno::Sequence<uno::Any> aArguments; + xPackageEncryption.set( + xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.oox.crypto." + sCryptoType, aArguments, xComponentContext), uno::UNO_QUERY); + + if (xPackageEncryption.is()) + { + // We have an encryptor. Export document into memory stream and encrypt it later + pMediaStrm.reset(new SvMemoryStream()); + pMedStrm = pMediaStrm.get(); + + // Temp removal of EncryptionData to avoid password protection triggering + rMedium.GetItemSet()->ClearItem(SID_ENCRYPTIONDATA); + } + } + } + // try to open an OLE storage tools::SvRef<SotStorage> xRootStrg = new SotStorage( pMedStrm, false ); if( xRootStrg->GetError() ) return SCERR_IMPORT_OPEN; @@ -296,6 +326,67 @@ static ErrCode lcl_ExportExcelBiff( SfxMedium& rMedium, ScDocument *pDocument, xStrgStrm->Commit(); xRootStrg->Commit(); + if (xPackageEncryption.is()) + { + // Perform DRM encryption + pMedStrm->Seek(0); + + xPackageEncryption->setupEncryption(aEncryptionData); + + uno::Reference<io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(pMedStrm, false)); + uno::Sequence<beans::NamedValue> aStreams = xPackageEncryption->encrypt(xInputStream); + + tools::SvRef<SotStorage> xEncryptedRootStrg = new SotStorage(pOriginalMediaStrm, false); + for (const beans::NamedValue & aStreamData : aStreams) + { + // To avoid long paths split and open substorages recursively + // Splitting paths manually, since comphelper::string::split is trimming special characters like \0x01, \0x09 + SotStorage * pStorage = xEncryptedRootStrg.get(); + OUString sFileName; + sal_Int32 idx = 0; + do + { + OUString sPathElem = aStreamData.Name.getToken(0, L'/', idx); + if (!sPathElem.isEmpty()) + { + if (idx < 0) + { + sFileName = sPathElem; + } + else + { + pStorage = pStorage->OpenSotStorage(sPathElem); + } + } + } while (pStorage && idx >= 0); + + if (!pStorage) + { + eRet = ERRCODE_IO_GENERAL; + break; + } + + SotStorageStream* pStream = pStorage->OpenSotStream(sFileName); + if (!pStream) + { + eRet = ERRCODE_IO_GENERAL; + break; + } + uno::Sequence<sal_Int8> aStreamContent; + aStreamData.Value >>= aStreamContent; + size_t nBytesWritten = pStream->WriteBytes(aStreamContent.getArray(), aStreamContent.getLength()); + if (nBytesWritten != aStreamContent.getLength()) + { + eRet = ERRCODE_IO_CANTWRITE; + break; + } + } + xEncryptedRootStrg->Commit(); + + // Restore encryption data + rMedium.GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, uno::makeAny(aEncryptionData))); + } + return eRet; } commit 9075e5d7b5249242f43bf723080a0f4e24ea93d7 Author: Vasily Melenchuk <vasily.melenc...@cib.de> AuthorDate: Fri Nov 8 17:53:30 2019 +0300 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:49:37 2019 +0100 calc: support for reading DRM encrypted xls files DRM encryption is implemented as an optional service, so just use it when available. Change-Id: Ie580e5c12c48ccf99f9a932b1c66eb35866b7ef4 diff --git a/sc/source/filter/excel/excel.cxx b/sc/source/filter/excel/excel.cxx index ca87efc2988c..56adce29a061 100644 --- a/sc/source/filter/excel/excel.cxx +++ b/sc/source/filter/excel/excel.cxx @@ -24,7 +24,9 @@ #include <sot/exchange.hxx> #include <filter/msfilter/classids.hxx> #include <tools/globname.hxx> +#include <com/sun/star/packages/XPAckageEncryption.hpp> #include <com/sun/star/ucb/ContentCreationException.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> #include <unotools/streamwrap.hxx> #include <osl/diagnose.h> #include <filter.hxx> @@ -32,6 +34,8 @@ #include <xistream.hxx> #include <xltools.hxx> #include <docoptio.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/processfactory.hxx> #include <docsh.hxx> #include <scerrors.hxx> @@ -42,6 +46,99 @@ #include <memory> +using namespace css; + +static void lcl_getListOfStreams(SotStorage * pStorage, comphelper::SequenceAsHashMap& aStreamsData, const OUString& sPrefix) +{ + SvStorageInfoList aElements; + pStorage->FillInfoList(&aElements); + for (const auto & aElement : aElements) + { + OUString sStreamFullName = sPrefix.getLength() ? sPrefix + "/" + aElement.GetName() : aElement.GetName(); + if (aElement.IsStorage()) + { + SotStorage * pSubStorage = pStorage->OpenSotStorage(aElement.GetName(), StreamMode::STD_READ | StreamMode::SHARE_DENYALL); + lcl_getListOfStreams(pSubStorage, aStreamsData, sStreamFullName); + } + else + { + // Read stream + tools::SvRef<SotStorageStream> rStream = pStorage->OpenSotStream(aElement.GetName(), StreamMode::READ | StreamMode::SHARE_DENYALL); + assert(rStream.is()); + + sal_Int32 nStreamSize = rStream->GetSize(); + uno::Sequence< sal_Int8 > oData; + oData.realloc(nStreamSize); + sal_Int32 nReadBytes = rStream->ReadBytes(oData.getArray(), nStreamSize); + assert(nStreamSize == nReadBytes); + aStreamsData[sStreamFullName] <<= oData; + } + } +} + +static tools::SvRef<SotStorage> lcl_DRMDecrypt(SfxMedium& rMedium, tools::SvRef<SotStorage>& rStorage, std::shared_ptr<SvStream>& rNewStorageStrm) +{ + tools::SvRef<SotStorage> aNewStorage; + + // We have DRM encrypted storage. We should try to decrypt it first, if we can + uno::Sequence< uno::Any > aArguments; + uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext()); + uno::Reference< packages::XPackageEncryption > xPackageEncryption( + xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.oox.crypto.DRMDataSpace", aArguments, xComponentContext), uno::UNO_QUERY); + + if (!xPackageEncryption.is()) + { + // We do not know how to decrypt this + return aNewStorage; + } + + std::vector<OUString> aStreamsList; + comphelper::SequenceAsHashMap aStreamsData; + lcl_getListOfStreams(rStorage.get(), aStreamsData, OUString("")); + + try { + uno::Sequence<beans::NamedValue> aStreams = aStreamsData.getAsConstNamedValueList(); + if (!xPackageEncryption->readEncryptionInfo(aStreams)) + { + // We failed with decryption + return aNewStorage; + } + + tools::SvRef<SotStorageStream> rContentStream = rStorage->OpenSotStream("\011DRMContent", StreamMode::READ | StreamMode::SHARE_DENYALL); + if (!rContentStream.is()) + { + return aNewStorage; + } + + rNewStorageStrm.reset(new SvMemoryStream()); + + uno::Reference<io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(rContentStream.get(), false)); + uno::Reference<io::XOutputStream > xDecryptedStream(new utl::OSeekableOutputStreamWrapper(*rNewStorageStrm.get())); + + if (!xPackageEncryption->decrypt(xInputStream, xDecryptedStream)) + { + // We failed with decryption + return aNewStorage; + } + + rNewStorageStrm->Seek(0); + + // Further reading is done from new document + aNewStorage = new SotStorage(*rNewStorageStrm); + + // Set the media descriptor data + uno::Sequence<beans::NamedValue> aEncryptionData = xPackageEncryption->createEncryptionData(""); + rMedium.GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, uno::makeAny(aEncryptionData))); + } + catch (const std::exception&) + { + return aNewStorage; + } + + return aNewStorage; +} + ErrCode ScFormatFilterPluginImpl::ScImportExcel( SfxMedium& rMedium, ScDocument* pDocument, const EXCIMPFORMAT eFormat ) { // check the passed Calc document @@ -67,6 +164,7 @@ ErrCode ScFormatFilterPluginImpl::ScImportExcel( SfxMedium& rMedium, ScDocument* // try to open an OLE storage tools::SvRef<SotStorage> xRootStrg; tools::SvRef<SotStorageStream> xStrgStrm; + std::shared_ptr<SvStream> aNewStorageStrm; if( SotStorage::IsStorageFile( pMedStrm ) ) { xRootStrg = new SotStorage( pMedStrm, false ); @@ -77,6 +175,13 @@ ErrCode ScFormatFilterPluginImpl::ScImportExcel( SfxMedium& rMedium, ScDocument* // try to open "Book" or "Workbook" stream in OLE storage if( xRootStrg.is() ) { + // Check if there is DRM encryption in storage + tools::SvRef<SotStorageStream> xDRMStrm = ScfTools::OpenStorageStreamRead(xRootStrg, "\011DRMContent"); + if (xDRMStrm.is()) + { + xRootStrg = lcl_DRMDecrypt(rMedium, xRootStrg, aNewStorageStrm); + } + // try to open the "Book" stream tools::SvRef<SotStorageStream> xBookStrm = ScfTools::OpenStorageStreamRead( xRootStrg, EXC_STREAM_BOOK ); XclBiff eBookBiff = xBookStrm.is() ? XclImpStream::DetectBiffVersion( *xBookStrm ) : EXC_BIFF_UNKNOWN; commit 468c34e74c4bd4e06c49443c38c371c26a4586fa Author: Vasily Melenchuk <vasily.melenc...@cib.de> AuthorDate: Thu Nov 7 11:13:49 2019 +0300 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:49:36 2019 +0100 ms doc: support for saving into binary doc with custom encryption if we have custome encryption data in media descriptor EncryptionData and corresponding service is available it will be used durng saving. Change-Id: I814e4a7f73979ff7a65831b99f77f1a9e85916de diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx index 91be4679ff4d..a87ea862bfd4 100644 --- a/sw/source/filter/ww8/wrtww8.cxx +++ b/sw/source/filter/ww8/wrtww8.cxx @@ -22,6 +22,8 @@ #include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/packages/XPackageEncryption.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> #include <unotools/ucbstreamhelper.hxx> #include <algorithm> #include <map> @@ -93,6 +95,7 @@ #include "sprmids.hxx" #include <comphelper/sequenceashashmap.hxx> +#include <comphelper/string.hxx> #include "writerhelper.hxx" #include "writerwordglue.hxx" #include "ww8attributeoutput.hxx" @@ -3541,6 +3544,105 @@ void WW8Export::PrepareStorage() ErrCode SwWW8Writer::WriteStorage() { + tools::SvRef<SotStorage> pOrigStg; + uno::Reference< packages::XPackageEncryption > xPackageEncryption; + std::shared_ptr<SvStream> pSotStorageStream; + uno::Sequence< beans::NamedValue > aEncryptionData; + if (mpMedium) + { + // Check for specific encryption requests + const SfxUnoAnyItem* pEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(mpMedium->GetItemSet(), SID_ENCRYPTIONDATA, false); + if (pEncryptionDataItem && (pEncryptionDataItem->GetValue() >>= aEncryptionData)) + { + ::comphelper::SequenceAsHashMap aHashData(aEncryptionData); + OUString sCryptoType = aHashData.getUnpackedValueOrDefault("CryptoType", OUString()); + + if (sCryptoType.getLength()) + { + uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext()); + uno::Sequence<uno::Any> aArguments; + xPackageEncryption.set( + xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.oox.crypto." + sCryptoType, aArguments, xComponentContext), uno::UNO_QUERY); + + if (xPackageEncryption.is()) + { + // We have an encryptor + // Create new temporary storage for content + pOrigStg = pStg; + pSotStorageStream.reset(new SvMemoryStream()); + pStg = new SotStorage(*pSotStorageStream); + } + } + } + } + + ErrCode nErrorCode = WriteStorageImpl(); + + if (xPackageEncryption.is()) + { + pStg->Commit(); + pSotStorageStream->Seek(0); + + // Encrypt data written into temporary storage + xPackageEncryption->setupEncryption(aEncryptionData); + + uno::Reference<io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(pSotStorageStream.get(), false)); + uno::Sequence<beans::NamedValue> aStreams = xPackageEncryption->encrypt(xInputStream); + + pStg = pOrigStg; + for (const beans::NamedValue & aStreamData : aStreams) + { + // To avoid long paths split and open substorages recursively + // Splitting paths manually, since comphelper::string::split is trimming special characters like \0x01, \0x09 + SotStorage * pStorage = pStg.get(); + OUString sFileName; + sal_Int32 idx = 0; + do + { + OUString sPathElem = aStreamData.Name.getToken(0, L'/', idx); + if (!sPathElem.isEmpty()) + { + if (idx < 0) + { + sFileName = sPathElem; + } + else + { + pStorage = pStorage->OpenSotStorage(sPathElem); + if (!pStorage) + break; + } + } + } while (pStorage && idx >= 0); + + if (!pStorage) + { + nErrorCode = ERRCODE_IO_GENERAL; + break; + } + + SotStorageStream* pStream = pStorage->OpenSotStream(sFileName); + if (!pStream) + { + nErrorCode = ERRCODE_IO_GENERAL; + break; + } + uno::Sequence<sal_Int8> aStreamContent; + aStreamData.Value >>= aStreamContent; + size_t nBytesWritten = pStream->WriteBytes(aStreamContent.getArray(), aStreamContent.getLength()); + if (nBytesWritten != aStreamContent.getLength()) + { + nErrorCode = ERRCODE_IO_CANTWRITE; + break; + } + } + } + + return nErrorCode; +} +ErrCode SwWW8Writer::WriteStorageImpl() +{ // #i34818# - update layout (if present), for SwWriteTable SwViewShell* pViewShell = m_pDoc->getIDocumentLayoutAccess().GetCurrentViewShell(); if( pViewShell != nullptr ) diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index f72302f88538..04e485e39708 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -913,7 +913,6 @@ friend void WW8_WrtRedlineAuthor::Write(Writer &rWrt); WW8Export *m_pExport; SfxMedium *mpMedium; - public: SwWW8Writer(const OUString& rFltName, const OUString& rBaseURL); virtual ~SwWW8Writer() override; @@ -958,6 +957,7 @@ public: private: SwWW8Writer(const SwWW8Writer&) = delete; SwWW8Writer& operator=(const SwWW8Writer&) = delete; + ErrCode WriteStorageImpl(); }; /// Exporter of the binary Word file formats. commit 85e49fbb9eaf730bffd556bd989a512bbedf2d9a Author: Vasily Melenchuk <vasily.melenc...@cib.de> AuthorDate: Mon Oct 28 14:23:36 2019 +0300 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:49:34 2019 +0100 sw: support for DRM encryption for binary doc formats DRM encryption is implemented as a service and desrption will be called if we found corresponding streams inside binary OLE package. Change-Id: Ie1a5b0417e1e7851b24d410c8f41dc85dd9210f7 Reviewed-on: https://gerrit.libreoffice.org/81600 Reviewed-by: Vasily Melenchuk <vasily.melenc...@cib.de> Tested-by: Vasily Melenchuk <vasily.melenc...@cib.de> diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index 1f823bcf9251..894558a445fd 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -25,12 +25,14 @@ #include <com/sun/star/embed/Aspects.hpp> #include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/packages/XPAckageEncryption.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <i18nlangtag/languagetag.hxx> #include <unotools/configmgr.hxx> #include <unotools/ucbstreamhelper.hxx> +#include <unotools/streamwrap.hxx> #include <rtl/random.h> #include <rtl/ustring.hxx> #include <rtl/ustrbuf.hxx> @@ -6305,6 +6307,95 @@ ErrCode WW8Reader::OpenMainStream( tools::SvRef<SotStorageStream>& rRef, sal_uIn return nRet; } +void lcl_getListOfStreams(SotStorage * pStorage, comphelper::SequenceAsHashMap& aStreamsData, const OUString& sPrefix) +{ + SvStorageInfoList aElements; + pStorage->FillInfoList(&aElements); + for (const auto & aElement : aElements) + { + OUString sStreamFullName = sPrefix.getLength() ? sPrefix + "/" + aElement.GetName() : aElement.GetName(); + if (aElement.IsStorage()) + { + SotStorage * pSubStorage = pStorage->OpenSotStorage(aElement.GetName(), StreamMode::STD_READ | StreamMode::SHARE_DENYALL); + lcl_getListOfStreams(pSubStorage, aStreamsData, sStreamFullName); + } + else + { + // Read stream + tools::SvRef<SotStorageStream> rStream = pStorage->OpenSotStream(aElement.GetName(), StreamMode::READ | StreamMode::SHARE_DENYALL); + assert(rStream.is()); + + sal_Int32 nStreamSize = rStream->GetSize(); + css::uno::Sequence< sal_Int8 > oData; + oData.realloc(nStreamSize); + sal_Int32 nReadBytes = rStream->ReadBytes(oData.getArray(), nStreamSize); + assert(nStreamSize == nReadBytes); + aStreamsData[sStreamFullName] <<= oData; + } + } +} + +ErrCode WW8Reader::DecryptDRMPackage() +{ + // We have DRM encrypted storage. We should try to decrypt it first, if we can + uno::Sequence< uno::Any > aArguments; + uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext()); + uno::Reference< packages::XPackageEncryption > xPackageEncryption( + xComponentContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.oox.crypto.DRMDataSpace", aArguments, xComponentContext), uno::UNO_QUERY); + + if (!xPackageEncryption.is()) + { + // We do not know how to decrypt this + return ERRCODE_IO_ACCESSDENIED; + } + + std::vector<OUString> aStreamsList; + comphelper::SequenceAsHashMap aStreamsData; + lcl_getListOfStreams(m_pStorage.get(), aStreamsData, OUString("")); + + try { + uno::Sequence<beans::NamedValue> aStreams = aStreamsData.getAsConstNamedValueList(); + if (!xPackageEncryption->readEncryptionInfo(aStreams)) + { + // We failed with decryption + return ERRCODE_IO_ACCESSDENIED; + } + + tools::SvRef<SotStorageStream> rContentStream = m_pStorage->OpenSotStream("\011DRMContent", StreamMode::READ | StreamMode::SHARE_DENYALL); + if (!rContentStream.is()) + { + return ERRCODE_IO_NOTEXISTS; + } + + mDecodedStream.reset(new SvMemoryStream()); + + uno::Reference<io::XInputStream > xInputStream(new utl::OSeekableInputStreamWrapper(rContentStream.get(), false)); + uno::Reference<io::XOutputStream > xDecryptedStream(new utl::OSeekableOutputStreamWrapper(*mDecodedStream.get())); + + if (!xPackageEncryption->decrypt(xInputStream, xDecryptedStream)) + { + // We failed with decryption + return ERRCODE_IO_ACCESSDENIED; + } + + mDecodedStream->Seek(0); + + // Further reading is done from new document + m_pStorage = new SotStorage(*mDecodedStream); + + // Set the media descriptor data + uno::Sequence<beans::NamedValue> aEncryptionData = xPackageEncryption->createEncryptionData(""); + m_pMedium->GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, uno::makeAny(aEncryptionData))); + } + catch (const std::exception&) + { + return ERRCODE_IO_ACCESSDENIED; + } + + return ERRCODE_NONE; +} + ErrCode WW8Reader::Read(SwDoc &rDoc, const OUString& rBaseURL, SwPaM &rPaM, const OUString & /* FileName */) { sal_uInt16 nOldBuffSize = 32768; @@ -6336,7 +6427,13 @@ ErrCode WW8Reader::Read(SwDoc &rDoc, const OUString& rBaseURL, SwPaM &rPaM, cons if( m_pStorage.is() ) { - nRet = OpenMainStream( refStrm, nOldBuffSize ); + // Check if we have special encrypted content + tools::SvRef<SotStorageStream> rRef = m_pStorage->OpenSotStream("\006DataSpaces/DataSpaceInfo/\011DRMDataSpace", StreamMode::READ | StreamMode::SHARE_DENYALL); + if (rRef.is()) + { + nRet = DecryptDRMPackage(); + } + nRet = OpenMainStream(refStrm, nOldBuffSize); pIn = refStrm.get(); } else diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx index aa17d06cf506..359339d0cac2 100644 --- a/sw/source/filter/ww8/ww8par.hxx +++ b/sw/source/filter/ww8/ww8par.hxx @@ -131,9 +131,13 @@ struct WW8LFOInfo; class WW8Reader : public StgReader { + std::shared_ptr<SvStream> mDecodedStream; virtual ErrCode Read(SwDoc &, const OUString& rBaseURL, SwPaM &, const OUString &) override; ErrCode OpenMainStream( tools::SvRef<SotStorageStream>& rRef, sal_uInt16& rBuffSize ); + ErrCode DecryptDRMPackage(); public: + WW8Reader() {} + ~WW8Reader() {} virtual SwReaderType GetReaderType() override; virtual bool HasGlossaries() const override; commit accf32693fb84e1ffae642bfc087e342a048b75c Author: Serge Krot <serge.k...@cib.de> AuthorDate: Fri Nov 8 17:31:49 2019 +0100 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:49:33 2019 +0100 Switch to read-only mode: do not force reload document if possible Change-Id: I5f83e7626e58cb4b558b54130b725b1041b7142f Reviewed-on: https://gerrit.libreoffice.org/82313 Reviewed-by: Serge Krot (CIB) <serge.k...@cib.de> Tested-by: Serge Krot (CIB) <serge.k...@cib.de> diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx old mode 100644 new mode 100755 index 1f4b4ef71a21..96f96223276a --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -434,6 +434,8 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) || pVersionItem ) // <- tdf#82744 { + bNeedsReload = true; + bool bOK = false; bool bRetryIgnoringLock = false; bool bOpenTemplate = false; @@ -550,7 +552,7 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) } } - rReq.AppendItem( SfxBoolItem( SID_FORCERELOAD, true) ); + rReq.AppendItem( SfxBoolItem( SID_FORCERELOAD, bNeedsReload) ); rReq.AppendItem( SfxBoolItem( SID_SILENT, true )); [[fallthrough]]; //TODO ??? commit fbbc014427a2d0111b8a9d4f84e2678ce9bd1c96 Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> AuthorDate: Mon Nov 11 14:53:51 2019 +0100 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:49:31 2019 +0100 Fix macro disabling in Basic IDE After 8d69ca60f3c8f53699986f924291a2acda5694a1 macros were always disabled as ScriptDocument::allowMacros always returned false when called from non-document context. Change-Id: Ibef4c7d561f4ee01cd44f5327e4ab948282bb07d Reviewed-on: https://gerrit.libreoffice.org/82444 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> diff --git a/basctl/source/basicide/baside2.cxx b/basctl/source/basicide/baside2.cxx index 4ee60fb48146..e9bdd7704613 100644 --- a/basctl/source/basicide/baside2.cxx +++ b/basctl/source/basicide/baside2.cxx @@ -60,6 +60,7 @@ #include <toolkit/helper/vclunohelper.hxx> #include <cassert> #include <osl/diagnose.h> +#include <officecfg/Office/Common.hxx> namespace basctl { @@ -302,7 +303,8 @@ void ModulWindow::BasicExecute() { // #116444# check security settings before macro execution ScriptDocument aDocument( GetDocument() ); - if (!aDocument.allowMacros()) + bool bMacrosDisabled = officecfg::Office::Common::Security::Scripting::DisableMacrosExecution::get(); + if (bMacrosDisabled || (aDocument.isDocument() && !aDocument.allowMacros())) { std::unique_ptr<weld::MessageDialog> xBox( Application::CreateMessageDialog(GetFrameWeld(), VclMessageType::Warning, commit 82515ed29f27cbd892461f195d8c69d31242150a Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> AuthorDate: Mon Oct 28 16:01:15 2019 +0100 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:46:14 2019 +0100 tdf#128418 Fix crash in print preview Change-Id: I2a8c5511563ac3205722d63f22cde472a8aaddde Reviewed-on: https://gerrit.libreoffice.org/81610 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> Conflicts: sw/source/uibase/app/docsh.cxx diff --git a/sw/source/uibase/app/docsh.cxx b/sw/source/uibase/app/docsh.cxx index 96c7634ea5c3..05b8de79eaa6 100644 --- a/sw/source/uibase/app/docsh.cxx +++ b/sw/source/uibase/app/docsh.cxx @@ -1059,7 +1059,7 @@ void SwDocShell::GetState(SfxItemSet& rSet) case FN_OUTLINE_TO_IMPRESS: { SvtModuleOptions aMOpt; - if ( !aMOpt.IsImpress() ) + if (!aMOpt.IsImpress() || (GetViewShell() && GetViewShell()->isExportLocked())) rSet.DisableItem( nWhich ); } [[fallthrough]]; @@ -1081,12 +1081,14 @@ void SwDocShell::GetState(SfxItemSet& rSet) break; case FN_NEW_GLOBAL_DOC: - if ( dynamic_cast< const SwGlobalDocShell *>( this ) != nullptr ) + if (dynamic_cast<const SwGlobalDocShell*>(this) != nullptr + || (GetViewShell() && GetViewShell()->isExportLocked())) rSet.DisableItem( nWhich ); break; case FN_NEW_HTML_DOC: - if( dynamic_cast< const SwWebDocShell *>( this ) != nullptr ) + if (dynamic_cast<const SwWebDocShell*>(this) != nullptr + || (GetViewShell() && GetViewShell()->isExportLocked())) rSet.DisableItem( nWhich ); break; commit 1e15a14103adccc858e3058ec11981aa36037671 Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> AuthorDate: Tue Nov 5 09:17:41 2019 +0100 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:44:39 2019 +0100 Fix option to disable macros so that it indeeds disables any macro execution. Before, you could still add macros to the toolbar and execute them from there (and probably many more places). Now, if this option is set, any macro will no longer be executed. This includes Javascript, Beanshell and Python scripts Change-Id: Icfa845e836782c8e1b670a67694f79a60ad74fad Reviewed-on: https://gerrit.libreoffice.org/82052 Reviewed-by: Serge Krot (CIB) <serge.k...@cib.de> Tested-by: Serge Krot (CIB) <serge.k...@cib.de> diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs index 6d54c8159706..be114e23637d 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs @@ -2692,6 +2692,7 @@ <prop oor:name="DisableMacrosExecution" oor:type="xs:boolean" oor:nillable="false"> <info> <desc>Specifies whether the macro execution is disabled in general. + This will disable Basic, Beanshell, Javascript and Python scripts. If it is set to true, the "MacroSecurityLevel" is ignored. If it is set to false, the mentioned entry specified the level of macro security.</desc> diff --git a/scripting/Library_protocolhandler.mk b/scripting/Library_protocolhandler.mk index e140bb322008..ce9b77ca2f63 100644 --- a/scripting/Library_protocolhandler.mk +++ b/scripting/Library_protocolhandler.mk @@ -20,6 +20,10 @@ $(eval $(call gb_Library_use_external,protocolhandler,boost_headers)) $(eval $(call gb_Library_use_sdk_api,protocolhandler)) +$(eval $(call gb_Library_use_custom_headers,protocolhandler,\ + officecfg/registry \ +)) + $(eval $(call gb_Library_use_libraries,protocolhandler,\ comphelper \ cppu \ diff --git a/scripting/source/protocolhandler/scripthandler.cxx b/scripting/source/protocolhandler/scripthandler.cxx index 2c76bac59697..6852ae59270a 100644 --- a/scripting/source/protocolhandler/scripthandler.cxx +++ b/scripting/source/protocolhandler/scripthandler.cxx @@ -46,6 +46,7 @@ #include <cppuhelper/exc_hlp.hxx> #include <cppuhelper/supportsservice.hxx> #include <framework/documentundoguard.hxx> +#include <officecfg/Office/Common.hxx> #include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/uri/XUriReference.hpp> @@ -70,7 +71,7 @@ namespace scripting_protocolhandler void SAL_CALL ScriptProtocolHandler::initialize( const css::uno::Sequence < css::uno::Any >& aArguments ) { - if ( m_bInitialised ) + if ( m_bInitialised || officecfg::Office::Common::Security::Scripting::DisableMacrosExecution::get() ) { return ; } commit 2e26d8355835cb2fa61cfa45f42028e5ebc5bd49 Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> AuthorDate: Tue Nov 5 16:43:50 2019 +0100 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:44:38 2019 +0100 Check if scripting disabled for each dispatch call Not only when initializing. This way, changing the property during runtime has an effect. Change-Id: Iba5f00996f0079fc4bafb5d373f34c6fd86c7959 Reviewed-on: https://gerrit.libreoffice.org/82078 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> diff --git a/scripting/source/protocolhandler/scripthandler.cxx b/scripting/source/protocolhandler/scripthandler.cxx index 256f621a5041..2c76bac59697 100644 --- a/scripting/source/protocolhandler/scripthandler.cxx +++ b/scripting/source/protocolhandler/scripthandler.cxx @@ -126,6 +126,9 @@ void SAL_CALL ScriptProtocolHandler::dispatchWithNotification( const URL& aURL, const Sequence < PropertyValue >& lArgs, const Reference< XDispatchResultListener >& xListener ) { + if (officecfg::Office::Common::Security::Scripting::DisableMacrosExecution::get()) + return; + bool bSuccess = false; Any invokeResult; bool bCaughtException = false; commit 14c0743ae8f832d6a826b82b6528556db58b3b5b Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> AuthorDate: Fri Nov 8 09:32:36 2019 +0100 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:44:14 2019 +0100 Respect DisableMacrosExecution option in beanshell editor Change-Id: I0713b3d1ab45519aef25b5bd3d912baf2252d37b Reviewed-on: https://gerrit.libreoffice.org/82262 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> diff --git a/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java index 07ea84b9710f..a43cec43b902 100644 --- a/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java +++ b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java @@ -17,11 +17,17 @@ */ package com.sun.star.script.framework.provider.beanshell; +import com.sun.star.beans.NamedValue; +import com.sun.star.configuration.theDefaultProvider; +import com.sun.star.container.XNameAccess; +import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.script.framework.container.ScriptMetaData; import com.sun.star.script.framework.provider.ClassLoaderFactory; import com.sun.star.script.framework.provider.ScriptEditor; import com.sun.star.script.framework.provider.SwingInvocation; import com.sun.star.script.provider.XScriptContext; +import com.sun.star.uno.AnyConverter; +import com.sun.star.uno.UnoRuntime; import java.awt.BorderLayout; import java.awt.FlowLayout; @@ -170,10 +176,33 @@ public class ScriptEditorForBeanShell extends ScriptEditor implements ActionList * */ public Object execute() throws Exception { + if (!isMacroExectionEnabled()) { + showErrorMessage("Macro Execution has been disabled."); + return null; + } + frame.toFront(); return model.execute(context, cl); } + private boolean isMacroExectionEnabled() { + XNameAccess xNameAccess = null; + try { + String sAccess = "com.sun.star.configuration.ConfigurationAccess"; + XMultiServiceFactory xMSFCfg = theDefaultProvider.get(context.getComponentContext()); + Object oAccess = xMSFCfg.createInstanceWithArguments(sAccess, + new Object[] { new NamedValue("nodepath", "org.openoffice.Office.Common/Security/Scripting") }); + xNameAccess = UnoRuntime.queryInterface(XNameAccess.class, oAccess); + Object result = xNameAccess.getByName("DisableMacrosExecution"); + boolean bMacrosDisabled = AnyConverter.toBoolean(result); + if (bMacrosDisabled) + return false; + } catch (com.sun.star.uno.Exception e) { + return false; + } + return true; + } + /** * Opens an editor window for the specified ScriptMetaData. * If an editor window is already open for that data it will be commit e8657a07eea6eb54fb611bd54bd47a1fec5328f7 Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> AuthorDate: Fri Nov 8 12:37:11 2019 +0100 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:44:05 2019 +0100 Respect DisableMacrosExecution option in javascript editor Change-Id: I44c2d3a706a99839369bd4aff2abbb675e430926 Reviewed-on: https://gerrit.libreoffice.org/82286 Tested-by: Jenkins Reviewed-by: Serge Krot (CIB) <serge.k...@cib.de> Conflicts: scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java diff --git a/scripting/java/com/sun/star/script/framework/provider/ScriptEditor.java b/scripting/java/com/sun/star/script/framework/provider/ScriptEditor.java index 32ebd2fefb41..dbcb3b0bc7a9 100644 --- a/scripting/java/com/sun/star/script/framework/provider/ScriptEditor.java +++ b/scripting/java/com/sun/star/script/framework/provider/ScriptEditor.java @@ -18,13 +18,62 @@ package com.sun.star.script.framework.provider; +import com.sun.star.beans.NamedValue; +import com.sun.star.configuration.theDefaultProvider; +import com.sun.star.container.XNameAccess; +import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.script.framework.container.ScriptMetaData; import com.sun.star.script.provider.XScriptContext; +import com.sun.star.uno.AnyConverter; +import com.sun.star.uno.UnoRuntime; -public interface ScriptEditor { - Object execute() throws Exception; - void indicateErrorLine(int lineNum); - void edit(XScriptContext context, ScriptMetaData entry); - String getTemplate(); - String getExtension(); +import javax.swing.JOptionPane; +import javax.swing.JDialog; + +public abstract class ScriptEditor { + public XScriptContext context; + + public abstract Object execute() throws Exception; + public abstract void indicateErrorLine(int lineNum); + public abstract void edit(XScriptContext context, ScriptMetaData entry); + public abstract String getTemplate(); + public abstract String getExtension(); + + public void setContext(XScriptContext context) { + this.context = context; + } + + public boolean isMacroExectionEnabled() { + XNameAccess xNameAccess = null; + try { + String sAccess = "com.sun.star.configuration.ConfigurationAccess"; + XMultiServiceFactory xMSFCfg = theDefaultProvider.get(context.getComponentContext()); + Object oAccess = xMSFCfg.createInstanceWithArguments(sAccess, + new Object[] { new NamedValue("nodepath", "org.openoffice.Office.Common/Security/Scripting") }); + xNameAccess = UnoRuntime.queryInterface(XNameAccess.class, oAccess); + Object result = xNameAccess.getByName("DisableMacrosExecution"); + boolean bMacrosDisabled = AnyConverter.toBoolean(result); + if (bMacrosDisabled) + return false; + } catch (com.sun.star.uno.Exception e) { + return false; + } + return true; + } + + // Wraps long error messages + private static class NarrowOptionPane extends JOptionPane { + private static final long serialVersionUID = 1L; + public int getMaxCharactersPerLineCount() { + return 100; + } + } + + public void showErrorMessage(String message) { + JOptionPane optionPane = new NarrowOptionPane(); + optionPane.setMessage(message); + optionPane.setMessageType(JOptionPane.ERROR_MESSAGE); + JDialog dialog = optionPane.createDialog(null, "Error"); + dialog.setVisible(true); + } } \ No newline at end of file diff --git a/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java index 279e75fb3584..07ea84b9710f 100644 --- a/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java +++ b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java @@ -42,7 +42,6 @@ import java.util.Map; import javax.swing.JButton; import javax.swing.JComponent; -import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -50,7 +49,7 @@ import javax.swing.JPanel; import javax.swing.JToolBar; import javax.swing.BorderFactory; -public class ScriptEditorForBeanShell implements ScriptEditor, ActionListener { +public class ScriptEditorForBeanShell extends ScriptEditor implements ActionListener { private JFrame frame; private String filename; @@ -58,7 +57,6 @@ public class ScriptEditorForBeanShell implements ScriptEditor, ActionListener { private ScriptSourceModel model; private ScriptSourceView view; - private XScriptContext context; private URL scriptURL = null; private ClassLoader cl = null; private JButton saveBtn; @@ -225,7 +223,7 @@ public class ScriptEditorForBeanShell implements ScriptEditor, ActionListener { private ScriptEditorForBeanShell(XScriptContext context, ClassLoader cl, URL url) { - this.context = context; + setContext(context); this.scriptURL = url; this.model = new ScriptSourceModel(url); this.filename = url.getFile(); @@ -266,22 +264,6 @@ public class ScriptEditorForBeanShell implements ScriptEditor, ActionListener { frame.setVisible(true); } - // Wraps long error messages - class NarrowOptionPane extends JOptionPane { - private static final long serialVersionUID = 1L; - public int getMaxCharactersPerLineCount() { - return 100; - } - } - - private void showErrorMessage(String message) { - JOptionPane optionPane = new NarrowOptionPane(); - optionPane.setMessage(message); - optionPane.setMessageType(JOptionPane.ERROR_MESSAGE); - JDialog dialog = optionPane.createDialog(null, "Error"); - dialog.setVisible(true); - } - private void initUI() { frame = new JFrame("BeanShell Debug Window: " + filename); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); diff --git a/scripting/java/com/sun/star/script/framework/provider/javascript/ScriptEditorForJavaScript.java b/scripting/java/com/sun/star/script/framework/provider/javascript/ScriptEditorForJavaScript.java index a43abc25f7cd..4cf5cc3384ca 100644 --- a/scripting/java/com/sun/star/script/framework/provider/javascript/ScriptEditorForJavaScript.java +++ b/scripting/java/com/sun/star/script/framework/provider/javascript/ScriptEditorForJavaScript.java @@ -40,7 +40,7 @@ import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.tools.debugger.Main; import org.mozilla.javascript.tools.debugger.ScopeProvider; -public class ScriptEditorForJavaScript implements ScriptEditor { +public class ScriptEditorForJavaScript extends ScriptEditor { // global ScriptEditorForJavaScript instance private static ScriptEditorForJavaScript theScriptEditorForJavaScript; @@ -194,6 +194,12 @@ public class ScriptEditorForJavaScript implements ScriptEditor { } private ScriptEditorForJavaScript(XScriptContext context, URL url) { + setContext(context); + // Need to check that before showing the window. Checking in execute() has no effect. + if (!isMacroExectionEnabled()) { + showErrorMessage("Macro Execution has been disabled."); + return ; + } initUI(); Scriptable scope = getScope(context); rhinoWindow.openFile(url, scope, new CloseHandler(url)); commit 88f4e6e2763dd4c5e65e04af650cc30a4666ddc9 Author: Thorsten Behrens <thorsten.behr...@cib.de> AuthorDate: Thu Oct 24 15:03:47 2019 +0200 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:41:58 2019 +0100 sfx2: enable save again This is a fixup for e37b70442ebf9e1628e7da16b7b6acf498897dee Change-Id: Ib360c196aa0571d035231cdf4410ab1db134480c diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx index 94dc1d5552a8..97d83a7afa3e 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -1801,7 +1801,7 @@ bool SfxViewShell::isSaveLocked() if (!xModel.is()) return false; comphelper::NamedValueCollection aArgs(xModel->getArgs()); - return aArgs.getOrDefault("LockSave", true); + return aArgs.getOrDefault("LockSave", false); } Reference < XController > SfxViewShell::GetController() commit 0039b633e28262cda2a79070b36966ad7b53484b Author: Serge Krot <serge.k...@cib.de> AuthorDate: Tue Nov 12 21:52:05 2019 +0100 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:41:49 2019 +0100 Add document level option to lock down edit doc command Change-Id: I431fa4cd0daa52c885030dbadcc4052b5a890d34 Reviewed-on: https://gerrit.libreoffice.org/82553 Reviewed-by: Serge Krot (CIB) <serge.k...@cib.de> Tested-by: Serge Krot (CIB) <serge.k...@cib.de> Conflicts: offapi/com/sun/star/frame/XModel2.idl sfx2/source/doc/sfxbasemodel.cxx diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc index e4b5f397dadc..e530e425e77d 100644 --- a/include/sfx2/sfxsids.hrc +++ b/include/sfx2/sfxsids.hrc @@ -264,8 +264,9 @@ class SvxSearchItem; #define SID_DIALOG_PARENT (SID_SFX_START + 1735) #define SID_LOCK_PRINT (SID_SFX_START + 1736) #define SID_LOCK_SAVE (SID_SFX_START + 1737) +#define SID_LOCK_EDITDOC (SID_SFX_START + 1738) -// SID_SFX_free_START (SID_SFX_START + 1738) +// SID_SFX_free_START (SID_SFX_START + 1739) // SID_SFX_free_END (SID_SFX_START + 3999) #define SID_OPEN_NEW_VIEW (SID_SFX_START + 520) diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx index c04f96211307..63deaabddbe9 100644 --- a/include/sfx2/viewsh.hxx +++ b/include/sfx2/viewsh.hxx @@ -291,6 +291,7 @@ public: bool isExportLocked(); bool isPrintLocked(); bool isSaveLocked(); + bool isEditDocLocked(); SAL_DLLPRIVATE SfxInPlaceClient* GetUIActiveIPClient_Impl() const; SAL_DLLPRIVATE void AddContextMenuInterceptor_Impl( const css::uno::Reference < css::ui::XContextMenuInterceptor >& xInterceptor ); diff --git a/offapi/com/sun/star/document/MediaDescriptor.idl b/offapi/com/sun/star/document/MediaDescriptor.idl index e6035517f26b..8ad27a48c53b 100644 --- a/offapi/com/sun/star/document/MediaDescriptor.idl +++ b/offapi/com/sun/star/document/MediaDescriptor.idl @@ -588,6 +588,12 @@ service MediaDescriptor @since LibreOffice 6.4 */ [optional,property] boolean LockSave; + + /** Setting this option will disable switching to edit mode from read-only mode. + * + @since LibreOffice 6.4 + */ + [optional,property] boolean LockEditDoc; }; diff --git a/offapi/com/sun/star/frame/XModel2.idl b/offapi/com/sun/star/frame/XModel2.idl index 1db3ae9bd024..20fc0bbaeb33 100644 --- a/offapi/com/sun/star/frame/XModel2.idl +++ b/offapi/com/sun/star/frame/XModel2.idl @@ -147,7 +147,7 @@ interface XModel2 : com::sun::star::frame::XModel <li>com::sun::star::document::MediaDescriptor::LockExport</li> <li>com::sun::star::document::MediaDescriptor::LockPrint</li> <li>com::sun::star::document::MediaDescriptor::LockSave</li> - + <li>com::sun::star::document::MediaDescriptor::LockEditDoc</li> </ul> @throws com::sun::star::lang::IllegalArgumentException When trying to set an unsupported property diff --git a/sfx2/source/appl/appuno.cxx b/sfx2/source/appl/appuno.cxx index b076b5c59a19..8a5fa22cbb06 100644 --- a/sfx2/source/appl/appuno.cxx +++ b/sfx2/source/appl/appuno.cxx @@ -173,6 +173,7 @@ static char const sLockContentExtraction[] = "LockContentExtraction"; static char const sLockExport[] = "LockExport"; static char const sLockPrint[] = "LockPrint"; static char const sLockSave[] = "LockSave"; +static char const sLockEditDoc[] = "LockEditDoc"; static bool isMediaDescriptor( sal_uInt16 nSlotId ) { @@ -888,6 +889,14 @@ void TransformParameters( sal_uInt16 nSlotId, const uno::Sequence<beans::Propert if (bOK) rSet.Put( SfxBoolItem( SID_LOCK_SAVE, bVal ) ); } + else if (aName == sLockEditDoc) + { + bool bVal = false; + bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for LockEditDoc" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_LOCK_EDITDOC, bVal ) ); + } #ifdef DBG_UTIL else --nFoundArgs; @@ -1117,6 +1126,8 @@ void TransformItems( sal_uInt16 nSlotId, const SfxItemSet& rSet, uno::Sequence<b nAdditional++; if ( rSet.GetItemState( SID_LOCK_SAVE ) == SfxItemState::SET ) nAdditional++; + if ( rSet.GetItemState( SID_LOCK_EDITDOC ) == SfxItemState::SET ) + nAdditional++; // consider additional arguments nProps += nAdditional; @@ -1282,6 +1293,8 @@ void TransformItems( sal_uInt16 nSlotId, const SfxItemSet& rSet, uno::Sequence<b continue; if ( nId == SID_LOCK_SAVE ) continue; + if ( nId == SID_LOCK_EDITDOC ) + continue; } OStringBuffer aDbg("Unknown item detected: "); @@ -1697,6 +1710,11 @@ void TransformItems( sal_uInt16 nSlotId, const SfxItemSet& rSet, uno::Sequence<b pValue[nActProp].Name = sLockSave; pValue[nActProp++].Value <<= static_cast<const SfxBoolItem*>(pItem)->GetValue() ; } + if ( rSet.GetItemState( SID_LOCK_EDITDOC, false, &pItem ) == SfxItemState::SET ) + { + pValue[nActProp].Name = sLockEditDoc; + 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 6856968789d8..e6bb45ea0c19 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -1102,6 +1102,11 @@ void SAL_CALL SfxBaseModel::setArgs(const Sequence<beans::PropertyValue>& aArgs) rArg.Value >>= bValue; pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_SAVE, bValue)); } + else if (rArg.Name == "LockEditDoc") + { + rArg.Value >>= bValue; + pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_EDITDOC, bValue)); + } else { throw lang::IllegalArgumentException("Setting property not supported: " + aArgs[i].Name, diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index f879bc1df21f..1f4b4ef71a21 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -277,6 +277,10 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) if( !pSh || !pSh->HasName() || !(pSh->Get_Impl()->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT )) break; + SfxViewShell* pViewSh = GetViewShell(); + if (pViewSh && pViewSh->isEditDocLocked()) + break; + // Only change read-only UI and remove info bar when we succeed struct ReadOnlyUIGuard { @@ -862,6 +866,7 @@ void SfxViewFrame::StateReload_Impl( SfxItemSet& rSet ) const SfxShell *pFSh; if ( !pSh->HasName() || !( pSh->Get_Impl()->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) || + (GetViewShell() && GetViewShell()->isEditDocLocked()) || ( pSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED && ( !(pVSh = pSh->GetViewShell()) || !(pFSh = pVSh->GetFormShell()) || @@ -1345,11 +1350,18 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) pInfoBar->addButton(xSignButton); } - VclPtrInstance<PushButton> xBtn(&GetWindow()); - xBtn->SetText(SfxResId(STR_READONLY_EDIT)); - xBtn->SetSizePixel(xBtn->GetOptimalSize()); - xBtn->SetClickHdl(LINK(this, SfxViewFrame, SwitchReadOnlyHandler)); - pInfoBar->addButton(xBtn); + bool showEditDocumentButton = true; + if (m_xObjSh->GetViewShell() && m_xObjSh->GetViewShell()->isEditDocLocked()) + showEditDocumentButton = false; + + if (showEditDocumentButton) + { + VclPtrInstance<PushButton> xBtn(&GetWindow()); + xBtn->SetText(SfxResId(STR_READONLY_EDIT)); + xBtn->SetSizePixel(xBtn->GetOptimalSize()); + xBtn->SetClickHdl(LINK(this, SfxViewFrame, SwitchReadOnlyHandler)); + pInfoBar->addButton(xBtn); + } } } diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx index 127c13d3be39..94dc1d5552a8 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -1786,6 +1786,15 @@ bool SfxViewShell::isPrintLocked() return aArgs.getOrDefault("LockPrint", false); } +bool SfxViewShell::isEditDocLocked() +{ + Reference<XModel> xModel = GetCurrentDocument(); + if (!xModel.is()) + return false; + comphelper::NamedValueCollection aArgs(xModel->getArgs()); + return aArgs.getOrDefault("LockEditDoc", false); +} + bool SfxViewShell::isSaveLocked() { Reference<XModel> xModel = GetCurrentDocument(); diff --git a/sw/qa/python/check_xmodel.py b/sw/qa/python/check_xmodel.py index c257ef33fb79..f6894dd21a3f 100644 --- a/sw/qa/python/check_xmodel.py +++ b/sw/qa/python/check_xmodel.py @@ -36,7 +36,8 @@ class TestXModel(unittest.TestCase): p4 = PropertyValue(Name="LockExport", Value=True) p5 = PropertyValue(Name="LockPrint", Value=True) p6 = PropertyValue(Name="LockSave", Value=True) - xDoc.setArgs([p1, p2, p3, p4, p5, p6]) + p7 = PropertyValue(Name="LockEditDoc", Value=True) + xDoc.setArgs([p1, p2, p3, p4, p5, p6, p7]) # Make sure that all properties are returned with getArgs() args = xDoc.getArgs() @@ -46,6 +47,7 @@ class TestXModel(unittest.TestCase): self.assertTrue(p4 in args) self.assertTrue(p5 in args) self.assertTrue(p6 in args) + self.assertTrue(p7 in args) xDoc.close(True) commit e0f9a1413647132209086447a54d5c9f0ecc66a0 Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> AuthorDate: Wed Oct 23 08:24:31 2019 +0200 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:39:51 2019 +0100 Add document-level option to lock down save Change-Id: I40b5e8c780894645e467e3891062c499707d69c7 Reviewed-on: https://gerrit.libreoffice.org/81359 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> Conflicts: include/sfx2/sfxsids.hrc include/sfx2/viewsh.hxx offapi/com/sun/star/document/MediaDescriptor.idl sfx2/source/appl/appuno.cxx sfx2/source/view/viewsh.cxx sw/qa/python/check_xmodel.py diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc index ca2349b0196c..e4b5f397dadc 100644 --- a/include/sfx2/sfxsids.hrc +++ b/include/sfx2/sfxsids.hrc @@ -262,8 +262,10 @@ class SvxSearchItem; #define SID_IS_REDACT_MODE (SID_SFX_START + 1733) #define SID_REDACTION_STYLE (SID_SFX_START + 1734) #define SID_DIALOG_PARENT (SID_SFX_START + 1735) +#define SID_LOCK_PRINT (SID_SFX_START + 1736) +#define SID_LOCK_SAVE (SID_SFX_START + 1737) -// SID_SFX_free_START (SID_SFX_START + 1736) +// SID_SFX_free_START (SID_SFX_START + 1738) // SID_SFX_free_END (SID_SFX_START + 3999) #define SID_OPEN_NEW_VIEW (SID_SFX_START + 520) diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx index e0240ae952b4..c04f96211307 100644 --- a/include/sfx2/viewsh.hxx +++ b/include/sfx2/viewsh.hxx @@ -287,6 +287,10 @@ public: void AddRemoveClipboardListener( const css::uno::Reference < css::datatransfer::clipboard::XClipboardListener>&, bool ); css::uno::Reference< css::datatransfer::clipboard::XClipboardNotifier > GetClipboardNotifier(); + bool isContentExtractionLocked(); + bool isExportLocked(); + bool isPrintLocked(); + bool isSaveLocked(); SAL_DLLPRIVATE SfxInPlaceClient* GetUIActiveIPClient_Impl() const; SAL_DLLPRIVATE void AddContextMenuInterceptor_Impl( const css::uno::Reference < css::ui::XContextMenuInterceptor >& xInterceptor ); diff --git a/offapi/com/sun/star/document/MediaDescriptor.idl b/offapi/com/sun/star/document/MediaDescriptor.idl index 58e773311875..e6035517f26b 100644 --- a/offapi/com/sun/star/document/MediaDescriptor.idl +++ b/offapi/com/sun/star/document/MediaDescriptor.idl @@ -560,6 +560,34 @@ 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; + + /** Setting this option will prevent exporting document content to any file. + Export, Send, save as, etc will be disabled, + as well as individual graphic/chart export and mail merge. + + @since LibreOffice 6.4 + */ + [optional,property] boolean LockExport; + + /** Setting this option will disable all print functions (including Printer setup) + + @since LibreOffice 6.4 + */ + [optional,property] boolean LockPrint; + + /** Setting this option will disable the save function. + * + @since LibreOffice 6.4 + */ + [optional,property] boolean LockSave; }; diff --git a/offapi/com/sun/star/frame/XModel2.idl b/offapi/com/sun/star/frame/XModel2.idl index c05257a988cd..1db3ae9bd024 100644 --- a/offapi/com/sun/star/frame/XModel2.idl +++ b/offapi/com/sun/star/frame/XModel2.idl @@ -146,6 +146,8 @@ interface XModel2 : com::sun::star::frame::XModel <li>com::sun::star::document::MediaDescriptor::LockContentExtraction</li> <li>com::sun::star::document::MediaDescriptor::LockExport</li> <li>com::sun::star::document::MediaDescriptor::LockPrint</li> + <li>com::sun::star::document::MediaDescriptor::LockSave</li> + </ul> @throws com::sun::star::lang::IllegalArgumentException When trying to set an unsupported property diff --git a/sfx2/source/appl/appuno.cxx b/sfx2/source/appl/appuno.cxx index f272a938775d..b076b5c59a19 100644 --- a/sfx2/source/appl/appuno.cxx +++ b/sfx2/source/appl/appuno.cxx @@ -169,6 +169,10 @@ 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 char const sLockExport[] = "LockExport"; +static char const sLockPrint[] = "LockPrint"; +static char const sLockSave[] = "LockSave"; static bool isMediaDescriptor( sal_uInt16 nSlotId ) { @@ -852,6 +856,38 @@ 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 ) ); + } + else if (aName == sLockExport) + { + bool bVal = false; + bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for LockExport" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_LOCK_EXPORT, bVal ) ); + } + else if (aName == sLockPrint) + { + bool bVal = false; + bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for LockPrint" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_LOCK_PRINT, bVal ) ); + } + else if (aName == sLockSave) + { + bool bVal = false; + bool bOK = (rProp.Value >>= bVal); + DBG_ASSERT( bOK, "invalid type for LockSave" ); + if (bOK) + rSet.Put( SfxBoolItem( SID_LOCK_SAVE, bVal ) ); + } #ifdef DBG_UTIL else --nFoundArgs; @@ -1073,6 +1109,14 @@ void TransformItems( sal_uInt16 nSlotId, const SfxItemSet& rSet, uno::Sequence<b ++nAdditional; if ( rSet.GetItemState( SID_CONVERT_IMAGES ) == SfxItemState::SET ) nAdditional++; + if ( rSet.GetItemState( SID_LOCK_CONTENT_EXTRACTION ) == SfxItemState::SET ) + nAdditional++; + if ( rSet.GetItemState( SID_LOCK_EXPORT ) == SfxItemState::SET ) + nAdditional++; + if ( rSet.GetItemState( SID_LOCK_PRINT ) == SfxItemState::SET ) + nAdditional++; + if ( rSet.GetItemState( SID_LOCK_SAVE ) == SfxItemState::SET ) + nAdditional++; // consider additional arguments nProps += nAdditional; @@ -1230,6 +1274,14 @@ void TransformItems( sal_uInt16 nSlotId, const SfxItemSet& rSet, uno::Sequence<b continue; if ( nId == SID_SUGGESTEDSAVEASNAME ) continue; + if ( nId == SID_LOCK_CONTENT_EXTRACTION ) + continue; + if ( nId == SID_LOCK_EXPORT ) + continue; + if ( nId == SID_LOCK_PRINT ) + continue; + if ( nId == SID_LOCK_SAVE ) + continue; } OStringBuffer aDbg("Unknown item detected: "); @@ -1625,6 +1677,26 @@ 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() ; + } + if ( rSet.GetItemState( SID_LOCK_EXPORT, false, &pItem ) == SfxItemState::SET ) + { + pValue[nActProp].Name = sLockExport; + pValue[nActProp++].Value <<= static_cast<const SfxBoolItem*>(pItem)->GetValue() ; + } + if ( rSet.GetItemState( SID_LOCK_PRINT, false, &pItem ) == SfxItemState::SET ) + { + pValue[nActProp].Name = sLockPrint; + pValue[nActProp++].Value <<= static_cast<const SfxBoolItem*>(pItem)->GetValue() ; + } + if ( rSet.GetItemState( SID_LOCK_SAVE, false, &pItem ) == SfxItemState::SET ) + { + pValue[nActProp].Name = sLockSave; + pValue[nActProp++].Value <<= static_cast<const SfxBoolItem*>(pItem)->GetValue() ; + } } rArgs = aSequ; diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index 786931f394aa..3b61915e99ac 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -1193,11 +1193,13 @@ void SfxObjectShell::GetState_Impl(SfxItemSet &rSet) } case SID_SAVEDOC: { - if ( !IsReadOnly() ) - rSet.Put(SfxStringItem( - nWhich, SfxResId(STR_SAVEDOC))); - else + SfxViewFrame *pFrame = SfxViewFrame::GetFirst(this); + if ( IsReadOnly() || (pFrame && pFrame->GetViewShell()->isSaveLocked())) + { rSet.DisableItem(nWhich); + break; + } + rSet.Put(SfxStringItem(nWhich, SfxResId(STR_SAVEDOC))); } break; diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index f4e39ea7ab82..6856968789d8 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -1097,6 +1097,11 @@ void SAL_CALL SfxBaseModel::setArgs(const Sequence<beans::PropertyValue>& aArgs) rArg.Value >>= bValue; pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_PRINT, bValue)); } + else if (rArg.Name == "LockSave") + { + rArg.Value >>= bValue; + pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_SAVE, bValue)); + } else { throw lang::IllegalArgumentException("Setting property not supported: " + aArgs[i].Name, diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx index fbd3a2bd29aa..127c13d3be39 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -1759,6 +1759,42 @@ 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); +} + +bool SfxViewShell::isExportLocked() +{ + Reference<XModel> xModel = GetCurrentDocument(); + if (!xModel.is()) + return false; + comphelper::NamedValueCollection aArgs(xModel->getArgs()); + return aArgs.getOrDefault("LockExport", false); +} + +bool SfxViewShell::isPrintLocked() +{ + Reference<XModel> xModel = GetCurrentDocument(); + if (!xModel.is()) + return false; + comphelper::NamedValueCollection aArgs(xModel->getArgs()); + return aArgs.getOrDefault("LockPrint", false); +} + +bool SfxViewShell::isSaveLocked() +{ + Reference<XModel> xModel = GetCurrentDocument(); + if (!xModel.is()) + return false; + comphelper::NamedValueCollection aArgs(xModel->getArgs()); + return aArgs.getOrDefault("LockSave", true); +} + Reference < XController > SfxViewShell::GetController() { return pImpl->m_pController.get(); diff --git a/sw/qa/python/check_xmodel.py b/sw/qa/python/check_xmodel.py index c5374c03c350..c257ef33fb79 100644 --- a/sw/qa/python/check_xmodel.py +++ b/sw/qa/python/check_xmodel.py @@ -32,12 +32,20 @@ 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) + p4 = PropertyValue(Name="LockExport", Value=True) + p5 = PropertyValue(Name="LockPrint", Value=True) + p6 = PropertyValue(Name="LockSave", Value=True) + xDoc.setArgs([p1, p2, p3, p4, p5, p6]) # 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) + self.assertTrue(p4 in args) + self.assertTrue(p5 in args) + self.assertTrue(p6 in args) xDoc.close(True) commit af07bf2c6306f04c8f251f320ebf9b9f93e50155 Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> AuthorDate: Tue Oct 22 15:58:31 2019 +0200 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:32:32 2019 +0100 Add document-level option to lock down printing Change-Id: I85694021d74be79293079d04d5ba1d9b48cfa557 Reviewed-on: https://gerrit.libreoffice.org/81340 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> (cherry picked from commit d5d96e04ad8014f3e68351ccb54221d9610b565b) Reviewed-on: https://gerrit.libreoffice.org/81391 Tested-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> Conflicts: sfx2/source/view/viewsh.cxx diff --git a/offapi/com/sun/star/frame/XModel2.idl b/offapi/com/sun/star/frame/XModel2.idl index 2996cd6de140..c05257a988cd 100644 --- a/offapi/com/sun/star/frame/XModel2.idl +++ b/offapi/com/sun/star/frame/XModel2.idl @@ -145,6 +145,7 @@ interface XModel2 : com::sun::star::frame::XModel <li>com::sun::star::document::MediaDescriptor::EncryptionData</li> <li>com::sun::star::document::MediaDescriptor::LockContentExtraction</li> <li>com::sun::star::document::MediaDescriptor::LockExport</li> + <li>com::sun::star::document::MediaDescriptor::LockPrint</li> </ul> @throws com::sun::star::lang::IllegalArgumentException When trying to set an unsupported property diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index ce411204bf7b..f4e39ea7ab82 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -1092,6 +1092,11 @@ void SAL_CALL SfxBaseModel::setArgs(const Sequence<beans::PropertyValue>& aArgs) rArg.Value >>= bValue; pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_EXPORT, bValue)); } + else if (rArg.Name == "LockPrint") + { + rArg.Value >>= bValue; + pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_PRINT, bValue)); + } else { throw lang::IllegalArgumentException("Setting property not supported: " + aArgs[i].Name, commit 5b8afca268a3297b221c091e4f0a0f329e4e2ca1 Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> AuthorDate: Tue Oct 22 11:32:09 2019 +0200 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:32:03 2019 +0100 Add document-level option to lock down file export Setting this option will disable any export command (File->Export*, File->Send*, graphic/chart export context menu, save as, mailmerge wizard, ...) Change-Id: I07a2a3b9179b494ac839e7d1e407194600679aa1 Reviewed-on: https://gerrit.libreoffice.org/81316 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> (cherry picked from commit ec0a3db0cbb5413d10e70c9843e679bbf2327c15) Reviewed-on: https://gerrit.libreoffice.org/81389 Tested-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> diff --git a/offapi/com/sun/star/frame/XModel2.idl b/offapi/com/sun/star/frame/XModel2.idl index 3e54913f98c0..2996cd6de140 100644 --- a/offapi/com/sun/star/frame/XModel2.idl +++ b/offapi/com/sun/star/frame/XModel2.idl @@ -144,6 +144,7 @@ interface XModel2 : com::sun::star::frame::XModel <li>com::sun::star::document::MediaDescriptor::SuggestedSaveAsName</li> <li>com::sun::star::document::MediaDescriptor::EncryptionData</li> <li>com::sun::star::document::MediaDescriptor::LockContentExtraction</li> + <li>com::sun::star::document::MediaDescriptor::LockExport</li> </ul> @throws com::sun::star::lang::IllegalArgumentException When trying to set an unsupported property diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index e862f9b9f3d0..ce411204bf7b 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -1087,6 +1087,11 @@ void SAL_CALL SfxBaseModel::setArgs(const Sequence<beans::PropertyValue>& aArgs) rArg.Value >>= bValue; pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_CONTENT_EXTRACTION, bValue)); } + else if (rArg.Name == "LockExport") + { + rArg.Value >>= bValue; + pMedium->GetItemSet()->Put(SfxBoolItem(SID_LOCK_EXPORT, bValue)); + } else { throw lang::IllegalArgumentException("Setting property not supported: " + aArgs[i].Name, commit 5afa72a64a67aeb0aa724516575b3211b9b2680c Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> AuthorDate: Thu Oct 10 08:13:51 2019 +0200 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:32:02 2019 +0100 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.mehrbr...@cib.de> (cherry picked from commit 075f20a4b696f9e85d11dc977806e41a49e6de61) Reviewed-on: https://gerrit.libreoffice.org/80757 Tested-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> diff --git a/offapi/com/sun/star/frame/XModel2.idl b/offapi/com/sun/star/frame/XModel2.idl index 0cc426e10933..3e54913f98c0 100644 --- a/offapi/com/sun/star/frame/XModel2.idl +++ b/offapi/com/sun/star/frame/XModel2.idl @@ -143,6 +143,7 @@ interface XModel2 : com::sun::star::frame::XModel <li>com::sun::star::document::MediaDescriptor::SuggestedSaveAsDir</li> <li>com::sun::star::document::MediaDescriptor::SuggestedSaveAsName</li> <li>com::sun::star::document::MediaDescriptor::EncryptionData</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/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index 2b93f29eb23c..e862f9b9f3d0 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -1082,6 +1082,11 @@ void SAL_CALL SfxBaseModel::setArgs(const Sequence<beans::PropertyValue>& aArgs) { pMedium->GetItemSet()->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, rArg.Value)); } + 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: " + aArgs[i].Name, commit 4cb3be4cdb8722d63992c490d77933c4050165e1 Author: Serge Krot <serge.k...@cib.de> AuthorDate: Tue Oct 15 13:04:49 2019 +0200 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:32:01 2019 +0100 Tooltips: Use HELPWINSTYLE_BALLOON when tooltip contains \n Change-Id: I33ef48b5a90338471d85a613ede73eada323381c Reviewed-on: https://gerrit.libreoffice.org/80825 Reviewed-by: Serge Krot (CIB) <serge.k...@cib.de> Tested-by: Serge Krot (CIB) <serge.k...@cib.de> diff --git a/vcl/source/app/help.cxx b/vcl/source/app/help.cxx old mode 100644 new mode 100755 index 035230c69235..ec0e1d0579fc --- a/vcl/source/app/help.cxx +++ b/vcl/source/app/help.cxx @@ -326,7 +326,7 @@ void HelpTextWindow::SetHelpText( const OUString& rHelpText ) { maHelpText = rHelpText; ApplySettings(*this); - if ( mnHelpWinStyle == HELPWINSTYLE_QUICK && maHelpText.getLength() < HELPTEXTMAXLEN) + if ( mnHelpWinStyle == HELPWINSTYLE_QUICK && maHelpText.getLength() < HELPTEXTMAXLEN && maHelpText.indexOf('\n') < 0) { Size aSize; aSize.setHeight( GetTextHeight() ); @@ -384,7 +384,7 @@ void HelpTextWindow::Paint( vcl::RenderContext& rRenderContext, const tools::Rec } // paint text - if (mnHelpWinStyle == HELPWINSTYLE_QUICK && maHelpText.getLength() < HELPTEXTMAXLEN) + if (mnHelpWinStyle == HELPWINSTYLE_QUICK && maHelpText.getLength() < HELPTEXTMAXLEN && maHelpText.indexOf('\n') < 0) { if ( mnStyle & QuickHelpFlags::CtrlText ) rRenderContext.DrawCtrlText(maTextRect.TopLeft(), maHelpText); commit 522594f7376e30d3dd5a99251e56d278666972a7 Author: Serge Krot <serge.k...@cib.de> AuthorDate: Wed Oct 16 16:03:41 2019 +0200 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Wed Nov 13 03:31:59 2019 +0100 ToggleButton: add ability to set tooltip text for pop-up menu items Change-Id: Iacd5c97438782ffddc8a9196688e1d58abce9abe Reviewed-on: https://gerrit.libreoffice.org/80906 Reviewed-by: Serge Krot (CIB) <serge.k...@cib.de> Tested-by: Serge Krot (CIB) <serge.k...@cib.de> (cherry picked from commit 8f79936d5278fd5172f5864f99befaa878de5f5d) Reviewed-on: https://gerrit.libreoffice.org/81642 Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de> Tested-by: Thorsten Behrens <thorsten.behr...@cib.de> diff --git a/framework/inc/uielement/togglebuttontoolbarcontroller.hxx b/framework/inc/uielement/togglebuttontoolbarcontroller.hxx old mode 100644 new mode 100755 index 1550e554d59f..ae532858d25b --- a/framework/inc/uielement/togglebuttontoolbarcontroller.hxx +++ b/framework/inc/uielement/togglebuttontoolbarcontroller.hxx @@ -36,6 +36,13 @@ class ToggleButtonToolbarController : public ComplexToolbarController { public: + class DropdownMenuItem + { + public: + OUString mLabel; + OUString mTipHelpText; + }; + enum class Style { DropDownButton, @@ -64,7 +71,7 @@ class ToggleButtonToolbarController : public ComplexToolbarController DECL_LINK( MenuSelectHdl, Menu *, bool); OUString m_aCurrentSelection; - std::vector< OUString > m_aDropdownMenuList; + std::vector< DropdownMenuItem > m_aDropdownMenuList; }; } diff --git a/framework/source/uielement/togglebuttontoolbarcontroller.cxx b/framework/source/uielement/togglebuttontoolbarcontroller.cxx index 964a871af5e2..10e0482c44f0 100755 --- a/framework/source/uielement/togglebuttontoolbarcontroller.cxx +++ b/framework/source/uielement/togglebuttontoolbarcontroller.cxx @@ -98,12 +98,15 @@ uno::Reference< awt::XWindow > SAL_CALL ToggleButtonToolbarController::createPop const sal_uInt32 nCount = m_aDropdownMenuList.size(); for ( sal_uInt32 i = 0; i < nCount; i++ ) { - OUString aLabel( m_aDropdownMenuList[i] ); - aPopup->InsertItem( sal_uInt16( i+1 ), aLabel ); - if ( aLabel == m_aCurrentSelection ) + const OUString & rLabel = m_aDropdownMenuList[i].mLabel; + aPopup->InsertItem( sal_uInt16( i+1 ), rLabel ); + if ( rLabel == m_aCurrentSelection ) aPopup->CheckItem( sal_uInt16( i+1 ) ); else aPopup->CheckItem( sal_uInt16( i+1 ), false ); + + if ( !m_aDropdownMenuList[i].mTipHelpText.isEmpty() ) + aPopup->SetTipHelpText( sal_uInt16( i+1 ), m_aDropdownMenuList[i].mTipHelpText ); } m_pToolbar->SetItemDown( m_nID, true ); @@ -126,10 +129,14 @@ void ToggleButtonToolbarController::executeControlCommand( const css::frame::Con { Sequence< OUString > aList; m_aDropdownMenuList.clear(); + m_aCurrentSelection.clear(); rControlCommand.Arguments[i].Value >>= aList; for ( sal_Int32 j = 0; j < aList.getLength(); j++ ) ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits