cui/source/tabpages/tpbitmap.cxx         |   28 +++++++++++++++++-----------
 cui/source/tabpages/tpgradnt.cxx         |   19 ++++++++++---------
 cui/source/tabpages/tphatch.cxx          |   19 ++++++++++---------
 cui/source/tabpages/tppattern.cxx        |   21 +++++++++++----------
 include/svtools/valueset.hxx             |    1 +
 include/svx/SvxPresetListBox.hxx         |    2 ++
 svx/source/tbxctrls/SvxPresetListBox.cxx |    7 +++++--
 7 files changed, 56 insertions(+), 41 deletions(-)

New commits:
commit 006541afcf9cf68425ad3eea466c5d9e129f3b63
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Mon Nov 11 16:50:40 2024 -0500
Commit:     Justin Luth <justin.l...@collabora.com>
CommitDate: Tue Nov 12 14:52:37 2024 +0100

    tdf#157467 SvxPresetListBox: contextmenu must affect item under mouse
    
    Yikes - especially when delete is involved.
    Previously it was deleting the in-use background,
    regardless of where the mouse right-click happened.
    
    You might wonder why not just query GetHighlightedItemId?
    That is because (at least for GTK)
    the highlightedItem is zero'd out as soon as the pop-up starts,
    i.e. when the mouse is moved over top of the context menu.
    
    Change-Id: Ib88cb0edb8c2c8f854c35821d8125a1991d12a55
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176447
    Reviewed-by: Justin Luth <jl...@mail.com>
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/cui/source/tabpages/tpbitmap.cxx b/cui/source/tabpages/tpbitmap.cxx
index 9ed75da8d3c8..17819fb36ebf 100644
--- a/cui/source/tabpages/tpbitmap.cxx
+++ b/cui/source/tabpages/tpbitmap.cxx
@@ -512,8 +512,8 @@ IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyBitmapHdl, 
ValueSet*, void)
 
 IMPL_LINK_NOARG(SvxBitmapTabPage, ClickRenameHdl, SvxPresetListBox*, void)
 {
-    sal_uInt16 nId = m_xBitmapLB->GetSelectedItemId();
-    size_t nPos = m_xBitmapLB->GetSelectItemPos();
+    const sal_uInt16 nId = m_xBitmapLB->GetContextMenuItemId();
+    const size_t nPos = m_xBitmapLB->GetItemPos(nId);
 
     if( nPos == VALUESET_ITEM_NOTFOUND )
         return;
@@ -537,7 +537,6 @@ IMPL_LINK_NOARG(SvxBitmapTabPage, ClickRenameHdl, 
SvxPresetListBox*, void)
             m_pBitmapList->GetBitmap(nPos)->SetName(aName);
 
             m_xBitmapLB->SetItemText(nId, aName);
-            m_xBitmapLB->SelectItem( nId );
 
             *m_pnBitmapListState |= ChangeType::MODIFIED;
         }
@@ -552,8 +551,8 @@ IMPL_LINK_NOARG(SvxBitmapTabPage, ClickRenameHdl, 
SvxPresetListBox*, void)
 
 IMPL_LINK_NOARG(SvxBitmapTabPage, ClickDeleteHdl, SvxPresetListBox*, void)
 {
-    sal_uInt16 nId = m_xBitmapLB->GetSelectedItemId();
-    size_t nPos = m_xBitmapLB->GetSelectItemPos();
+    const sal_uInt16 nId = m_xBitmapLB->GetContextMenuItemId();
+    const size_t nPos = m_xBitmapLB->GetItemPos(nId);
 
     if( nPos == VALUESET_ITEM_NOTFOUND )
         return;
@@ -564,16 +563,23 @@ IMPL_LINK_NOARG(SvxBitmapTabPage, ClickDeleteHdl, 
SvxPresetListBox*, void)
     if (xQueryBox->run() != RET_YES)
         return;
 
-    sal_uInt16 nNextId = m_xBitmapLB->GetItemId(nPos + 1);
-    if (!nNextId)
-        nNextId = m_xBitmapLB->GetItemId(nPos - 1);
+    sal_uInt16 nNextId = m_xBitmapLB->GetSelectedItemId();
+    const bool bDeletingSelectedItem(nId == nNextId);
+    if (bDeletingSelectedItem)
+    {
+        nNextId = m_xBitmapLB->GetItemId(nPos + 1);
+        if (!nNextId)
+            nNextId = m_xBitmapLB->GetItemId(nPos - 1);
+    }
 
     m_pBitmapList->Remove( static_cast<sal_uInt16>(nPos) );
     m_xBitmapLB->RemoveItem( nId );
 
-    m_xBitmapLB->SelectItem(nNextId);
-
-    m_aCtlBitmapPreview.Invalidate();
+    if (bDeletingSelectedItem)
+    {
+        m_xBitmapLB->SelectItem(nNextId);
+        m_aCtlBitmapPreview.Invalidate();
+    }
     ModifyBitmapHdl(m_xBitmapLB.get());
     *m_pnBitmapListState |= ChangeType::MODIFIED;
 }
diff --git a/cui/source/tabpages/tpgradnt.cxx b/cui/source/tabpages/tpgradnt.cxx
index feab16ef7743..555cc834c91e 100644
--- a/cui/source/tabpages/tpgradnt.cxx
+++ b/cui/source/tabpages/tpgradnt.cxx
@@ -431,8 +431,8 @@ IMPL_LINK_NOARG(SvxGradientTabPage, ClickModifyHdl_Impl, 
weld::Button&, void)
 
 IMPL_LINK_NOARG(SvxGradientTabPage, ClickDeleteHdl_Impl, SvxPresetListBox*, 
void)
 {
-    sal_uInt16 nId = m_xGradientLB->GetSelectedItemId();
-    size_t nPos = m_xGradientLB->GetSelectItemPos();
+    const sal_uInt16 nId = m_xGradientLB->GetContextMenuItemId();
+    const size_t nPos = m_xGradientLB->GetItemPos(nId);
 
     if( nPos != VALUESET_ITEM_NOTFOUND )
     {
@@ -440,14 +440,16 @@ IMPL_LINK_NOARG(SvxGradientTabPage, ClickDeleteHdl_Impl, 
SvxPresetListBox*, void
         std::unique_ptr<weld::MessageDialog> 
xQueryBox(xBuilder->weld_message_dialog(u"AskDelGradientDialog"_ustr));
         if (xQueryBox->run() == RET_YES)
         {
+            const bool bDeletingSelectedItem(nId == 
m_xGradientLB->GetSelectedItemId());
             m_pGradientList->Remove(nPos);
             m_xGradientLB->RemoveItem( nId );
-            nId = m_xGradientLB->GetItemId( 0 );
-            m_xGradientLB->SelectItem( nId );
+            if (bDeletingSelectedItem)
+            {
+                
m_xGradientLB->SelectItem(m_xGradientLB->GetItemId(/*Position=*/0));
+                m_aCtlPreview.Invalidate();
+            }
             m_xGradientLB->Resize();
 
-            m_aCtlPreview.Invalidate();
-
             ChangeGradientHdl_Impl();
 
             *m_pnGradientListState |= ChangeType::MODIFIED;
@@ -460,8 +462,8 @@ IMPL_LINK_NOARG(SvxGradientTabPage, ClickDeleteHdl_Impl, 
SvxPresetListBox*, void
 
 IMPL_LINK_NOARG(SvxGradientTabPage, ClickRenameHdl_Impl, SvxPresetListBox*, 
void)
 {
-    sal_uInt16 nId = m_xGradientLB->GetSelectedItemId();
-    size_t nPos = m_xGradientLB->GetSelectItemPos();
+    const sal_uInt16 nId = m_xGradientLB->GetContextMenuItemId();
+    const size_t nPos = m_xGradientLB->GetItemPos(nId);
 
     if ( nPos == VALUESET_ITEM_NOTFOUND )
         return;
@@ -485,7 +487,6 @@ IMPL_LINK_NOARG(SvxGradientTabPage, ClickRenameHdl_Impl, 
SvxPresetListBox*, void
             m_pGradientList->GetGradient(nPos)->SetName(aName);
 
             m_xGradientLB->SetItemText( nId, aName );
-            m_xGradientLB->SelectItem( nId );
 
             *m_pnGradientListState |= ChangeType::MODIFIED;
         }
diff --git a/cui/source/tabpages/tphatch.cxx b/cui/source/tabpages/tphatch.cxx
index bfa6d2fa417a..311e7d46b934 100644
--- a/cui/source/tabpages/tphatch.cxx
+++ b/cui/source/tabpages/tphatch.cxx
@@ -494,8 +494,8 @@ IMPL_LINK_NOARG(SvxHatchTabPage, ClickModifyHdl_Impl, 
weld::Button&, void)
 
 IMPL_LINK_NOARG(SvxHatchTabPage, ClickDeleteHdl_Impl, SvxPresetListBox*, void)
 {
-    sal_uInt16 nId = m_xHatchLB->GetSelectedItemId();
-    size_t nPos = m_xHatchLB->GetSelectItemPos();
+    const sal_uInt16 nId = m_xHatchLB->GetContextMenuItemId();
+    const size_t nPos = m_xHatchLB->GetItemPos(nId);
 
     if( nPos == VALUESET_ITEM_NOTFOUND )
         return;
@@ -505,14 +505,16 @@ IMPL_LINK_NOARG(SvxHatchTabPage, ClickDeleteHdl_Impl, 
SvxPresetListBox*, void)
     if (xQueryBox->run() != RET_YES)
         return;
 
+    const bool bDeletingSelectedItem(nId == m_xHatchLB->GetSelectedItemId());
     m_pHatchingList->Remove(nPos);
     m_xHatchLB->RemoveItem( nId );
-    nId = m_xHatchLB->GetItemId(0);
-    m_xHatchLB->SelectItem( nId );
+    if (bDeletingSelectedItem)
+    {
+        m_xHatchLB->SelectItem(m_xHatchLB->GetItemId(/*Position=*/0));
+        m_aCtlPreview.Invalidate();
+    }
     m_xHatchLB->Resize();
 
-    m_aCtlPreview.Invalidate();
-
     ChangeHatchHdl_Impl();
 
     *m_pnHatchingListState |= ChangeType::MODIFIED;
@@ -520,8 +522,8 @@ IMPL_LINK_NOARG(SvxHatchTabPage, ClickDeleteHdl_Impl, 
SvxPresetListBox*, void)
 
 IMPL_LINK_NOARG(SvxHatchTabPage, ClickRenameHdl_Impl, SvxPresetListBox*, void )
 {
-    sal_uInt16 nId = m_xHatchLB->GetSelectedItemId();
-    size_t nPos = m_xHatchLB->GetSelectItemPos();
+    const sal_uInt16 nId = m_xHatchLB->GetContextMenuItemId();
+    const size_t nPos = m_xHatchLB->GetItemPos(nId);
 
     if( nPos == VALUESET_ITEM_NOTFOUND )
         return;
@@ -545,7 +547,6 @@ IMPL_LINK_NOARG(SvxHatchTabPage, ClickRenameHdl_Impl, 
SvxPresetListBox*, void )
             m_pHatchingList->GetHatch(nPos)->SetName(aName);
 
             m_xHatchLB->SetItemText(nId, aName);
-            m_xHatchLB->SelectItem( nId );
 
             *m_pnHatchingListState |= ChangeType::MODIFIED;
         }
diff --git a/cui/source/tabpages/tppattern.cxx 
b/cui/source/tabpages/tppattern.cxx
index 481248e29278..d6f591d1fcbe 100644
--- a/cui/source/tabpages/tppattern.cxx
+++ b/cui/source/tabpages/tppattern.cxx
@@ -425,8 +425,8 @@ IMPL_LINK_NOARG(SvxPatternTabPage, ClickModifyHdl_Impl, 
weld::Button&, void)
 
 IMPL_LINK_NOARG(SvxPatternTabPage, ClickRenameHdl_Impl, SvxPresetListBox*, 
void)
 {
-    size_t nPos = m_xPatternLB->GetSelectItemPos();
-    sal_Int32 nId = m_xPatternLB->GetSelectedItemId();
+    const sal_uInt16 nId = m_xPatternLB->GetContextMenuItemId();
+    const size_t nPos = m_xPatternLB->GetItemPos(nId);
 
     if ( nPos == VALUESET_ITEM_NOTFOUND )
         return;
@@ -452,7 +452,6 @@ IMPL_LINK_NOARG(SvxPatternTabPage, ClickRenameHdl_Impl, 
SvxPresetListBox*, void)
             m_pPatternList->GetBitmap(nPos)->SetName(aName);
 
             m_xPatternLB->SetItemText( nId, aName );
-            m_xPatternLB->SelectItem( nId );
 
             *m_pnPatternListState |= ChangeType::MODIFIED;
         }
@@ -467,8 +466,8 @@ IMPL_LINK_NOARG(SvxPatternTabPage, ClickRenameHdl_Impl, 
SvxPresetListBox*, void)
 
 IMPL_LINK_NOARG(SvxPatternTabPage, ClickDeleteHdl_Impl, SvxPresetListBox*, 
void)
 {
-    sal_uInt16 nId = m_xPatternLB->GetSelectedItemId();
-    size_t nPos = m_xPatternLB->GetSelectItemPos();
+    const sal_uInt16 nId = m_xPatternLB->GetContextMenuItemId();
+    const size_t nPos = m_xPatternLB->GetItemPos(nId);
 
     if( nPos != VALUESET_ITEM_NOTFOUND )
     {
@@ -476,15 +475,17 @@ IMPL_LINK_NOARG(SvxPatternTabPage, ClickDeleteHdl_Impl, 
SvxPresetListBox*, void)
         std::unique_ptr<weld::MessageDialog> 
xQueryBox(xBuilder->weld_message_dialog(u"AskDelBitmapDialog"_ustr));
         if (xQueryBox->run() == RET_YES)
         {
+            const bool bDeletingSelectedItem(nId == 
m_xPatternLB->GetSelectedItemId());
             m_pPatternList->Remove(nPos);
             m_xPatternLB->RemoveItem( nId );
-            nId = m_xPatternLB->GetItemId(0);
-            m_xPatternLB->SelectItem( nId );
+            if (bDeletingSelectedItem)
+            {
+                
m_xPatternLB->SelectItem(m_xPatternLB->GetItemId(/*Position=*/0));
+                m_aCtlPreview.Invalidate();
+                m_xCtlPixel->Invalidate();
+            }
             m_xPatternLB->Resize();
 
-            m_aCtlPreview.Invalidate();
-            m_xCtlPixel->Invalidate();
-
             ChangePatternHdl_Impl(m_xPatternLB.get());
 
             *m_pnPatternListState |= ChangeType::MODIFIED;
diff --git a/include/svtools/valueset.hxx b/include/svtools/valueset.hxx
index 2a51c19d0990..03dea4c03749 100644
--- a/include/svtools/valueset.hxx
+++ b/include/svtools/valueset.hxx
@@ -348,6 +348,7 @@ public:
     {
         return mbNoSelection;
     }
+    sal_uInt16 GetHighlightedItemId() const { return mnHighItemId; }
 
     void            SetItemImage( sal_uInt16 nItemId, const Image& rImage );
     Image           GetItemImage( sal_uInt16 nItemId ) const;
diff --git a/include/svx/SvxPresetListBox.hxx b/include/svx/SvxPresetListBox.hxx
index e5733097adcf..5255f4156be7 100644
--- a/include/svx/SvxPresetListBox.hxx
+++ b/include/svx/SvxPresetListBox.hxx
@@ -28,6 +28,7 @@ class SVXCORE_DLLPUBLIC SvxPresetListBox final : public 
ValueSet
 private:
     static constexpr sal_uInt32  nColCount = 3;
     Size                         aIconSize;
+    sal_uInt16 mnContextMenuItemId;
     Link<SvxPresetListBox*,void> maRenameHdl;
     Link<SvxPresetListBox*,void> maDeleteHdl;
 
@@ -43,6 +44,7 @@ public:
     virtual bool Command(const CommandEvent& rEvent) override;
     virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
     Size const & GetIconSize() const { return aIconSize; }
+    sal_uInt16 GetContextMenuItemId() const { return mnContextMenuItemId; }
 
     void SetRenameHdl( const Link<SvxPresetListBox*,void>& rLink )
     {
diff --git a/svx/source/tbxctrls/SvxPresetListBox.cxx 
b/svx/source/tbxctrls/SvxPresetListBox.cxx
index 2e8c71af3902..39b34e9ae476 100644
--- a/svx/source/tbxctrls/SvxPresetListBox.cxx
+++ b/svx/source/tbxctrls/SvxPresetListBox.cxx
@@ -26,6 +26,7 @@
 SvxPresetListBox::SvxPresetListBox(std::unique_ptr<weld::ScrolledWindow> 
pWindow)
     : ValueSet(std::move(pWindow))
     , aIconSize(60, 64)
+    , mnContextMenuItemId(0)
 {
     SetEdgeBlending(true);
 }
@@ -49,14 +50,16 @@ bool SvxPresetListBox::Command(const CommandEvent& rEvent)
 {
     if (rEvent.GetCommand() != CommandEventId::ContextMenu)
         return CustomWidgetController::Command(rEvent);
-    const sal_uInt16 nIndex = GetSelectedItemId();
-    if (nIndex > 0)
+    mnContextMenuItemId = GetHighlightedItemId();
+    if (mnContextMenuItemId > 0)
     {
         std::unique_ptr<weld::Builder> xBuilder(
             Application::CreateBuilder(GetDrawingArea(), 
u"svx/ui/presetmenu.ui"_ustr));
         std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu(u"menu"_ustr));
         OnMenuItemSelected(xMenu->popup_at_rect(
             GetDrawingArea(), tools::Rectangle(rEvent.GetMousePosPixel(), 
Size(1, 1))));
+
+        mnContextMenuItemId = 0;
         return true;
     }
     return false;

Reply via email to