[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - include/vcl vcl/inc vcl/source vcl/unx

Szymon KÅ‚os (via logerrit) logerrit at kemper.freedesktop.org
Sat Dec 19 16:54:36 UTC 2020


 include/vcl/salvtables.hxx          |    5 +
 include/vcl/transfer.hxx            |    2 
 include/vcl/treelistbox.hxx         |    6 ++
 include/vcl/weld.hxx                |   10 +++
 vcl/inc/treeglue.hxx                |    7 +-
 vcl/inc/unx/gtk/gtkinst.hxx         |    7 ++
 vcl/source/app/salvtables.cxx       |   12 +++-
 vcl/source/treelist/treelistbox.cxx |   27 +++++++---
 vcl/unx/gtk3/gtk3gtkframe.cxx       |   34 +++++++++----
 vcl/unx/gtk3/gtk3gtkinst.cxx        |   92 ++++++++++++++++++++++++++++++++++++
 10 files changed, 178 insertions(+), 24 deletions(-)

New commits:
commit d4268144906ef261c6a7e32502925edd5c6dc16b
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Sat Dec 19 15:52:33 2020 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Sat Dec 19 17:54:01 2020 +0100

    Start Drag event support
    
    part of 19d17a7
    
    Change-Id: I1a1b5fd4f4aedbf79f64fdb4334aadc014b4eabb
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108026
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>

diff --git a/include/vcl/salvtables.hxx b/include/vcl/salvtables.hxx
index 401cbb0702a3..b96d02f0a5a8 100644
--- a/include/vcl/salvtables.hxx
+++ b/include/vcl/salvtables.hxx
@@ -1138,7 +1138,7 @@ protected:
     DECL_LINK(HeaderBarClickedHdl, HeaderBar*, void);
     DECL_LINK(ToggleHdl, SvLBoxButtonData*, void);
     DECL_LINK(ModelChangedHdl, SvTreeListBox*, void);
-    DECL_LINK(StartDragHdl, SvTreeListBox*, void);
+    DECL_LINK(StartDragHdl, SvTreeListBox*, bool);
     DECL_STATIC_LINK(SalInstanceTreeView, FinishDragHdl, SvTreeListBox*, void);
     DECL_LINK(EditingEntryHdl, SvTreeListEntry*, bool);
     typedef std::pair<SvTreeListEntry*, OUString> IterString;
@@ -1373,6 +1373,9 @@ public:
 
     virtual void set_id(const weld::TreeIter& rIter, const OUString& rId) override;
 
+    virtual void enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper,
+                                    sal_uInt8 eDNDConstants) override;
+
     virtual void set_selection_mode(SelectionMode eMode) override;
 
     virtual void all_foreach(const std::function<bool(weld::TreeIter&)>& func) override;
diff --git a/include/vcl/transfer.hxx b/include/vcl/transfer.hxx
index 75af922a007c..a0b773984d3b 100644
--- a/include/vcl/transfer.hxx
+++ b/include/vcl/transfer.hxx
@@ -483,7 +483,7 @@ public:
 
 struct TransferDataContainer_Impl;
 
-class VCL_DLLPUBLIC TransferDataContainer final : public TransferableHelper
+class VCL_DLLPUBLIC TransferDataContainer : public TransferableHelper
 {
     std::unique_ptr<TransferDataContainer_Impl> pImpl;
 
diff --git a/include/vcl/treelistbox.hxx b/include/vcl/treelistbox.hxx
index d0fcfabd9e01..537e4abc7a8d 100644
--- a/include/vcl/treelistbox.hxx
+++ b/include/vcl/treelistbox.hxx
@@ -227,9 +227,13 @@ class VCL_DLLPUBLIC SvTreeListBox
     SelectionMode   eSelMode;
     sal_Int32       nMinWidthInChars;
 
+    sal_Int8        mnDragAction;
+
     SvTreeListEntry*        pEdEntry;
     SvLBoxItem*             pEdItem;
 
+    rtl::Reference<TransferDataContainer> m_xTransferHelper;
+
 protected:
     std::unique_ptr<SvImpLBox>              pImpl;
     short                   nColumns;
@@ -736,6 +740,8 @@ public:
     void            SetForceMakeVisible(bool bEnable);
 
     virtual FactoryFunction GetUITestFactory() const override;
+
+    void            SetDragHelper(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants);
 };
 
 class SvInplaceEdit2
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 496f1e718f7c..3acf96b1fcf7 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -63,6 +63,7 @@ enum class PointerStyle;
 class SvNumberFormatter;
 class KeyEvent;
 class MouseEvent;
