desktop/source/deployment/gui/dp_gui_dialog2.cxx | 29 -------------- desktop/source/deployment/gui/dp_gui_dialog2.hxx | 13 ++++-- filter/source/xsltdialog/xmlfiltersettingsdialog.cxx | 26 ------------- filter/source/xsltdialog/xmlfiltersettingsdialog.hxx | 6 ++- include/sfx2/sfxhelp.hxx | 2 - include/vcl/waitobj.hxx | 15 +++++++ sfx2/source/appl/sfxhelp.cxx | 37 +++---------------- vcl/source/window/dialog.cxx | 25 ++++++++++++ 8 files changed, 59 insertions(+), 94 deletions(-)
New commits: commit 3a4a90e6e59e16e2ea0883caba87e114a07642f3 Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Thu Jan 10 10:44:31 2019 +0000 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Fri Jan 11 14:09:42 2019 +0100 Resolves: tdf#122404 unlock just the toplevels that were locked push what toplevels got locked to just unlock those ones. otherwise the just dismissed toplevel may still be present in the Application toplevel list. merge all the similar examples of this. Change-Id: I77c0d55d1e4b3bcc3b8d88fef00ba289edd1e831 Reviewed-on: https://gerrit.libreoffice.org/66078 Tested-by: Jenkins Tested-by: Xisco Faulí <xiscofa...@libreoffice.org> Reviewed-by: Caolán McNamara <caol...@redhat.com> Tested-by: Caolán McNamara <caol...@redhat.com> diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.cxx b/desktop/source/deployment/gui/dp_gui_dialog2.cxx index 62e2e301bfc4..765ac22a49f6 100644 --- a/desktop/source/deployment/gui/dp_gui_dialog2.cxx +++ b/desktop/source/deployment/gui/dp_gui_dialog2.cxx @@ -340,7 +340,6 @@ DialogHelper::DialogHelper(const uno::Reference< uno::XComponentContext > &xCont Dialog *pWindow) : m_xVCLWindow(pWindow) , m_nEventID(nullptr) - , m_nBusy(0) { m_xContext = xContext; } @@ -462,34 +461,6 @@ void DialogHelper::PostUserEvent( const Link<void*,void>& rLink, void* pCaller ) m_nEventID = Application::PostUserEvent( rLink, pCaller, true/*bReferenceLink*/ ); } -void DialogHelper::incBusy() -{ - ++m_nBusy; - // 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 != m_xVCLWindow) - xTopWin->IncModalCount(); - xTopWin = Application::GetNextTopLevelWindow(xTopWin); - } -} - -void DialogHelper::decBusy() -{ - --m_nBusy; - // 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 != m_xVCLWindow) - xTopWin->DecModalCount(); - xTopWin = Application::GetNextTopLevelWindow(xTopWin); - } -} - // ExtMgrDialog ExtMgrDialog::ExtMgrDialog(vcl::Window *pParent, TheExtensionManager *pManager, Dialog::InitFlag eFlag) : ModelessDialog(pParent, "ExtensionManagerDialog", "desktop/ui/extensionmanager.ui", eFlag) diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.hxx b/desktop/source/deployment/gui/dp_gui_dialog2.hxx index dd0dc8bb8160..a2d88c0f458e 100644 --- a/desktop/source/deployment/gui/dp_gui_dialog2.hxx +++ b/desktop/source/deployment/gui/dp_gui_dialog2.hxx @@ -29,6 +29,7 @@ #include <vcl/prgsbar.hxx> #include <vcl/timer.hxx> #include <vcl/idle.hxx> +#include <vcl/waitobj.hxx> #include <vcl/weld.hxx> #include <svtools/svmedit.hxx> @@ -47,6 +48,9 @@ #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> #include <com/sun/star/util/XModifyListener.hpp> +#include <stack> +#include <vector> + namespace dp_gui { @@ -60,7 +64,7 @@ class DialogHelper css::uno::Reference< css::uno::XComponentContext > m_xContext; VclPtr<Dialog> m_xVCLWindow; ImplSVEvent * m_nEventID; - int m_nBusy; + TopLevelWindowLocker m_aBusy; public: DialogHelper( const css::uno::Reference< css::uno::XComponentContext > &, @@ -91,14 +95,13 @@ public: const char* pResID, bool &bHadWarning ); - void incBusy(); - void decBusy(); - bool isBusy() const { return m_nBusy > 0; } + void incBusy() { m_aBusy.incBusy(m_xVCLWindow); } + void decBusy() { m_aBusy.decBusy(); } + bool isBusy() const { return m_aBusy.isBusy(); } bool installExtensionWarn(const OUString &rExtensionURL); bool installForAllUsers(bool &bInstallForAll); }; - class ExtMgrDialog : public ModelessDialog, public DialogHelper { diff --git a/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx b/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx index a65b5824664b..3aef69274ba8 100644 --- a/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx +++ b/filter/source/xsltdialog/xmlfiltersettingsdialog.cxx @@ -132,32 +132,6 @@ 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 ) { // tdf#122171 block closing libreoffice until the following dialog is dismissed diff --git a/filter/source/xsltdialog/xmlfiltersettingsdialog.hxx b/filter/source/xsltdialog/xmlfiltersettingsdialog.hxx index e1e1d82418d5..6c1e89c4a9bd 100644 --- a/filter/source/xsltdialog/xmlfiltersettingsdialog.hxx +++ b/filter/source/xsltdialog/xmlfiltersettingsdialog.hxx @@ -27,6 +27,7 @@ #include <vcl/dialog.hxx> #include <vcl/layout.hxx> #include <vcl/svtabbx.hxx> +#include <vcl/waitobj.hxx> #include <svl/poolitem.hxx> #include <unotools/moduleoptions.hxx> @@ -109,8 +110,8 @@ private: void initFilterList(); void disposeFilterList(); - void incBusy(); - void decBusy(); + void incBusy() { maBusy.incBusy(this); } + void decBusy() { maBusy.decBusy(); } bool insertOrEdit( filter_info_impl* pNewInfo, const filter_info_impl* pOldInfo = nullptr ); @@ -126,6 +127,7 @@ private: std::vector< std::unique_ptr<filter_info_impl> > maFilterVector; + TopLevelWindowLocker maBusy; VclPtr<XMLFilterListBox> m_pFilterListBox; VclPtr<SvxPathControl> m_pCtrlFilterList; VclPtr<PushButton> m_pPBNew; diff --git a/include/sfx2/sfxhelp.hxx b/include/sfx2/sfxhelp.hxx index eaee5346b30e..d7afeb2b9af0 100644 --- a/include/sfx2/sfxhelp.hxx +++ b/include/sfx2/sfxhelp.hxx @@ -40,8 +40,6 @@ private: SAL_DLLPRIVATE virtual bool Start(const OUString& rURL, weld::Widget* pWidget) override; SAL_DLLPRIVATE static OUString GetHelpModuleName_Impl(const OUString &rHelpId); SAL_DLLPRIVATE static OUString CreateHelpURL_Impl( const OUString& aCommandURL, const OUString& rModuleName ); - SAL_DLLPRIVATE static void incBusy(const vcl::Window* pParent); - SAL_DLLPRIVATE static void decBusy(const vcl::Window* pParent); public: SfxHelp(); diff --git a/include/vcl/waitobj.hxx b/include/vcl/waitobj.hxx index daf0e2a68a4f..858f49d4ae9b 100644 --- a/include/vcl/waitobj.hxx +++ b/include/vcl/waitobj.hxx @@ -23,6 +23,9 @@ #include <vcl/dllapi.h> #include <vcl/window.hxx> +#include <stack> +#include <vector> + class VCL_DLLPUBLIC WaitObject { private: @@ -37,6 +40,18 @@ public: ~WaitObject(); }; +class VCL_DLLPUBLIC TopLevelWindowLocker +{ +private: + std::stack<std::vector<VclPtr<vcl::Window>>> m_aBusyStack; +public: + // lock all toplevels, except the argument + void incBusy(const vcl::Window* pIgnore); + // unlock previous lock + void decBusy(); + bool isBusy() const { return !m_aBusyStack.empty(); } +}; + #endif // INCLUDED_VCL_WAITOBJ_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/appl/sfxhelp.cxx b/sfx2/source/appl/sfxhelp.cxx index 08de23e30de6..169d6a641425 100644 --- a/sfx2/source/appl/sfxhelp.cxx +++ b/sfx2/source/appl/sfxhelp.cxx @@ -60,6 +60,7 @@ #include <rtl/uri.hxx> #include <vcl/commandinfoprovider.hxx> #include <vcl/layout.hxx> +#include <vcl/waitobj.hxx> #include <vcl/weld.hxx> #include <svtools/ehdl.hxx> #include <svtools/sfxecode.hxx> @@ -1023,32 +1024,6 @@ namespace } } -void SfxHelp::incBusy(const vcl::Window* pParent) -{ - // 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 != pParent) - xTopWin->IncModalCount(); - xTopWin = Application::GetNextTopLevelWindow(xTopWin); - } -} - -void SfxHelp::decBusy(const vcl::Window* pParent) -{ - // 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 != pParent) - xTopWin->DecModalCount(); - xTopWin = Application::GetNextTopLevelWindow(xTopWin); - } -} - bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const OUString& rKeyword) { OUStringBuffer aHelpRootURL("vnd.sun.star.help://"); @@ -1155,9 +1130,11 @@ bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const pWindow = GetBestParent(pWindow); + TopLevelWindowLocker aBusy; + if(bShowOfflineHelpPopUp) { - incBusy(pWindow); + aBusy.incBusy(pWindow); std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pWindow ? pWindow->GetFrameWeld() : nullptr, "sfx/ui/helpmanual.ui")); std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("onlinehelpmanual")); std::unique_ptr<weld::CheckButton> m_xHideOfflineHelpCB(xBuilder->weld_check_button("hidedialog")); @@ -1168,7 +1145,7 @@ bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const short OnlineHelpBox = xQueryBox->run(); bShowOfflineHelpPopUp = OnlineHelpBox != RET_OK; aHelpOptions.SetOfflineHelpPopUp(!m_xHideOfflineHelpCB->get_state()); - decBusy(pWindow); + aBusy.decBusy(); } if(!bShowOfflineHelpPopUp) { @@ -1176,10 +1153,10 @@ bool SfxHelp::Start_Impl(const OUString& rURL, const vcl::Window* pWindow, const return true; else { - incBusy(pWindow); + aBusy.incBusy(pWindow); NoHelpErrorBox aErrBox(pWindow ? pWindow->GetFrameWeld() : nullptr); aErrBox.run(); - decBusy(pWindow); + aBusy.decBusy(); return false; } } diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx index 71542d8bcf93..4b6a019263cc 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -43,6 +43,7 @@ #include <vcl/layout.hxx> #include <vcl/svapp.hxx> #include <vcl/event.hxx> +#include <vcl/waitobj.hxx> #include <vcl/wrkwin.hxx> #include <vcl/button.hxx> #include <vcl/mnemonic.hxx> @@ -1548,4 +1549,28 @@ void Dialog::Activate() SystemWindow::Activate(); } +void TopLevelWindowLocker::incBusy(const vcl::Window* pIgnore) +{ + // lock any toplevel windows from being closed until busy is over + std::vector<VclPtr<vcl::Window>> aTopLevels; + vcl::Window *pTopWin = Application::GetFirstTopLevelWindow(); + while (pTopWin) + { + if (pTopWin != pIgnore) + aTopLevels.push_back(pTopWin); + pTopWin = Application::GetNextTopLevelWindow(pTopWin); + } + for (auto& a : aTopLevels) + a->IncModalCount(); + m_aBusyStack.push(aTopLevels); +} + +void TopLevelWindowLocker::decBusy() +{ + // unlock locked toplevel windows from being closed now busy is over + for (auto& a : m_aBusyStack.top()) + a->DecModalCount(); + m_aBusyStack.pop(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits