filter/source/pdf/impdialog.cxx              |    7 
 filter/source/pdf/impdialog.hxx              |    2 
 filter/source/pdf/pdfdialog.cxx              |   24 ++
 filter/source/pdf/pdfdialog.hxx              |   13 +
 include/LibreOfficeKit/LibreOfficeKitEnums.h |   10 +
 include/sfx2/viewsh.hxx                      |    6 
 include/svtools/genericasyncunodialog.hxx    |  132 ++++++++++++++
 libreofficekit/source/gtk/lokdocview.cxx     |    1 
 offapi/com/sun/star/document/PDFDialog.idl   |    1 
 sfx2/inc/guisaveas.hxx                       |   32 +++
 sfx2/source/doc/guisaveas.cxx                |  246 +++++++++++++++++++--------
 sfx2/source/doc/objserv.cxx                  |   15 +
 sfx2/source/view/ipclient.cxx                |    3 
 vcl/jsdialog/enabled.cxx                     |    9 
 14 files changed, 419 insertions(+), 82 deletions(-)

New commits:
commit 89f5912ad2eee786508414791653a017206a7c04
Author:     NickWingate <nick.wing...@collabora.com>
AuthorDate: Thu Sep 22 09:02:42 2022 +0100
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Tue Dec 20 03:11:16 2022 +0000

    Async PDFExport dialog and parent methods
    
    Filter dialogs are all called generically from
    guisaveas.cxx in GUIStoreModel()
    
    Signed-off-by: NickWingate <nick.wing...@collabora.com>
    Change-Id: Idfbe85c09f84d4a7cf3f00b9704d5af94868a051
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140403
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Andras Timar <andras.ti...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144511
    Tested-by: Jenkins

diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx
index fd68322f1a23..a02412ac6caa 100644
--- a/filter/source/pdf/impdialog.cxx
+++ b/filter/source/pdf/impdialog.cxx
@@ -541,6 +541,8 @@ ImpPDFTabGeneralPage::ImpPDFTabGeneralPage(weld::Container* 
pPage, weld::DialogC
 
 ImpPDFTabGeneralPage::~ImpPDFTabGeneralPage()
 {
+    if (mxPasswordUnusedWarnDialog)
+        mxPasswordUnusedWarnDialog->response(RET_CANCEL);
 }
 
 void ImpPDFTabGeneralPage::SetFilterConfigItem(ImpPDFTabDialog* pParent)
@@ -871,10 +873,11 @@ IMPL_LINK_NOARG(ImpPDFTabGeneralPage, 
TogglePDFVersionOrUniversalAccessibilityHa
         // if a password was set, inform the user that this will not be used
         if (pSecPage && pSecPage->hasPassword())
         {
-            std::unique_ptr<weld::MessageDialog> 
xBox(Application::CreateMessageDialog(m_xContainer.get(),
+            mxPasswordUnusedWarnDialog =
+                
std::shared_ptr<weld::MessageDialog>(Application::CreateMessageDialog(m_xContainer.get(),
                                                       VclMessageType::Warning, 
VclButtonsType::Ok,
                                                       
FilterResId(STR_WARN_PASSWORD_PDFA)));
-            xBox->run();
+            mxPasswordUnusedWarnDialog->runAsync(mxPasswordUnusedWarnDialog, 
[] (sal_uInt32){ });
         }
     }
     else
diff --git a/filter/source/pdf/impdialog.hxx b/filter/source/pdf/impdialog.hxx
index 828422bdc63e..d0d63bccc86b 100644
--- a/filter/source/pdf/impdialog.hxx
+++ b/filter/source/pdf/impdialog.hxx
@@ -232,6 +232,8 @@ class ImpPDFTabGeneralPage : public SfxTabPage
 
     DECL_LINK(TogglePDFVersionOrUniversalAccessibilityHandle, 
weld::Toggleable&, void);
 
+    std::shared_ptr<weld::MessageDialog> mxPasswordUnusedWarnDialog;
+
 public:
 
     ImpPDFTabGeneralPage(weld::Container* pPage, weld::DialogController* 
pController, const SfxItemSet& rSet);
diff --git a/filter/source/pdf/pdfdialog.cxx b/filter/source/pdf/pdfdialog.cxx
index 7c3e5dda1956..c036fc747b2a 100644
--- a/filter/source/pdf/pdfdialog.cxx
+++ b/filter/source/pdf/pdfdialog.cxx
@@ -62,6 +62,13 @@ std::unique_ptr<weld::DialogController> 
PDFDialog::createDialog(const css::uno::
     return nullptr;
 }
 
+std::shared_ptr<SfxTabDialogController> PDFDialog::createAsyncDialog(const 
css::uno::Reference<css::awt::XWindow>& rParent)
+{
+    if( mxSrcDoc.is() )
+        return 
std::make_shared<ImpPDFTabDialog>(Application::GetFrameWeld(rParent), 
maFilterData, mxSrcDoc);
+    return nullptr;
+}
+
 void PDFDialog::executedDialog( sal_Int16 nExecutionResult )
 {
     if (nExecutionResult && m_xDialog)
@@ -69,6 +76,23 @@ void PDFDialog::executedDialog( sal_Int16 nExecutionResult )
     destroyDialog();
 }
 
+void PDFDialog::runAsync(const css::uno::Reference< 
css::ui::dialogs::XDialogClosedListener >& xListener)
+{
+    SfxTabDialogController::runAsync(m_xAsyncDialog, [this, 
xListener](sal_Int32 nResponse) {
+        executedAsyncDialog( m_xAsyncDialog, nResponse );
+        css::ui::dialogs::DialogClosedEvent aEvent;
+        aEvent.DialogResult = nResponse;
+        xListener->dialogClosed( aEvent );
+        destroyAsyncDialog();
+    });
+}
+
+void PDFDialog::executedAsyncDialog( std::shared_ptr<SfxTabDialogController> 
xAsyncDialog, sal_Int32 nExecutionResult )
+{
+    if (nExecutionResult && xAsyncDialog)
+        maFilterData = 
static_cast<ImpPDFTabDialog*>(xAsyncDialog.get())->GetFilterData();
+}
+
 Reference< XPropertySetInfo > SAL_CALL PDFDialog::getPropertySetInfo()
 {
     Reference< XPropertySetInfo >  xInfo( createPropertySetInfo( 
getInfoHelper() ) );
diff --git a/filter/source/pdf/pdfdialog.hxx b/filter/source/pdf/pdfdialog.hxx
index fcfd1d0976bd..2410192a2617 100644
--- a/filter/source/pdf/pdfdialog.hxx
+++ b/filter/source/pdf/pdfdialog.hxx
@@ -19,8 +19,6 @@
 
 #pragma once
 
-#include <svtools/genericunodialog.hxx>
-
 #include <comphelper/proparrhlp.hxx>
 #include <cppuhelper/implbase.hxx>
 
@@ -28,12 +26,16 @@
 #include <com/sun/star/document/XExporter.hpp>
 #include <com/sun/star/lang/XComponent.hpp>
 
+#include <sfx2/tabdlg.hxx>
+#include <svtools/genericasyncunodialog.hxx>
+
 using namespace ::com::sun::star::beans;
 using namespace ::com::sun::star::document;
 using namespace ::com::sun::star::lang;
 using namespace ::com::sun::star::uno;
 
-typedef ::cppu::ImplInheritanceHelper < ::svt::OGenericUnoDialog, 
XPropertyAccess, XExporter >  PDFDialog_Base;
+typedef ::cppu::ImplInheritanceHelper < 
::svt::OGenericUnoAsyncDialog<SfxTabDialogController>,
+                                        XPropertyAccess, XExporter >  
PDFDialog_Base;
 
 class PDFDialog final:
     public PDFDialog_Base,
@@ -54,6 +56,11 @@ private:
     virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
     virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const override;
 
+    // OGenericUnoAsyncDialog
+    virtual std::shared_ptr<SfxTabDialogController> createAsyncDialog(const 
css::uno::Reference<css::awt::XWindow>& rParent) override;
+    virtual void runAsync(const css::uno::Reference< 
css::ui::dialogs::XDialogClosedListener >& xListener) override;
+    virtual void executedAsyncDialog(std::shared_ptr<SfxTabDialogController> 
xAsyncDialog, sal_Int32 nExecutionResult) override;
+
     // XPropertyAccess
     using OPropertySetHelper::getPropertyValues;
     virtual Sequence< PropertyValue > SAL_CALL getPropertyValues(  ) override;
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h 
b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index 1e9821204c0b..38b3e5e62a40 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -899,6 +899,14 @@ typedef enum
      *      which is a representation of the pie segment.
      */
     LOK_CALLBACK_MEDIA_SHAPE = 58,
+
+    /**
+     * The document is available to download by the client.
+     *
+     * Payload example:
+     * "file:///tmp/hello-world.pdf"
+     */
+    LOK_CALLBACK_EXPORT_FILE = 59,
 }
 LibreOfficeKitCallbackType;
 
@@ -1045,6 +1053,8 @@ static inline const char* lokCallbackTypeToString(int 
nType)
         return "LOK_CALLBACK_FONTS_MISSING";
     case LOK_CALLBACK_MEDIA_SHAPE:
         return "LOK_CALLBACK_MEDIA_SHAPE";
+    case LOK_CALLBACK_EXPORT_FILE:
+        return "LOK_CALLBACK_EXPORT_FILE";
     }
 
     assert(!"Unknown LibreOfficeKitCallbackType type.");
diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx
index 5c8e8b1152f8..bb805cdc4179 100644
--- a/include/sfx2/viewsh.hxx
+++ b/include/sfx2/viewsh.hxx
@@ -56,6 +56,7 @@ class SfxPrinter;
 class NotifyEvent;
 class SfxInPlaceClient;
 class SfxLokCallbackInterface;
+class SfxStoringHelper;
 namespace rtl { class OStringBuffer; }
 namespace vcl { class PrinterController; }
 
@@ -173,6 +174,9 @@ friend class SfxPrinterController;
     /// Used to set the DocId at construction time. See SetCurrentDocId.
     static ViewShellDocId       mnCurrentDocId;
 
+    /// Used for async export
+    std::shared_ptr<SfxStoringHelper> m_xHelper;
+
 protected:
     virtual void                Activate(bool IsMDIActivate) override;
     virtual void                Deactivate(bool IsMDIActivate) override;
@@ -416,6 +420,8 @@ public:
     // Blocked Command view settings
     void setBlockedCommandList(const char* blockedCommandList);
     bool isBlockedCommand(OUString command);
+
+    void SetStoringHelper(std::shared_ptr<SfxStoringHelper> xHelper) { 
m_xHelper = xHelper; }
 };
 
 
diff --git a/include/svtools/genericasyncunodialog.hxx 
b/include/svtools/genericasyncunodialog.hxx
new file mode 100644
index 000000000000..7168d08f4301
--- /dev/null
+++ b/include/svtools/genericasyncunodialog.hxx
@@ -0,0 +1,132 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
+#include <sfx2/tabdlg.hxx>
+#include <svtools/genericunodialog.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace css::uno;
+
+namespace svt
+{
+typedef cppu::ImplInheritanceHelper<::svt::OGenericUnoDialog,
+                                    
css::ui::dialogs::XAsynchronousExecutableDialog>
+    OGenericUnoAsyncDialogBase;
+
+/** abstract base class for implementing UNO objects representing asynchronous 
dialogs
+    */
+template <typename T> class OGenericUnoAsyncDialog : public 
OGenericUnoAsyncDialogBase
+{
+    class UnoAsyncDialogEntryGuard
+    {
+    public:
+        UnoAsyncDialogEntryGuard(OGenericUnoAsyncDialog<T>& _rDialog)
+            : m_aGuard(_rDialog.GetMutex())
+        {
+        }
+
+    private:
+        ::osl::MutexGuard m_aGuard;
+    };
+
+protected:
+    std::shared_ptr<T> m_xAsyncDialog;
+
+protected:
+    OGenericUnoAsyncDialog(const 
css::uno::Reference<css::uno::XComponentContext>& _rxContext)
+        : OGenericUnoAsyncDialogBase(_rxContext)
+    {
+    }
+
+    virtual ~OGenericUnoAsyncDialog() override
+    {
+        SolarMutexGuard aSolarGuard;
+        ::osl::MutexGuard aGuard(m_aMutex);
+        if (m_xAsyncDialog)
+            destroyAsyncDialog();
+    }
+
+public:
+    // XAsynchronousExecutableDialog
+    void SAL_CALL setDialogTitle(const OUString& aTitle) override
+    {
+        OGenericUnoDialog::setTitle(aTitle);
+    }
+
+    virtual void SAL_CALL startExecuteModal(
+        const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& 
xListener) override
+    {
+        SolarMutexGuard aSolarGuard;
+
+        {
+            UnoAsyncDialogEntryGuard aGuard(*this);
+
+            if (m_bExecuting)
+                throw RuntimeException("already executing the dialog 
(recursive call)", *this);
+
+            if (!m_xAsyncDialog)
+            {
+                m_xAsyncDialog = createAsyncDialog(m_xParent);
+                OSL_ENSURE(m_xAsyncDialog, 
"OGenericUnoAsyncDialog::startExecuteModal: "
+                                           "createAsyncDialog returned 
nonsense!");
+                if (!m_xAsyncDialog)
+                    return;
+
+                // do some initialisations
+                if (!m_bTitleAmbiguous)
+                    m_xAsyncDialog->set_title(m_sTitle);
+            }
+
+            m_bExecuting = true;
+        }
+
+        runAsync(xListener);
+    }
+
+protected:
+    virtual std::shared_ptr<T>
+    createAsyncDialog(const css::uno::Reference<css::awt::XWindow>& 
/*rParent*/)
+    {
+        return nullptr;
+    }
+
+    void destroyAsyncDialog()
+    {
+        SolarMutexGuard aSolarGuard;
+        if (m_xAsyncDialog)
+            m_xAsyncDialog.reset();
+    }
+
+    virtual void
+    runAsync(const 
css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& /*xListener*/)
+    {
+    }
+
+    virtual void executedAsyncDialog(std::shared_ptr<T> /*xAsyncDialog*/,
+                                     sal_Int32 /*_nExecutionResult*/)
+    {
+    }
+};
+
+} // namespace svt
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/libreofficekit/source/gtk/lokdocview.cxx 
b/libreofficekit/source/gtk/lokdocview.cxx
index 4fc6fe0452c1..ff40e4929781 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -1485,6 +1485,7 @@ callback (gpointer pData)
     case LOK_CALLBACK_PRINT_RANGES:
     case LOK_CALLBACK_FONTS_MISSING:
     case LOK_CALLBACK_MEDIA_SHAPE:
+    case LOK_CALLBACK_EXPORT_FILE:
     {
         // TODO: Implement me
         break;
diff --git a/offapi/com/sun/star/document/PDFDialog.idl 
b/offapi/com/sun/star/document/PDFDialog.idl
index e92b57accd2d..007b30ebef22 100644
--- a/offapi/com/sun/star/document/PDFDialog.idl
+++ b/offapi/com/sun/star/document/PDFDialog.idl
@@ -36,6 +36,7 @@ service PDFDialog
         "officecfg/registry/schema/org/openoffice/Office/Common.xcs"
     */
 
+    interface ::com::sun::star::ui::dialogs::XAsynchronousExecutableDialog;
 };
 
 
diff --git a/sfx2/inc/guisaveas.hxx b/sfx2/inc/guisaveas.hxx
index c19f78e3fdf1..88a69711c8fd 100644
--- a/sfx2/inc/guisaveas.hxx
+++ b/sfx2/inc/guisaveas.hxx
@@ -31,8 +31,15 @@
 #include <com/sun/star/frame/XModel.hpp>
 #include <com/sun/star/frame/XModuleManager2.hpp>
 
+#include <comphelper/sequenceashashmap.hxx>
+
+#include <sfx2/bindings.hxx>
 #include <sfx2/signaturestate.hxx>
 
+#include <svtools/dialogclosedlistener.hxx>
+
+#include <tools/urlobj.hxx>
+
 
 namespace com::sun::star::document { class XDocumentProperties; }
 
@@ -48,10 +55,32 @@ private:
     css::uno::Reference< css::container::XContainerQuery > m_xFilterQuery;
     css::uno::Reference< css::frame::XModuleManager2 >     m_xModuleManager;
 
+    std::shared_ptr<ModelData_Impl> m_xModelData;
+    css::uno::Sequence< css::beans::PropertyValue > m_aArgsSequence;
+
     css::uno::Reference< css::container::XNameAccess > const & 
GetFilterConfiguration();
     css::uno::Reference< css::container::XContainerQuery > const & 
GetFilterQuery();
     css::uno::Reference< css::frame::XModuleManager2 > const & 
GetModuleManager();
 
+    bool m_xDialogUsed;
+    bool m_bRemote;
+    bool m_bPreselectPassword;
+    bool m_bDialogUsed;
+    bool m_bSetStandardName;
+    sal_Int16 m_nStoreMode;
+
+    DECL_LINK(FilterDialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, 
void);
+
+    static bool 
FinishGUIStoreModel(::comphelper::SequenceAsHashMap::const_iterator& 
aFileNameIter,
+                             ModelData_Impl& aModelData, bool bRemote, 
sal_Int16 nStoreMode,
+                             css::uno::Sequence< css::beans::PropertyValue >& 
aFilterProps,
+                             bool bSetStandardName, bool bPreselectPassword, 
bool bDialogUsed,
+                             std::u16string_view aFilterFromMediaDescr, 
std::u16string_view aOldFilterName,
+                             css::uno::Sequence< css::beans::PropertyValue >& 
aArgsSequence,
+                             OUString aFilterName);
+
+    void CallFinishGUIStoreModel();
+
 public:
     SfxStoringHelper();
 
@@ -60,7 +89,8 @@ public:
                     std::u16string_view aSlotName,
                     css::uno::Sequence< css::beans::PropertyValue >& 
aArgsSequence,
                     bool bPreselectPassword,
-                    SignatureState nDocumentSignatureState );
+                    SignatureState nDocumentSignatureState,
+                    bool bIsAsync );
 
     static bool CheckFilterOptionsAppearance(
                     const css::uno::Reference< css::container::XNameAccess >& 
xFilterCFG,
diff --git a/sfx2/source/doc/guisaveas.cxx b/sfx2/source/doc/guisaveas.cxx
index 7cce6b515db4..d95d2bb2c289 100644
--- a/sfx2/source/doc/guisaveas.cxx
+++ b/sfx2/source/doc/guisaveas.cxx
@@ -18,6 +18,7 @@
  */
 
 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
@@ -55,16 +56,20 @@
 #include <tools/debug.hxx>
 #include <comphelper/diagnose_ex.hxx>
 #include <tools/urlobj.hxx>
+#include <tools/json_writer.hxx>
+#include <tools/urlobj.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/propertysequence.hxx>
 #include <comphelper/propertyvalue.hxx>
 #include <comphelper/sequenceashashmap.hxx>
 #include <comphelper/mimeconfighelper.hxx>
 #include <comphelper/lok.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <utility>
 #include <vcl/svapp.hxx>
 #include <vcl/weld.hxx>
 #include <o3tl/char16_t2wchar_t.hxx>
+#include <unotools/tempfile.hxx>
 
 #include <sfx2/sfxsids.hrc>
 #include <sfx2/strings.hrc>
@@ -72,6 +77,8 @@
 #include <sfx2/filedlghelper.hxx>
 #include <sfx2/app.hxx>
 #include <sfx2/sfxuno.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/bindings.hxx>
 #include <alienwarn.hxx>
 
 #include <memory>
@@ -261,10 +268,15 @@ class ModelData_Impl
     std::unique_ptr<::comphelper::SequenceAsHashMap> m_pDocumentPropsHM;
     std::unique_ptr<::comphelper::SequenceAsHashMap> m_pModulePropsHM;
 
+    uno::Reference<beans::XPropertyAccess> m_xFilterProperties;
+    uno::Reference<ui::dialogs::XAsynchronousExecutableDialog> m_xFilterDialog;
+
     ::comphelper::SequenceAsHashMap m_aMediaDescrHM;
 
     bool m_bRecommendReadOnly;
 
+    DECL_LINK(OptionsDialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, 
void);
+
 public:
     ModelData_Impl( SfxStoringHelper& aOwner,
                     uno::Reference< frame::XModel > xModel,
@@ -296,7 +308,7 @@ public:
     uno::Sequence< beans::PropertyValue > GetPreselectedFilter_Impl( sal_Int16 
nStoreMode );
     uno::Sequence< beans::PropertyValue > GetDocServiceDefaultFilter();
 
-    bool ExecuteFilterDialog_Impl( const OUString& aFilterName );
+    bool ExecuteFilterDialog_Impl( const OUString& aFilterName, bool bAsync );
 
     sal_Int8 CheckSaveAcceptable( sal_Int8 nCurStatus );
     sal_Int8 CheckStateForSave();
@@ -322,7 +334,6 @@ public:
     OUString GetRecommendedDir( const OUString& aSuggestedDir );
     OUString GetRecommendedName( const OUString& aSuggestedName,
                                         const OUString& aTypeName );
-
 };
 
 
@@ -343,6 +354,8 @@ ModelData_Impl::~ModelData_Impl()
     FreeDocumentProps();
     m_pDocumentPropsHM.reset();
     m_pModulePropsHM.reset();
+    if (m_xFilterProperties)
+        m_xFilterProperties.clear();
 }
 
 
@@ -535,7 +548,7 @@ uno::Sequence< beans::PropertyValue > 
ModelData_Impl::GetPreselectedFilter_Impl(
 }
 
 
-bool ModelData_Impl::ExecuteFilterDialog_Impl( const OUString& aFilterName )
+bool ModelData_Impl::ExecuteFilterDialog_Impl( const OUString& aFilterName, 
bool bIsAsync )
 {
     bool bDialogUsed = false;
 
@@ -557,15 +570,31 @@ bool ModelData_Impl::ExecuteFilterDialog_Impl( const 
OUString& aFilterName )
                         {"ParentWindow", 
uno::Any(SfxStoringHelper::GetModelXWindow(m_xModel))},
                     }));
 