+class TransferDataContainer;
 class OutputDevice;
 class VirtualDevice;
 struct SystemEnvData;
@@ -709,7 +710,10 @@ protected:
     Link<const TreeIter&, bool> m_aCollapsingHdl;
     Link<TreeView&, void> m_aVisibleRangeChangedHdl;
     Link<TreeView&, void> m_aModelChangedHdl;
+    // if handler returns true, then menu has been show and event is consumed
     Link<const CommandEvent&, bool> m_aPopupMenuHdl;
+    // if handler returns true, drag is disallowed
+    Link<TreeView&, bool> m_aDragBeginHdl;
     std::function<int(const weld::TreeIter&, const weld::TreeIter&)> m_aCustomSort;
 
     std::vector<int> m_aRadioIndexes;
@@ -978,6 +982,12 @@ public:
         m_aPopupMenuHdl = rLink;
     }
 
+    virtual void enable_drag_source(rtl::Reference<TransferDataContainer>& rTransferrable,
+                                    sal_uInt8 eDNDConstants)
+        = 0;
+
+    void connect_drag_begin(const Link<TreeView&, bool>& rLink) { m_aDragBeginHdl = rLink; }
+
     //all of them
     void select_all() { unselect(-1); }
     void unselect_all() { select(-1); }
diff --git a/vcl/inc/treeglue.hxx b/vcl/inc/treeglue.hxx
index 69641906aa17..49eccdbca4d5 100644
--- a/vcl/inc/treeglue.hxx
+++ b/vcl/inc/treeglue.hxx
@@ -56,7 +56,7 @@ public:
 class LclTabListBox : public SvTabListBox
 {
     Link<SvTreeListBox*, void> m_aModelChangedHdl;
-    Link<SvTreeListBox*, void> m_aStartDragHdl;
+    Link<SvTreeListBox*, bool> m_aStartDragHdl;
     Link<SvTreeListBox*, void> m_aEndDragHdl;
     Link<SvTreeListEntry*, bool> m_aEditingEntryHdl;
     Link<std::pair<SvTreeListEntry*, OUString>, bool> m_aEditedEntryHdl;
@@ -68,7 +68,7 @@ public:
     }
 
     void SetModelChangedHdl(const Link<SvTreeListBox*, void>& rLink) { m_aModelChangedHdl = rLink; }
-    void SetStartDragHdl(const Link<SvTreeListBox*, void>& rLink) { m_aStartDragHdl = rLink; }
+    void SetStartDragHdl(const Link<SvTreeListBox*, bool>& rLink) { m_aStartDragHdl = rLink; }
     void SetEndDragHdl(const Link<SvTreeListBox*, void>& rLink) { m_aEndDragHdl = rLink; }
     void SetEditingEntryHdl(const Link<SvTreeListEntry*, bool>& rLink)
     {
@@ -86,7 +86,8 @@ public:
 
     virtual void StartDrag(sal_Int8 nAction, const Point& rPosPixel) override
     {
-        m_aStartDragHdl.Call(this);
+        if (m_aStartDragHdl.Call(this))
+            return;
         SvTabListBox::StartDrag(nAction, rPosPixel);
     }
 
diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx
index 4cf7369c7992..f2d049448a5c 100644
--- a/vcl/inc/unx/gtk/gtkinst.hxx
+++ b/vcl/inc/unx/gtk/gtkinst.hxx
@@ -150,6 +150,13 @@ public:
     {
     }
 
+    void set_datatransfer(const css::uno::Reference<css::datatransfer::XTransferable>& rTrans,
+                          const css::uno::Reference<css::datatransfer::dnd::XDragSourceListener>& rListener);
+
+    std::vector<GtkTargetEntry> FormatsToGtk(const css::uno::Sequence<css::datatransfer::DataFlavor> &rFormats);
+
+    void setActiveDragSource();
+
     virtual ~GtkDragSource() override;
 
     // XDragSource
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 4285b037c880..ee0e074bad2e 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -4294,6 +4294,11 @@ void SalInstanceTreeView::set_id(const weld::TreeIter& rIter, const OUString& rI
     set_id(rVclIter.iter, rId);
 }
 
+void SalInstanceTreeView::enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants)
+{
+    m_xTreeView->SetDragHelper(rHelper, eDNDConstants);
+}
+
 void SalInstanceTreeView::set_selection_mode(SelectionMode eMode)
 {
     m_xTreeView->SetSelectionMode(eMode);
@@ -4538,7 +4543,7 @@ SalInstanceTreeView::~SalInstanceTreeView()
     else
     {
         static_cast<LclTabListBox&>(*m_xTreeView).SetEndDragHdl(Link<SvTreeListBox*, void>());
-        static_cast<LclTabListBox&>(*m_xTreeView).SetStartDragHdl(Link<SvTreeListBox*, void>());
+        static_cast<LclTabListBox&>(*m_xTreeView).SetStartDragHdl(Link<SvTreeListBox*, bool>());
         static_cast<LclTabListBox&>(*m_xTreeView).SetModelChangedHdl(Link<SvTreeListBox*, void>());
     }
     m_xTreeView->SetPopupMenuHdl(Link<const CommandEvent&, bool>());
@@ -4604,9 +4609,12 @@ IMPL_LINK_NOARG(SalInstanceTreeView, ModelChangedHdl, SvTreeListBox*, void)
     signal_model_changed();
 }
 
-IMPL_LINK_NOARG(SalInstanceTreeView, StartDragHdl, SvTreeListBox*, void)
+IMPL_LINK_NOARG(SalInstanceTreeView, StartDragHdl, SvTreeListBox*, bool)
 {
+    if (m_aDragBeginHdl.Call(*this))
+        return true;
     g_DragSource = this;
+    return false;
 }
 
 IMPL_STATIC_LINK_NOARG(SalInstanceTreeView, FinishDragHdl, SvTreeListBox*, void)
diff --git a/vcl/source/treelist/treelistbox.cxx b/vcl/source/treelist/treelistbox.cxx
index 6c91289f019d..f6653c7b508d 100644
--- a/vcl/source/treelist/treelistbox.cxx
+++ b/vcl/source/treelist/treelistbox.cxx
@@ -373,6 +373,7 @@ SvTreeListBox::SvTreeListBox(vcl::Window* pParent, WinBits nWinStyle) :
     mbHoverSelection(false),
     eSelMode(SelectionMode::NONE),
     nMinWidthInChars(0),
+    mnDragAction(DND_ACTION_COPYMOVE | DND_ACTION_LINK),
     mbCenterAndClipText(false)
 {
     nImpFlags = SvTreeListBoxFlags::NONE;
@@ -1152,7 +1153,6 @@ void SvTreeListBox::SetupDragOrigin()
 
 void SvTreeListBox::StartDrag( sal_Int8, const Point& rPosPixel )
 {
-
     Point aEventPos( rPosPixel );
     MouseEvent aMouseEvt( aEventPos, 1, MouseEventModifiers::SELECT, MOUSE_LEFT );
     MouseButtonUp( aMouseEvt );
@@ -1170,8 +1170,17 @@ void SvTreeListBox::StartDrag( sal_Int8, const Point& rPosPixel )
         return;
     }
 
-    rtl::Reference<TransferDataContainer> pContainer = new TransferDataContainer;
-    nDragDropMode = NotifyStartDrag( *pContainer, pEntry );
+    rtl::Reference<TransferDataContainer> xContainer = m_xTransferHelper;
+
+    if (!xContainer)
+    {
+        xContainer.set(new TransferDataContainer);
+        // apparently some (unused) content is needed
+        xContainer->CopyAnyData( SotClipboardFormatId::TREELISTBOX,
+                                    "unused", SAL_N_ELEMENTS("unused") );
+    }
+
+    nDragDropMode = NotifyStartDrag( *xContainer, pEntry );
     if( nDragDropMode == DragDropMode::NONE || 0 == GetSelectionCount() )
     {
         nDragDropMode = nOldDragMode;
@@ -1181,10 +1190,6 @@ void SvTreeListBox::StartDrag( sal_Int8, const Point& rPosPixel )
 
     SetupDragOrigin();
 
-    // apparently some (unused) content is needed
-    pContainer->CopyAnyData( SotClipboardFormatId::TREELISTBOX,
-                             "unused", SAL_N_ELEMENTS("unused") );
-
     bool bOldUpdateMode = Control::IsUpdateMode();
     Control::SetUpdateMode( true );
     Update();
@@ -1196,7 +1201,13 @@ void SvTreeListBox::StartDrag( sal_Int8, const Point& rPosPixel )
     // (GetSourceListBox()->EnableSelectionAsDropTarget( true, true );)
     EnableSelectionAsDropTarget( false );
 
-    pContainer->StartDrag( this, DND_ACTION_COPYMOVE | DND_ACTION_LINK, GetDragFinishedHdl() );
+    xContainer->StartDrag(this, mnDragAction, GetDragFinishedHdl());
+}
+
+void SvTreeListBox::SetDragHelper(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants)
+{
+    m_xTransferHelper = rHelper;
+    mnDragAction = eDNDConstants;
 }
 
 void SvTreeListBox::DragFinished( sal_Int8
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index 4651f81a0830..4156316a7c3c 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -4227,18 +4227,38 @@ sal_uIntPtr GtkSalFrame::GetNativeWindowHandle()
     return GetNativeWindowHandle(m_pWindow);
 }
 
+void GtkDragSource::set_datatransfer(const css::uno::Reference<css::datatransfer::XTransferable>& rTrans,
+                                     const css::uno::Reference<css::datatransfer::dnd::XDragSourceListener>& rListener)
+{
+    m_xListener = rListener;
+    m_xTrans = rTrans;
+}
+
+void GtkDragSource::setActiveDragSource()
+{
+   // For LibreOffice internal D&D we provide the Transferable without Gtk
+   // intermediaries as a shortcut, see tdf#100097 for how dbaccess depends on this
+   g_ActiveDragSource = this;
+   g_DropSuccessSet = false;
+   g_DropSuccess = false;
+}
+
+std::vector<GtkTargetEntry> GtkDragSource::FormatsToGtk(const css::uno::Sequence<css::datatransfer::DataFlavor> &rFormats)
+{
+    return m_aConversionHelper.FormatsToGtk(rFormats);
+}
+
 void GtkDragSource::startDrag(const datatransfer::dnd::DragGestureEvent& rEvent,
                               sal_Int8 sourceActions, sal_Int32 /*cursor*/, sal_Int32 /*image*/,
                               const css::uno::Reference<css::datatransfer::XTransferable>& rTrans,
                               const css::uno::Reference<css::datatransfer::dnd::XDragSourceListener>& rListener)
 {
-    m_xListener = rListener;
-    m_xTrans = rTrans;
+    set_datatransfer(rTrans, rListener);
 
     if (m_pFrame)
     {
-        css::uno::Sequence<css::datatransfer::DataFlavor> aFormats = rTrans->getTransferDataFlavors();
-        std::vector<GtkTargetEntry> aGtkTargets(m_aConversionHelper.FormatsToGtk(aFormats));
+        auto aFormats = m_xTrans->getTransferDataFlavors();
+        std::vector<GtkTargetEntry> aGtkTargets(FormatsToGtk(aFormats));
         GtkTargetList *pTargetList = gtk_target_list_new(aGtkTargets.data(), aGtkTargets.size());
 
         gint nDragButton = 1; // default to left button
@@ -4253,11 +4273,7 @@ void GtkDragSource::startDrag(const datatransfer::dnd::DragGestureEvent& rEvent,
                 nDragButton = 2;
         }
 
-        // For LibreOffice internal D&D we provide the Transferable without Gtk
-        // intermediaries as a shortcut, see tdf#100097 for how dbaccess depends on this
-        g_ActiveDragSource = this;
-        g_DropSuccessSet = false;
-        g_DropSuccess = false;
+        setActiveDragSource();
 
         m_pFrame->startDrag(nDragButton, rEvent.DragOriginX, rEvent.DragOriginY,
                             VclToGdk(sourceActions), pTargetList);
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 8850c8f87c88..b5251c2cd90f 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -8168,6 +8168,7 @@ private:
     o3tl::sorted_vector<GtkTreePath*, CompareGtkTreePath> m_aExpandingPlaceHolderParents;
     std::vector<GtkSortType> m_aSavedSortTypes;
     std::vector<int> m_aSavedSortColumns;
+    rtl::Reference<GtkDragSource> m_xDragSource;
     bool m_bWorkAroundBadDragRegion;
     bool m_bInDrag;
     gint m_nTextCol;
@@ -8186,6 +8187,9 @@ private:
     gulong m_nPopupMenuSignalId;
     gulong m_nDragBeginSignalId;
     gulong m_nDragEndSignalId;
+    gulong m_nDragFailedSignalId;
+    gulong m_nDragDataDeleteignalId;
+    gulong m_nDragGetSignalId;
     gulong m_nKeyPressSignalId;
     GtkAdjustment* m_pVAdjustment;
     ImplSVEvent* m_pChangeEvent;
@@ -8643,6 +8647,65 @@ private:
         return default_sort_func(pModel, a, b, m_xSorter.get());
     }
 
+    static void signalDragBegin(GtkWidget*, GdkDragContext* context, gpointer widget)
+    {
+        GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget);
+        pThis->signal_drag_begin(context);
+    }
+
+    void ensure_drag_source()
+    {
+        if (!m_xDragSource)
+        {
+            m_xDragSource.set(new GtkDragSource);
+
+            m_nDragFailedSignalId = g_signal_connect(m_pWidget, "drag-failed", G_CALLBACK(signalDragFailed), this);
+            m_nDragDataDeleteignalId = g_signal_connect(m_pWidget, "drag-data-delete", G_CALLBACK(signalDragDelete), this);
+            m_nDragGetSignalId = g_signal_connect(m_pWidget, "drag-data-get", G_CALLBACK(signalDragDataGet), this);
+        }
+    }
+
+    void signal_drag_begin(GdkDragContext* context)
+    {
+        if (m_aDragBeginHdl.Call(*this))
+        {
+            gtk_drag_cancel(context);
+            return;
+        }
+        g_DragSource = this;
+        if (!m_xDragSource)
+            return;
+        m_xDragSource->setActiveDragSource();
+    }
+
+    static void signalDragEnd(GtkWidget* /*widget*/, GdkDragContext* context, gpointer widget)
+    {
+        g_DragSource = nullptr;
+        GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget);
+        if (pThis->m_xDragSource.is())
+            pThis->m_xDragSource->dragEnd(context);
+    }
+
+    static gboolean signalDragFailed(GtkWidget* /*widget*/, GdkDragContext* /*context*/, GtkDragResult /*result*/, gpointer widget)
+    {
+        GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget);
+        pThis->m_xDragSource->dragFailed();
+        return false;
+    }
+
+    static void signalDragDelete(GtkWidget* /*widget*/, GdkDragContext* /*context*/, gpointer widget)
+    {
+        GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget);
+        pThis->m_xDragSource->dragDelete();
+    }
+
+    static void signalDragDataGet(GtkWidget* /*widget*/, GdkDragContext* /*context*/, GtkSelectionData *data, guint info,
+                                  guint /*time*/, gpointer widget)
+    {
+        GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget);
+        pThis->m_xDragSource->dragDataGet(data, info);
+    }
+
     bool signal_key_press(GdkEventKey* pEvent)
     {
         if (pEvent->keyval != GDK_KEY_Left && pEvent->keyval != GDK_KEY_Right)
@@ -8749,6 +8812,11 @@ public:
         , m_nTestCollapseRowSignalId(g_signal_connect(pTreeView, "test-collapse-row", G_CALLBACK(signalTestCollapseRow), this))
         , m_nVAdjustmentChangedSignalId(0)
         , m_nPopupMenuSignalId(g_signal_connect(pTreeView, "popup-menu", G_CALLBACK(signalPopupMenu), this))
+        , m_nDragBeginSignalId(g_signal_connect(pTreeView, "drag-begin", G_CALLBACK(signalDragBegin), this))
+        , m_nDragEndSignalId(g_signal_connect(pTreeView, "drag-end", G_CALLBACK(signalDragEnd), this))
+        , m_nDragFailedSignalId(0)
+        , m_nDragDataDeleteignalId(0)
+        , m_nDragGetSignalId(0)
         , m_nKeyPressSignalId(g_signal_connect(pTreeView, "key-press-event", G_CALLBACK(signalKeyPress), this))
         , m_pVAdjustment(gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(pTreeView)))
         , m_pChangeEvent(nullptr)
