tdf#122171 block closing final window while xslt filter dialog is modal

and

Resolves: tdf#122219 base form writer-window doesn't honour CloseVeto properly

just hit this with the same all-modal hammer we now use in the extension manager,
a modeless dialog, with modal subdialogs run by a normal non-async subloop, turns
into a modal dialog for all other toplevels

Change-Id: Ia35fad7a1be2ec493011c7e4354b70231b78a7fc
Reviewed-on: https://gerrit.libreoffice.org/65511
Tested-by: Jenkins
Reviewed-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
diff --git a/filter/source/xsltdialog/xmlfilterdialogcomponent.cxx b/filter/source/xsltdialog/xmlfilterdialogcomponent.cxx
index 31e69c3..cea939f6 100644
--- a/filter/source/xsltdialog/xmlfilterdialogcomponent.cxx
+++ b/filter/source/xsltdialog/xmlfilterdialogcomponent.cxx
@@ -249,24 +249,20 @@ void SAL_CALL XMLFilterDialogComponent::disposing()
void SAL_CALL XMLFilterDialogComponent::queryTermination( const EventObject& /* Event */ )
{
    ::SolarMutexGuard aGuard;

    if (!mpDialog)
        return;

    // we will never give a veto here
    if (!mpDialog->isClosable())
    {
        mpDialog->ToTop();
        throw TerminationVetoException(
            "The office cannot be closed while the XMLFilterDialog is running",
            static_cast<XTerminateListener*>(this));
    }
    else
        mpDialog->Close();
    mpDialog->ToTop();
}

void SAL_CALL XMLFilterDialogComponent::notifyTermination( const EventObject& /* Event */ )
{
    {
        ::SolarMutexGuard aGuard;
        if (!mpDialog)
            return;
        mpDialog->Close();
    }

    // we are going down, so dispose us!
    dispose();
}
diff --git a/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx b/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx
index d54ee23..3af2023 100644
--- a/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx
+++ b/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx
@@ -17,17 +17,19 @@
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/util/XFlushable.hpp>

#include <com/sun/star/beans/PropertyValue.hpp>

#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
#include <unotools/resmgr.hxx>
#include <tools/urlobj.hxx>
#include <svtools/headbar.hxx>
#include <unotools/streamwrap.hxx>
#include <unotools/pathoptions.hxx>
#include <unotools/resmgr.hxx>
#include <unotools/streamwrap.hxx>
#include <osl/file.hxx>
#include <o3tl/enumrange.hxx>
#include <vcl/builderfactory.hxx>
@@ -68,7 +70,6 @@ XMLFilterSettingsDialog::XMLFilterSettingsDialog(vcl::Window* pParent,
    Dialog::InitFlag eFlag)
    : ModelessDialog(pParent, "XMLFilterSettingsDialog", "filter/ui/xmlfiltersettings.ui", eFlag)
    , mxContext( rxContext )
    , m_bIsClosable(true)
    , m_sTemplatePath("$(user)/template/")
    , m_sDocTypePrefix("doctype:")
{
@@ -130,9 +131,36 @@ void XMLFilterSettingsDialog::dispose()
    ModelessDialog::dispose();
}

void XMLFilterSettingsDialog::incBusy()
{
    // lock any toplevel windows from being closed until busy is over
    // ensure any dialogs are reset before entering
    vcl::Window *xTopWin = Application::GetFirstTopLevelWindow();
    while (xTopWin)
    {
        if (xTopWin != this)
            xTopWin->IncModalCount();
        xTopWin = Application::GetNextTopLevelWindow(xTopWin);
    }
}

void XMLFilterSettingsDialog::decBusy()
{
    // unlock any toplevel windows from being closed until busy is over
    // ensure any dialogs are reset before entering
    vcl::Window *xTopWin = Application::GetFirstTopLevelWindow();
    while (xTopWin)
    {
        if (xTopWin != this)
            xTopWin->DecModalCount();
        xTopWin = Application::GetNextTopLevelWindow(xTopWin);
    }
}

IMPL_LINK(XMLFilterSettingsDialog, ClickHdl_Impl, Button *, pButton, void )
{
    m_bIsClosable = false;
    // tdf#122171 block closing libreoffice until the following dialog is dismissed
    incBusy();

    if (m_pPBNew == pButton)
    {
@@ -163,7 +191,7 @@ IMPL_LINK(XMLFilterSettingsDialog, ClickHdl_Impl, Button *, pButton, void )
        Close();
    }

    m_bIsClosable = true;
    decBusy();
}

IMPL_LINK_NOARG(XMLFilterSettingsDialog, SelectionChangedHdl_Impl, SvTreeListBox*, void)
diff --git a/filter/source/xsltdialog/xmlfiltersettingsdialog.hxx b/filter/source/xsltdialog/xmlfiltersettingsdialog.hxx
index 7ca7d43..37ed80f 100644
--- a/filter/source/xsltdialog/xmlfiltersettingsdialog.hxx
+++ b/filter/source/xsltdialog/xmlfiltersettingsdialog.hxx
@@ -105,12 +105,13 @@ public:

    virtual bool EventNotify( NotifyEvent& rNEvt ) override;

    bool    isClosable() { return m_bIsClosable;}

private:
    void    initFilterList();
    void    disposeFilterList();

    void    incBusy();
    void    decBusy();

    bool    insertOrEdit( filter_info_impl* pNewInfo, const filter_info_impl* pOldInfo = nullptr );

    OUString createUniqueFilterName( const OUString& rUIName );
@@ -135,8 +136,6 @@ private:
    VclPtr<PushButton> m_pPBOpen;
    VclPtr<CloseButton> m_pPBClose;

    bool m_bIsClosable;

    OUString m_sTemplatePath;
    OUString m_sDocTypePrefix;