[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-6-4+backports' - include/vcl vcl/inc vcl/source

Armin Le Grand (Allotropia) (via logerrit) logerrit at kemper.freedesktop.org
Sun Aug 1 14:22:43 UTC 2021


 include/vcl/treelistbox.hxx         |    1 
 vcl/inc/svimpbox.hxx                |   10 ++++
 vcl/source/treelist/svimpbox.cxx    |    3 -
 vcl/source/treelist/treelistbox.cxx |   76 ++++++++++++++++++++++++++++++++++--
 4 files changed, 85 insertions(+), 5 deletions(-)

New commits:
commit 02d348acf21312c885ab202a53b3a1aecd69cc06
Author:     Armin Le Grand (Allotropia) <Armin.Le.Grand at me.com>
AuthorDate: Wed Jul 28 19:01:15 2021 +0200
Commit:     Thorsten Behrens <thorsten.behrens at allotropia.de>
CommitDate: Sun Aug 1 16:22:08 2021 +0200

    tdf#143114 Avoid StartDrag on TreeListBox when CaptureOnButton
    
    Note: Had to add missing SvTreeListBox::GetItemPos impl and
    reduce to single component to make 2nd part of fix work
    in this branch.
    Also needed to add m_pCursorOld to SvImpLBox and decided
    to just remove mnClicksToToggle in this version.
    
    The original method SvTreeListBox::StartDrag always triggers
    a MouseButtonUp event and tries to initiate a Drag of a Line of
    a TreeListBox (on MouseMove, btw).
    
    This is not wanted if the last MouseButtonDown started a
    ButtonActive mode and activated CaptureMouse, prepared to
    trigger Action on that Button on MouseButtonUp. It leads to
    unwanted/strange behaviour of Buttons/CheckBoxes when used in
    TreeListBoxes.
    
    The behaviour is also dependent on the UI implementation used
    under Linux (gen/gtk3_kde5/gtk3/qt5/kf5) which are all
    (unfortunately) behaving differently, but a first suggestion/
    step to enhance the situation.
    
    Found now for gen/qt5/kf5 that when on the LineEntry, but
    not on the CheckBox, on MouseButtonUp the other line gets
    switched. Corrected that.
    
    Note: for gtk3_kde5/gtk3 there remains the problem that the
    CheckBoxes get switched on MouseButtonDown, butt these are
    generic widgets and this needs to be solved differently.
    
    Change-Id: If4cfe894b716185293beff64fc7e482d6f6313d3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119644
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <Armin.Le.Grand at me.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119756
    Tested-by: Thorsten Behrens <thorsten.behrens at allotropia.de>
    Reviewed-by: Thorsten Behrens <thorsten.behrens at allotropia.de>

diff --git a/include/vcl/treelistbox.hxx b/include/vcl/treelistbox.hxx
index 0f47b402dc91..012fbd9c4bd3 100644
--- a/include/vcl/treelistbox.hxx
+++ b/include/vcl/treelistbox.hxx
@@ -670,6 +670,7 @@ public:
     void            InvalidateEntry( SvTreeListEntry* );
     SvLBoxItem*     GetItem( SvTreeListEntry*, long nX, SvLBoxTab** ppTab);
     SvLBoxItem*     GetItem( SvTreeListEntry*, long nX );
+    long            GetItemPos(SvTreeListEntry* pEntry, sal_uInt16 nTabIdx);
 
     void            SetDragDropMode( DragDropMode );
     void            SetSelectionMode( SelectionMode );
diff --git a/vcl/inc/svimpbox.hxx b/vcl/inc/svimpbox.hxx
index 0ba5517671cf..ce2f58579232 100644
--- a/vcl/inc/svimpbox.hxx
+++ b/vcl/inc/svimpbox.hxx
@@ -210,6 +210,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;
@@ -343,8 +344,17 @@ public:
 
     bool                IsSelectable( const SvTreeListEntry* pEntry );
     void                SetForceMakeVisible(bool bEnable) { mbForceMakeVisible = bEnable; }
+
+    // tdf#143114 allow to ask if CaptureOnButton is active
+    // (MouseButtonDown hit on SvLBoxButton, CaptureMouse() active)
+    bool                IsCaptureOnButtonActive() const;
 };
 
+inline bool SvImpLBox::IsCaptureOnButtonActive() const
+{
+    return nullptr != m_pActiveButton && nullptr != m_pActiveEntry;
+}
+
 inline Image& SvImpLBox::implGetImageLocation( const ImageType _eType )
 {
     return m_aNodeAndEntryImages[_eType];
diff --git a/vcl/source/treelist/svimpbox.cxx b/vcl/source/treelist/svimpbox.cxx
index 75b482ecaa0b..7220267409ff 100644
--- a/vcl/source/treelist/svimpbox.cxx
+++ b/vcl/source/treelist/svimpbox.cxx
@@ -81,6 +81,7 @@ SvImpLBox::SvImpLBox( SvTreeListBox* pLBView, SvTreeList* pLBTree, WinBits nWinS
 
     m_pStartEntry = nullptr;
     m_pCursor             = nullptr;
+    m_pCursorOld          = nullptr;
     m_pAnchor             = nullptr;
     m_nVisibleCount       = 0;    // number of rows of data in control
     m_nNodeBmpTabDistance = NODE_BMP_TABDIST_NOTVALID;
@@ -265,6 +266,7 @@ void SvImpLBox::Clear()
             m_pView->HideFocus();
         m_pCursor = nullptr;
     }
+    m_pCursorOld = nullptr;
     m_aVerSBar->Hide();
     m_aVerSBar->SetThumbPos( 0 );
     Range aRange( 0, 0 );
@@ -1858,7 +1860,6 @@ void SvImpLBox::EntryInserted( SvTreeListEntry* pEntry )
 
 
 // ****** Control the control animation
-
 bool SvImpLBox::ButtonDownCheckCtrl(const MouseEvent& rMEvt, SvTreeListEntry* pEntry)
 {
     SvLBoxItem* pItem = m_pView->GetItem(pEntry,rMEvt.GetPosPixel().X(),&m_pActiveTab);
diff --git a/vcl/source/treelist/treelistbox.cxx b/vcl/source/treelist/treelistbox.cxx
index aa56db5b718f..23729f56b25a 100644
--- a/vcl/source/treelist/treelistbox.cxx
+++ b/vcl/source/treelist/treelistbox.cxx
@@ -1151,10 +1151,13 @@ void SvTreeListBox::SetupDragOrigin()
 
 void SvTreeListBox::StartDrag( sal_Int8, const Point& rPosPixel )
 {
-
-    Point aEventPos( rPosPixel );
-    MouseEvent aMouseEvt( aEventPos, 1, MouseEventModifiers::SELECT, MOUSE_LEFT );
-    MouseButtonUp( aMouseEvt );
+    if(nullptr != pImpl)
+    {
+        // tdf#143114 do not start drag when a Button/Checkbox is in
+        // drag-before-ButtonUp mode (CaptureMouse() active)
+        if(pImpl->IsCaptureOnButtonActive())
+            return;
+    }
 
     nOldDragMode = GetDragDropMode();
     if ( nOldDragMode == DragDropMode::NONE )
@@ -2315,10 +2318,75 @@ void SvTreeListBox::Paint(vcl::RenderContext& rRenderContext, const tools::Recta
 void SvTreeListBox::MouseButtonDown( const MouseEvent& rMEvt )
 {
     pImpl->MouseButtonDown( rMEvt );
+
+    // tdf#143114 remember the *correct* starting entry
+    pImpl->m_pCursorOld = (rMEvt.IsLeft() && (nTreeFlags & SvTreeFlags::CHKBTN))
+        ? GetEntry(rMEvt.GetPosPixel())
+        : nullptr;
+}
+
+long SvTreeListBox::GetItemPos(SvTreeListEntry* pEntry, sal_uInt16 nTabIdx)
+{
+    sal_uInt16 nTabCount = aTabs.size();
+    sal_uInt16 nItemCount = pEntry->ItemCount();
+    if (nTabIdx >= nItemCount || nTabIdx >= nTabCount)
+        return -1;
+
+    SvLBoxTab* pTab = aTabs.front().get();
+    SvLBoxItem* pItem = &pEntry->GetItem(nTabIdx);
+    sal_uInt16 nNextItem = nTabIdx + 1;
+
+    long nRealWidth = pImpl->GetOutputSize().Width();
+    nRealWidth -= GetMapMode().GetOrigin().X();
+
+    SvLBoxTab* pNextTab = nNextItem < nTabCount ? aTabs[nNextItem].get() : nullptr;
+    long nStart = GetTabPos(pEntry, pTab);
+
+    long nNextTabPos;
+    if (pNextTab)
+        nNextTabPos = GetTabPos(pEntry, pNextTab);
+    else
+    {
+        nNextTabPos = nRealWidth;
+        if (nStart > nRealWidth)
+            nNextTabPos += 50;
+    }
+
+    auto nItemWidth(pItem->GetWidth(this, pEntry));
+    nStart += pTab->CalcOffset(nItemWidth, nNextTabPos - nStart);
+
+    return nStart; //, nLen);
 }
 
 void SvTreeListBox::MouseButtonUp( const MouseEvent& rMEvt )
 {
+    // tdf#116675 clicking on an entry should toggle its checkbox
+    // tdf#143114 use the already created starting entry and if it exists
+    if (nullptr != pImpl->m_pCursorOld)
+    {
+        const Point aPnt = rMEvt.GetPosPixel();
+        SvTreeListEntry* pEntry = GetEntry(aPnt);
+
+        // compare if MouseButtonUp *is* on the same entry, regardless of scrolling
+        // or other things
+        if (pEntry && pEntry->m_Items.size() > 0 && 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
+            // anyway users probably don't want to toggle the checkbox by clickink on another button
+            if (!pItem || pItem->GetType() != SvLBoxItemType::Button)
+            {
+                SvLBoxButton* pItemCheckBox
+                    = static_cast<SvLBoxButton*>(pEntry->GetFirstItem(SvLBoxItemType::Button));
+                if (pItemCheckBox && GetItemPos(pEntry, 0) < aPnt.X() - GetMapMode().GetOrigin().X())
+                {
+                    pItemCheckBox->ClickHdl(pEntry);
+                    InvalidateEntry(pEntry);
+                }
+            }
+        }
+    }
+
     pImpl->MouseButtonUp( rMEvt );
 }
 


More information about the Libreoffice-commits mailing list