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: */

Reply via email to