-                    uno::Reference< ui::dialogs::XExecutableDialog > 
xFilterDialog(
-                                                
comphelper::getProcessServiceFactory()->createInstanceWithArguments(aServiceName,
 aDialogArgs), uno::UNO_QUERY );
-                    uno::Reference< beans::XPropertyAccess > 
xFilterProperties( xFilterDialog, uno::UNO_QUERY );
+                    uno::Reference< beans::XPropertyAccess > xFilterProperties;
+                    uno::Reference< ui::dialogs::XExecutableDialog > 
xFilterDialog;
+                    uno::Reference< ui::dialogs::XAsynchronousExecutableDialog 
> xAsyncFilterDialog;
+                    uno::Reference< document::XExporter > xExporter;
 
-                    if( xFilterDialog.is() && xFilterProperties.is() )
+                    if ( bIsAsync )
+                    {
+                        xAsyncFilterDialog = uno::Reference< 
ui::dialogs::XAsynchronousExecutableDialog >(
+                            
comphelper::getProcessServiceFactory()->createInstanceWithArguments( 
aServiceName, aDialogArgs ), uno::UNO_QUERY );
+                        OSL_ENSURE(xAsyncFilterDialog.is(), 
"ModelData_Impl::ExecuteFilterDialog_Impl: Dialog is not async!");
+                        xFilterProperties = uno::Reference< 
beans::XPropertyAccess >( xAsyncFilterDialog, uno::UNO_QUERY );
+                        xExporter = uno::Reference< document::XExporter >( 
xAsyncFilterDialog, uno::UNO_QUERY );
+                    }
+                    else
+                    {
+                        xFilterDialog = uno::Reference< 
ui::dialogs::XExecutableDialog >(
+                            
comphelper::getProcessServiceFactory()->createInstanceWithArguments( 
aServiceName, aDialogArgs ), uno::UNO_QUERY );
+                        xFilterProperties = uno::Reference< 
beans::XPropertyAccess >( xFilterDialog, uno::UNO_QUERY );
+                        xExporter = uno::Reference< document::XExporter >( 
xFilterDialog, uno::UNO_QUERY );
+                    }
+
+                    if ( xFilterProperties.is() && ( xFilterDialog.is() || 
xAsyncFilterDialog.is() ) )
                     {
                         bDialogUsed = true;
 
-                        uno::Reference< document::XExporter > xExporter( 
xFilterDialog, uno::UNO_QUERY );
                         if( xExporter.is() )
                             xExporter->setSourceDocument( GetModel() );
 
@@ -573,19 +602,32 @@ bool ModelData_Impl::ExecuteFilterDialog_Impl( const 
OUString& aFilterName )
                         GetMediaDescr() >> aPropsForDialog;
                         xFilterProperties->setPropertyValues( aPropsForDialog 
);
 
-                        if( !xFilterDialog->execute() )
+                        if ( bIsAsync )
                         {
-                            throw task::ErrorCodeIOException(
-                                ("ModelData_Impl::ExecuteFilterDialog_Impl:"
-                                 " ERRCODE_IO_ABORT"),
-                                uno::Reference< uno::XInterface >(),
-                                sal_uInt32(ERRCODE_IO_ABORT));
-                        }
+                            m_xFilterProperties = xFilterProperties;
+                            m_xFilterDialog = xAsyncFilterDialog;
+
+                            auto aDialogClosedListener = rtl::Reference(new 
svt::DialogClosedListener());
+                            aDialogClosedListener->SetDialogClosedLink( LINK( 
this, ModelData_Impl, OptionsDialogClosedHdl ) );
 
-                        const uno::Sequence< beans::PropertyValue > 
aPropsFromDialog =
-                                                                    
xFilterProperties->getPropertyValues();
-                        for ( const auto& rProp : aPropsFromDialog )
-                            GetMediaDescr()[rProp.Name] = rProp.Value;
+                            m_xFilterDialog->startExecuteModal( 
aDialogClosedListener );
+                        }
+                        else
+                        {
+                            if( !xFilterDialog->execute() )
+                            {
+                                throw task::ErrorCodeIOException(
+                                    
("ModelData_Impl::ExecuteFilterDialog_Impl:"
+                                    " ERRCODE_IO_ABORT"),
+                                    uno::Reference< uno::XInterface >(),
+                                    sal_uInt32(ERRCODE_IO_ABORT));
+                            }
+
+                            const uno::Sequence< beans::PropertyValue > 
aPropsFromDialog =
+                                                                        
xFilterProperties->getPropertyValues();
+                            for ( const auto& rProp : aPropsFromDialog )
+                                GetMediaDescr()[rProp.Name] = rProp.Value;
+                        }
                     }
                 }
             }
