framework/source/uielement/newmenucontroller.cxx | 58 ++++++++++++++++++++--- 1 file changed, 51 insertions(+), 7 deletions(-)
New commits: commit 846c9f7d87f88b15996bbc38bc72c98e2a039e44 Author: Mike Kaganski <[email protected]> AuthorDate: Fri Dec 6 23:14:57 2024 +0500 Commit: Miklos Vajna <[email protected]> CommitDate: Tue Dec 10 15:15:55 2024 +0100 Check if the slot is active in NewMenuController::fillPopupMenu Otherwise, the popup menu gets filled, even when the respective slot is disabled. Change-Id: I74ff3692500ca76e6e15bf3725dd295f0213403c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178014 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/framework/source/uielement/newmenucontroller.cxx b/framework/source/uielement/newmenucontroller.cxx index fb133540c358..f2d43a40643e 100644 --- a/framework/source/uielement/newmenucontroller.cxx +++ b/framework/source/uielement/newmenucontroller.cxx @@ -32,6 +32,7 @@ #include <com/sun/star/util/XURLTransformer.hpp> #include <comphelper/propertyvalue.hxx> +#include <cppuhelper/implbase.hxx> #include <vcl/svapp.hxx> #include <vcl/settings.hxx> #include <vcl/commandinfoprovider.hxx> @@ -45,7 +46,7 @@ // Defines constexpr OUString aSlotNewDocDirect = u".uno:AddDirect"_ustr; -constexpr OUStringLiteral aSlotAutoPilot = u".uno:AutoPilotMenu"; +constexpr OUString aSlotAutoPilot = u".uno:AutoPilotMenu"_ustr; using namespace com::sun::star::uno; using namespace com::sun::star::lang; @@ -55,6 +56,54 @@ using namespace com::sun::star::util; using namespace com::sun::star::container; using namespace com::sun::star::ui; +namespace +{ +class SlotStatusGetter : public cppu::WeakImplHelper<css::frame::XStatusListener> +{ +public: + SlotStatusGetter(const css::util::URL& url, + const css::uno::Reference<css::frame::XFrame>& frame) + { + if (auto provider = frame.query<css::frame::XDispatchProvider>()) + { + if (auto xDispatch = provider->queryDispatch(url, {}, 0)) + { + // Avoid self-destruction + osl_atomic_increment(&m_refCount); + // Adding as listener will automatically emit an initial notification + xDispatch->addStatusListener(this, url); + xDispatch->removeStatusListener(this, url); + osl_atomic_decrement(&m_refCount); + } + } + } + + bool isEnabled() const { return m_bEnabled; } + +private: + // XStatusListener + void SAL_CALL statusChanged(const css::frame::FeatureStateEvent& state) override + { + m_bEnabled = state.IsEnabled; + } + + // XEventListener + void SAL_CALL disposing(const css::lang::EventObject&) override {} // unused + + bool m_bEnabled = false; +}; + +bool isSlotActive(const OUString& slot, const css::uno::Reference<css::frame::XFrame>& frame, + const css::uno::Reference<css::util::XURLTransformer>& transformer) +{ + css::util::URL url; + url.Complete = slot; + transformer->parseStrict(url); + rtl::Reference slotStatus(new SlotStatusGetter(url, frame)); + return slotStatus->isEnabled(); +} +} + namespace framework { @@ -295,12 +344,7 @@ void NewMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu > const & if ( !pVCLPopupMenu ) return; - Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); - URL aTargetURL; - aTargetURL.Complete = m_bNewMenu ? aSlotNewDocDirect : OUString(aSlotAutoPilot); - m_xURLTransformer->parseStrict( aTargetURL ); - Reference< XDispatch > xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 ); - if(xMenuItemDispatch == nullptr) + if (!isSlotActive(m_bNewMenu ? aSlotNewDocDirect : aSlotAutoPilot, m_xFrame, m_xURLTransformer)) return; const std::vector< SvtDynMenuEntry > aDynamicMenuEntries =