@@ -9980,6 +10048,24 @@ public:
         gtk_widget_hide(m_pWidget);
     }
 
+    virtual void enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants) override
+    {
+        css::uno::Reference<css::datatransfer::XTransferable> xTrans(rHelper.get());
+        css::uno::Reference<css::datatransfer::dnd::XDragSourceListener> xListener(rHelper.get());
+
+        ensure_drag_source();
+
+        auto aFormats = xTrans->getTransferDataFlavors();
+        std::vector<GtkTargetEntry> aGtkTargets(m_xDragSource->FormatsToGtk(aFormats));
+
+        gtk_tree_view_enable_model_drag_source(m_pTreeView, GDK_BUTTON1_MASK, aGtkTargets.data(), aGtkTargets.size(), VclToGdk(eDNDConstants));
+
+        for (auto &a : aGtkTargets)
+            g_free(a.target);
+
+        m_xDragSource->set_datatransfer(xTrans, xListener);
+    }
+
     virtual void set_selection_mode(SelectionMode eMode) override
     {
         disable_notify_events();
@@ -10228,6 +10314,12 @@ public:
         g_signal_handler_disconnect(m_pTreeView, m_nKeyPressSignalId);
         g_signal_handler_disconnect(m_pTreeView, m_nDragEndSignalId);
         g_signal_handler_disconnect(m_pTreeView, m_nDragBeginSignalId);
+        if (m_nDragFailedSignalId)
+            g_signal_handler_disconnect(m_pTreeView, m_nDragFailedSignalId);
+        if (m_nDragDataDeleteignalId)
+            g_signal_handler_disconnect(m_pTreeView, m_nDragDataDeleteignalId);
+        if (m_nDragGetSignalId)
+            g_signal_handler_disconnect(m_pTreeView, m_nDragGetSignalId);
         g_signal_handler_disconnect(m_pTreeView, m_nPopupMenuSignalId);
         g_signal_handler_disconnect(m_pTreeModel, m_nRowDeletedSignalId);
         g_signal_handler_disconnect(m_pTreeModel, m_nRowInsertedSignalId);


More information about the Libreoffice-commits mailing list