Resolves: tdf#128802 manage dnd ourself

instead of relying on the built-in dnd which is allowing
toplevel entries to be dropped on other ones to become
children of another entry, which is not what we want here.

Change-Id: I8c5528d9b26e994b7eda9d2972af0b3783187f3e
Reviewed-on: https://gerrit.libreoffice.org/82770
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/cui/source/customize/SvxMenuConfigPage.cxx b/cui/source/customize/SvxMenuConfigPage.cxx
index f560a25..2b6ef9e 100644
--- a/cui/source/customize/SvxMenuConfigPage.cxx
+++ b/cui/source/customize/SvxMenuConfigPage.cxx
@@ -46,6 +46,7 @@ SvxMenuConfigPage::SvxMenuConfigPage(weld::Container* pPage, weld::DialogControl
    m_xGearBtn->show();
    m_xContentsListBox.reset(new SvxMenuEntriesListBox(m_xBuilder->weld_tree_view("menucontents"), this));
    weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
    m_xDropTargetHelper.reset(new SvxConfigPageFunctionDropTarget(*this, rTreeView));
    rTreeView.connect_size_allocate(LINK(this, SvxMenuConfigPage, MenuEntriesSizeAllocHdl));
    Size aSize(m_xFunctions->get_size_request());
    rTreeView.set_size_request(aSize.Width(), aSize.Height());
@@ -57,8 +58,6 @@ SvxMenuConfigPage::SvxMenuConfigPage(weld::Container* pPage, weld::DialogControl
    rTreeView.connect_changed(
        LINK( this, SvxMenuConfigPage, SelectMenuEntry ) );

    rTreeView.connect_model_changed(LINK(this, SvxMenuConfigPage, ListModifiedHdl));

    m_xGearBtn->connect_selected(LINK(this, SvxMenuConfigPage, GearHdl));

    m_xCommandCategoryListBox->connect_changed(LINK(this, SvxMenuConfigPage, SelectCategory));
@@ -94,7 +93,7 @@ SvxMenuConfigPage::SvxMenuConfigPage(weld::Container* pPage, weld::DialogControl
    }
}

IMPL_LINK_NOARG(SvxMenuConfigPage, ListModifiedHdl, weld::TreeView&, void)
void SvxMenuConfigPage::ListModified()
{
    // regenerate with the current ordering within the list
    SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
diff --git a/cui/source/customize/SvxNotebookbarConfigPage.cxx b/cui/source/customize/SvxNotebookbarConfigPage.cxx
index 26cebe8..af5bed8 100644
--- a/cui/source/customize/SvxNotebookbarConfigPage.cxx
+++ b/cui/source/customize/SvxNotebookbarConfigPage.cxx
@@ -127,6 +127,8 @@ SvxNotebookbarConfigPage::SvxNotebookbarConfigPage(weld::Container* pPage,

    m_xContentsListBox.reset(
        new SvxNotebookbarEntriesListBox(m_xBuilder->weld_tree_view("toolcontents"), this));
    m_xDropTargetHelper.reset(
        new SvxConfigPageFunctionDropTarget(*this, m_xContentsListBox->get_widget()));
    std::vector<int> aWidths;
    weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
    Size aSize(m_xFunctions->get_size_request());
diff --git a/cui/source/customize/SvxToolbarConfigPage.cxx b/cui/source/customize/SvxToolbarConfigPage.cxx
index 36b3fd2..aee4abf 100644
--- a/cui/source/customize/SvxToolbarConfigPage.cxx
+++ b/cui/source/customize/SvxToolbarConfigPage.cxx
@@ -51,6 +51,8 @@ SvxToolbarConfigPage::SvxToolbarConfigPage(weld::Container* pPage, weld::DialogC
    m_xContainer->set_help_id(HID_SVX_CONFIG_TOOLBAR);

    m_xContentsListBox.reset(new SvxToolbarEntriesListBox(m_xBuilder->weld_tree_view("toolcontents"), this));
    m_xDropTargetHelper.reset(new SvxConfigPageFunctionDropTarget(*this, m_xContentsListBox->get_widget()));

    std::vector<int> aWidths;
    weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
    Size aSize(m_xFunctions->get_size_request());
@@ -82,8 +84,6 @@ SvxToolbarConfigPage::SvxToolbarConfigPage(weld::Container* pPage, weld::DialogC
    rTreeView.connect_changed(
        LINK( this, SvxToolbarConfigPage, SelectToolbarEntry ) );

    rTreeView.connect_model_changed(LINK(this, SvxToolbarConfigPage, ListModifiedHdl));

    m_xTopLevelListBox->set_help_id ( HID_SVX_TOPLEVELLISTBOX );
    m_xSaveInListBox->set_help_id( HID_SVX_SAVE_IN );
    m_xMoveUpButton->set_help_id( HID_SVX_UP_TOOLBAR_ITEM );
@@ -137,7 +137,7 @@ SvxToolbarConfigPage::SvxToolbarConfigPage(weld::Container* pPage, weld::DialogC
    }
}

IMPL_LINK_NOARG(SvxToolbarConfigPage, ListModifiedHdl, weld::TreeView&, void)
void SvxToolbarConfigPage::ListModified()
{
    // regenerate with the current ordering within the list
    SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
diff --git a/cui/source/customize/cfg.cxx b/cui/source/customize/cfg.cxx
index 2879d17..0f0f6dc 100644
--- a/cui/source/customize/cfg.cxx
+++ b/cui/source/customize/cfg.cxx
@@ -3163,4 +3163,40 @@ SvxIconChangeDialog::SvxIconChangeDialog(weld::Window *pWindow, const OUString& 
    m_xLineEditDescription->set_text(rMessage);
}

SvxConfigPageFunctionDropTarget::SvxConfigPageFunctionDropTarget(SvxConfigPage&rPage, weld::TreeView& rTreeView)
    : DropTargetHelper(rTreeView.get_drop_target())
    , m_rPage(rPage)
    , m_rTreeView(rTreeView)
{
}

sal_Int8 SvxConfigPageFunctionDropTarget::AcceptDrop(const AcceptDropEvent& rEvt)
{
    // to enable the autoscroll when we're close to the edges
    m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, nullptr);
    return DND_ACTION_MOVE;
}

sal_Int8 SvxConfigPageFunctionDropTarget::ExecuteDrop( const ExecuteDropEvent& rEvt )
{
    weld::TreeView* pSource = m_rTreeView.get_drag_source();
    // only draging within the same widget allowed
    if (!pSource || pSource != &m_rTreeView)
        return DND_ACTION_NONE;

    std::unique_ptr<weld::TreeIter> xSource(m_rTreeView.make_iterator());
    if (!m_rTreeView.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()))
        nTargetPos = m_rTreeView.get_iter_index_in_parent(*xTarget);
    m_rTreeView.move_subtree(*xSource, nullptr, nTargetPos);

    m_rPage.ListModified();

    return DND_ACTION_NONE;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/SvxMenuConfigPage.hxx b/cui/source/inc/SvxMenuConfigPage.hxx
index 881f805..5ff3aea 100644
--- a/cui/source/inc/SvxMenuConfigPage.hxx
+++ b/cui/source/inc/SvxMenuConfigPage.hxx
@@ -45,7 +45,7 @@ private:

    DECL_LINK( MenuEntriesSizeAllocHdl, const Size&, void );

    DECL_LINK( ListModifiedHdl, weld::TreeView&, void );
    virtual void ListModified() override;

    void            Init() override;
    void            UpdateButtonStates() override;
diff --git a/cui/source/inc/SvxToolbarConfigPage.hxx b/cui/source/inc/SvxToolbarConfigPage.hxx
index 5420467..542eee2 100644
--- a/cui/source/inc/SvxToolbarConfigPage.hxx
+++ b/cui/source/inc/SvxToolbarConfigPage.hxx
@@ -45,7 +45,7 @@ private:
    DECL_LINK( ModifyItemHdl, const OString&, void );
    DECL_LINK( ResetToolbarHdl, weld::Button&, void );

    DECL_LINK( ListModifiedHdl, weld::TreeView&, void );
    virtual void ListModified() override;

    void            UpdateButtonStates() override;
    short           QueryReset() override;
diff --git a/cui/source/inc/cfg.hxx b/cui/source/inc/cfg.hxx
index 71a36bd..93f4346 100644
--- a/cui/source/inc/cfg.hxx
+++ b/cui/source/inc/cfg.hxx
@@ -19,6 +19,7 @@
#ifndef INCLUDED_CUI_SOURCE_INC_CFG_HXX
#define INCLUDED_CUI_SOURCE_INC_CFG_HXX

#include <vcl/transfer.hxx>
#include <vcl/weld.hxx>
#include <svtools/valueset.hxx>

@@ -329,6 +330,7 @@ public:
    void remove(int nPos) { m_xControl->remove(nPos); }
    int n_children() const { return m_xControl->n_children(); }
    void set_text(int row, const OUString& rText, int col) { m_xControl->set_text(row, rText, col); }
    OUString get_text(int row) { return m_xControl->get_text(row); }
    void set_image(int row, const css::uno::Reference<css::graphic::XGraphic>& rImage, int col) { m_xControl->set_image(row, rImage, col); }
    void set_dropdown(int row, int col) { m_xControl->set_image(row, *m_xDropDown, col); }
    void set_id(int row, const OUString& rId) { m_xControl->set_id(row, rId); }
@@ -350,6 +352,19 @@ public:
    void CreateDropDown();
};

class SvxConfigPageFunctionDropTarget : public DropTargetHelper
{
private:
    SvxConfigPage& m_rPage;
    weld::TreeView& m_rTreeView;

    virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override;
    virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override;

public:
    SvxConfigPageFunctionDropTarget(SvxConfigPage&rPage, weld::TreeView& rTreeView);
};

class SvxConfigPage : public SfxTabPage
{
private:
@@ -387,6 +402,7 @@ protected:
    // Used to add and remove toolbars/menus
    std::unique_ptr<weld::MenuButton>          m_xGearBtn;
    std::unique_ptr<SvxMenuEntriesListBox>     m_xContentsListBox;
    std::unique_ptr<SvxConfigPageFunctionDropTarget> m_xDropTargetHelper;

    std::unique_ptr<weld::Button>              m_xMoveUpButton;
    std::unique_ptr<weld::Button>              m_xMoveDownButton;
@@ -462,6 +478,8 @@ public:
    virtual void    DeleteSelectedContent() = 0;
    virtual void    DeleteSelectedTopLevel() = 0;

    virtual void    ListModified() {}

    SvxConfigEntry* GetTopLevelSelection()
    {
        return reinterpret_cast<SvxConfigEntry*>(m_xTopLevelListBox->get_active_id().toInt64());
diff --git a/cui/uiconfig/ui/menuassignpage.ui b/cui/uiconfig/ui/menuassignpage.ui
index e3ce997..7f37aad 100644
--- a/cui/uiconfig/ui/menuassignpage.ui
+++ b/cui/uiconfig/ui/menuassignpage.ui
@@ -607,7 +607,6 @@
                    <property name="reorderable">True</property>
                    <property name="search_column">1</property>
                    <property name="show_expanders">False</property>
                    <property name="enable_tree_lines">True</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
                    </child>