cui/source/customize/SvxMenuConfigPage.cxx        |   15 +++++---
 cui/source/customize/SvxNotebookbarConfigPage.cxx |    4 +-
 cui/source/customize/SvxToolbarConfigPage.cxx     |   15 ++++----
 cui/source/customize/cfg.cxx                      |   40 +++++++++++++++++-----
 cui/source/inc/SvxMenuConfigPage.hxx              |    3 +
 cui/source/inc/SvxToolbarConfigPage.hxx           |    3 +
 cui/source/inc/cfg.hxx                            |   12 ++++--
 cui/uiconfig/ui/menuassignpage.ui                 |    1 
 include/vcl/weldutils.hxx                         |    2 -
 9 files changed, 69 insertions(+), 26 deletions(-)

New commits:
commit 1c9a034783686f5b4bcbd29b4025d0a43d9a5c83
Author:     Caolán McNamara <[email protected]>
AuthorDate: Sat Sep 13 12:07:48 2025 +0100
Commit:     Adolfo Jayme Barrientos <[email protected]>
CommitDate: Sat Sep 20 10:07:26 2025 +0200

    Resolves: tdf#156739 implement dnd for menu/toolbar customization pages
    
    dubious as a regression, but can be done now regardless
    
    Change-Id: I67bc322cd63e65b5347b3e54651e3618d09a99b6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190917
    Reviewed-by: Caolán McNamara <[email protected]>
    Tested-by: Jenkins
    (cherry picked from commit f4e2563012ff091ee27999713063fc87cd01fe7e)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190958
    Reviewed-by: Adolfo Jayme Barrientos <[email protected]>

diff --git a/cui/source/customize/SvxMenuConfigPage.cxx 
b/cui/source/customize/SvxMenuConfigPage.cxx
index d8d1d86387d2..72a3d350125e 100644
--- a/cui/source/customize/SvxMenuConfigPage.cxx
+++ b/cui/source/customize/SvxMenuConfigPage.cxx
@@ -45,7 +45,8 @@ SvxMenuConfigPage::SvxMenuConfigPage(weld::Container* pPage, 
weld::DialogControl
     m_xContentsListBox.reset(
         new 
SvxMenuEntriesListBox(m_xBuilder->weld_tree_view(u"menucontents"_ustr), this));
     weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
-    m_xDropTargetHelper.reset(new SvxConfigPageFunctionDropTarget(*this, 
rTreeView));
+    m_xDropTargetHelper.reset(new SvxConfigPageFunctionDropTarget(
+        *this, rTreeView, m_xFunctions->get_widget(), LINK(this, 
SvxMenuConfigPage, DropHdl)));
     rTreeView.connect_size_allocate(LINK(this, SvxMenuConfigPage, 
MenuEntriesSizeAllocHdl));
     Size aSize(m_xFunctions->get_size_request());
     rTreeView.set_size_request(aSize.Width(), aSize.Height());
@@ -106,6 +107,8 @@ void SvxMenuConfigPage::ListModified()
     UpdateButtonStates();
 }
 
+IMPL_LINK(SvxMenuConfigPage, DropHdl, int, nTarget, void) { 
AddCommand(nTarget, false); }
+
 IMPL_LINK(SvxMenuConfigPage, MenuEntriesSizeAllocHdl, const Size&, rSize, void)
 {
     weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
@@ -351,9 +354,9 @@ IMPL_LINK_NOARG(SvxMenuConfigPage, SelectCategory, 
weld::ComboBox&, void)
     SelectFunctionHdl(m_xFunctions->get_widget());
 }
 
-IMPL_LINK_NOARG(SvxMenuConfigPage, AddCommandHdl, weld::Button&, void)
+void SvxMenuConfigPage::AddCommand(int nTarget, bool bAfter)
 {
-    int nPos = AddFunction(-1, /*bAllowDuplicates*/ false);
+    int nPos = AddFunction(nTarget, /*bAllowDuplicates*/ false, bAfter);
     if (nPos == -1)
         return;
     weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
@@ -361,6 +364,8 @@ IMPL_LINK_NOARG(SvxMenuConfigPage, AddCommandHdl, 
weld::Button&, void)
     InsertEntryIntoUI(pEntry, rTreeView, nPos, true);
 }
 
+IMPL_LINK_NOARG(SvxMenuConfigPage, AddCommandHdl, weld::Button&, void) { 
AddCommand(-1, true); }
+
 IMPL_LINK_NOARG(SvxMenuConfigPage, RemoveCommandHdl, weld::Button&, void)
 {
     DeleteSelectedContent();
@@ -377,7 +382,7 @@ IMPL_LINK(SvxMenuConfigPage, InsertHdl, const OUString&, 
rIdent, void)
     {
         SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
         pNewEntryData->SetUserDefined();
-        int nPos = AppendEntry(pNewEntryData, -1);
+        int nPos = AppendEntry(pNewEntryData, -1, true);
         InsertEntryIntoUI(pNewEntryData, rTreeView, nPos, true);
     }
     else if (rIdent == "insertsubmenu")
@@ -398,7 +403,7 @@ IMPL_LINK(SvxMenuConfigPage, InsertHdl, const OUString&, 
rIdent, void)
             pNewEntryData->SetName(aNewName);
             pNewEntryData->SetUserDefined();
 
-            int nPos = AppendEntry(pNewEntryData, -1);
+            int nPos = AppendEntry(pNewEntryData, -1, true);
             InsertEntryIntoUI(pNewEntryData, rTreeView, nPos, true);
 
             ReloadTopLevelListBox();
diff --git a/cui/source/customize/SvxNotebookbarConfigPage.cxx 
b/cui/source/customize/SvxNotebookbarConfigPage.cxx
index 7bde0055bcfc..081b49babfbf 100644
--- a/cui/source/customize/SvxNotebookbarConfigPage.cxx
+++ b/cui/source/customize/SvxNotebookbarConfigPage.cxx
@@ -117,8 +117,8 @@ 
SvxNotebookbarConfigPage::SvxNotebookbarConfigPage(weld::Container* pPage,
 
     m_xContentsListBox.reset(
         new 
SvxNotebookbarEntriesListBox(m_xBuilder->weld_tree_view(u"toolcontents"_ustr), 
this));
-    m_xDropTargetHelper.reset(
-        new SvxConfigPageFunctionDropTarget(*this, 
m_xContentsListBox->get_widget()));
+    m_xDropTargetHelper.reset(new SvxConfigPageFunctionDropTarget(
+        *this, m_xContentsListBox->get_widget(), rCommandCategoryBox, 
Link<int, void>()));
     weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
     Size aSize(m_xFunctions->get_size_request());
     rTreeView.set_size_request(aSize.Width(), aSize.Height());
diff --git a/cui/source/customize/SvxToolbarConfigPage.cxx 
b/cui/source/customize/SvxToolbarConfigPage.cxx
index 8e5197ea6a0e..19d3644dc11f 100644
--- a/cui/source/customize/SvxToolbarConfigPage.cxx
+++ b/cui/source/customize/SvxToolbarConfigPage.cxx
@@ -56,8 +56,9 @@ SvxToolbarConfigPage::SvxToolbarConfigPage(weld::Container* 
pPage,
 
     m_xContentsListBox.reset(
         new 
SvxToolbarEntriesListBox(m_xBuilder->weld_tree_view(u"toolcontents"_ustr), 
this));
-    m_xDropTargetHelper.reset(
-        new SvxConfigPageFunctionDropTarget(*this, 
m_xContentsListBox->get_widget()));
+    m_xDropTargetHelper.reset(new SvxConfigPageFunctionDropTarget(
+        *this, m_xContentsListBox->get_widget(), m_xFunctions->get_widget(),
+        LINK(this, SvxToolbarConfigPage, DropHdl)));
 
     weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
     Size aSize(m_xFunctions->get_size_request());
@@ -430,7 +431,9 @@ IMPL_LINK_NOARG(SvxToolbarConfigPage, SelectCategory, 
weld::ComboBox&, void)
     SelectFunctionHdl(m_xFunctions->get_widget());
 }
 
-IMPL_LINK_NOARG(SvxToolbarConfigPage, AddCommandHdl, weld::Button&, void) { 
AddFunction(); }
+IMPL_LINK(SvxToolbarConfigPage, DropHdl, int, nTarget, void) { 
AddFunction(nTarget, false); }
+
+IMPL_LINK_NOARG(SvxToolbarConfigPage, AddCommandHdl, weld::Button&, void) { 
AddFunction(-1, true); }
 
 IMPL_LINK_NOARG(SvxToolbarConfigPage, RemoveCommandHdl, weld::Button&, void)
 {
@@ -447,7 +450,7 @@ IMPL_LINK(SvxToolbarConfigPage, InsertHdl, const OUString&, 
rIdent, void)
         SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
         pNewEntryData->SetUserDefined();
 
-        int nPos = AppendEntry(pNewEntryData, -1);
+        int nPos = AppendEntry(pNewEntryData, -1, true);
         InsertEntryIntoUI(pNewEntryData, m_xContentsListBox->get_widget(), 
nPos);
 
         
static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
@@ -771,7 +774,7 @@ void SvxToolbarConfigPage::SelectElement()
     UpdateButtonStates();
 }
 
-void SvxToolbarConfigPage::AddFunction(int nTarget)
+void SvxToolbarConfigPage::AddFunction(int nTarget, bool bAfter)
 {
     SvxConfigEntry* pToolbar = GetTopLevelSelection();
 
@@ -779,7 +782,7 @@ void SvxToolbarConfigPage::AddFunction(int nTarget)
         return;
 
     // Add the command to the contents listbox of the selected toolbar
-    int nNewLBEntry = SvxConfigPage::AddFunction(nTarget, true 
/*bAllowDuplicates*/);
+    int nNewLBEntry = SvxConfigPage::AddFunction(nTarget, true 
/*bAllowDuplicates*/, bAfter);
 
     if (nNewLBEntry == -1)
         return;
diff --git a/cui/source/customize/cfg.cxx b/cui/source/customize/cfg.cxx
index b1fb244d2060..28ee42a89438 100644
--- a/cui/source/customize/cfg.cxx
+++ b/cui/source/customize/cfg.cxx
@@ -1487,7 +1487,7 @@ bool SvxConfigPage::IsCommandInMenuList(const 
SvxConfigEntry *pEntryData,
     return toret;
 }
 
-int SvxConfigPage::AddFunction(int nTarget, bool bAllowDuplicates)
+int SvxConfigPage::AddFunction(int nTarget, bool bAllowDuplicates, bool bAfter)
 {
     int toret = -1;
     OUString aURL = GetScriptURL();
@@ -1508,7 +1508,7 @@ int SvxConfigPage::AddFunction(int nTarget, bool 
bAllowDuplicates)
     {
         delete pNewEntryData;
     } else {
-        toret = AppendEntry( pNewEntryData, nTarget );
+        toret = AppendEntry( pNewEntryData, nTarget, bAfter );
     }
 
     UpdateButtonStates();
@@ -1517,7 +1517,7 @@ int SvxConfigPage::AddFunction(int nTarget, bool 
bAllowDuplicates)
 
 int SvxConfigPage::AppendEntry(
     SvxConfigEntry* pNewEntryData,
-    int nTarget)
+    int nTarget, bool bAfter)
 {
     SvxConfigEntry* pTopLevelSelection = GetTopLevelSelection();
 
@@ -1554,9 +1554,12 @@ int SvxConfigPage::AppendEntry(
             ++nPos;
         }
 
-        // Now step past it to the entry after the currently selected one
-        ++iter;
-        ++nPos;
+        if (bAfter)
+        {
+            // Now step past it to the entry after the currently selected one
+            ++iter;
+            ++nPos;
+        }
 
         // Now add the new entry to the UI and to the parent's list
         if ( iter != end )
@@ -3192,15 +3195,36 @@ SvxIconChangeDialog::SvxIconChangeDialog(weld::Window 
*pWindow, const OUString&
     m_xLineEditDescription->set_text(rMessage);
 }
 
-SvxConfigPageFunctionDropTarget::SvxConfigPageFunctionDropTarget(SvxConfigPage&rPage,
 weld::TreeView& rTreeView)
+SvxConfigPageFunctionDropTarget::SvxConfigPageFunctionDropTarget(SvxConfigPage&rPage,
+        weld::TreeView& rTreeView, weld::TreeView& rFunctions,
+        const Link<int, void>& rDropHdl)
     : weld::ReorderingDropTarget(rTreeView)
     , m_rPage(rPage)
+    , m_rFunctions(rFunctions)
+    , m_aDropHdl(rDropHdl)
 {
 }
 
 sal_Int8 SvxConfigPageFunctionDropTarget::ExecuteDrop(const ExecuteDropEvent& 
rEvt)
 {
-    sal_Int8 nRet = weld::ReorderingDropTarget::ExecuteDrop(rEvt);
+    sal_Int8 nRet;
+    weld::TreeView* pSource = m_rTreeView.get_drag_source();
+    if (pSource && pSource == &m_rFunctions)
+    {
+        if (!m_aDropHdl.IsSet())
+            return DND_ACTION_NONE;
+        std::unique_ptr<weld::TreeIter> xSource(m_rFunctions.make_iterator());
+        if (!m_rFunctions.get_selected(xSource.get()))
+            return DND_ACTION_NONE;
+        std::unique_ptr<weld::TreeIter> xTarget(m_rTreeView.make_iterator());
+        int nTargetPos = -1;
+        if (m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, xTarget.get(), 
true))
+            nTargetPos = m_rTreeView.get_iter_index_in_parent(*xTarget);
+        m_aDropHdl.Call(nTargetPos);
+        nRet = DND_ACTION_NONE;
+    }
+    else
+        nRet = weld::ReorderingDropTarget::ExecuteDrop(rEvt);
     m_rPage.ListModified();
     return nRet;;
 }
diff --git a/cui/source/inc/SvxMenuConfigPage.hxx 
b/cui/source/inc/SvxMenuConfigPage.hxx
index 36fee041de76..7dfeb30cdee9 100644
--- a/cui/source/inc/SvxMenuConfigPage.hxx
+++ b/cui/source/inc/SvxMenuConfigPage.hxx
@@ -44,8 +44,11 @@ private:
     DECL_LINK(ModifyItemHdl, const OUString&, void);
     DECL_LINK(ResetMenuHdl, weld::Button&, void);
 
+    DECL_LINK(DropHdl, int, void);
     DECL_LINK(MenuEntriesSizeAllocHdl, const Size&, void);
 
+    void AddCommand(int nTarget, bool bAfter);
+
     virtual void ListModified() override;
 
     void Init() override;
diff --git a/cui/source/inc/SvxToolbarConfigPage.hxx 
b/cui/source/inc/SvxToolbarConfigPage.hxx
index 28fe658f2cca..7c17bc363ada 100644
--- a/cui/source/inc/SvxToolbarConfigPage.hxx
+++ b/cui/source/inc/SvxToolbarConfigPage.hxx
@@ -45,6 +45,7 @@ private:
     DECL_LINK(InsertHdl, const OUString&, void);
     DECL_LINK(ModifyItemHdl, const OUString&, void);
     DECL_LINK(ResetToolbarHdl, weld::Button&, void);
+    DECL_LINK(DropHdl, int, void);
 
     virtual void ListModified() override;
 
@@ -60,7 +61,7 @@ public:
                          const SfxItemSet& rItemSet);
     virtual ~SvxToolbarConfigPage() override;
 
-    void AddFunction(int nTarget = -1);
+    void AddFunction(int nTarget, bool bAfter);
 
     void MoveEntry(bool bMoveUp) override;
 
diff --git a/cui/source/inc/cfg.hxx b/cui/source/inc/cfg.hxx
index 1ae5b23a2999..43a355b5beb6 100644
--- a/cui/source/inc/cfg.hxx
+++ b/cui/source/inc/cfg.hxx
@@ -360,11 +360,16 @@ class SvxConfigPageFunctionDropTarget : public 
weld::ReorderingDropTarget
 {
 private:
     SvxConfigPage& m_rPage;
+    weld::TreeView& m_rFunctions;
+    Link<int, void> m_aDropHdl;
 
     virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override;
 
 public:
-    SvxConfigPageFunctionDropTarget(SvxConfigPage&rPage, weld::TreeView& 
rTreeView);
+    SvxConfigPageFunctionDropTarget(SvxConfigPage&rPage,
+            weld::TreeView& rTreeView,
+            weld::TreeView& rFunctions,
+            const Link<int, void>& rDropHdl);
 };
 
 class SvxConfigPage : public SfxTabPage
@@ -449,7 +454,7 @@ protected:
     virtual void            SelectElement() = 0;
 
     int                 AppendEntry(SvxConfigEntry* pNewEntryData,
-                                    int nTarget);
+                                    int nTarget, bool bAfter);
 
     void                AddSubMenusToUI(    std::u16string_view rBaseTitle,
                                         SvxConfigEntry const * pParentData );
@@ -486,7 +491,8 @@ public:
     const OUString& GetFileName() const { return m_sFileName; }
 
     int             AddFunction(int nTarget,
-                                bool bAllowDuplicates);
+                                bool bAllowDuplicates,
+                                bool bAfter);
 
     virtual void    MoveEntry( bool bMoveUp );
 
diff --git a/cui/uiconfig/ui/menuassignpage.ui 
b/cui/uiconfig/ui/menuassignpage.ui
index b545c193a352..b26a70f25497 100644
--- a/cui/uiconfig/ui/menuassignpage.ui
+++ b/cui/uiconfig/ui/menuassignpage.ui
@@ -328,6 +328,7 @@
                 <property name="vexpand">True</property>
                 <property name="model">liststore1</property>
                 <property name="headers-visible">False</property>
+                <property name="reorderable">True</property>
                 <property name="search-column">1</property>
                 <property name="enable-tree-lines">True</property>
                 <child internal-child="selection">
diff --git a/include/vcl/weldutils.hxx b/include/vcl/weldutils.hxx
index 8a3291c42345..3ba0bac4c0a0 100644
--- a/include/vcl/weldutils.hxx
+++ b/include/vcl/weldutils.hxx
@@ -435,9 +435,9 @@ public:
 */
 class VCL_DLLPUBLIC ReorderingDropTarget : public DropTargetHelper
 {
+protected:
     weld::TreeView& m_rTreeView;
 
-protected:
     virtual sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt) override;
     virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt) override;
 

Reply via email to