summaryrefslogtreecommitdiff
path: root/vcl/unx/gtk3/gtk3gtkinst.cxx
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-01-16 16:38:15 +0000
committerCaolán McNamara <caolanm@redhat.com>2020-01-21 09:57:58 +0100
commitfa8c85fa90e9565a357b247a69f930098d11ff84 (patch)
treed14cb6db4faa840ae23b435bbdcd3ff5987c3f44 /vcl/unx/gtk3/gtk3gtkinst.cxx
parent9394ad31fb9c325001c97702feda317d61f1cbbb (diff)
weld gallery panel
Change-Id: I4aebb3f90e9943044d106a507972c39434988f03 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87003 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/unx/gtk3/gtk3gtkinst.cxx')
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx290
1 files changed, 187 insertions, 103 deletions
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 024b71c782e6..486b522dfe71 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -1792,6 +1792,18 @@ namespace
namespace {
+GdkDragAction VclToGdk(sal_Int8 dragOperation)
+{
+ GdkDragAction eRet(static_cast<GdkDragAction>(0));
+ if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_COPY)
+ eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_COPY);
+ if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_MOVE)
+ eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_MOVE);
+ if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_LINK)
+ eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_LINK);
+ return eRet;
+}
+
class GtkInstanceWidget : public virtual weld::Widget
{
protected:
@@ -1894,6 +1906,25 @@ protected:
return AllSettings::GetLayoutRTL();
}
+ void do_enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants)
+ {
+ 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));
+
+ m_eDragAction = VclToGdk(eDNDConstants);
+ drag_source_set(aGtkTargets, m_eDragAction);
+
+ for (auto &a : aGtkTargets)
+ g_free(a.target);
+
+ m_xDragSource->set_datatransfer(xTrans, xListener);
+ }
+
void localizeDecimalSeparator()
{
// tdf#128867 if localize decimal separator is active we will always
@@ -1908,9 +1939,13 @@ private:
bool m_bDraggedOver;
sal_uInt16 m_nLastMouseButton;
sal_uInt16 m_nLastMouseClicks;
+ int m_nPressedButton;
+ int m_nPressStartX;
+ int m_nPressStartY;
ImplSVEvent* m_pFocusInEvent;
ImplSVEvent* m_pFocusOutEvent;
GtkCssProvider* m_pBgCssProvider;
+ GdkDragAction m_eDragAction;
gulong m_nFocusInSignalId;
gulong m_nMnemonicActivateSignalId;
gulong m_nFocusOutSignalId;
@@ -1926,8 +1961,14 @@ private:
gulong m_nDragDropSignalId;
gulong m_nDragDropReceivedSignalId;
gulong m_nDragLeaveSignalId;
+ gulong m_nDragBeginSignalId;
+ gulong m_nDragEndSignalId;
+ gulong m_nDragFailedSignalId;
+ gulong m_nDragDataDeleteignalId;
+ gulong m_nDragGetSignalId;
rtl::Reference<GtkDropTarget> m_xDropTarget;
+ rtl::Reference<GtkDragSource> m_xDragSource;
std::vector<AtkRelation*> m_aExtraAtkRelations;
static void signalSizeAllocate(GtkWidget*, GdkRectangle* allocation, gpointer widget)
@@ -1964,6 +2005,8 @@ private:
bool signal_button(GdkEventButton* pEvent)
{
+ m_nPressedButton = -1;
+
Point aPos(pEvent->x, pEvent->y);
if (SwapForRTL())
aPos.setX(gtk_widget_get_allocated_width(m_pWidget) - 1 - aPos.X());
@@ -2026,6 +2069,14 @@ private:
return false;
}
+ /* Save press to possibly begin a drag */
+ if (pEvent->type != GDK_BUTTON_RELEASE)
+ {
+ m_nPressedButton = pEvent->button;
+ m_nPressStartX = pEvent->x;
+ m_nPressStartY = pEvent->y;
+ }
+
sal_uInt32 nModCode = GtkSalFrame::GetMouseModCode(pEvent->state);
sal_uInt16 nCode = m_nLastMouseButton | (nModCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2));
MouseEvent aMEvt(aPos, m_nLastMouseClicks, ImplGetMouseButtonMode(m_nLastMouseButton, nModCode), nCode, nCode);
@@ -2051,6 +2102,19 @@ private:
bool signal_motion(const GdkEventMotion* pEvent)
{
+ GtkTargetList* pDragData = (m_eDragAction != 0 && m_nPressedButton != -1 && m_xDragSource.is()) ? gtk_drag_source_get_target_list(m_pWidget) : nullptr;
+ if (pDragData && gtk_drag_check_threshold(m_pWidget, m_nPressStartX, m_nPressStartY, pEvent->x, pEvent->y) && !do_signal_drag_begin())
+ {
+ gtk_drag_begin_with_coordinates(m_pWidget,
+ pDragData,
+ m_eDragAction,
+ m_nPressedButton,
+ const_cast<GdkEvent*>(reinterpret_cast<const GdkEvent*>(pEvent)),
+ m_nPressStartX, m_nPressStartY);
+ m_nPressedButton = -1;
+ return false;
+ }
+
if (!m_aMouseMotionHdl.IsSet())
return false;
@@ -2132,6 +2196,80 @@ private:
}
}
+ static void signalDragBegin(GtkWidget*, GdkDragContext* context, gpointer widget)
+ {
+ GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(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);
+ m_nDragBeginSignalId = g_signal_connect(m_pWidget, "drag-begin", G_CALLBACK(signalDragBegin), this);
+ m_nDragEndSignalId = g_signal_connect(m_pWidget, "drag-end", G_CALLBACK(signalDragEnd), this);
+ }
+ }
+
+ virtual bool do_signal_drag_begin()
+ {
+ return false;
+ }
+
+ void signal_drag_begin(GdkDragContext* context)
+ {
+ if (do_signal_drag_begin())
+ {
+ gtk_drag_cancel(context);
+ return;
+ }
+ if (!m_xDragSource)
+ return;
+ m_xDragSource->setActiveDragSource();
+ }
+
+ virtual void do_signal_drag_end()
+ {
+ }
+
+ static void signalDragEnd(GtkWidget* /*widget*/, GdkDragContext* context, gpointer widget)
+ {
+ GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget);
+ pThis->do_signal_drag_end();
+ if (pThis->m_xDragSource.is())
+ pThis->m_xDragSource->dragEnd(context);
+ }
+
+ static gboolean signalDragFailed(GtkWidget* /*widget*/, GdkDragContext* /*context*/, GtkDragResult /*result*/, gpointer widget)
+ {
+ GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget);
+ pThis->m_xDragSource->dragFailed();
+ return false;
+ }
+
+ static void signalDragDelete(GtkWidget* /*widget*/, GdkDragContext* /*context*/, gpointer widget)
+ {
+ GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget);
+ pThis->m_xDragSource->dragDelete();
+ }
+
+ static void signalDragDataGet(GtkWidget* /*widget*/, GdkDragContext* /*context*/, GtkSelectionData *data, guint info,
+ guint /*time*/, gpointer widget)
+ {
+ GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget);
+ pThis->m_xDragSource->dragDataGet(data, info);
+ }
+
+ virtual void drag_source_set(const std::vector<GtkTargetEntry>& rGtkTargets, GdkDragAction eDragAction)
+ {
+ gtk_drag_source_set(m_pWidget, GDK_BUTTON1_MASK, rGtkTargets.data(), rGtkTargets.size(), eDragAction);
+ }
+
void set_background(const OUString* pColor)
{
if (!pColor && !m_pBgCssProvider)
@@ -2162,9 +2300,13 @@ public:
, m_bDraggedOver(false)
, m_nLastMouseButton(0)
, m_nLastMouseClicks(0)
+ , m_nPressedButton(-1)
+ , m_nPressStartX(-1)
+ , m_nPressStartY(-1)
, m_pFocusInEvent(nullptr)
, m_pFocusOutEvent(nullptr)
, m_pBgCssProvider(nullptr)
+ , m_eDragAction(GdkDragAction(0))
, m_nFocusInSignalId(0)
, m_nMnemonicActivateSignalId(0)
, m_nFocusOutSignalId(0)
@@ -2180,6 +2322,11 @@ public:
, m_nDragDropSignalId(0)
, m_nDragDropReceivedSignalId(0)
, m_nDragLeaveSignalId(0)
+ , m_nDragBeginSignalId(0)
+ , m_nDragEndSignalId(0)
+ , m_nDragFailedSignalId(0)
+ , m_nDragDataDeleteignalId(0)
+ , m_nDragGetSignalId(0)
{
if (!bTakeOwnership)
g_object_ref(m_pWidget);
@@ -2733,6 +2880,16 @@ public:
g_signal_handler_disconnect(m_pWidget, m_nDragDropReceivedSignalId);
if (m_nDragLeaveSignalId)
g_signal_handler_disconnect(m_pWidget, m_nDragLeaveSignalId);
+ if (m_nDragEndSignalId)
+ g_signal_handler_disconnect(m_pWidget, m_nDragEndSignalId);
+ if (m_nDragBeginSignalId)
+ g_signal_handler_disconnect(m_pWidget, m_nDragBeginSignalId);
+ if (m_nDragFailedSignalId)
+ g_signal_handler_disconnect(m_pWidget, m_nDragFailedSignalId);
+ if (m_nDragDataDeleteignalId)
+ g_signal_handler_disconnect(m_pWidget, m_nDragDataDeleteignalId);
+ if (m_nDragGetSignalId)
+ g_signal_handler_disconnect(m_pWidget, m_nDragGetSignalId);
if (m_nKeyPressSignalId)
g_signal_handler_disconnect(m_pWidget, m_nKeyPressSignalId);
if (m_nKeyReleaseSignalId)
@@ -8227,18 +8384,6 @@ namespace
return -1;
}
- GdkDragAction VclToGdk(sal_Int8 dragOperation)
- {
- GdkDragAction eRet(static_cast<GdkDragAction>(0));
- if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_COPY)
- eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_COPY);
- if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_MOVE)
- eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_MOVE);
- if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_LINK)
- eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_LINK);
- return eRet;
- }
-
struct GtkInstanceTreeIter : public weld::TreeIter
{
GtkInstanceTreeIter(const GtkInstanceTreeIter* pOrig)
@@ -8287,7 +8432,6 @@ private:
std::vector<int> m_aSavedSortColumns;
std::vector<int> m_aViewColToModelCol;
std::vector<int> m_aModelColToViewCol;
- rtl::Reference<GtkDragSource> m_xDragSource;
bool m_bWorkAroundBadDragRegion;
bool m_bInDrag;
gint m_nTextCol;
@@ -8301,11 +8445,6 @@ private:
gulong m_nRowDeletedSignalId;
gulong m_nRowInsertedSignalId;
gulong m_nPopupMenuSignalId;
- gulong m_nDragBeginSignalId;
- gulong m_nDragEndSignalId;
- gulong m_nDragFailedSignalId;
- gulong m_nDragDataDeleteignalId;
- gulong m_nDragGetSignalId;
gulong m_nKeyPressSignalId;
gulong m_nQueryTooltipSignalId;
ImplSVEvent* m_pChangeEvent;
@@ -8691,65 +8830,6 @@ 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)
@@ -8828,11 +8908,6 @@ public:
, m_nTestExpandRowSignalId(g_signal_connect(pTreeView, "test-expand-row", G_CALLBACK(signalTestExpandRow), 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_nQueryTooltipSignalId(0)
, m_pChangeEvent(nullptr)
@@ -10034,20 +10109,12 @@ public:
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);
+ do_enable_drag_source(rHelper, eDNDConstants);
+ }
- m_xDragSource->set_datatransfer(xTrans, xListener);
+ virtual void drag_source_set(const std::vector<GtkTargetEntry>& rGtkTargets, GdkDragAction eDragAction) override
+ {
+ gtk_tree_view_enable_model_drag_source(m_pTreeView, GDK_BUTTON1_MASK, rGtkTargets.data(), rGtkTargets.size(), eDragAction);
}
virtual void set_selection_mode(SelectionMode eMode) override
@@ -10259,6 +10326,19 @@ public:
return g_DragSource;
}
+ virtual bool do_signal_drag_begin() override
+ {
+ if (m_aDragBeginHdl.Call(*this))
+ return true;
+ g_DragSource = this;
+ return false;
+ }
+
+ virtual void do_signal_drag_end() override
+ {
+ g_DragSource = nullptr;
+ }
+
// Under gtk 3.24.8 dragging into the TreeView is not highlighting
// entire TreeView widget, just the rectangle which has no entries
// in it, so as a workaround highlight the parent container
@@ -10298,14 +10378,6 @@ public:
if (m_nQueryTooltipSignalId)
g_signal_handler_disconnect(m_pTreeView, m_nQueryTooltipSignalId);
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);
GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore);
g_signal_handler_disconnect(pModel, m_nRowDeletedSignalId);
@@ -11557,6 +11629,18 @@ public:
return OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
}
+ virtual void enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants) override
+ {
+ do_enable_drag_source(rHelper, eDNDConstants);
+ }
+
+ virtual bool do_signal_drag_begin() override
+ {
+ if (m_aDragBeginHdl.Call(*this))
+ return true;
+ return false;
+ }
+
virtual ~GtkInstanceDrawingArea() override
{
g_object_steal_data(G_OBJECT(m_pDrawingArea), "g-lo-GtkInstanceDrawingArea");