From 3add3e5b70ad991c8351a54b0da62d05e977458f Mon Sep 17 00:00:00 2001 From: Henry Castro Date: Mon, 9 Jul 2018 20:20:10 -0400 Subject: [PATCH] tdf#117895: "Edit document properties before saving"... option leaves just-saved document modified; changes are not saved Change-Id: Icad48fe1edcfb4c10c40f297326c23110144df53 Reviewed-on: https://gerrit.libreoffice.org/57211 Tested-by: Jenkins Reviewed-by: Mike Kaganski --- include/sfx2/asyncfunc.hxx | 39 ++++++++++++++++++++++++ include/sfx2/frame.hxx | 1 + sfx2/Library_sfx.mk | 1 + sfx2/sdi/sfx.sdi | 2 +- sfx2/source/control/asyncfunc.cxx | 63 +++++++++++++++++++++++++++++++++++++++ sfx2/source/doc/guisaveas.cxx | 54 +++++++++++++++++---------------- sfx2/source/doc/objserv.cxx | 9 ++++++ sfx2/source/view/frame.cxx | 10 ++++++- 8 files changed, 152 insertions(+), 27 deletions(-) create mode 100644 include/sfx2/asyncfunc.hxx create mode 100644 sfx2/source/control/asyncfunc.cxx diff --git a/include/sfx2/asyncfunc.hxx b/include/sfx2/asyncfunc.hxx new file mode 100644 index 000000000000..16e01969baba --- /dev/null +++ b/include/sfx2/asyncfunc.hxx @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_SFX2_ASYNCFUNC_HXX +#define INCLUDED_SFX2_ASYNCFUNC_HXX + +#include + +#include +#include + +class AsyncFunc : public cppu::WeakImplHelper +{ +private: + std::function m_pAsyncFunc; + +public: + AsyncFunc(const std::function&); + virtual ~AsyncFunc() override; + + static const css::uno::Sequence& getUnoTunnelId(); + static AsyncFunc* getImplementation(const css::uno::Reference&); + + void Execute(); + + //XUnoTunnel + virtual sal_Int64 SAL_CALL + getSomething(const css::uno::Sequence& aIdentifier) override; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/sfx2/frame.hxx b/include/sfx2/frame.hxx index dcec2b1ae037..151f728adc11 100644 --- a/include/sfx2/frame.hxx +++ b/include/sfx2/frame.hxx @@ -197,6 +197,7 @@ class SFX2_DLLPUBLIC SfxUnoAnyItem : public SfxPoolItem css::uno::Any aValue; public: static SfxPoolItem* CreateDefault(); + SfxUnoAnyItem(); SfxUnoAnyItem( sal_uInt16 nWhich, const css::uno::Any& rAny ); const css::uno::Any& GetValue() const { return aValue; } diff --git a/sfx2/Library_sfx.mk b/sfx2/Library_sfx.mk index 2cfa3b5dcf21..97f6f9706e76 100644 --- a/sfx2/Library_sfx.mk +++ b/sfx2/Library_sfx.mk @@ -125,6 +125,7 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\ sfx2/source/bastyp/sfxhtml \ sfx2/source/bastyp/sfxresid \ sfx2/source/config/evntconf \ + sfx2/source/control/asyncfunc \ sfx2/source/control/bindings \ sfx2/source/control/ctrlitem \ sfx2/source/control/ctrlfactoryimpl \ diff --git a/sfx2/sdi/sfx.sdi b/sfx2/sdi/sfx.sdi index 9031982badb5..927957e3684f 100644 --- a/sfx2/sdi/sfx.sdi +++ b/sfx2/sdi/sfx.sdi @@ -3244,7 +3244,7 @@ SfxBoolItem PrintPreview SID_PRINTPREVIEW SfxVoidItem SetDocumentProperties SID_DOCINFO -(SfxDocumentInfoItem Properties SID_DOCINFO) +(SfxDocumentInfoItem Properties SID_DOCINFO,SfxUnoAnyItem AsyncFunc FN_PARAM_2) [ AutoUpdate = FALSE, FastCall = FALSE, diff --git a/sfx2/source/control/asyncfunc.cxx b/sfx2/source/control/asyncfunc.cxx new file mode 100644 index 000000000000..f27931dcbf09 --- /dev/null +++ b/sfx2/source/control/asyncfunc.cxx @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include +#include + +#include + +namespace +{ +class theAsyncFuncUnoTunnelId : public rtl::Static +{ +}; +} + +AsyncFunc::AsyncFunc(const std::function& rAsyncFunc) + : m_pAsyncFunc(rAsyncFunc) +{ +} + +AsyncFunc::~AsyncFunc() {} + +void AsyncFunc::Execute() +{ + if (m_pAsyncFunc) + m_pAsyncFunc(); +} + +const css::uno::Sequence& AsyncFunc::getUnoTunnelId() +{ + return theAsyncFuncUnoTunnelId::get().getSeq(); +} + +AsyncFunc* AsyncFunc::getImplementation(const css::uno::Reference& xInterface) +{ + css::uno::Reference xUnoTunnel(xInterface, css::uno::UNO_QUERY); + if (xUnoTunnel.is()) + { + return reinterpret_cast(xUnoTunnel->getSomething(AsyncFunc::getUnoTunnelId())); + } + + return nullptr; +} + +//XUnoTunnel +sal_Int64 SAL_CALL AsyncFunc::getSomething(const css::uno::Sequence& rId) +{ + if (rId.getLength() == 16 + && 0 == memcmp(getUnoTunnelId().getConstArray(), rId.getConstArray(), 16)) + { + return sal::static_int_cast(reinterpret_cast(this)); + } + + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/doc/guisaveas.cxx b/sfx2/source/doc/guisaveas.cxx index 4df2c639da83..e01b51576d98 100644 --- a/sfx2/source/doc/guisaveas.cxx +++ b/sfx2/source/doc/guisaveas.cxx @@ -76,6 +76,7 @@ #include #include #include +#include #include #include #include @@ -334,7 +335,7 @@ public: const css::uno::Sequence< OUString >& rBlackList ); - bool ShowDocumentInfoDialog(); + bool ShowDocumentInfoDialog(const std::function< void () >&); static OUString GetRecommendedExtension( const OUString& aTypeName ); OUString GetRecommendedDir( const OUString& aSuggestedDir ); @@ -1102,7 +1103,7 @@ bool ModelData_Impl::OutputFileDialog( sal_Int16 nStoreMode, } -bool ModelData_Impl::ShowDocumentInfoDialog() +bool ModelData_Impl::ShowDocumentInfoDialog(const std::function< void () >& aFunc) { bool bDialogUsed = false; @@ -1125,7 +1126,11 @@ bool ModelData_Impl::ShowDocumentInfoDialog() 0 ); if ( xDispatch.is() ) { - xDispatch->dispatch( aURL, uno::Sequence< beans::PropertyValue >() ); + uno::Sequence< beans::PropertyValue > aProperties(1); + uno::Reference< lang::XUnoTunnel > aAsyncFunc(new AsyncFunc(aFunc)); + aProperties[0].Name = "AsyncFunc"; + aProperties[0].Value <<= aAsyncFunc; + xDispatch->dispatch( aURL, aProperties ); bDialogUsed = true; } } @@ -1631,34 +1636,33 @@ bool SfxStoringHelper::GUIStoreModel( const uno::Reference< frame::XModel >& xMo uno::Reference xOldDocProps( xCloneable->createClone(), uno::UNO_QUERY_THROW); - // use dispatch API to show document info dialog - if ( aModelData.ShowDocumentInfoDialog() ) - bDialogUsed = true; - else - { - OSL_FAIL( "Can't execute document info dialog!" ); - } + std::function< void () > aFunc = [xModel, xOldDocProps, nStoreMode, aURL, aArgsSequence]() { + SfxStoringHelper aStoringHelper; + ModelData_Impl aModel(aStoringHelper, xModel, aArgsSequence ); + + try + { + if ( nStoreMode & EXPORT_REQUESTED ) + aModel.GetStorable()->storeToURL( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aArgsSequence ); + else + aModel.GetStorable()->storeAsURL( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aArgsSequence ); + } + catch( const uno::Exception& ) + { + } - try { - // Document properties can contain streams that should be freed before storing - aModelData.FreeDocumentProps(); - if ( nStoreMode & EXPORT_REQUESTED ) - aModelData.GetStorable()->storeToURL( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aArgsSequence ); - else - aModelData.GetStorable()->storeAsURL( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aArgsSequence ); - } - catch( const uno::Exception& ) - { if ( nStoreMode & EXPORT_REQUESTED ) { - SetDocInfoState(aModelData.GetModel(), xOldDocProps, true); + SfxStoringHelper::SetDocInfoState(aModel.GetModel(), xOldDocProps, true); } - throw; - } + }; - if ( nStoreMode & EXPORT_REQUESTED ) + // use dispatch API to show document info dialog + if ( aModelData.ShowDocumentInfoDialog(aFunc) ) + bDialogUsed = true; + else { - SetDocInfoState(aModelData.GetModel(), xOldDocProps, true); + OSL_FAIL( "Can't execute document info dialog!" ); } } else diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index 0be2858aad5b..ad53b1a7bb56 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -66,6 +66,7 @@ #include #include +#include #include #include #include @@ -496,6 +497,14 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) pReq->AppendItem( SfxDocumentInfoItem( GetTitle(), getDocProperties(), aNewCmisProperties, IsUseUserData(), IsUseThumbnailSave() ) ); } + + css::uno::Reference< css::uno::XInterface > xInterface; + const SfxUnoAnyItem* pUnoAny = pReq->GetArg(FN_PARAM_2); + AsyncFunc* pAsyncFunc = pUnoAny && (pUnoAny->GetValue() >>= xInterface ) ? + AsyncFunc::getImplementation(xInterface) : nullptr; + if (pAsyncFunc) + pAsyncFunc->Execute(); + pReq->Done(); } else diff --git a/sfx2/source/view/frame.cxx b/sfx2/source/view/frame.cxx index 8441d12c0a32..82591b21c8fa 100644 --- a/sfx2/source/view/frame.cxx +++ b/sfx2/source/view/frame.cxx @@ -73,12 +73,16 @@ using namespace ::com::sun::star::util; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::container; -SfxPoolItem* SfxUnoAnyItem::CreateDefault() { SAL_WARN( "sfx", "No SfxUnoAnyItem factory available"); return nullptr; } +SfxPoolItem* SfxUnoAnyItem::CreateDefault() +{ + return new SfxUnoAnyItem(); +} SfxPoolItem* SfxUnoFrameItem::CreateDefault() { return new SfxUnoFrameItem(); } + void SfxFrame::Construct_Impl() { pImpl.reset(new SfxFrame_Impl); @@ -456,6 +460,10 @@ bool SfxFrameItem::PutValue( const css::uno::Any& rVal, sal_uInt8 ) return false; } +SfxUnoAnyItem::SfxUnoAnyItem() + : SfxPoolItem( 0 ) +{ +} SfxUnoAnyItem::SfxUnoAnyItem( sal_uInt16 nWhichId, const css::uno::Any& rAny ) : SfxPoolItem( nWhichId ) -- 2.11.4.GIT