@@ -611,6 +653,34 @@ bool ModelData_Impl::ExecuteFilterDialog_Impl( const 
OUString& aFilterName )
     return bDialogUsed;
 }
 
+void SfxStoringHelper::CallFinishGUIStoreModel()
+{
+    ::comphelper::SequenceAsHashMap::const_iterator aFileNameIter = 
m_xModelData->GetMediaDescr().find( OUString("URL") );
+    uno::Sequence< beans::PropertyValue > aFilterProps = 
m_xModelData->GetPreselectedFilter_Impl( m_nStoreMode );
+    const OUString aFilterFromMediaDescr = 
m_xModelData->GetMediaDescr().getUnpackedValueOrDefault( aFilterNameString, 
OUString() );
+    const OUString aOldFilterName = 
m_xModelData->GetDocProps().getUnpackedValueOrDefault( aFilterNameString, 
OUString() );
+    ::comphelper::SequenceAsHashMap aFilterPropsHM( aFilterProps );
+    OUString aFilterName = aFilterPropsHM.getUnpackedValueOrDefault( "Name", 
OUString() );
+
+    SfxStoringHelper::FinishGUIStoreModel(aFileNameIter, *m_xModelData, 
m_bRemote, m_nStoreMode, aFilterProps,
+                                          m_bSetStandardName, 
m_bPreselectPassword, m_bDialogUsed,
+                                          aFilterFromMediaDescr, 
aOldFilterName, m_aArgsSequence, aFilterName);
+
+    if (SfxViewShell::Current())
+        SfxViewShell::Current()->SetStoringHelper(nullptr);
+}
+
+IMPL_LINK( ModelData_Impl, OptionsDialogClosedHdl, 
css::ui::dialogs::DialogClosedEvent*, pEvt, void )
+{
+    if (pEvt->DialogResult == RET_OK && m_xFilterProperties)
+    {
+        const uno::Sequence< beans::PropertyValue > aPropsFromDialog = 
m_xFilterProperties->getPropertyValues();
+        for ( const auto& rProp : aPropsFromDialog )
+            GetMediaDescr()[rProp.Name] = rProp.Value;
+
+        m_pOwner->CallFinishGUIStoreModel();
+    }
+}
 
 sal_Int8 ModelData_Impl::CheckSaveAcceptable( sal_Int8 nCurStatus )
 {
@@ -994,12 +1064,18 @@ bool ModelData_Impl::OutputFileDialog( sal_Int16 
nStoreMode,
 
     // aFilterName is a pure output parameter, pDialogParams is an in/out 
parameter
     OUString aFilterName;
-    if ( pFileDlg->Execute( pDialogParams, aFilterName ) != ERRCODE_NONE )
+    // in LOK case we don't show File Picker so it will fail, but execute to 
do other preparations
+    if ( pFileDlg->Execute( pDialogParams, aFilterName ) != ERRCODE_NONE
+        && !comphelper::LibreOfficeKit::isActive() )
     {
         throw task::ErrorCodeIOException(
             "ModelData_Impl::OutputFileDialog: ERRCODE_IO_ABORT",
             uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_IO_ABORT));
     }
+    else if (comphelper::LibreOfficeKit::isActive())
+    {
+        aFilterName = aPreselectedFilterPropsHM.getUnpackedValueOrDefault( 
"Name", OUString() );
+    }
 
     // the following two arguments can not be converted in MediaDescriptor,
     // so they should be removed from the ItemSet after retrieving
@@ -1022,9 +1098,6 @@ bool ModelData_Impl::OutputFileDialog( sal_Int16 
nStoreMode,
     const OUString aFilterFromMediaDescr = 
GetMediaDescr().getUnpackedValueOrDefault( sFilterNameString, OUString() );
     const OUString aOldFilterName = GetDocProps().getUnpackedValueOrDefault( 
sFilterNameString, OUString() );
 
-    const OUString sFilterOptionsString(aFilterOptionsString);
-    const OUString sFilterDataString(aFilterDataString);
-
     if ( aFilterName == aFilterFromMediaDescr )
     {
         // preserve current settings if any
@@ -1034,32 +1107,32 @@ bool ModelData_Impl::OutputFileDialog( sal_Int16 
nStoreMode,
         if ( aFilterFromMediaDescr == aOldFilterName )
         {
             ::comphelper::SequenceAsHashMap::const_iterator aIter =
-                                        GetDocProps().find( 
sFilterOptionsString );
+                                        GetDocProps().find( 
aFilterOptionsString );
             if ( aIter != GetDocProps().end()
-              && GetMediaDescr().find( sFilterOptionsString ) == 
GetMediaDescr().end() )
+              && GetMediaDescr().find( aFilterOptionsString ) == 
GetMediaDescr().end() )
                 GetMediaDescr()[aIter->first] = aIter->second;
 
-            aIter = GetDocProps().find( sFilterDataString );
+            aIter = GetDocProps().find( aFilterDataString );
             if ( aIter != GetDocProps().end()
-              && GetMediaDescr().find( sFilterDataString ) == 
GetMediaDescr().end() )
+              && GetMediaDescr().find( aFilterDataString ) == 
GetMediaDescr().end() )
                 GetMediaDescr()[aIter->first] = aIter->second;
         }
     }
     else
     {
-        GetMediaDescr().erase( sFilterDataString );
-        GetMediaDescr().erase( sFilterOptionsString );
+        GetMediaDescr().erase( aFilterDataString );
+        GetMediaDescr().erase( aFilterOptionsString );
 
         if ( aFilterName == aOldFilterName )
         {
             // merge filter option of the document filter
 
             ::comphelper::SequenceAsHashMap::const_iterator aIter =
-                                GetDocProps().find( sFilterOptionsString );
+                                GetDocProps().find( aFilterOptionsString );
             if ( aIter != GetDocProps().end() )
                 GetMediaDescr()[aIter->first] = aIter->second;
 
-            aIter = GetDocProps().find( sFilterDataString );
+            aIter = GetDocProps().find( aFilterDataString );
             if ( aIter != GetDocProps().end() )
                 GetMediaDescr()[aIter->first] = aIter->second;
         }
@@ -1083,8 +1156,8 @@ bool ModelData_Impl::OutputFileDialog( sal_Int16 
nStoreMode,
                 aVal >>= bUseFilterOptions;
                 if ( !bUseFilterOptions )
                     bUseFilterOptions =
-                      ( GetMediaDescr().find( sFilterDataString ) == 
GetMediaDescr().end()
-                      && GetMediaDescr().find( sFilterOptionsString ) == 
GetMediaDescr().end() );
+                      ( GetMediaDescr().find( aFilterDataString ) == 
GetMediaDescr().end()
+                      && GetMediaDescr().find( aFilterOptionsString ) == 
GetMediaDescr().end() );
             }
             catch( const lang::IllegalArgumentException& )
             {}
@@ -1309,24 +1382,26 @@ bool SfxStoringHelper::GUIStoreModel( const 
uno::Reference< frame::XModel >& xMo
                                             std::u16string_view aSlotName,
                                             uno::Sequence< 
beans::PropertyValue >& aArgsSequence,
                                             bool bPreselectPassword,
-                                            SignatureState 
nDocumentSignatureState )
+                                            SignatureState 
nDocumentSignatureState,
+                                            bool bIsAsync)
 {
-    ModelData_Impl aModelData( *this, xModel, aArgsSequence );
-
-    bool bDialogUsed = false;
+    m_xModelData = std::make_shared<ModelData_Impl>( *this, xModel, 
aArgsSequence );
+    m_aArgsSequence = aArgsSequence;
+    ModelData_Impl& aModelData = *m_xModelData;
 
-    INetURLObject aURL;
+    m_bDialogUsed = false;
 
-    bool bSetStandardName = false; // can be set only for SaveAs
+    m_bSetStandardName = false; // can be set only for SaveAs
+    m_bPreselectPassword = bPreselectPassword;
 
     // parse the slot name
-    bool bRemote = false;
-    sal_Int16 nStoreMode = getStoreModeFromSlotName( aSlotName );
+    m_bRemote = false;
+    m_nStoreMode = getStoreModeFromSlotName( aSlotName );
 
-    if ( nStoreMode == SAVEASREMOTE_REQUESTED )
+    if ( m_nStoreMode == SAVEASREMOTE_REQUESTED )
     {
-        nStoreMode = SAVEAS_REQUESTED;
-        bRemote = true;
+        m_nStoreMode = SAVEAS_REQUESTED;
+        m_bRemote = true;
     }
 
     sal_Int8 nStatusSave = STATUS_NO_ACTION;
@@ -1338,10 +1413,10 @@ bool SfxStoringHelper::GUIStoreModel( const 
uno::Reference< frame::XModel >& xMo
         bool bSaveACopy = false;
         aSaveACopyIter->second >>= bSaveACopy;
         if ( bSaveACopy )
-            nStoreMode = EXPORT_REQUESTED | SAVEACOPY_REQUESTED | 
WIDEEXPORT_REQUESTED;
+            m_nStoreMode = EXPORT_REQUESTED | SAVEACOPY_REQUESTED | 
WIDEEXPORT_REQUESTED;
     }
     // handle the special cases
-    if ( nStoreMode & SAVEAS_REQUESTED )
+    if ( m_nStoreMode & SAVEAS_REQUESTED )
     {
         ::comphelper::SequenceAsHashMap::const_iterator aSaveToIter =
                         aModelData.GetMediaDescr().find( OUString("SaveTo") );
@@ -1350,16 +1425,16 @@ bool SfxStoringHelper::GUIStoreModel( const 
uno::Reference< frame::XModel >& xMo
             bool bWideExport = false;
             aSaveToIter->second >>= bWideExport;
             if ( bWideExport )
-                nStoreMode = EXPORT_REQUESTED | WIDEEXPORT_REQUESTED;
+                m_nStoreMode = EXPORT_REQUESTED | WIDEEXPORT_REQUESTED;
         }
 
         // if saving is not acceptable the warning must be shown even in case 
of SaveAs operation
-        if ( ( nStoreMode & SAVEAS_REQUESTED ) && 
aModelData.CheckSaveAcceptable( STATUS_SAVEAS ) == STATUS_NO_ACTION )
+        if ( ( m_nStoreMode & SAVEAS_REQUESTED ) && 
aModelData.CheckSaveAcceptable( STATUS_SAVEAS ) == STATUS_NO_ACTION )
             throw task::ErrorCodeIOException(
                 "SfxStoringHelper::GUIStoreModel: ERRCODE_IO_ABORT",
                 uno::Reference< uno::XInterface >(), 
sal_uInt32(ERRCODE_IO_ABORT));
     }
-    else if ( nStoreMode & SAVE_REQUESTED )
+    else if ( m_nStoreMode & SAVE_REQUESTED )
     {
         // if saving is not acceptable by the configuration the warning must 
be shown
         nStatusSave = aModelData.CheckSaveAcceptable( STATUS_SAVE );
@@ -1383,13 +1458,13 @@ bool SfxStoringHelper::GUIStoreModel( const 
uno::Reference< frame::XModel >& xMo
         else if ( nStatusSave != STATUS_SAVE )
         {
             // this should be a usual SaveAs operation
-            nStoreMode = SAVEAS_REQUESTED;
+            m_nStoreMode = SAVEAS_REQUESTED;
             if ( nStatusSave == STATUS_SAVEAS_STANDARDNAME )
-                bSetStandardName = true;
+                m_bSetStandardName = true;
         }
     }
 
-    if (!comphelper::LibreOfficeKit::isActive() && !( nStoreMode & 
EXPORT_REQUESTED ) )
+    if (!comphelper::LibreOfficeKit::isActive() && !( m_nStoreMode & 
EXPORT_REQUESTED ) )
     {
         // if it is no export, warn user that the signature will be removed
         if (  SignatureState::OK == nDocumentSignatureState
@@ -1409,7 +1484,7 @@ bool SfxStoringHelper::GUIStoreModel( const 
uno::Reference< frame::XModel >& xMo
         }
     }
 
-    if ( nStoreMode & SAVE_REQUESTED && nStatusSave == STATUS_SAVE )
+    if ( m_nStoreMode & SAVE_REQUESTED && nStatusSave == STATUS_SAVE )
     {
         // Document properties can contain streams that should be freed before 
storing
         aModelData.FreeDocumentProps();
@@ -1436,7 +1511,7 @@ bool SfxStoringHelper::GUIStoreModel( const 
uno::Reference< frame::XModel >& xMo
     }
 
     // preselect a filter for the storing process
-    uno::Sequence< beans::PropertyValue > aFilterProps = 
aModelData.GetPreselectedFilter_Impl( nStoreMode );
+    uno::Sequence< beans::PropertyValue > aFilterProps = 
aModelData.GetPreselectedFilter_Impl( m_nStoreMode );
 
     DBG_ASSERT( aFilterProps.hasElements(), "No filter for storing!\n" );
     if ( !aFilterProps.hasElements() )
@@ -1447,33 +1522,50 @@ bool SfxStoringHelper::GUIStoreModel( const 
uno::Reference< frame::XModel >& xMo
     ::comphelper::SequenceAsHashMap aFilterPropsHM( aFilterProps );
     OUString aFilterName = aFilterPropsHM.getUnpackedValueOrDefault( "Name", 
OUString() );
 
-    const OUString sFilterNameString(aFilterNameString);
+    const OUString aFilterFromMediaDescr = 
aModelData.GetMediaDescr().getUnpackedValueOrDefault( aFilterNameString, 
OUString() );
+    const OUString aOldFilterName = 
aModelData.GetDocProps().getUnpackedValueOrDefault( aFilterNameString, 
OUString() );
 
-    const OUString aFilterFromMediaDescr = 
aModelData.GetMediaDescr().getUnpackedValueOrDefault( sFilterNameString, 
OUString() );
-    const OUString aOldFilterName = 
aModelData.GetDocProps().getUnpackedValueOrDefault( sFilterNameString, 
OUString() );
-
-    bool bUseFilterOptions = false;
     ::comphelper::SequenceAsHashMap::const_iterator aFileNameIter = 
aModelData.GetMediaDescr().find( OUString("URL") );
 
-    const OUString sFilterOptionsString(aFilterOptionsString);
-    const OUString sFilterDataString(aFilterDataString);
-
-    bool bPDFOptions = (nStoreMode & PDFEXPORT_REQUESTED) && !(nStoreMode & 
PDFDIRECTEXPORT_REQUESTED);
-    bool bEPUBOptions = (nStoreMode & EPUBEXPORT_REQUESTED) && !(nStoreMode & 
EPUBDIRECTEXPORT_REQUESTED);
-    if ( ( nStoreMode & EXPORT_REQUESTED ) && (bPDFOptions || bEPUBOptions) )
+    bool bPDFOptions = (m_nStoreMode & PDFEXPORT_REQUESTED) && !(m_nStoreMode 
& PDFDIRECTEXPORT_REQUESTED);
+    bool bEPUBOptions = (m_nStoreMode & EPUBEXPORT_REQUESTED) && 
!(m_nStoreMode & EPUBDIRECTEXPORT_REQUESTED);
+    if ( ( m_nStoreMode & EXPORT_REQUESTED ) && (bPDFOptions || bEPUBOptions) )
     {
         // this is PDF or EPUB export, the filter options dialog should be 
shown before the export
-        aModelData.GetMediaDescr()[sFilterNameString] <<= aFilterName;
+        aModelData.GetMediaDescr()[aFilterNameString] <<= aFilterName;
         if ( aModelData.GetMediaDescr().find( "FilterFlags" ) == 
aModelData.GetMediaDescr().end()
-          && aModelData.GetMediaDescr().find( sFilterOptionsString ) == 
aModelData.GetMediaDescr().end()
-          && aModelData.GetMediaDescr().find( sFilterDataString ) == 
aModelData.GetMediaDescr().end() )
+          && aModelData.GetMediaDescr().find( aFilterOptionsString ) == 
aModelData.GetMediaDescr().end()
+          && aModelData.GetMediaDescr().find( aFilterDataString ) == 
aModelData.GetMediaDescr().end() )
         {
             // execute filter options dialog since no options are set in the 
media descriptor
-            if ( aModelData.ExecuteFilterDialog_Impl( aFilterName ) )
-                bDialogUsed = true;
+            if ( aModelData.ExecuteFilterDialog_Impl( aFilterName, bIsAsync ) )
+                m_bDialogUsed = true;
         }
     }
 
+    if (bIsAsync)
+        return false;
+
+    return SfxStoringHelper::FinishGUIStoreModel(aFileNameIter, aModelData, 
m_bRemote, m_nStoreMode, aFilterProps,
+                                                 m_bSetStandardName, 
m_bPreselectPassword, m_bDialogUsed,
+                                                 aFilterFromMediaDescr, 
aOldFilterName, aArgsSequence, aFilterName);
+}
+
+bool 
SfxStoringHelper::FinishGUIStoreModel(::comphelper::SequenceAsHashMap::const_iterator&
 aFileNameIter,
+                                          ModelData_Impl& aModelData, bool 
bRemote, sal_Int16 nStoreMode,
+                                          uno::Sequence< beans::PropertyValue 
>& aFilterProps,
+                                          bool bSetStandardName, bool 
bPreselectPassword, bool bDialogUsed,
+                                          std::u16string_view 
aFilterFromMediaDescr,
+                                          std::u16string_view aOldFilterName,
+                                          uno::Sequence< beans::PropertyValue 
>& aArgsSequence,
+                                          OUString aFilterName)
+{
+    const OUString sFilterNameString(aFilterNameString);
+    const OUString sFilterOptionsString(aFilterOptionsString);
+    const OUString sFilterDataString(aFilterDataString);
+    bool bUseFilterOptions = false;
+    INetURLObject aURL;
+
     if ( aFileNameIter == aModelData.GetMediaDescr().end() )
     {
         sal_Int16 nDialog = SFX2_IMPL_DIALOG_CONFIG;
@@ -1605,7 +1697,7 @@ bool SfxStoringHelper::GUIStoreModel( const 
uno::Reference< frame::XModel >& xMo
         && ( ( nStoreMode & EXPORT_REQUESTED ) || bUseFilterOptions ) )
     {
         // execute filter options dialog
-        if ( aModelData.ExecuteFilterDialog_Impl( aFilterName ) )
+        if ( aModelData.ExecuteFilterDialog_Impl( aFilterName, false ) )
         {
             bDialogUsed = true;
             // check if the file is a pdf or not and change the storing mode 
at convenience
@@ -1681,7 +1773,7 @@ bool SfxStoringHelper::GUIStoreModel( const 
uno::Reference< frame::XModel >& xMo
     }
 
     // Launch PDF viewer
-    if ( nStoreMode & PDFEXPORT_REQUESTED )
+    if ( nStoreMode & PDFEXPORT_REQUESTED && 
!comphelper::LibreOfficeKit::isActive() )
     {
         FilterConfigItem aItem(u"Office.Common/Filter/PDF/Export/");
         bool aViewPDF = aItem.ReadBool( "ViewPDFAfterExport", false );
@@ -1693,6 +1785,16 @@ bool SfxStoringHelper::GUIStoreModel( const 
uno::Reference< frame::XModel >& xMo
         }
     }
 
+    if ( comphelper::LibreOfficeKit::isActive() )
+    {
+        if ( SfxViewShell* pShell = SfxViewShell::Current() )
+        {
+            OUString sURL = aURL.GetMainURL( 
INetURLObject::DecodeMechanism::NONE );
+            pShell->libreOfficeKitViewCallback( LOK_CALLBACK_EXPORT_FILE,
+                OUStringToOString(sURL, RTL_TEXTENCODING_UTF8).getStr() );
+        }
+    }
+
     return bDialogUsed;
 }
 
diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx
index f0bc6172ab1d..35716406cd80 100644
--- a/sfx2/source/doc/objserv.cxx
+++ b/sfx2/source/doc/objserv.cxx
@@ -590,6 +590,7 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq)
 
     bool bIsPDFExport = false;
     bool bIsAutoRedact = false;
+    bool bIsAsync = false;
     std::vector<std::pair<RedactionTarget, OUString>> aRedactionTargets;
     switch(nId)
     {
@@ -896,6 +897,11 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq)
         case SID_SAVEASREMOTE:
         case SID_SAVEDOC:
         {
+            // so far only pdf and epub support Async interface
+            if (comphelper::LibreOfficeKit::isActive() && rReq.GetCallMode() 
== SfxCallMode::ASYNCHRON
+                && (nId == SID_EXPORTDOCASEPUB || nId == SID_EXPORTDOCASPDF))
+                bIsAsync = true;
+
             // derived class may decide to abort this
             if( !QuerySlotExecutable( nId ) )
             {
@@ -1014,7 +1020,9 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq)
                 if ( !pSlot )
                     throw uno::Exception("no slot", nullptr);
 
-                SfxStoringHelper aHelper;
+                std::shared_ptr<SfxStoringHelper> xHelper = 
std::make_shared<SfxStoringHelper>();
+                if (bIsAsync && SfxViewShell::Current())
+                    SfxViewShell::Current()->SetStoringHelper(xHelper);
 
                 if ( QueryHiddenInformation( bIsPDFExport ? 
HiddenWarningFact::WhenCreatingPDF : HiddenWarningFact::WhenSaving, nullptr ) 
!= RET_YES )
                 {
@@ -1036,11 +1044,12 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq)
                     ExecuteSlot(aRequest);
                 }
 
-                aHelper.GUIStoreModel( GetModel(),
+                xHelper->GUIStoreModel( GetModel(),
                                        OUString::createFromAscii( 
pSlot->GetUnoName() ),
                                        aDispatchArgs,
                                        bPreselectPassword,
-                                       GetDocumentSignatureState() );
+                                       GetDocumentSignatureState(),
+                                       bIsAsync );
 
                 if (bMailPrepareExport)
                 {
diff --git a/sfx2/source/view/ipclient.cxx b/sfx2/source/view/ipclient.cxx
index 03ed38a78f3b..fd52355f3ed5 100644
--- a/sfx2/source/view/ipclient.cxx
+++ b/sfx2/source/view/ipclient.cxx
@@ -922,7 +922,8 @@ ErrCode SfxInPlaceClient::DoVerb(sal_Int32 nVerb)
                                             u"SaveAs",
                                             aDispatchArgs,
                                             false,
-                                            SignatureState::NOSIGNATURES );
+                                            SignatureState::NOSIGNATURES,
+                                            false );
                 }
                 catch( const task::ErrorCodeIOException& aErrorEx )
                 {
diff --git a/vcl/jsdialog/enabled.cxx b/vcl/jsdialog/enabled.cxx
index 9a54ed001d39..3f58aa100b94 100644
--- a/vcl/jsdialog/enabled.cxx
+++ b/vcl/jsdialog/enabled.cxx
@@ -97,6 +97,15 @@ bool isBuilderEnabled(std::u16string_view rUIFile, bool 
bMobile)
         || rUIFile == u"xmlsec/ui/certpage.ui"
         || rUIFile == u"xmlsec/ui/digitalsignaturesdialog.ui"
         || rUIFile == u"xmlsec/ui/viewcertdialog.ui"
+        || rUIFile == u"filter/ui/pdfoptionsdialog.ui"
+        || rUIFile == u"filter/ui/pdfgeneralpage.ui"
+        || rUIFile == u"filter/ui/pdfviewpage.ui"
+        || rUIFile == u"filter/ui/pdfuserinterfacepage.ui"
+        || rUIFile == u"filter/ui/pdfsecuritypage.ui"
+        || rUIFile == u"filter/ui/pdflinkspage.ui"
+        || rUIFile == u"filter/ui/warnpdfdialog.ui"
+        || rUIFile == u"filter/ui/pdfsignpage.ui"
+        || rUIFile == u"writerperfect/ui/exportepub.ui"
         )
     {
         return true;

Reply via email to