[Libreoffice-commits] core.git: vcl/inc vcl/jsdialog
Szymon KÅos (via logerrit)
logerrit at kemper.freedesktop.org
Fri Nov 27 10:42:54 UTC 2020
vcl/inc/jsdialog/jsdialogbuilder.hxx | 55 +++++++++++++++
vcl/jsdialog/executor.cxx | 21 +++++
vcl/jsdialog/jsdialogbuilder.cxx | 123 +++++++++++++++++++++++++++++++++++
3 files changed, 199 insertions(+)
New commits:
commit 3000f3ee1ac63deff58fa5725a6f6c2f05aec9bb
Author: Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Wed Nov 18 10:12:38 2020 +0100
Commit: Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Fri Nov 27 11:42:16 2020 +0100
jsdialog: drag and drop support for TreeView
Change-Id: I67e2eb986b48591b7f758bbb5c1d72b6a322d4d8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106705
Tested-by: Jenkins
Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>
diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx
index 4b9e042960f4..ab7c038648d3 100644
--- a/vcl/inc/jsdialog/jsdialogbuilder.hxx
+++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx
@@ -19,6 +19,11 @@
#include <vcl/toolkit/button.hxx>
#include <vcl/toolkit/fmtfield.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
+#include <cppuhelper/compbase.hxx>
+
class ToolBox;
class ComboBox;
class VclMultiLineEdit;
@@ -58,6 +63,40 @@ public:
void notifyDialogState(bool bForce = false);
};
+class JSDropTarget final
+ : public cppu::WeakComponentImplHelper<css::datatransfer::dnd::XDropTarget,
+ css::lang::XInitialization, css::lang::XServiceInfo>
+{
+ osl::Mutex m_aMutex;
+ std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> m_aListeners;
+
+public:
+ JSDropTarget();
+
+ // XInitialization
+ virtual void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& rArgs) override;
+
+ // XDropTarget
+ virtual void SAL_CALL addDropTargetListener(
+ const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>&) override;
+ virtual void SAL_CALL removeDropTargetListener(
+ const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>&) override;
+ virtual sal_Bool SAL_CALL isActive() override;
+ virtual void SAL_CALL setActive(sal_Bool active) override;
+ virtual sal_Int8 SAL_CALL getDefaultActions() override;
+ virtual void SAL_CALL setDefaultActions(sal_Int8 actions) override;
+
+ OUString SAL_CALL getImplementationName() override;
+
+ sal_Bool SAL_CALL supportsService(OUString const& ServiceName) override;
+
+ css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+
+ void fire_drop(const css::datatransfer::dnd::DropTargetDropEvent& dtde);
+
+ void fire_dragEnter(const css::datatransfer::dnd::DropTargetDragEnterEvent& dtde);
+};
+
class JSInstanceBuilder : public SalInstanceBuilder
{
sal_uInt64 m_nWindowId;
@@ -128,6 +167,9 @@ private:
template <class BaseInstanceClass, class VclClass>
class JSWidget : public BaseInstanceClass, public JSDialogSender
{
+protected:
+ rtl::Reference<JSDropTarget> m_xDropTarget;
+
public:
JSWidget(VclPtr<vcl::Window> aNotifierWindow, VclPtr<vcl::Window> aContentWindow,
VclClass* pObject, SalInstanceBuilder* pBuilder, bool bTakeOwnership,
@@ -155,6 +197,14 @@ public:
BaseInstanceClass::set_sensitive(sensitive);
notifyDialogState();
}
+
+ virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> get_drop_target() override
+ {
+ if (!m_xDropTarget)
+ m_xDropTarget.set(new JSDropTarget);
+
+ return m_xDropTarget.get();
+ }
};
class JSDialog : public JSWidget<SalInstanceDialog, ::Dialog>
@@ -309,6 +359,11 @@ public:
using SalInstanceTreeView::select;
/// pos is used differently here, it defines how many steps of iterator we need to perform to take entry
virtual void select(int pos) override;
+
+ virtual weld::TreeView* get_drag_source() const override;
+
+ void drag_start();
+ void drag_end();
};
class JSExpander : public JSWidget<SalInstanceExpander, ::VclExpander>
diff --git a/vcl/jsdialog/executor.cxx b/vcl/jsdialog/executor.cxx
index 24e3eb1f14d3..13ffc1a33e06 100644
--- a/vcl/jsdialog/executor.cxx
+++ b/vcl/jsdialog/executor.cxx
@@ -206,6 +206,27 @@ bool ExecuteAction(sal_uInt64 nWindowId, const OString& rWidget, StringMap& rDat
pTreeView->select(nRow);
LOKTrigger::trigger_row_activated(*pTreeView);
+ return true;
+ }
+ else if (sAction == "dragstart")
+ {
+ OString nRowString
+ = OUStringToOString(rData["data"], RTL_TEXTENCODING_ASCII_US);
+ int nRow = std::atoi(nRowString.getStr());
+
+ pTreeView->select(nRow);
+
+ JSTreeView* pJSTreeView = dynamic_cast<JSTreeView*>(pTreeView);
+ if (pJSTreeView)
+ pJSTreeView->drag_start();
+ return true;
+ }
+ else if (sAction == "dragend")
+ {
+ JSTreeView* pJSTreeView = dynamic_cast<JSTreeView*>(pTreeView);
+ if (pJSTreeView)
+ pJSTreeView->drag_end();
+ return true;
}
}
}
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index 4fb351b5439f..58c8c64d1108 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -24,6 +24,7 @@
#include <boost/property_tree/json_parser.hpp>
#include <vcl/toolkit/treelistentry.hxx>
#include <vcl/jsdialog/executor.hxx>
+#include <cppuhelper/supportsservice.hxx>
JSDialogNotifyIdle::JSDialogNotifyIdle(VclPtr<vcl::Window> aNotifierWindow,
VclPtr<vcl::Window> aContentWindow, std::string sTypeOfJSON)
@@ -96,6 +97,102 @@ vcl::Window* extract_sal_widget(weld::Widget* pParent)
}
}
+// Drag and drop
+
+namespace
+{
+class JSDropTargetDropContext
+ : public cppu::WeakImplHelper<css::datatransfer::dnd::XDropTargetDropContext>
+{
+public:
+ JSDropTargetDropContext() {}
+
+ // XDropTargetDropContext
+ virtual void SAL_CALL acceptDrop(sal_Int8 /*dragOperation*/) override {}
+
+ virtual void SAL_CALL rejectDrop() override {}
+
+ virtual void SAL_CALL dropComplete(sal_Bool /*bSuccess*/) override {}
+};
+}
+
+static JSTreeView* g_DragSource;
+
+JSDropTarget::JSDropTarget()
+ : WeakComponentImplHelper(m_aMutex)
+{
+}
+
+void JSDropTarget::initialize(const css::uno::Sequence<css::uno::Any>& /*rArgs*/) {}
+
+void JSDropTarget::addDropTargetListener(
+ const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>& xListener)
+{
+ ::osl::Guard<::osl::Mutex> aGuard(m_aMutex);
+
+ m_aListeners.push_back(xListener);
+}
+
+void JSDropTarget::removeDropTargetListener(
+ const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>& xListener)
+{
+ ::osl::Guard<::osl::Mutex> aGuard(m_aMutex);
+
+ m_aListeners.erase(std::remove(m_aListeners.begin(), m_aListeners.end(), xListener),
+ m_aListeners.end());
+}
+
+sal_Bool JSDropTarget::isActive() { return false; }
+
+void JSDropTarget::setActive(sal_Bool /*active*/) {}
+
+sal_Int8 JSDropTarget::getDefaultActions() { return 0; }
+
+void JSDropTarget::setDefaultActions(sal_Int8 /*actions*/) {}
+
+OUString JSDropTarget::getImplementationName()
+{
+ return "com.sun.star.datatransfer.dnd.JSDropTarget";
+}
+
+sal_Bool JSDropTarget::supportsService(OUString const& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+css::uno::Sequence<OUString> JSDropTarget::getSupportedServiceNames()
+{
+ css::uno::Sequence<OUString> aRet{ "com.sun.star.datatransfer.dnd.JSDropTarget" };
+ return aRet;
+}
+
+void JSDropTarget::fire_drop(const css::datatransfer::dnd::DropTargetDropEvent& dtde)
+{
+ osl::ClearableGuard<osl::Mutex> aGuard(m_aMutex);
+ std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(
+ m_aListeners);
+ aGuard.clear();
+
+ for (auto const& listener : aListeners)
+ {
+ listener->drop(dtde);
+ }
+}
+
+void JSDropTarget::fire_dragEnter(const css::datatransfer::dnd::DropTargetDragEnterEvent& dtde)
+{
+ osl::ClearableGuard<::osl::Mutex> aGuard(m_aMutex);
+ std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(
+ m_aListeners);
+ aGuard.clear();
+
+ for (auto const& listener : aListeners)
+ {
+ listener->dragEnter(dtde);
+ }
+}
+
+// used for dialogs
JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIRoot,
const OUString& rUIFile)
: SalInstanceBuilder(extract_sal_widget(pParent), rUIRoot, rUIFile)
@@ -793,6 +890,32 @@ void JSTreeView::select(int pos)
enable_notify_events();
}
+weld::TreeView* JSTreeView::get_drag_source() const { return g_DragSource; }
+
+void JSTreeView::drag_start() { g_DragSource = this; }
+
+void JSTreeView::drag_end()
+{
+ css::datatransfer::dnd::XDropTarget* xDropTarget = m_xDropTarget.get();
+ if (xDropTarget)
+ {
+ css::datatransfer::dnd::DropTargetDropEvent aEvent;
+ aEvent.Source = xDropTarget;
+ aEvent.Context = new JSDropTargetDropContext();
+ // dummy values
+ aEvent.LocationX = 50;
+ aEvent.LocationY = 50;
+ aEvent.DropAction = css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT;
+ aEvent.SourceActions = css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT;
+
+ m_xDropTarget->fire_drop(aEvent);
+
+ notifyDialogState();
+ }
+
+ g_DragSource = nullptr;
+}
+
JSExpander::JSExpander(VclPtr<vcl::Window> aNotifierWindow, VclPtr<vcl::Window> aContentWindow,
::VclExpander* pExpander, SalInstanceBuilder* pBuilder, bool bTakeOwnership,
std::string sTypeOfJSON)
More information about the Libreoffice-commits
mailing list