include/sfx2/charmapcontainer.hxx        |    2 +-
 include/sfx2/charwin.hxx                 |   10 ++++------
 include/svx/cuicharmap.hxx               |    1 +
 sfx2/inc/charmapcontrol.hxx              |    2 +-
 sfx2/source/control/charmapcontainer.cxx |   11 ++++++-----
 sfx2/source/control/charmapcontrol.cxx   |    4 ++--
 sfx2/source/control/charwin.cxx          |   19 +++++++------------
 svx/source/dialog/cuicharmap.cxx         |   10 ++++++++--
 8 files changed, 30 insertions(+), 29 deletions(-)

New commits:
commit 176f8acd7a993fc45ac7f027123270f80e4924ea
Author:     Michael Weghorn <[email protected]>
AuthorDate: Fri Dec 19 19:52:45 2025 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Fri Dec 19 22:52:59 2025 +0100

    tdf#168594 Rework SvxCharView activation logic
    
    SvxCharView is used in
    
    1) the special characters toolbar popup
       (triggered by the "Insert Special Characters"
       toolbar button)
    
    2) the special characters dialog
       (triggered via "Insert" -> "Special Character...")
    
    In 1), a single click on a SvxCharView (i.e. a recent or
    favorite character in the popup) triggers insertion into
    the document and closes the popup.
    
    In 2), a double-click triggers insertion into the document.
    
    In both, 1) and 2), pressing the space or Enter key while
    an SvxCharView has focus triggers the insertion into the
    document.
    
    This is implemented in different ways and places, partially
    directly in SvxCharView, and partially in mouse click handlers.
    
    Unify the approach by allowing to set a single activation handler,
    and then making it the responsibility of that handler to insert
    the character into the document and to do whatever else is needed
    (closing the popup in case of 1).
    This moves the char insertion logic out of SvxCharView.
    
    SvxCharView::m_bActivateOnSingleClick now determines whether
    the activation handler is called on a single mouse click
    (true for the popup case, false for the dialog).
    
    This also prepares for replacing the use of SvxCharView
    in SfxCharmapContainer, by switching to a weld::IconView
    instead.
    SvxCharView::m_bActivateOnSingleClick can then be mapped to
    the equivalent GtkIconView:activate-on-single-click [1]
    property.
    
    [1] 
https://docs.gtk.org/gtk3/property.IconView.activate-on-single-click.html
    
    Change-Id: Ieadd263876b4e9ed0caf6aea45573655bacb4876
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195940
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/include/sfx2/charmapcontainer.hxx 
b/include/sfx2/charmapcontainer.hxx
index 062dbb610717..0c6ba5069f44 100644
--- a/include/sfx2/charmapcontainer.hxx
+++ b/include/sfx2/charmapcontainer.hxx
@@ -66,7 +66,7 @@ public:
     SfxCharmapContainer(weld::Builder& rBuilder, const VclPtr<VirtualDevice>& 
rVirDev,
                         bool bLockGridSizes);
 
-    void init(bool bHasInsert, const Link<const CharAndFont&, void>& 
rMouseClickHdl,
+    void init(bool bActivateOnSingleClick, const Link<const CharAndFont&, 
void>& rActivateHdl,
               const Link<void*, void>& rUpdateFavHdl, const Link<void*, void>& 
rUpdateRecentHdl,
               const Link<const CharAndFont&, void>& rFocusInHdl = Link<const 
CharAndFont&, void>());
 
diff --git a/include/sfx2/charwin.hxx b/include/sfx2/charwin.hxx
index c0fe040579a3..d5956a795f6d 100644
--- a/include/sfx2/charwin.hxx
+++ b/include/sfx2/charwin.hxx
@@ -43,12 +43,12 @@ class SAL_DLLPUBLIC_RTTI SvxCharView final : public 
weld::CustomWidgetController
 private:
     VclPtr<VirtualDevice> mxVirDev;
     vcl::Font       maFont;
-    bool            maHasInsert;
+    bool            m_bActivateOnSingleClick;
     OUString        m_sText;
     OUString        m_sToolTip;
 
     Link<const CharAndFont&, void> maFocusInHdl;
-    Link<const CharAndFont&, void> maMouseClickHdl;
+    Link<const CharAndFont&, void> maActivateHdl;
     Link<const CommandEvent&, void> maContextMenuHdl;
 
     virtual void Paint(vcl::RenderContext& rRenderContext, const 
tools::Rectangle& rRect) override;
@@ -61,8 +61,6 @@ private:
     virtual bool Command(const CommandEvent&) override;
     virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
 
-    void InsertCharToDoc();
-
 public:
     SvxCharView(const VclPtr<VirtualDevice>& rVirDev);
     SFX2_DLLPUBLIC virtual ~SvxCharView() override;
@@ -73,12 +71,12 @@ public:
     OUString const & GetText() const { return m_sText; }
     CharAndFont GetCharAndFont() const;
     void SetToolTip(const OUString& rToolTip) { m_sToolTip = rToolTip; };
-    void            SetHasInsert( bool bInsert );
+    void SetActivateOnSingleClick(bool bActivate);
 
     Size            get_preferred_size() const { return 
GetDrawingArea()->get_preferred_size(); }
 
     void setFocusInHdl(const Link<const CharAndFont&, void>& rLink);
-    void setMouseClickHdl(const Link<const CharAndFont&, void>& rLink);
+    void setActivateHdl(const Link<const CharAndFont&, void>& rLink);
     void setContextMenuHdl(const Link<const CommandEvent&, void>& rLink);
 };
 
diff --git a/include/svx/cuicharmap.hxx b/include/svx/cuicharmap.hxx
index 632f4db6b5c7..53680b447b9f 100644
--- a/include/svx/cuicharmap.hxx
+++ b/include/svx/cuicharmap.hxx
@@ -109,6 +109,7 @@ private:
 
     DECL_DLLPRIVATE_LINK(FontSelectHdl, weld::ComboBox&, void);
     DECL_DLLPRIVATE_LINK(SubsetSelectHdl, weld::ComboBox&, void);
+    DECL_DLLPRIVATE_LINK(CharActivateHdl, const CharAndFont&, void);
     DECL_DLLPRIVATE_LINK(CharDoubleClickHdl, SvxShowCharSet&, void);
     DECL_DLLPRIVATE_LINK(CharSelectHdl, SvxShowCharSet&, void);
     DECL_DLLPRIVATE_LINK(CharHighlightHdl, SvxShowCharSet&, void);
diff --git a/sfx2/inc/charmapcontrol.hxx b/sfx2/inc/charmapcontrol.hxx
index 614d7d7fd4ea..400216ca2a3d 100644
--- a/sfx2/inc/charmapcontrol.hxx
+++ b/sfx2/inc/charmapcontrol.hxx
@@ -45,7 +45,7 @@ private:
     std::unique_ptr<weld::Label> m_xCharInfoLabel;
 
     DECL_LINK(CharFocusInHdl, const CharAndFont&, void);
-    DECL_LINK(CharClickHdl, const CharAndFont&, void);
+    DECL_LINK(CharActivateHdl, const CharAndFont&, void);
     DECL_LINK(OpenDlgHdl, weld::Button&, void);
     DECL_LINK(DlgBtnFocusInHdl, weld::Widget&, void);
     DECL_LINK(UpdateRecentHdl, void*, void);
diff --git a/sfx2/source/control/charmapcontainer.cxx 
b/sfx2/source/control/charmapcontainer.cxx
index 45d5cc115c98..7a521a5abc0a 100644
--- a/sfx2/source/control/charmapcontainer.cxx
+++ b/sfx2/source/control/charmapcontainer.cxx
@@ -110,7 +110,8 @@ SfxCharmapContainer::SfxCharmapContainer(weld::Builder& 
rBuilder, const VclPtr<V
     }
 }
 
-void SfxCharmapContainer::init(bool bHasInsert, const Link<const CharAndFont&, 
void>& rMouseClickHdl,
+void SfxCharmapContainer::init(bool bActivateOnSingleClick,
+                               const Link<const CharAndFont&, void>& 
rActivateHdl,
                                const Link<void*, void>& rUpdateFavHdl,
                                const Link<void*, void>& rUpdateRecentHdl,
                                const Link<const CharAndFont&, void>& 
rFocusInHdl)
@@ -125,14 +126,14 @@ void SfxCharmapContainer::init(bool bHasInsert, const 
Link<const CharAndFont&, v
 
     for(int i = 0; i < 16; i++)
     {
-        m_aRecentCharView[i].SetHasInsert(bHasInsert);
+        m_aRecentCharView[i].SetActivateOnSingleClick(bActivateOnSingleClick);
         m_aRecentCharView[i].setFocusInHdl(rFocusInHdl);
-        m_aRecentCharView[i].setMouseClickHdl(rMouseClickHdl);
+        m_aRecentCharView[i].setActivateHdl(rActivateHdl);
         m_aRecentCharView[i].setContextMenuHdl(
             LINK(this, SfxCharmapContainer, RecentContextMenuHdl));
-        m_aFavCharView[i].SetHasInsert(bHasInsert);
+        m_aFavCharView[i].SetActivateOnSingleClick(bActivateOnSingleClick);
         m_aFavCharView[i].setFocusInHdl(rFocusInHdl);
-        m_aFavCharView[i].setMouseClickHdl(rMouseClickHdl);
+        m_aFavCharView[i].setActivateHdl(rActivateHdl);
         m_aFavCharView[i].setContextMenuHdl(LINK(this, SfxCharmapContainer, 
FavContextMenuHdl));
     }
 }
diff --git a/sfx2/source/control/charmapcontrol.cxx 
b/sfx2/source/control/charmapcontrol.cxx
index 9f2cc2c9f3c6..d4997ee55d54 100644
--- a/sfx2/source/control/charmapcontrol.cxx
+++ b/sfx2/source/control/charmapcontrol.cxx
@@ -38,7 +38,7 @@ SfxCharmapCtrl::SfxCharmapCtrl(CharmapPopup* pControl, 
weld::Widget* pParent)
 {
     m_xCharInfoLabel->set_size_request(-1, m_xCharInfoLabel->get_text_height() 
* 2);
 
-    m_aCharmapContents.init(false, LINK(this, SfxCharmapCtrl, CharClickHdl),
+    m_aCharmapContents.init(true, LINK(this, SfxCharmapCtrl, CharActivateHdl),
                             Link<void*,void>(), LINK(this, SfxCharmapCtrl, 
UpdateRecentHdl),
                             LINK(this, SfxCharmapCtrl, CharFocusInHdl));
 
@@ -55,7 +55,7 @@ IMPL_LINK(SfxCharmapCtrl, CharFocusInHdl, const CharAndFont&, 
rChar, void)
     
m_xCharInfoLabel->set_label(SfxCharmapContainer::GetCharInfoText(rChar.sChar));
 }
 
-IMPL_LINK(SfxCharmapCtrl, CharClickHdl, const CharAndFont&, rChar, void)
+IMPL_LINK(SfxCharmapCtrl, CharActivateHdl, const CharAndFont&, rChar, void)
 {
     m_xControl->EndPopupMode();
 
diff --git a/sfx2/source/control/charwin.cxx b/sfx2/source/control/charwin.cxx
index eab18e268a5c..d4693f9e7e58 100644
--- a/sfx2/source/control/charwin.cxx
+++ b/sfx2/source/control/charwin.cxx
@@ -32,7 +32,7 @@ using namespace com::sun::star;
 
 SvxCharView::SvxCharView(const VclPtr<VirtualDevice>& rVirDev)
     : mxVirDev(rVirDev)
-    , maHasInsert(true)
+    , m_bActivateOnSingleClick(false)
 {
 }
 
@@ -71,13 +71,10 @@ bool SvxCharView::MouseButtonDown(const MouseEvent& rMEvt)
 {
     if (rMEvt.IsLeft())
     {
-        if (!(rMEvt.GetClicks() % 2) && maHasInsert)
-        {
-            InsertCharToDoc();
-        }
         GrabFocus();
         Invalidate();
-        maMouseClickHdl.Call(GetCharAndFont());
+        if (rMEvt.GetClicks() == 2 || m_bActivateOnSingleClick)
+            maActivateHdl.Call(GetCharAndFont());
         return true;
     }
 
@@ -92,7 +89,7 @@ bool SvxCharView::KeyInput(const KeyEvent& rKEvt)
     {
         case KEY_SPACE:
         case KEY_RETURN:
-            InsertCharToDoc();
+            maActivateHdl.Call(GetCharAndFont());
             bRet = true;
             break;
     }
@@ -112,8 +109,6 @@ bool SvxCharView::Command(const CommandEvent& rCommandEvent)
     return weld::CustomWidgetController::Command(rCommandEvent);
 }
 
-void SvxCharView::InsertCharToDoc() { 
SfxCharmapContainer::InsertCharToDoc(GetCharAndFont()); }
-
 void SvxCharView::Paint(vcl::RenderContext& rRenderContext, const 
tools::Rectangle&)
 {
     rRenderContext.SetFont(maFont);
@@ -214,9 +209,9 @@ void SvxCharView::setFocusInHdl(const Link<const 
CharAndFont&, void>& rLink)
     maFocusInHdl = rLink;
 }
 
-void SvxCharView::setMouseClickHdl(const Link<const CharAndFont&, void>& rLink)
+void SvxCharView::setActivateHdl(const Link<const CharAndFont&, void>& rLink)
 {
-    maMouseClickHdl = rLink;
+    maActivateHdl = rLink;
 }
 
 void SvxCharView::setContextMenuHdl(const Link<const CommandEvent&, void>& 
rLink)
@@ -253,6 +248,6 @@ CharAndFont SvxCharView::GetCharAndFont() const
     return CharAndFont(GetText(), GetFontFamilyName());
 }
 
-void SvxCharView::SetHasInsert(bool bInsert) { maHasInsert = bInsert; }
+void SvxCharView::SetActivateOnSingleClick(bool bActivate) { 
m_bActivateOnSingleClick = bActivate; }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/svx/source/dialog/cuicharmap.cxx b/svx/source/dialog/cuicharmap.cxx
index 9926fa43c0f6..7120eea29112 100644
--- a/svx/source/dialog/cuicharmap.cxx
+++ b/svx/source/dialog/cuicharmap.cxx
@@ -261,8 +261,8 @@ void SvxCharacterMap::init()
         m_xOKBtn->set_sensitive(true);
     }
 
-    m_aCharmapContents.init(m_xFrame.is(),
-                            Link<const CharAndFont&, void>(),
+    m_aCharmapContents.init(false,
+                            LINK(this, SvxCharacterMap, CharActivateHdl),
                             LINK(this, SvxCharacterMap, UpdateFavHdl),
                             Link<void*, void>(),
                             LINK(this, SvxCharacterMap, CharFocusHdl));
@@ -563,6 +563,12 @@ void SvxCharacterMap::insertSelectedCharacter(const 
SvxShowCharSet& rCharSet)
     insertCharToDoc(aOUStr);
 }
 
+IMPL_LINK(SvxCharacterMap, CharActivateHdl, const CharAndFont&, rChar, void)
+{
+    if (m_xFrame.is())
+        SfxCharmapContainer::InsertCharToDoc(rChar);
+}
+
 IMPL_LINK(SvxCharacterMap, CharDoubleClickHdl, SvxShowCharSet&, rCharSet, void)
 {
     insertSelectedCharacter(rCharSet);

Reply via email to