summaryrefslogtreecommitdiff
path: root/sfx2
diff options
context:
space:
mode:
authorMert Tumer <mert.tumer@collabora.com>2022-09-12 12:58:20 +0300
committerSzymon Kłos <szymon.klos@collabora.com>2022-11-21 11:45:10 +0100
commit67eb60672936a10fba840078e6aca918c3331f52 (patch)
treebe75c38f175d682aa4834d9064cb11171604c13a /sfx2
parent2adaac8bf01a6caffd0eedb9f456eeadc43f1759 (diff)
lok: make properties>change password dialog async
* We now can set a password through properties->change password without having to have a password initially only for online because it needs a created file already, online works with files that are created before loading but the desktop does not need this. * The same dialog is still used as non-async for desktop version because it goes through an InteractionHandler and the result is expected not from the dialog but from the interaction handler. Therefore, making it async there did not make sense. Signed-off-by: Mert Tumer <mert.tumer@collabora.com> Change-Id: I3d02822be0b71836b1592abca191b3b1c5f6374e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139884 Reviewed-by: Szymon Kłos <szymon.klos@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142991 Tested-by: Jenkins
Diffstat (limited to 'sfx2')
-rw-r--r--sfx2/source/dialog/dinfdlg.cxx31
-rw-r--r--sfx2/source/dialog/filedlghelper.cxx182
2 files changed, 127 insertions, 86 deletions
diff --git a/sfx2/source/dialog/dinfdlg.cxx b/sfx2/source/dialog/dinfdlg.cxx
index 3dd14c423af7..3d1ee1dadac5 100644
--- a/sfx2/source/dialog/dinfdlg.cxx
+++ b/sfx2/source/dialog/dinfdlg.cxx
@@ -70,6 +70,7 @@
#include <helper.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/docfile.hxx>
+#include <vcl/abstdlg.hxx>
#include <documentfontsdialog.hxx>
#include <dinfdlg.hrc>
@@ -723,6 +724,11 @@ SfxDocumentPage::SfxDocumentPage(weld::Container* pPage, weld::DialogController*
SfxDocumentPage::~SfxDocumentPage()
{
+ if (m_xPasswordDialog)
+ {
+ m_xPasswordDialog->Response(RET_CANCEL);
+ m_xPasswordDialog.clear();
+ }
}
IMPL_LINK_NOARG(SfxDocumentPage, DeleteHdl, weld::Button&, void)
@@ -772,9 +778,26 @@ IMPL_LINK_NOARG(SfxDocumentPage, ChangePassHdl, weld::Button&, void)
std::shared_ptr<const SfxFilter> pFilter = pShell->GetMedium()->GetFilter();
if (!pFilter)
break;
-
- sfx2::RequestPassword(pFilter, OUString(), pMedSet, GetFrameWeld()->GetXWindow());
- pShell->SetModified();
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ // MS Types support max len of 15 characters while OOXML is "unlimited"
+ const sal_uInt16 maxPwdLen = sfx2::IsMSType(pFilter) && !sfx2::IsOOXML(pFilter) ? 15 : 0;
+ // handle the pwd dialog asynchronously
+ VclAbstractDialogFactory * pFact = VclAbstractDialogFactory::Create();
+ m_xPasswordDialog = pFact->CreatePasswordToOpenModifyDialog(GetFrameWeld(), maxPwdLen, false);
+ m_xPasswordDialog->StartExecuteAsync([this, pFilter, pMedSet, pShell](sal_Int32 nResult)
+ {
+ if (nResult == RET_OK)
+ {
+ sfx2::SetPassword(pFilter, pMedSet, m_xPasswordDialog->GetPasswordToOpen(), m_xPasswordDialog->GetPasswordToOpen());
+ pShell->SetModified();
+ }
+ m_xPasswordDialog->disposeOnce();
+ });
+ } else {
+ sfx2::RequestPassword(pFilter, OUString(), pMedSet, GetFrameWeld()->GetXWindow());
+ pShell->SetModified();
+ }
}
while (false);
}
@@ -838,7 +861,7 @@ void SfxDocumentPage::ImplCheckPasswordState()
return;
}
while (false);
- m_xChangePassBtn->set_sensitive(false);
+ m_xChangePassBtn->set_sensitive(comphelper::LibreOfficeKit::isActive());
}
std::unique_ptr<SfxTabPage> SfxDocumentPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rItemSet)
diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx
index 0f9f4739596b..93505057779f 100644
--- a/sfx2/source/dialog/filedlghelper.cxx
+++ b/sfx2/source/dialog/filedlghelper.cxx
@@ -2865,21 +2865,109 @@ ErrCode FileOpenDialog_Impl( weld::Window* pParent,
return nRet;
}
-ErrCode RequestPassword(const std::shared_ptr<const SfxFilter>& pCurrentFilter, OUString const & aURL, SfxItemSet* pSet, const css::uno::Reference<css::awt::XWindow>& rParent)
+bool IsMSType(const std::shared_ptr<const SfxFilter>& pCurrentFilter)
{
- uno::Reference<task::XInteractionHandler2> xInteractionHandler = task::InteractionHandler::createWithParent(::comphelper::getProcessComponentContext(), rParent);
// TODO: need a save way to distinguish MS filters from other filters
// for now MS-filters are the only alien filters that support encryption
- const bool bMSType = !pCurrentFilter->IsOwnFormat();
+ return !pCurrentFilter->IsOwnFormat();
+}
+
+bool IsOOXML(const std::shared_ptr<const SfxFilter>& pCurrentFilter)
+{
// For OOXML we can use the standard password ("unlimited" characters)
- // request, otherwise the MS limited password request is needed.
- const bool bOOXML = bMSType && lclSupportsOOXMLEncryption( pCurrentFilter->GetFilterName());
- const ::comphelper::DocPasswordRequestType eType = bMSType && !bOOXML ?
+ return IsMSType(pCurrentFilter) && lclSupportsOOXMLEncryption( pCurrentFilter->GetFilterName());
+}
+
+ErrCode SetPassword(const std::shared_ptr<const SfxFilter>& pCurrentFilter, SfxItemSet* pSet, const OUString& rPasswordToOpen, std::u16string_view rPasswordToModify)
+{
+ const bool bMSType = IsMSType(pCurrentFilter);
+ const bool bOOXML = IsOOXML(pCurrentFilter);
+
+ if ( rPasswordToOpen.getLength() )
+ {
+ css::uno::Sequence< css::beans::NamedValue > aEncryptionData;
+
+ if ( bMSType )
+ {
+ if (bOOXML)
+ {
+ ::comphelper::SequenceAsHashMap aHashData;
+ aHashData[ OUString( "OOXPassword" ) ] <<= rPasswordToOpen;
+ aHashData[ OUString( "CryptoType" ) ] <<= OUString( "Standard" );
+ aEncryptionData = aHashData.getAsConstNamedValueList();
+ }
+ else
+ {
+ uno::Sequence< sal_Int8 > aUniqueID = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 );
+ uno::Sequence< sal_Int8 > aEncryptionKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( rPasswordToOpen, aUniqueID );
+
+ if ( aEncryptionKey.hasElements() )
+ {
+ ::comphelper::SequenceAsHashMap aHashData;
+ aHashData[ OUString( "STD97EncryptionKey" ) ] <<= aEncryptionKey;
+ aHashData[ OUString( "STD97UniqueID" ) ] <<= aUniqueID;
+
+ aEncryptionData = aHashData.getAsConstNamedValueList();
+ }
+ else
+ {
+ return ERRCODE_IO_NOTSUPPORTED;
+ }
+ }
+ }
+
+ // tdf#118639: We need ODF encryption data for autorecovery where password will already
+ // be unavailable, even for non-ODF documents, so append it here unconditionally
+ pSet->Put(SfxUnoAnyItem(
+ SID_ENCRYPTIONDATA,
+ uno::Any(comphelper::concatSequences(
+ aEncryptionData, comphelper::OStorageHelper::CreatePackageEncryptionData(
+ rPasswordToOpen)))));
+ }
+
+ if ( bMSType )
+ {
+ if (bOOXML)
+ {
+ uno::Sequence<beans::PropertyValue> aModifyPasswordInfo
+ = ::comphelper::DocPasswordHelper::GenerateNewModifyPasswordInfoOOXML(
+ rPasswordToModify);
+ if (aModifyPasswordInfo.hasElements() && pSet)
+ pSet->Put(
+ SfxUnoAnyItem(SID_MODIFYPASSWORDINFO, uno::Any(aModifyPasswordInfo)));
+ }
+ else
+ {
+ // the empty password has 0 as Hash
+ sal_Int32 nHash = SfxMedium::CreatePasswordToModifyHash(
+ rPasswordToModify,
+ pCurrentFilter->GetServiceName() == "com.sun.star.text.TextDocument");
+ if (nHash && pSet)
+ pSet->Put(SfxUnoAnyItem(SID_MODIFYPASSWORDINFO, uno::Any(nHash)));
+ }
+ }
+ else
+ {
+ uno::Sequence< beans::PropertyValue > aModifyPasswordInfo = ::comphelper::DocPasswordHelper::GenerateNewModifyPasswordInfo( rPasswordToModify );
+ if ( aModifyPasswordInfo.hasElements() && pSet)
+ pSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::Any( aModifyPasswordInfo ) ) );
+ }
+ return ERRCODE_NONE;
+}
+
+
+
+ErrCode RequestPassword(const std::shared_ptr<const SfxFilter>& pCurrentFilter, OUString const & aURL, SfxItemSet* pSet, const css::uno::Reference<css::awt::XWindow>& rParent)
+{
+ uno::Reference<task::XInteractionHandler2> xInteractionHandler = task::InteractionHandler::createWithParent(::comphelper::getProcessComponentContext(), rParent);
+ const auto eType = IsMSType(pCurrentFilter) && !IsOOXML(pCurrentFilter) ?
::comphelper::DocPasswordRequestType::MS :
::comphelper::DocPasswordRequestType::Standard;
::rtl::Reference< ::comphelper::DocPasswordRequest > pPasswordRequest( new ::comphelper::DocPasswordRequest( eType, css::task::PasswordRequestMode_PASSWORD_CREATE, aURL, bool( pCurrentFilter->GetFilterFlags() & SfxFilterFlags::PASSWORDTOMODIFY ) ) );
+ const bool bMSType = IsMSType(pCurrentFilter);
+
uno::Reference< css::task::XInteractionRequest > rRequest( pPasswordRequest );
do
{
@@ -2902,85 +2990,15 @@ ErrCode RequestPassword(const std::shared_ptr<const SfxFilter>& pCurrentFilter,
xBox->run();
}
while (true);
- if ( pPasswordRequest->isPassword() )
- {
- if ( pPasswordRequest->getPassword().getLength() )
- {
- css::uno::Sequence< css::beans::NamedValue > aEncryptionData;
-
- // TODO/LATER: The filters should show the password dialog themself in future
- if ( bMSType )
- {
- if (bOOXML)
- {
- ::comphelper::SequenceAsHashMap aHashData;
- aHashData[ OUString( "OOXPassword" ) ] <<= pPasswordRequest->getPassword();
- aHashData[ OUString( "CryptoType" ) ] <<= OUString( "Standard" );
- aEncryptionData = aHashData.getAsConstNamedValueList();
- }
- else
- {
- uno::Sequence< sal_Int8 > aUniqueID = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 );
- uno::Sequence< sal_Int8 > aEncryptionKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( pPasswordRequest->getPassword(), aUniqueID );
-
- if ( aEncryptionKey.hasElements() )
- {
- ::comphelper::SequenceAsHashMap aHashData;
- aHashData[ OUString( "STD97EncryptionKey" ) ] <<= aEncryptionKey;
- aHashData[ OUString( "STD97UniqueID" ) ] <<= aUniqueID;
-
- aEncryptionData = aHashData.getAsConstNamedValueList();
- }
- else
- {
- return ERRCODE_IO_NOTSUPPORTED;
- }
- }
- }
+ if ( !pPasswordRequest->isPassword() )
+ return ERRCODE_ABORT;
- // tdf#118639: We need ODF encryption data for autorecovery where password will already
- // be unavailable, even for non-ODF documents, so append it here unconditionally
- pSet->Put(SfxUnoAnyItem(
- SID_ENCRYPTIONDATA,
- uno::Any(comphelper::concatSequences(
- aEncryptionData, comphelper::OStorageHelper::CreatePackageEncryptionData(
- pPasswordRequest->getPassword())))));
- }
+ const auto result = SetPassword(pCurrentFilter, pSet, pPasswordRequest->getPassword(), pPasswordRequest->getPasswordToModify());
- if ( pPasswordRequest->getRecommendReadOnly() )
- pSet->Put( SfxBoolItem( SID_RECOMMENDREADONLY, true ) );
+ if ( result != ERRCODE_IO_NOTSUPPORTED && pPasswordRequest->getRecommendReadOnly() )
+ pSet->Put( SfxBoolItem( SID_RECOMMENDREADONLY, true ) );
- if ( bMSType )
- {
- if (bOOXML)
- {
- uno::Sequence<beans::PropertyValue> aModifyPasswordInfo
- = ::comphelper::DocPasswordHelper::GenerateNewModifyPasswordInfoOOXML(
- pPasswordRequest->getPasswordToModify());
- if (aModifyPasswordInfo.hasElements())
- pSet->Put(
- SfxUnoAnyItem(SID_MODIFYPASSWORDINFO, uno::Any(aModifyPasswordInfo)));
- }
- else
- {
- // the empty password has 0 as Hash
- sal_Int32 nHash = SfxMedium::CreatePasswordToModifyHash(
- pPasswordRequest->getPasswordToModify(),
- pCurrentFilter->GetServiceName() == "com.sun.star.text.TextDocument");
- if (nHash)
- pSet->Put(SfxUnoAnyItem(SID_MODIFYPASSWORDINFO, uno::Any(nHash)));
- }
- }
- else
- {
- uno::Sequence< beans::PropertyValue > aModifyPasswordInfo = ::comphelper::DocPasswordHelper::GenerateNewModifyPasswordInfo( pPasswordRequest->getPasswordToModify() );
- if ( aModifyPasswordInfo.hasElements() )
- pSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::Any( aModifyPasswordInfo ) ) );
- }
- }
- else
- return ERRCODE_ABORT;
- return ERRCODE_NONE;
+ return result;
}
OUString EncodeSpaces_Impl( const OUString& rSource )