vcl/Library_vcl.mk | 1 vcl/inc/jsdialog/jsdialogbuilder.hxx | 50 ----- vcl/inc/jsdialog/jsdialogsender.hxx | 77 +++++++ vcl/jsdialog/jsdialogbuilder.cxx | 325 --------------------------------- vcl/jsdialog/jsdialogsender.cxx | 337 +++++++++++++++++++++++++++++++++++ 5 files changed, 416 insertions(+), 374 deletions(-)
New commits: commit aa93771b041f96f11e1cf8a6948a6a458fee946c Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Thu Dec 5 15:53:46 2024 +0100 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Wed Dec 11 12:50:51 2024 +0100 jsdialog: move sender to separate file builder file is already very long, let's split that no functional change, just moved code to new file Change-Id: I12dcb8cbc8a17091282b557f459f07510a016af9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178302 Tested-by: Jenkins Reviewed-by: Szymon Kłos <szymon.k...@collabora.com> diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 8c8f5fb88199..ff18cd99a19c 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -541,6 +541,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/jsdialog/enabled \ vcl/jsdialog/jsdialogbuilder \ vcl/jsdialog/jsdialogregister \ + vcl/jsdialog/jsdialogsender \ vcl/jsdialog/executor \ )) diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx index 82481b6fba1a..34ff37ed48d6 100644 --- a/vcl/inc/jsdialog/jsdialogbuilder.hxx +++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx @@ -11,6 +11,7 @@ #include <jsdialog/jsdialogregister.hxx> #include <jsdialog/jsdialogmessages.hxx> +#include <jsdialog/jsdialogsender.hxx> #include <utility> #include <vcl/weld.hxx> @@ -28,11 +29,6 @@ #include <list> #include <mutex> -#define ACTION_TYPE "action_type" -#define PARENT_ID "parent_id" -#define WINDOW_ID "id" -#define CLOSE_ID "close_id" - class ToolBox; class ComboBox; class VclMultiLineEdit; @@ -40,52 +36,8 @@ class SvTabListBox; class IconView; class VclScrolledWindow; -namespace vcl -{ -class ILibreOfficeKitNotifier; -} - typedef jsdialog::WidgetRegister<weld::Widget*> WidgetMap; -class JSDialogSender -{ - std::unique_ptr<JSDialogNotifyIdle> mpIdleNotify; - -protected: - bool m_bCanClose; // specifies if can send a close message - -public: - JSDialogSender() - : m_bCanClose(true) - { - } - JSDialogSender(VclPtr<vcl::Window> aNotifierWindow, VclPtr<vcl::Window> aContentWindow, - const OUString& sTypeOfJSON) - : m_bCanClose(true) - { - initializeSender(aNotifierWindow, aContentWindow, sTypeOfJSON); - } - - virtual ~JSDialogSender() COVERITY_NOEXCEPT_FALSE; - - virtual void sendFullUpdate(bool bForce = false); - void sendClose(); - void sendUpdate(VclPtr<vcl::Window> pWindow, bool bForce = false); - void sendAction(const VclPtr<vcl::Window>& pWindow, - std::unique_ptr<jsdialog::ActionDataMap> pData); - void sendPopup(const VclPtr<vcl::Window>& pWindow, const OUString& rParentId, - const OUString& rCloseId); - virtual void sendClosePopup(vcl::LOKWindowId nWindowId); - void flush() { mpIdleNotify->Invoke(); } - -protected: - void initializeSender(const VclPtr<vcl::Window>& rNotifierWindow, - const VclPtr<vcl::Window>& rContentWindow, const OUString& rTypeOfJSON) - { - mpIdleNotify.reset(new JSDialogNotifyIdle(rNotifierWindow, rContentWindow, rTypeOfJSON)); - } -}; - class JSDropTarget final : public comphelper::WeakComponentImplHelper< css::datatransfer::dnd::XDropTarget, css::lang::XInitialization, css::lang::XServiceInfo> diff --git a/vcl/inc/jsdialog/jsdialogsender.hxx b/vcl/inc/jsdialog/jsdialogsender.hxx new file mode 100644 index 000000000000..f6a899a23d90 --- /dev/null +++ b/vcl/inc/jsdialog/jsdialogsender.hxx @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <jsdialog/jsdialogregister.hxx> +#include <jsdialog/jsdialogmessages.hxx> + +#include <utility> +#include <vcl/weld.hxx> +#include <vcl/virdev.hxx> +#include <salvtables.hxx> +#include <vcl/toolkit/button.hxx> +#include <vcl/toolkit/fmtfield.hxx> +#include <vcl/toolkit/prgsbar.hxx> + +#include <comphelper/compbase.hxx> + +#include <list> +#include <mutex> + +#define ACTION_TYPE "action_type" +#define PARENT_ID "parent_id" +#define WINDOW_ID "id" +#define CLOSE_ID "close_id" +#define MENU_PTR "menu_ptr" + +namespace vcl +{ +class ILibreOfficeKitNotifier; +} + +class JSDialogSender +{ + std::unique_ptr<JSDialogNotifyIdle> mpIdleNotify; + +protected: + bool m_bCanClose; // specifies if can send a close message + +public: + JSDialogSender() + : m_bCanClose(true) + { + } + JSDialogSender(VclPtr<vcl::Window> aNotifierWindow, VclPtr<vcl::Window> aContentWindow, + const OUString& sTypeOfJSON) + : m_bCanClose(true) + { + initializeSender(aNotifierWindow, aContentWindow, sTypeOfJSON); + } + + virtual ~JSDialogSender() COVERITY_NOEXCEPT_FALSE; + + virtual void sendFullUpdate(bool bForce = false); + void sendClose(); + void sendUpdate(VclPtr<vcl::Window> pWindow, bool bForce = false); + virtual void sendAction(VclPtr<vcl::Window> pWindow, + std::unique_ptr<jsdialog::ActionDataMap> pData); + virtual void sendPopup(VclPtr<vcl::Window> pWindow, OUString sParentId, OUString sCloseId); + virtual void sendClosePopup(vcl::LOKWindowId nWindowId); + void flush() { mpIdleNotify->Invoke(); } + +protected: + void initializeSender(const VclPtr<vcl::Window>& rNotifierWindow, + const VclPtr<vcl::Window>& rContentWindow, const OUString& rTypeOfJSON) + { + mpIdleNotify.reset(new JSDialogNotifyIdle(rNotifierWindow, rContentWindow, rTypeOfJSON)); + } +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx index 263ce53d8754..501f14cea09a 100644 --- a/vcl/jsdialog/jsdialogbuilder.cxx +++ b/vcl/jsdialog/jsdialogbuilder.cxx @@ -10,7 +10,6 @@ #include <jsdialog/jsdialogbuilder.hxx> #include <sal/log.hxx> #include <comphelper/base64.hxx> -#include <comphelper/lok.hxx> #include <iconview.hxx> #include <utility> #include <vcl/menu.hxx> @@ -22,7 +21,6 @@ #include <vcl/toolkit/treelistentry.hxx> #include <vcl/toolkit/vclmedit.hxx> #include <verticaltabctrl.hxx> -#include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <messagedialog.hxx> #include <tools/json_writer.hxx> #include <memory> @@ -56,329 +54,6 @@ void response_help(vcl::Window* pWindow) } } -JSDialogNotifyIdle::JSDialogNotifyIdle(VclPtr<vcl::Window> aNotifierWindow, - VclPtr<vcl::Window> aContentWindow, - const OUString& sTypeOfJSON) - : Idle("JSDialog notify") - , m_aNotifierWindow(std::move(aNotifierWindow)) - , m_aContentWindow(std::move(aContentWindow)) - , m_sTypeOfJSON(sTypeOfJSON) - , m_bForce(false) -{ - SetPriority(TaskPriority::POST_PAINT); -} - -void JSDialogNotifyIdle::forceUpdate() { m_bForce = true; } - -void JSDialogNotifyIdle::send(const OString& sMsg) -{ - if (!m_aNotifierWindow) - { - return; - } - - const vcl::ILibreOfficeKitNotifier* pNotifier = m_aNotifierWindow->GetLOKNotifier(); - if (pNotifier) - { - if (m_bForce || sMsg != m_LastNotificationMessage) - { - m_bForce = false; - m_LastNotificationMessage = sMsg; - pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, m_LastNotificationMessage); - } - } -} - -void JSDialogNotifyIdle::sendMessage(jsdialog::MessageType eType, - const VclPtr<vcl::Window>& pWindow, - std::unique_ptr<jsdialog::ActionDataMap> pData) -{ - std::scoped_lock aGuard(m_aQueueMutex); - - // we want only the latest update of same type - // TODO: also if we met full update - previous updates are not valid - auto it = m_aMessageQueue.begin(); - - while (it != m_aMessageQueue.end()) - { - if (it->m_eType == eType && it->m_pWindow == pWindow) - { - // actions should be always sent, eg. rendering of custom entries in combobox - if (eType == jsdialog::MessageType::Action) - { - it++; - continue; - } - it = m_aMessageQueue.erase(it); - } - else - it++; - } - - JSDialogMessageInfo aMessage(eType, pWindow, std::move(pData)); - m_aMessageQueue.push_back(aMessage); -} - -OString JSDialogNotifyIdle::generateFullUpdate() const -{ - if (!m_aContentWindow || !m_aNotifierWindow) - return OString(); - - tools::JsonWriter aJsonWriter; - - m_aContentWindow->DumpAsPropertyTree(aJsonWriter); - if (m_aNotifierWindow) - aJsonWriter.put("id", m_aNotifierWindow->GetLOKWindowId()); - aJsonWriter.put("jsontype", m_sTypeOfJSON); - - return aJsonWriter.finishAndGetAsOString(); -} - -OString JSDialogNotifyIdle::generateWidgetUpdate(VclPtr<vcl::Window> pWindow) const -{ - if (!pWindow || !m_aNotifierWindow) - return OString(); - - tools::JsonWriter aJsonWriter; - - aJsonWriter.put("jsontype", m_sTypeOfJSON); - aJsonWriter.put("action", "update"); - if (m_aNotifierWindow) - aJsonWriter.put("id", m_aNotifierWindow->GetLOKWindowId()); - { - auto aEntries = aJsonWriter.startNode("control"); - pWindow->DumpAsPropertyTree(aJsonWriter); - } - - return aJsonWriter.finishAndGetAsOString(); -} - -OString JSDialogNotifyIdle::generateCloseMessage() const -{ - tools::JsonWriter aJsonWriter; - if (m_aNotifierWindow) - aJsonWriter.put("id", m_aNotifierWindow->GetLOKWindowId()); - aJsonWriter.put("jsontype", m_sTypeOfJSON); - aJsonWriter.put("action", "close"); - - return aJsonWriter.finishAndGetAsOString(); -} - -OString -JSDialogNotifyIdle::generateActionMessage(VclPtr<vcl::Window> pWindow, - std::unique_ptr<jsdialog::ActionDataMap> pData) const -{ - tools::JsonWriter aJsonWriter; - - aJsonWriter.put("jsontype", m_sTypeOfJSON); - aJsonWriter.put("action", "action"); - if (m_aNotifierWindow) - aJsonWriter.put("id", m_aNotifierWindow->GetLOKWindowId()); - - { - auto aDataNode = aJsonWriter.startNode("data"); - aJsonWriter.put("control_id", pWindow->get_id()); - - for (auto it = pData->begin(); it != pData->end(); it++) - aJsonWriter.put(it->first, it->second); - } - - return aJsonWriter.finishAndGetAsOString(); -} - -OString JSDialogNotifyIdle::generatePopupMessage(VclPtr<vcl::Window> pWindow, - const OUString& sParentId, - const OUString& sCloseId) const -{ - if (!pWindow || !m_aNotifierWindow) - return OString(); - - if (!pWindow->GetParentWithLOKNotifier()) - return OString(); - - tools::JsonWriter aJsonWriter; - - { - auto aChildren = aJsonWriter.startArray("children"); - { - auto aStruct = aJsonWriter.startStruct(); - pWindow->DumpAsPropertyTree(aJsonWriter); - } - } - - // try to get the position eg. for the autofilter - { - vcl::Window* pVclWindow = pWindow.get(); - DockingWindow* pDockingWindow = dynamic_cast<DockingWindow*>(pVclWindow); - while (pVclWindow && !pDockingWindow) - { - pVclWindow = pVclWindow->GetParent(); - pDockingWindow = dynamic_cast<DockingWindow*>(pVclWindow); - } - - if (pDockingWindow) - { - Point aPos = pDockingWindow->GetFloatingPos(); - aJsonWriter.put("posx", aPos.getX()); - aJsonWriter.put("posy", aPos.getY()); - if (!pDockingWindow->IsVisible()) - aJsonWriter.put("visible", "false"); - } - } - - aJsonWriter.put("jsontype", "dialog"); - aJsonWriter.put("type", "modalpopup"); - aJsonWriter.put("cancellable", true); - aJsonWriter.put("popupParent", sParentId); - aJsonWriter.put("clickToClose", sCloseId); - aJsonWriter.put("id", pWindow->GetParentWithLOKNotifier()->GetLOKWindowId()); - - return aJsonWriter.finishAndGetAsOString(); -} - -OString JSDialogNotifyIdle::generateClosePopupMessage(const OUString& sWindowId) const -{ - if (!m_aNotifierWindow) - return OString(); - - tools::JsonWriter aJsonWriter; - - aJsonWriter.put("jsontype", "dialog"); - aJsonWriter.put("type", "modalpopup"); - aJsonWriter.put("action", "close"); - aJsonWriter.put("id", sWindowId); - - return aJsonWriter.finishAndGetAsOString(); -} - -void JSDialogNotifyIdle::Invoke() -{ - std::deque<JSDialogMessageInfo> aMessageQueue; - { - std::scoped_lock aGuard(m_aQueueMutex); - - std::swap(aMessageQueue, m_aMessageQueue); - } - - for (auto& rMessage : aMessageQueue) - { - jsdialog::MessageType eType = rMessage.m_eType; - - if (m_sTypeOfJSON == "formulabar" && eType != jsdialog::MessageType::Action) - continue; - - switch (eType) - { - case jsdialog::MessageType::FullUpdate: - send(generateFullUpdate()); - break; - - case jsdialog::MessageType::WidgetUpdate: - send(generateWidgetUpdate(rMessage.m_pWindow)); - break; - - case jsdialog::MessageType::Close: - send(generateCloseMessage()); - break; - - case jsdialog::MessageType::Action: - send(generateActionMessage(rMessage.m_pWindow, std::move(rMessage.m_pData))); - break; - - case jsdialog::MessageType::Popup: - send(generatePopupMessage(rMessage.m_pWindow, - (*rMessage.m_pData)[PARENT_ID ""_ostr], - (*rMessage.m_pData)[CLOSE_ID ""_ostr])); - break; - - case jsdialog::MessageType::PopupClose: - send(generateClosePopupMessage((*rMessage.m_pData)[WINDOW_ID ""_ostr])); - break; - } - } -} - -void JSDialogNotifyIdle::clearQueue() { m_aMessageQueue.clear(); } - -JSDialogSender::~JSDialogSender() COVERITY_NOEXCEPT_FALSE -{ - sendClose(); - - if (mpIdleNotify) - mpIdleNotify->Stop(); -} - -void JSDialogSender::sendFullUpdate(bool bForce) -{ - if (!mpIdleNotify) - { - assert(false); - return; - } - - if (bForce) - mpIdleNotify->forceUpdate(); - - mpIdleNotify->sendMessage(jsdialog::MessageType::FullUpdate, nullptr); - mpIdleNotify->Start(); -} - -void JSDialogSender::sendClose() -{ - if (!mpIdleNotify || !m_bCanClose) - return; - - mpIdleNotify->clearQueue(); - mpIdleNotify->sendMessage(jsdialog::MessageType::Close, nullptr); - flush(); -} - -void JSDialogSender::sendUpdate(VclPtr<vcl::Window> pWindow, bool bForce) -{ - if (!mpIdleNotify) - return; - - if (bForce) - mpIdleNotify->forceUpdate(); - - mpIdleNotify->sendMessage(jsdialog::MessageType::WidgetUpdate, pWindow); - mpIdleNotify->Start(); -} - -void JSDialogSender::sendAction(const VclPtr<vcl::Window>& pWindow, - std::unique_ptr<jsdialog::ActionDataMap> pData) -{ - if (!mpIdleNotify) - return; - - mpIdleNotify->sendMessage(jsdialog::MessageType::Action, pWindow, std::move(pData)); - mpIdleNotify->Start(); -} - -void JSDialogSender::sendPopup(const VclPtr<vcl::Window>& pWindow, const OUString& rParentId, - const OUString& rCloseId) -{ - if (!mpIdleNotify) - return; - - std::unique_ptr<jsdialog::ActionDataMap> pData = std::make_unique<jsdialog::ActionDataMap>(); - (*pData)[PARENT_ID ""_ostr] = rParentId; - (*pData)[CLOSE_ID ""_ostr] = rCloseId; - mpIdleNotify->sendMessage(jsdialog::MessageType::Popup, pWindow, std::move(pData)); - mpIdleNotify->Start(); -} - -void JSDialogSender::sendClosePopup(vcl::LOKWindowId nWindowId) -{ - if (!mpIdleNotify) - return; - - std::unique_ptr<jsdialog::ActionDataMap> pData = std::make_unique<jsdialog::ActionDataMap>(); - (*pData)[WINDOW_ID ""_ostr] = OUString::number(nWindowId); - mpIdleNotify->sendMessage(jsdialog::MessageType::PopupClose, nullptr, std::move(pData)); - flush(); -} - namespace { vcl::Window* extract_sal_widget(weld::Widget* pParent) diff --git a/vcl/jsdialog/jsdialogsender.cxx b/vcl/jsdialog/jsdialogsender.cxx new file mode 100644 index 000000000000..04c0d2a1e639 --- /dev/null +++ b/vcl/jsdialog/jsdialogsender.cxx @@ -0,0 +1,337 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <jsdialog/jsdialogsender.hxx> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> +#include <tools/json_writer.hxx> +#include <vcl/dockwin.hxx> + +JSDialogNotifyIdle::JSDialogNotifyIdle(VclPtr<vcl::Window> aNotifierWindow, + VclPtr<vcl::Window> aContentWindow, + const OUString& sTypeOfJSON) + : Idle("JSDialog notify") + , m_aNotifierWindow(std::move(aNotifierWindow)) + , m_aContentWindow(std::move(aContentWindow)) + , m_sTypeOfJSON(sTypeOfJSON) + , m_bForce(false) +{ + SetPriority(TaskPriority::POST_PAINT); +} + +void JSDialogNotifyIdle::forceUpdate() { m_bForce = true; } + +void JSDialogNotifyIdle::send(const OString& sMsg) +{ + if (!m_aNotifierWindow) + { + return; + } + + const vcl::ILibreOfficeKitNotifier* pNotifier = m_aNotifierWindow->GetLOKNotifier(); + if (pNotifier) + { + if (m_bForce || sMsg != m_LastNotificationMessage) + { + m_bForce = false; + m_LastNotificationMessage = sMsg; + pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, m_LastNotificationMessage); + } + } +} + +void JSDialogNotifyIdle::sendMessage(jsdialog::MessageType eType, + const VclPtr<vcl::Window>& pWindow, + std::unique_ptr<jsdialog::ActionDataMap> pData) +{ + std::scoped_lock aGuard(m_aQueueMutex); + + // we want only the latest update of same type + // TODO: also if we met full update - previous updates are not valid + auto it = m_aMessageQueue.begin(); + + while (it != m_aMessageQueue.end()) + { + if (it->m_eType == eType && it->m_pWindow == pWindow) + { + // actions should be always sent, eg. rendering of custom entries in combobox + if (eType == jsdialog::MessageType::Action) + { + it++; + continue; + } + it = m_aMessageQueue.erase(it); + } + else + it++; + } + + JSDialogMessageInfo aMessage(eType, pWindow, std::move(pData)); + m_aMessageQueue.push_back(aMessage); +} + +OString JSDialogNotifyIdle::generateFullUpdate() const +{ + if (!m_aContentWindow || !m_aNotifierWindow) + return OString(); + + tools::JsonWriter aJsonWriter; + + m_aContentWindow->DumpAsPropertyTree(aJsonWriter); + if (m_aNotifierWindow) + aJsonWriter.put("id", m_aNotifierWindow->GetLOKWindowId()); + aJsonWriter.put("jsontype", m_sTypeOfJSON); + + return aJsonWriter.finishAndGetAsOString(); +} + +OString JSDialogNotifyIdle::generateWidgetUpdate(VclPtr<vcl::Window> pWindow) const +{ + if (!pWindow || !m_aNotifierWindow) + return OString(); + + tools::JsonWriter aJsonWriter; + + aJsonWriter.put("jsontype", m_sTypeOfJSON); + aJsonWriter.put("action", "update"); + if (m_aNotifierWindow) + aJsonWriter.put("id", m_aNotifierWindow->GetLOKWindowId()); + { + auto aEntries = aJsonWriter.startNode("control"); + pWindow->DumpAsPropertyTree(aJsonWriter); + } + + return aJsonWriter.finishAndGetAsOString(); +} + +OString JSDialogNotifyIdle::generateCloseMessage() const +{ + tools::JsonWriter aJsonWriter; + if (m_aNotifierWindow) + aJsonWriter.put("id", m_aNotifierWindow->GetLOKWindowId()); + aJsonWriter.put("jsontype", m_sTypeOfJSON); + aJsonWriter.put("action", "close"); + + return aJsonWriter.finishAndGetAsOString(); +} + +OString +JSDialogNotifyIdle::generateActionMessage(VclPtr<vcl::Window> pWindow, + std::unique_ptr<jsdialog::ActionDataMap> pData) const +{ + tools::JsonWriter aJsonWriter; + + aJsonWriter.put("jsontype", m_sTypeOfJSON); + aJsonWriter.put("action", "action"); + if (m_aNotifierWindow) + aJsonWriter.put("id", m_aNotifierWindow->GetLOKWindowId()); + + { + auto aDataNode = aJsonWriter.startNode("data"); + aJsonWriter.put("control_id", pWindow->get_id()); + + for (auto it = pData->begin(); it != pData->end(); it++) + aJsonWriter.put(it->first, it->second); + } + + return aJsonWriter.finishAndGetAsOString(); +} + +OString JSDialogNotifyIdle::generatePopupMessage(VclPtr<vcl::Window> pWindow, + const OUString& sParentId, + const OUString& sCloseId) const +{ + if (!pWindow || !m_aNotifierWindow) + return OString(); + + if (!pWindow->GetParentWithLOKNotifier()) + return OString(); + + tools::JsonWriter aJsonWriter; + + { + auto aChildren = aJsonWriter.startArray("children"); + { + auto aStruct = aJsonWriter.startStruct(); + pWindow->DumpAsPropertyTree(aJsonWriter); + } + } + + // try to get the position eg. for the autofilter + { + vcl::Window* pVclWindow = pWindow.get(); + DockingWindow* pDockingWindow = dynamic_cast<DockingWindow*>(pVclWindow); + while (pVclWindow && !pDockingWindow) + { + pVclWindow = pVclWindow->GetParent(); + pDockingWindow = dynamic_cast<DockingWindow*>(pVclWindow); + } + + if (pDockingWindow) + { + Point aPos = pDockingWindow->GetFloatingPos(); + aJsonWriter.put("posx", aPos.getX()); + aJsonWriter.put("posy", aPos.getY()); + if (!pDockingWindow->IsVisible()) + aJsonWriter.put("visible", "false"); + } + } + + aJsonWriter.put("jsontype", "dialog"); + aJsonWriter.put("type", "modalpopup"); + aJsonWriter.put("cancellable", true); + aJsonWriter.put("popupParent", sParentId); + aJsonWriter.put("clickToClose", sCloseId); + aJsonWriter.put("id", pWindow->GetParentWithLOKNotifier()->GetLOKWindowId()); + + return aJsonWriter.finishAndGetAsOString(); +} + +OString JSDialogNotifyIdle::generateClosePopupMessage(const OUString& sWindowId) const +{ + if (!m_aNotifierWindow) + return OString(); + + tools::JsonWriter aJsonWriter; + + aJsonWriter.put("jsontype", "dialog"); + aJsonWriter.put("type", "modalpopup"); + aJsonWriter.put("action", "close"); + aJsonWriter.put("id", sWindowId); + + return aJsonWriter.finishAndGetAsOString(); +} + +void JSDialogNotifyIdle::Invoke() +{ + std::deque<JSDialogMessageInfo> aMessageQueue; + { + std::scoped_lock aGuard(m_aQueueMutex); + + std::swap(aMessageQueue, m_aMessageQueue); + } + + for (auto& rMessage : aMessageQueue) + { + jsdialog::MessageType eType = rMessage.m_eType; + + if (m_sTypeOfJSON == "formulabar" && eType != jsdialog::MessageType::Action) + continue; + + switch (eType) + { + case jsdialog::MessageType::FullUpdate: + send(generateFullUpdate()); + break; + + case jsdialog::MessageType::WidgetUpdate: + send(generateWidgetUpdate(rMessage.m_pWindow)); + break; + + case jsdialog::MessageType::Close: + send(generateCloseMessage()); + break; + + case jsdialog::MessageType::Action: + send(generateActionMessage(rMessage.m_pWindow, std::move(rMessage.m_pData))); + break; + + case jsdialog::MessageType::Popup: + send(generatePopupMessage(rMessage.m_pWindow, + (*rMessage.m_pData)[PARENT_ID ""_ostr], + (*rMessage.m_pData)[CLOSE_ID ""_ostr])); + break; + + case jsdialog::MessageType::PopupClose: + send(generateClosePopupMessage((*rMessage.m_pData)[WINDOW_ID ""_ostr])); + break; + } + } +} + +void JSDialogNotifyIdle::clearQueue() { m_aMessageQueue.clear(); } + +JSDialogSender::~JSDialogSender() COVERITY_NOEXCEPT_FALSE +{ + sendClose(); + + if (mpIdleNotify) + mpIdleNotify->Stop(); +} + +void JSDialogSender::sendFullUpdate(bool bForce) +{ + if (!mpIdleNotify) + { + assert(false); + return; + } + + if (bForce) + mpIdleNotify->forceUpdate(); + + mpIdleNotify->sendMessage(jsdialog::MessageType::FullUpdate, nullptr); + mpIdleNotify->Start(); +} + +void JSDialogSender::sendClose() +{ + if (!mpIdleNotify || !m_bCanClose) + return; + + mpIdleNotify->clearQueue(); + mpIdleNotify->sendMessage(jsdialog::MessageType::Close, nullptr); + flush(); +} + +void JSDialogSender::sendUpdate(VclPtr<vcl::Window> pWindow, bool bForce) +{ + if (!mpIdleNotify) + return; + + if (bForce) + mpIdleNotify->forceUpdate(); + + mpIdleNotify->sendMessage(jsdialog::MessageType::WidgetUpdate, pWindow); + mpIdleNotify->Start(); +} + +void JSDialogSender::sendAction(VclPtr<vcl::Window> pWindow, + std::unique_ptr<jsdialog::ActionDataMap> pData) +{ + if (!mpIdleNotify) + return; + + mpIdleNotify->sendMessage(jsdialog::MessageType::Action, pWindow, std::move(pData)); + mpIdleNotify->Start(); +} + +void JSDialogSender::sendPopup(VclPtr<vcl::Window> pWindow, OUString sParentId, OUString sCloseId) +{ + if (!mpIdleNotify) + return; + + std::unique_ptr<jsdialog::ActionDataMap> pData = std::make_unique<jsdialog::ActionDataMap>(); + (*pData)[PARENT_ID ""_ostr] = sParentId; + (*pData)[CLOSE_ID ""_ostr] = sCloseId; + mpIdleNotify->sendMessage(jsdialog::MessageType::Popup, pWindow, std::move(pData)); + mpIdleNotify->Start(); +} + +void JSDialogSender::sendClosePopup(vcl::LOKWindowId nWindowId) +{ + if (!mpIdleNotify) + return; + + std::unique_ptr<jsdialog::ActionDataMap> pData = std::make_unique<jsdialog::ActionDataMap>(); + (*pData)[WINDOW_ID ""_ostr] = OUString::number(nWindowId); + mpIdleNotify->sendMessage(jsdialog::MessageType::PopupClose, nullptr, std::move(pData)); + flush(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */