tdf#139115 vcl tree list: add new toggle behaviors

at clicking on list items with checkboxes to clean-up
generic VCL plugin commit 2471d6f44c7e8ecbe86a90eeb593b899a08a7408
(tdf#116675 vcl tree list: toggle by label click (e.g. in AutoFilter)).

This limits the new toggle-always to ScCheckListMenuControl
(e.g. AutoFilter).

set_clicks_to_toggle() options to set the effect of the
click on a treeview list item:

0 == clicking never toggles the checkbox (default setting)

1 == clicking always toggles the checkbox

2 == clicking only toggles the checkbox of a selected list item,
     i.e. the first click selects a not selected list item, and
     only the second click toggles its checkbox.

It would be better if we could set this information in the
.ui files, but I did not find a good way for that.

A good place in the code to call this function can be
found by searching for the .ui filename.

Co-authored-by: Tibor Nagy (NISZ)

Change-Id: I5c72d710508fc397f2b6f959d7680b23f8dc6f67
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108947
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/include/vcl/toolkit/treelistbox.hxx b/include/vcl/toolkit/treelistbox.hxx
index 199f37c..895c6c1 100644
--- a/include/vcl/toolkit/treelistbox.hxx
+++ b/include/vcl/toolkit/treelistbox.hxx
@@ -221,6 +221,9 @@ class VCL_DLLPUBLIC SvTreeListBox
    bool mbQuickSearch; // Enables type-ahead search in the check list box.
    bool mbActivateOnSingleClick; // Make single click "activate" a row like a double-click normally does
    bool mbHoverSelection; // Make mouse over a row "select" a row like a single-click normally does
    sal_Int8        mnClicksToToggle; // 0 == Click on a row not toggle its checkbox.
                                      // 1 == Every click on row toggle its checkbox.
                                      // 2 == First click select, second click toggle.

    SvTreeListEntry*    pHdlEntry;

@@ -680,6 +683,9 @@ public:
    void            SetHoverSelection(bool bEnable) { mbHoverSelection = bEnable; }
    bool            GetHoverSelection() const { return mbHoverSelection; }

    // Set when clicks toggle the checkbox of the row.
    void            SetClicksToToggle(sal_Int8 nCount) { mnClicksToToggle = nCount; }

    void            SetForceMakeVisible(bool bEnable);

    virtual FactoryFunction GetUITestFactory() const override;
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index fcf0749..b788a13 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -958,6 +958,8 @@ public:
    // inserted after this call which can be accessed with col index -1
    virtual void enable_toggle_buttons(ColumnToggleType eType) = 0;

    virtual void set_clicks_to_toggle(int nToggleBehavior) = 0;

    //by index
    virtual int get_selected_index() const = 0;
    //Don't select when frozen, select after thaw. Note selection doesn't survive a freeze.
diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx
index b9f51cb..00d8a88 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -463,6 +463,9 @@ ScCheckListMenuControl::ScCheckListMenuControl(ScCheckListMenuWindow* pParent, v
    , maOpenTimer(this)
    , maCloseTimer(this)
{
    mxTreeChecks->set_clicks_to_toggle(1);
    mxListChecks->set_clicks_to_toggle(1);

    /*
       tdf#136559 If we have no dates we don't need a tree
       structure, just a list. GtkListStore can be then
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index b8a71e0..8d813869 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -1496,6 +1496,8 @@ public:

    virtual void set_toggle(const weld::TreeIter& rIter, TriState eState, int col = -1) override;

    virtual void set_clicks_to_toggle(int nToggleBehavior) override;

    virtual void set_extra_row_indent(const weld::TreeIter& rIter, int nIndentLevel) override;

    void set_text_emphasis(SvTreeListEntry* pEntry, bool bOn, int col = -1);
diff --git a/vcl/inc/svimpbox.hxx b/vcl/inc/svimpbox.hxx
index ae171cc..54382ea 100644
--- a/vcl/inc/svimpbox.hxx
+++ b/vcl/inc/svimpbox.hxx
@@ -188,6 +188,7 @@ protected:
    VclPtr<SvTreeListBox>   m_pView;
    VclPtr<ScrollBar>       m_aVerSBar;
    SvTreeListEntry*        m_pCursor;
    SvTreeListEntry*        m_pCursorOld;
    SvTreeListEntry*        m_pStartEntry;
    ImplSVEvent*            m_nCurUserEvent;
    Size                    m_aOutputSize;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 06d8c8f..6183b1a 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -4061,6 +4061,11 @@ void SalInstanceTreeView::set_toggle(const weld::TreeIter& rIter, TriState eStat
    set_toggle(rVclIter.iter, eState, col);
}

void SalInstanceTreeView::set_clicks_to_toggle(int nToggleBehavior)
{
    m_xTreeView->SetClicksToToggle(nToggleBehavior);
}

void SalInstanceTreeView::set_extra_row_indent(const weld::TreeIter& rIter, int nIndentLevel)
{
    weld::TreeIter& rNonConstIter = const_cast<weld::TreeIter&>(rIter);
diff --git a/vcl/source/treelist/treelistbox.cxx b/vcl/source/treelist/treelistbox.cxx
index 818c6481..5211bb5 100644
--- a/vcl/source/treelist/treelistbox.cxx
+++ b/vcl/source/treelist/treelistbox.cxx
@@ -399,6 +399,7 @@ SvTreeListBox::SvTreeListBox(vcl::Window* pParent, WinBits nWinStyle) :
    mbQuickSearch(false),
    mbActivateOnSingleClick(false),
    mbHoverSelection(false),
    mnClicksToToggle(0), //at default clicking on a row won't toggle its default checkbox
    eSelMode(SelectionMode::NONE),
    nMinWidthInChars(0),
    mnDragAction(DND_ACTION_COPYMOVE | DND_ACTION_LINK),
@@ -2283,17 +2284,18 @@ void SvTreeListBox::Paint(vcl::RenderContext& rRenderContext, const tools::Recta

void SvTreeListBox::MouseButtonDown( const MouseEvent& rMEvt )
{
    pImpl->m_pCursorOld = pImpl->m_pCursor;
    pImpl->MouseButtonDown( rMEvt );
}

void SvTreeListBox::MouseButtonUp( const MouseEvent& rMEvt )
{
    // tdf#116675 clicking on an entry should toggle its checkbox
    if (rMEvt.IsLeft() && (nTreeFlags & SvTreeFlags::CHKBTN))
    if (rMEvt.IsLeft() && (nTreeFlags & SvTreeFlags::CHKBTN) && mnClicksToToggle > 0)
    {
        const Point aPnt = rMEvt.GetPosPixel();
        SvTreeListEntry* pEntry = GetEntry(aPnt);
        if (pEntry && pEntry->m_Items.size() > 0)
        if (pEntry && pEntry->m_Items.size() > 0 && (mnClicksToToggle == 1 || pEntry == pImpl->m_pCursorOld))
        {
            SvLBoxItem* pItem = GetItem(pEntry, aPnt.X());
            // if the checkbox button was clicked, that will be toggled later, do not toggle here
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index f019bd0..a42dbd5 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -11334,6 +11334,10 @@ public:
        }
    }

    virtual void set_clicks_to_toggle(int /*nToggleBehavior*/) override
    {
    }

    virtual void set_extra_row_indent(const weld::TreeIter& rIter, int nIndentLevel) override
    {
        const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter);