include/vcl/dialog.hxx | 3 vcl/inc/jsdialog/jsdialogbuilder.hxx | 55 +++++++++++++++ vcl/jsdialog/executor.cxx | 33 +++++++++ vcl/jsdialog/jsdialogbuilder.cxx | 123 +++++++++++++++++++++++++++++++++++ vcl/source/window/dialog.cxx | 37 ++++++++-- 5 files changed, 244 insertions(+), 7 deletions(-)
New commits: commit d8995bc8ed93272a3b9771138ec3ff7733434c5b Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Thu Nov 19 13:50:30 2020 +0100 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Thu Nov 19 13:50:30 2020 +0100 jsdialog: dump dialog title Change-Id: Id4c9f336039f8a0b8d1d43fdff4852f32e2c7ae6 diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx index 1f777dfc1629..d02772ce0e63 100644 --- a/include/vcl/dialog.hxx +++ b/include/vcl/dialog.hxx @@ -155,6 +155,8 @@ public: void set_default_response(int nResponse); int get_default_response() const; vcl::Window* get_widget_for_response(int nResponse); + + virtual boost::property_tree::ptree DumpAsPropertyTree() override; }; #endif // INCLUDED_VCL_DIALOG_HXX diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx index 85f87ad92a54..f0b5a96462c9 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -1607,4 +1607,11 @@ void TopLevelWindowLocker::decBusy() m_aBusyStack.pop(); } +boost::property_tree::ptree Dialog::DumpAsPropertyTree() +{ + boost::property_tree::ptree aTree(SystemWindow::DumpAsPropertyTree()); + aTree.put("title", GetText()); + return aTree; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 7342272490b32be6958460f32b821df43fe05acb Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Wed Nov 18 12:14:35 2020 +0100 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Wed Nov 18 12:29:17 2020 +0100 jsdialog: remember dialog instance & handle close Change-Id: I1b10d12edfa7ffca1061f50b5219baae1ac3caeb diff --git a/vcl/jsdialog/executor.cxx b/vcl/jsdialog/executor.cxx index 81b84a99f6f4..0d8e1f121ced 100644 --- a/vcl/jsdialog/executor.cxx +++ b/vcl/jsdialog/executor.cxx @@ -223,6 +223,18 @@ bool ExecuteAction(sal_uInt64 nWindowId, const OString& rWidget, StringMap& rDat } } } + else if (sControlType == "dialog") + { + auto pDialog = dynamic_cast<weld::Dialog*>(pWidget); + if (pDialog) + { + if (sAction == "close") + { + pDialog->response(RET_CANCEL); + return true; + } + } + } } return false; diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx index 19a652e8e440..bc80416ac335 100644 --- a/vcl/jsdialog/jsdialogbuilder.cxx +++ b/vcl/jsdialog/jsdialogbuilder.cxx @@ -359,6 +359,9 @@ std::unique_ptr<weld::Dialog> JSInstanceBuilder::weld_dialog(const OString& id, std::unique_ptr<weld::Dialog> pRet(pDialog ? new JSDialog(m_aOwnedToplevel, m_aOwnedToplevel, pDialog, this, false, m_sTypeOfJSON) : nullptr); + + RememberWidget("__DIALOG__", pRet.get()); + if (bTakeOwnership && pDialog) { assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed"); commit df3f2a1c541abcba981cdcb483b375ae4069ddbe Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Wed Nov 18 12:00:03 2020 +0100 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Wed Nov 18 12:29:09 2020 +0100 jsdialog: turn off tunneling for JSON dialogs Change-Id: I9a9d359d1769f6c34203bc558efe8189fbf81fd3 diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx index 1840635f151f..1f777dfc1629 100644 --- a/include/vcl/dialog.hxx +++ b/include/vcl/dialog.hxx @@ -149,6 +149,7 @@ public: void SetPopupMenuHdl(const Link<const CommandEvent&, bool>& rLink); void SetInstallLOKNotifierHdl(const Link<void*, vcl::ILibreOfficeKitNotifier*>& rLink); + void SetLOKTunnelingState(bool bEnabled); void add_button(PushButton* pButton, int nResponse, bool bTransferOwnership); void set_default_response(int nResponse); diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx index 05903cef6f49..19a652e8e440 100644 --- a/vcl/jsdialog/jsdialogbuilder.cxx +++ b/vcl/jsdialog/jsdialogbuilder.cxx @@ -352,6 +352,7 @@ std::unique_ptr<weld::Dialog> JSInstanceBuilder::weld_dialog(const OString& id, { ::Dialog* pDialog = m_xBuilder->get<::Dialog>(id); m_nWindowId = pDialog->GetLOKWindowId(); + pDialog->SetLOKTunnelingState(false); InsertWindowToMap(m_nWindowId); diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx index a754182d3eeb..85f87ad92a54 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -353,8 +353,9 @@ struct DialogImpl VclAbstractDialog::AsyncContext maEndCtx; Link<const CommandEvent&, bool> m_aPopupMenuHdl; Link<void*, vcl::ILibreOfficeKitNotifier*> m_aInstallLOKNotifierHdl; + bool m_bLOKTunneling; - DialogImpl() : mnResult( -1 ), mbStartedModal( false ) {} + DialogImpl() : mnResult( -1 ), mbStartedModal( false ), m_bLOKTunneling( true ) {} #ifndef NDEBUG short get_response(vcl::Window *pWindow) const @@ -607,6 +608,8 @@ Dialog::~Dialog() void Dialog::dispose() { + bool bTunnelingEnabled = mpDialogImpl->m_bLOKTunneling; + mpDialogImpl.reset(); RemoveFromDlgList(); mpActionArea.clear(); @@ -624,7 +627,8 @@ void Dialog::dispose() { if(const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier()) { - pNotifier->notifyWindow(GetLOKWindowId(), "close"); + if (bTunnelingEnabled) + pNotifier->notifyWindow(GetLOKWindowId(), "close"); ReleaseLOKNotifier(); } } @@ -731,14 +735,21 @@ void Dialog::SetInstallLOKNotifierHdl(const Link<void*, vcl::ILibreOfficeKitNoti mpDialogImpl->m_aInstallLOKNotifierHdl = rLink; } +void Dialog::SetLOKTunnelingState(bool bEnabled) +{ + mpDialogImpl->m_bLOKTunneling = bEnabled; +} + void Dialog::StateChanged( StateChangedType nType ) { + bool bTunnelingEnabled = mpDialogImpl->m_bLOKTunneling; + if (nType == StateChangedType::InitShow) { DoInitialLayout(); const bool bKitActive = comphelper::LibreOfficeKit::isActive(); - if (bKitActive) + if (bKitActive && bTunnelingEnabled) { std::vector<vcl::LOKPayloadItem> aItems; aItems.emplace_back("type", "dialog"); @@ -777,7 +788,8 @@ void Dialog::StateChanged( StateChangedType nType ) } else if (nType == StateChangedType::Text) { - if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier()) + const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier(); + if (pNotifier && bTunnelingEnabled) { std::vector<vcl::LOKPayloadItem> aPayload; aPayload.emplace_back("title", GetText().toUtf8()); @@ -795,7 +807,8 @@ void Dialog::StateChanged( StateChangedType nType ) if (!mbModalMode && nType == StateChangedType::Visible) { - if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier()) + const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier(); + if (pNotifier && bTunnelingEnabled) { std::vector<vcl::LOKPayloadItem> aPayload; aPayload.emplace_back("title", GetText().toUtf8()); @@ -983,7 +996,8 @@ bool Dialog::ImplStartExecute() else UITestLogger::getInstance().log("Open Modeless " + get_id()); - if (comphelper::LibreOfficeKit::isActive()) + bool bTunnelingEnabled = mpDialogImpl->m_bLOKTunneling; + if (comphelper::LibreOfficeKit::isActive() && bTunnelingEnabled) { if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier()) { @@ -1327,7 +1341,9 @@ void Dialog::Resize() if (comphelper::LibreOfficeKit::isDialogPainting()) return; - if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier()) + bool bTunnelingEnabled = mpDialogImpl->m_bLOKTunneling; + const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier(); + if (pNotifier && bTunnelingEnabled) { std::vector<vcl::LOKPayloadItem> aItems; aItems.emplace_back("size", GetSizePixel().toString()); commit 86551fe8967e1aea3174cc4a682ce7ae50e83d96 Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Wed Nov 18 10:12:38 2020 +0100 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Wed Nov 18 12:15:07 2020 +0100 jsdialog: drag and drop support for TreeView Change-Id: I67e2eb986b48591b7f758bbb5c1d72b6a322d4d8 diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx index 5df3f0d4f324..45da94abfb33 100644 --- a/vcl/inc/jsdialog/jsdialogbuilder.hxx +++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx @@ -21,6 +21,11 @@ #include <vcl/fmtfield.hxx> #include <vcl/svtabbx.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 SfxViewShell; class VclMultiLineEdit; @@ -59,6 +64,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; @@ -141,6 +180,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, @@ -167,6 +209,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 VCL_DLLPUBLIC JSDialog : public JSWidget<SalInstanceDialog, ::Dialog> @@ -319,6 +369,11 @@ public: virtual void set_toggle(int pos, TriState eState, int col = -1) override; /// 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 281c7b4d3893..81b84a99f6f4 100644 --- a/vcl/jsdialog/executor.cxx +++ b/vcl/jsdialog/executor.cxx @@ -187,6 +187,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 f02d469dc701..05903cef6f49 100644 --- a/vcl/jsdialog/jsdialogbuilder.cxx +++ b/vcl/jsdialog/jsdialogbuilder.cxx @@ -16,6 +16,7 @@ #include <vcl/toolbox.hxx> #include <vcl/vclmedit.hxx> #include <vcl/treelistentry.hxx> +#include <cppuhelper/supportsservice.hxx> using namespace weld; @@ -89,6 +90,98 @@ void JSDialogSender::notifyDialogState(bool bForce) mpIdleNotify->Start(); } +// Drag and drop + +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) @@ -806,6 +899,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) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits