extensions/source/propctrlr/commoncontrol.cxx | 166 +++++++------- extensions/source/propctrlr/commoncontrol.hxx | 291 +++++++++++++------------- solenv/clang-format/excludelist | 2 vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx | 3 vcl/qt5/QtInstanceFormattedSpinButton.cxx | 24 ++ 5 files changed, 255 insertions(+), 231 deletions(-)
New commits: commit 6ac96156a761b74b90c223b6dff06fdf1cea57e5 Author: Michael Weghorn <[email protected]> AuthorDate: Thu Feb 26 00:54:10 2026 +0100 Commit: Michael Weghorn <[email protected]> CommitDate: Sat Feb 28 00:54:55 2026 +0100 tdf#130857 qt weld: Override connect_* in FormattedSpinButton In the same way that GtkInstanceFormattedSpinButton and SalInstanceFormattedSpinButton override these methods to connect handlers to the "focus-out" and "changed" signals, also do in QtInstanceFormattedSpinButton. Without this, triggering the dialog supported with upcoming commit Change-Id: Ibb40f90a886527bdbf25cb537b678055ddd063da Author: Michael Weghorn <[email protected]> Date: Thu Feb 26 00:55:43 2026 +0100 tdf#130857 qt weld: Support "Properties: Time Field" dlg in place would result in this assert getting triggered: soffice.bin: /home/michi/development/git/libreoffice/include/vcl/weld/weld.hxx:270: virtual void weld::Widget::connect_focus_out(const Link<Widget &, void> &): Assertion `!m_aFocusOutHdl.IsSet() || !rLink.IsSet()' failed. Change-Id: Iaed96fe889727b0961c8004034377f6cb9b2ce11 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200367 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx b/vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx index 141f23d30b62..f9c32864329f 100644 --- a/vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx +++ b/vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx @@ -32,6 +32,9 @@ public: virtual QWidget* getQWidget() const override; + virtual void connect_changed(const Link<weld::Entry&, void>& rLink) override; + virtual void connect_focus_out(const Link<weld::Widget&, void>& rLink) override; + virtual Formatter& GetFormatter() override; virtual void SetFormatter(weld::EntryFormatter* pFormatter) override; diff --git a/vcl/qt5/QtInstanceFormattedSpinButton.cxx b/vcl/qt5/QtInstanceFormattedSpinButton.cxx index 655efc04e28e..9d0314d45fb5 100644 --- a/vcl/qt5/QtInstanceFormattedSpinButton.cxx +++ b/vcl/qt5/QtInstanceFormattedSpinButton.cxx @@ -51,6 +51,30 @@ QtInstanceFormattedSpinButton::QtInstanceFormattedSpinButton(QtDoubleSpinBox* pS QWidget* QtInstanceFormattedSpinButton::getQWidget() const { return m_pSpinBox; } +void QtInstanceFormattedSpinButton::connect_changed(const Link<weld::Entry&, void>& rLink) +{ + if (m_pFormatter) + { + // once a formatter is set, it takes over "changed" + m_pFormatter->connect_changed(rLink); + return; + } + + QtInstanceEntry::connect_changed(rLink); +} + +void QtInstanceFormattedSpinButton::connect_focus_out(const Link<weld::Widget&, void>& rLink) +{ + if (m_pFormatter) + { + // once a formatter is set, it takes over "focus-out" + m_pFormatter->connect_focus_out(rLink); + return; + } + + QtInstanceEntry::connect_focus_out(rLink); +} + Formatter& QtInstanceFormattedSpinButton::GetFormatter() { SolarMutexGuard g; commit 2d984cbeb359f3ab475f2aa23dbf821765fe05f3 Author: Michael Weghorn <[email protected]> AuthorDate: Thu Feb 26 00:21:45 2026 +0100 Commit: Michael Weghorn <[email protected]> CommitDate: Sat Feb 28 00:54:47 2026 +0100 propctrlr: clang-format commoncontrol.{hxx,cxx} This in particularly gets red of an extra level of indentation. Change-Id: I1fc3e68ee9cc3cdfd143f09656dacad9e6098d17 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200366 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/extensions/source/propctrlr/commoncontrol.cxx b/extensions/source/propctrlr/commoncontrol.cxx index 4f44f3e568ca..5fcca3a9aed6 100644 --- a/extensions/source/propctrlr/commoncontrol.cxx +++ b/extensions/source/propctrlr/commoncontrol.cxx @@ -20,114 +20,108 @@ #include "commoncontrol.hxx" #include <comphelper/diagnose_ex.hxx> - namespace pcr { +using ::com::sun::star::uno::Reference; +using ::com::sun::star::inspection::XPropertyControlContext; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::inspection::XPropertyControl; + +CommonBehaviourControlHelper::CommonBehaviourControlHelper(sal_Int16 _nControlType, + XPropertyControl& _rAntiImpl) + : m_nControlType(_nControlType) + , m_rAntiImpl(_rAntiImpl) + , m_bModified(false) +{ +} +CommonBehaviourControlHelper::~CommonBehaviourControlHelper() {} - using ::com::sun::star::uno::Reference; - using ::com::sun::star::inspection::XPropertyControlContext; - using ::com::sun::star::uno::Exception; - using ::com::sun::star::inspection::XPropertyControl; - - CommonBehaviourControlHelper::CommonBehaviourControlHelper( sal_Int16 _nControlType, XPropertyControl& _rAntiImpl ) - :m_nControlType( _nControlType ) - ,m_rAntiImpl( _rAntiImpl ) - ,m_bModified( false ) - { - } - - - CommonBehaviourControlHelper::~CommonBehaviourControlHelper() - { - } - - void CommonBehaviourControlHelper::setControlContext( const Reference< XPropertyControlContext >& _controlcontext ) - { - m_xContext = _controlcontext; - } +void CommonBehaviourControlHelper::setControlContext( + const Reference<XPropertyControlContext>& _controlcontext) +{ + m_xContext = _controlcontext; +} - void CommonBehaviourControlHelper::notifyModifiedValue( ) +void CommonBehaviourControlHelper::notifyModifiedValue() +{ + if (isModified() && m_xContext.is()) { - if ( isModified() && m_xContext.is() ) + try + { + m_xContext->valueChanged(&m_rAntiImpl); + m_bModified = false; + } + catch (const Exception&) { - try - { - m_xContext->valueChanged( &m_rAntiImpl ); - m_bModified = false; - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("extensions.propctrlr"); - } + DBG_UNHANDLED_EXCEPTION("extensions.propctrlr"); } } +} - void CommonBehaviourControlHelper::editChanged() - { - setModified(); - } +void CommonBehaviourControlHelper::editChanged() { setModified(); } - IMPL_LINK_NOARG( CommonBehaviourControlHelper, EditModifiedHdl, weld::Entry&, void ) - { - editChanged(); - } +IMPL_LINK_NOARG(CommonBehaviourControlHelper, EditModifiedHdl, weld::Entry&, void) +{ + editChanged(); +} - IMPL_LINK_NOARG( CommonBehaviourControlHelper, ModifiedHdl, weld::ComboBox&, void ) - { - setModified(); - // notify as soon as the Data source is changed, don't wait until we lose focus - // because the Content dropdown cannot be populated after it is popped up - // and going from Data source direct to Content may give focus-lost to - // Content after the popup attempt is made - notifyModifiedValue(); - } +IMPL_LINK_NOARG(CommonBehaviourControlHelper, ModifiedHdl, weld::ComboBox&, void) +{ + setModified(); + // notify as soon as the Data source is changed, don't wait until we lose focus + // because the Content dropdown cannot be populated after it is popped up + // and going from Data source direct to Content may give focus-lost to + // Content after the popup attempt is made + notifyModifiedValue(); +} + +IMPL_LINK_NOARG(CommonBehaviourControlHelper, MetricModifiedHdl, weld::MetricSpinButton&, void) +{ + setModified(); +} - IMPL_LINK_NOARG( CommonBehaviourControlHelper, MetricModifiedHdl, weld::MetricSpinButton&, void ) - { - setModified(); - } +IMPL_LINK_NOARG(CommonBehaviourControlHelper, FormattedModifiedHdl, weld::FormattedSpinButton&, + void) +{ + setModified(); +} - IMPL_LINK_NOARG( CommonBehaviourControlHelper, FormattedModifiedHdl, weld::FormattedSpinButton&, void ) - { - setModified(); - } +IMPL_LINK_NOARG(CommonBehaviourControlHelper, TimeModifiedHdl, weld::FormattedSpinButton&, void) +{ + setModified(); +} - IMPL_LINK_NOARG( CommonBehaviourControlHelper, TimeModifiedHdl, weld::FormattedSpinButton&, void ) - { - setModified(); - } +IMPL_LINK_NOARG(CommonBehaviourControlHelper, DateModifiedHdl, SvtCalendarBox&, void) +{ + setModified(); +} - IMPL_LINK_NOARG( CommonBehaviourControlHelper, DateModifiedHdl, SvtCalendarBox&, void ) - { - setModified(); - } +IMPL_LINK_NOARG(CommonBehaviourControlHelper, ColorModifiedHdl, ColorListBox&, void) +{ + setModified(); +} - IMPL_LINK_NOARG( CommonBehaviourControlHelper, ColorModifiedHdl, ColorListBox&, void ) +IMPL_LINK_NOARG(CommonBehaviourControlHelper, GetFocusHdl, weld::Widget&, void) +{ + try { - setModified(); + if (m_xContext.is()) + m_xContext->focusGained(&m_rAntiImpl); } - - IMPL_LINK_NOARG( CommonBehaviourControlHelper, GetFocusHdl, weld::Widget&, void ) + catch (const Exception&) { - try - { - if ( m_xContext.is() ) - m_xContext->focusGained( &m_rAntiImpl ); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION("extensions.propctrlr"); - } + DBG_UNHANDLED_EXCEPTION("extensions.propctrlr"); } +} - IMPL_LINK_NOARG( CommonBehaviourControlHelper, LoseFocusHdl, weld::Widget&, void ) - { - // TODO/UNOize: should this be outside the default control's implementations? If somebody - // has an own control implementation, which does *not* do this - would this be allowed? - // If not, then we must move this logic out of here. - notifyModifiedValue(); - } +IMPL_LINK_NOARG(CommonBehaviourControlHelper, LoseFocusHdl, weld::Widget&, void) +{ + // TODO/UNOize: should this be outside the default control's implementations? If somebody + // has an own control implementation, which does *not* do this - would this be allowed? + // If not, then we must move this logic out of here. + notifyModifiedValue(); +} } // namespace pcr diff --git a/extensions/source/propctrlr/commoncontrol.hxx b/extensions/source/propctrlr/commoncontrol.hxx index 7d8c2a6d5a34..d9191b66efcd 100644 --- a/extensions/source/propctrlr/commoncontrol.hxx +++ b/extensions/source/propctrlr/commoncontrol.hxx @@ -35,26 +35,23 @@ class SvtCalendarBox; namespace pcr { +//= CommonBehaviourControlHelper - //= CommonBehaviourControlHelper - - /** A helper class for implementing the <type scope="css::inspection">XPropertyControl</type> +/** A helper class for implementing the <type scope="css::inspection">XPropertyControl</type> or one of its derived interfaces. This class is used as a base class the CommonBehaviourControl template. */ - class CommonBehaviourControlHelper - { - private: - sal_Int16 m_nControlType; - css::uno::Reference< css::inspection::XPropertyControlContext > - m_xContext; - css::inspection::XPropertyControl& - m_rAntiImpl; - bool m_bModified; - - public: - /** creates the instance +class CommonBehaviourControlHelper +{ +private: + sal_Int16 m_nControlType; + css::uno::Reference<css::inspection::XPropertyControlContext> m_xContext; + css::inspection::XPropertyControl& m_rAntiImpl; + bool m_bModified; + +public: + /** creates the instance @param nControlType the type of the control - one of the <type scope="css::inspection">PropertyControlType</type> constants @@ -62,46 +59,48 @@ namespace pcr Reference to the instance as whose "impl-class" we act i.e. the CommonBehaviourControl<> template, which is why we hold it without acquiring it/ */ - CommonBehaviourControlHelper( - sal_Int16 nControlType, - css::inspection::XPropertyControl& rAntiImpl); - - virtual ~CommonBehaviourControlHelper(); - - virtual void setModified() { m_bModified = true; } - - virtual void editChanged(); - - // XPropertyControl - /// @throws css::uno::RuntimeException - ::sal_Int16 getControlType() const { return m_nControlType; } - /// @throws css::uno::RuntimeException - const css::uno::Reference< css::inspection::XPropertyControlContext >& getControlContext() const { return m_xContext; } - /// @throws css::uno::RuntimeException - void setControlContext( const css::uno::Reference< css::inspection::XPropertyControlContext >& controlcontext ); - /// @throws css::uno::RuntimeException - bool isModified( ) const { return m_bModified; } - /// @throws css::uno::RuntimeException - void notifyModifiedValue( ); - - virtual weld::Widget* getWidget() = 0; - - /// may be used by derived classes, they forward the event to the PropCtrListener - DECL_LINK( ModifiedHdl, weld::ComboBox&, void ); - DECL_LINK( ColorModifiedHdl, ColorListBox&, void ); - DECL_LINK( EditModifiedHdl, weld::Entry&, void ); - DECL_LINK( MetricModifiedHdl, weld::MetricSpinButton&, void ); - DECL_LINK( FormattedModifiedHdl, weld::FormattedSpinButton&, void ); - DECL_LINK( TimeModifiedHdl, weld::FormattedSpinButton&, void ); - DECL_LINK( DateModifiedHdl, SvtCalendarBox&, void ); - DECL_LINK( GetFocusHdl, weld::Widget&, void ); - DECL_LINK( LoseFocusHdl, weld::Widget&, void ); - }; - - - //= CommonBehaviourControl - - /** implements a base class for <type scope="css::inspection">XPropertyControl</type> + CommonBehaviourControlHelper(sal_Int16 nControlType, + css::inspection::XPropertyControl& rAntiImpl); + + virtual ~CommonBehaviourControlHelper(); + + virtual void setModified() { m_bModified = true; } + + virtual void editChanged(); + + // XPropertyControl + /// @throws css::uno::RuntimeException + ::sal_Int16 getControlType() const { return m_nControlType; } + /// @throws css::uno::RuntimeException + const css::uno::Reference<css::inspection::XPropertyControlContext>& getControlContext() const + { + return m_xContext; + } + /// @throws css::uno::RuntimeException + void setControlContext( + const css::uno::Reference<css::inspection::XPropertyControlContext>& controlcontext); + /// @throws css::uno::RuntimeException + bool isModified() const { return m_bModified; } + /// @throws css::uno::RuntimeException + void notifyModifiedValue(); + + virtual weld::Widget* getWidget() = 0; + + /// may be used by derived classes, they forward the event to the PropCtrListener + DECL_LINK(ModifiedHdl, weld::ComboBox&, void); + DECL_LINK(ColorModifiedHdl, ColorListBox&, void); + DECL_LINK(EditModifiedHdl, weld::Entry&, void); + DECL_LINK(MetricModifiedHdl, weld::MetricSpinButton&, void); + DECL_LINK(FormattedModifiedHdl, weld::FormattedSpinButton&, void); + DECL_LINK(TimeModifiedHdl, weld::FormattedSpinButton&, void); + DECL_LINK(DateModifiedHdl, SvtCalendarBox&, void); + DECL_LINK(GetFocusHdl, weld::Widget&, void); + DECL_LINK(LoseFocusHdl, weld::Widget&, void); +}; + +//= CommonBehaviourControl + +/** implements a base class for <type scope="css::inspection">XPropertyControl</type> implementations @param TControlInterface @@ -109,101 +108,107 @@ namespace pcr @param TControlWindow a class which is derived from weld::Widget */ - template < class TControlInterface, class TControlWindow > - class CommonBehaviourControl :public ::cppu::BaseMutex - ,public ::cppu::WeakComponentImplHelper< TControlInterface > - ,public CommonBehaviourControlHelper +template <class TControlInterface, class TControlWindow> +class CommonBehaviourControl : public ::cppu::BaseMutex, + public ::cppu::WeakComponentImplHelper<TControlInterface>, + public CommonBehaviourControlHelper +{ +protected: + typedef ::cppu::WeakComponentImplHelper<TControlInterface> ComponentBaseClass; + + inline CommonBehaviourControl(sal_Int16 nControlType, std::unique_ptr<weld::Builder> xBuilder, + std::unique_ptr<TControlWindow> xWidget, bool bReadOnly); + + virtual ~CommonBehaviourControl() override { clear_widgetry(); } + + // XPropertyControl - delegated to ->m_aImplControl + virtual ::sal_Int16 SAL_CALL getControlType() override + { + return CommonBehaviourControlHelper::getControlType(); + } + virtual css::uno::Reference<css::inspection::XPropertyControlContext> + SAL_CALL getControlContext() override + { + return CommonBehaviourControlHelper::getControlContext(); + } + virtual void SAL_CALL setControlContext( + const css::uno::Reference<css::inspection::XPropertyControlContext>& controlcontext) + override + { + CommonBehaviourControlHelper::setControlContext(controlcontext); + } + virtual css::uno::Reference<css::awt::XWindow> SAL_CALL getControlWindow() override { - protected: - typedef ::cppu::WeakComponentImplHelper< TControlInterface > ComponentBaseClass; - - inline CommonBehaviourControl(sal_Int16 nControlType, - std::unique_ptr<weld::Builder> xBuilder, - std::unique_ptr<TControlWindow> xWidget, - bool bReadOnly); - - virtual ~CommonBehaviourControl() override - { - clear_widgetry(); - } - - // XPropertyControl - delegated to ->m_aImplControl - virtual ::sal_Int16 SAL_CALL getControlType() override - { return CommonBehaviourControlHelper::getControlType(); } - virtual css::uno::Reference< css::inspection::XPropertyControlContext > SAL_CALL getControlContext() override - { return CommonBehaviourControlHelper::getControlContext(); } - virtual void SAL_CALL setControlContext( const css::uno::Reference< css::inspection::XPropertyControlContext >& controlcontext ) override - { CommonBehaviourControlHelper::setControlContext( controlcontext ); } - virtual css::uno::Reference< css::awt::XWindow > SAL_CALL getControlWindow() override - { return new weld::TransportAsXWindow(getWidget()); } - virtual sal_Bool SAL_CALL isModified( ) override - { return CommonBehaviourControlHelper::isModified(); } - virtual void SAL_CALL notifyModifiedValue( ) override - { CommonBehaviourControlHelper::notifyModifiedValue(); } - - void clear_widgetry() - { - if (!m_xControlWindow) - return; - weld::Widget* pWidget = getWidget(); - std::unique_ptr<weld::Container> xParent(pWidget->weld_parent()); - xParent->move(pWidget, nullptr); - m_xControlWindow.reset(); - m_xBuilder.reset(); - } - - // XComponent - virtual void SAL_CALL disposing() override - { - clear_widgetry(); - } - - TControlWindow* getTypedControlWindow() - { return m_xControlWindow.get(); } - const TControlWindow* getTypedControlWindow() const - { return m_xControlWindow.get(); } - - virtual void SetModifyHandler() - { - m_xControlWindow->connect_focus_in( LINK( this, CommonBehaviourControlHelper, GetFocusHdl ) ); - m_xControlWindow->connect_focus_out( LINK( this, CommonBehaviourControlHelper, LoseFocusHdl ) ); - } - - /** checks whether the instance is already disposed + return new weld::TransportAsXWindow(getWidget()); + } + virtual sal_Bool SAL_CALL isModified() override + { + return CommonBehaviourControlHelper::isModified(); + } + virtual void SAL_CALL notifyModifiedValue() override + { + CommonBehaviourControlHelper::notifyModifiedValue(); + } + + void clear_widgetry() + { + if (!m_xControlWindow) + return; + weld::Widget* pWidget = getWidget(); + std::unique_ptr<weld::Container> xParent(pWidget->weld_parent()); + xParent->move(pWidget, nullptr); + m_xControlWindow.reset(); + m_xBuilder.reset(); + } + + // XComponent + virtual void SAL_CALL disposing() override { clear_widgetry(); } + + TControlWindow* getTypedControlWindow() { return m_xControlWindow.get(); } + const TControlWindow* getTypedControlWindow() const { return m_xControlWindow.get(); } + + virtual void SetModifyHandler() + { + m_xControlWindow->connect_focus_in(LINK(this, CommonBehaviourControlHelper, GetFocusHdl)); + m_xControlWindow->connect_focus_out(LINK(this, CommonBehaviourControlHelper, LoseFocusHdl)); + } + + /** checks whether the instance is already disposed @throws DisposedException if the instance is already disposed */ - inline void impl_checkDisposed_throw(); - protected: - std::unique_ptr<weld::Builder> m_xBuilder; - private: - std::unique_ptr<TControlWindow> m_xControlWindow; - }; - - //= CommonBehaviourControl - implementation - template< class TControlInterface, class TControlWindow > - inline CommonBehaviourControl< TControlInterface, TControlWindow >::CommonBehaviourControl(sal_Int16 nControlType, - std::unique_ptr<weld::Builder> xBuilder, - std::unique_ptr<TControlWindow> xWidget, - bool bReadOnly) - : ComponentBaseClass( m_aMutex ) - , CommonBehaviourControlHelper( nControlType, *this ) - , m_xBuilder(std::move(xBuilder)) - , m_xControlWindow(std::move(xWidget)) + inline void impl_checkDisposed_throw(); + +protected: + std::unique_ptr<weld::Builder> m_xBuilder; + +private: + std::unique_ptr<TControlWindow> m_xControlWindow; +}; + +//= CommonBehaviourControl - implementation +template <class TControlInterface, class TControlWindow> +inline CommonBehaviourControl<TControlInterface, TControlWindow>::CommonBehaviourControl( + sal_Int16 nControlType, std::unique_ptr<weld::Builder> xBuilder, + std::unique_ptr<TControlWindow> xWidget, bool bReadOnly) + : ComponentBaseClass(m_aMutex) + , CommonBehaviourControlHelper(nControlType, *this) + , m_xBuilder(std::move(xBuilder)) + , m_xControlWindow(std::move(xWidget)) +{ + if (bReadOnly) { - if (bReadOnly) - { - // disable widget by default, entries will override to enable the widget but set it non-editable - m_xControlWindow->set_sensitive(false); - } + // disable widget by default, entries will override to enable the widget but set it non-editable + m_xControlWindow->set_sensitive(false); } +} - template< class TControlInterface, class TControlWindow > - inline void CommonBehaviourControl< TControlInterface, TControlWindow >::impl_checkDisposed_throw() - { - if ( ComponentBaseClass::rBHelper.bDisposed ) - throw css::lang::DisposedException( OUString(), *this ); - } +template <class TControlInterface, class TControlWindow> +inline void CommonBehaviourControl<TControlInterface, TControlWindow>::impl_checkDisposed_throw() +{ + if (ComponentBaseClass::rBHelper.bDisposed) + throw css::lang::DisposedException(OUString(), *this); +} } // namespace pcr diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist index 146b70619c59..e1339d63d54b 100644 --- a/solenv/clang-format/excludelist +++ b/solenv/clang-format/excludelist @@ -3482,8 +3482,6 @@ extensions/source/propctrlr/cellbindinghandler.cxx extensions/source/propctrlr/cellbindinghandler.hxx extensions/source/propctrlr/cellbindinghelper.cxx extensions/source/propctrlr/cellbindinghelper.hxx -extensions/source/propctrlr/commoncontrol.cxx -extensions/source/propctrlr/commoncontrol.hxx extensions/source/propctrlr/composeduiupdate.cxx extensions/source/propctrlr/composeduiupdate.hxx extensions/source/propctrlr/controlfontdialog.cxx
