svx/source/tbxctrls/tbcontrl.cxx     |    3 +++
 vcl/inc/jsdialog/jsdialogbuilder.hxx |    2 ++
 vcl/jsdialog/jsdialogbuilder.cxx     |   33 ++++++++++++++++++++++++++++++---
 3 files changed, 35 insertions(+), 3 deletions(-)

New commits:
commit 09976bda9c196b2426b8826941f21384a58bf536
Author:     Szymon Kłos <szymon.k...@collabora.com>
AuthorDate: Mon Mar 6 11:33:08 2023 +0100
Commit:     Szymon Kłos <szymon.k...@collabora.com>
CommitDate: Tue Mar 7 09:29:50 2023 +0000

    jsdialog: don't close dialog on tab page destroy
    
    was closing the whole dialog on tab switch in
    Format -> Characters -> Highlight when switching to
    "None"
    
    also avoid sending multiple "full updates" by using the same
    builder for sending message
    
    Change-Id: I4540c9c857acf2b9f40482678a30335edc24e7cb
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148314
    Tested-by: Jenkins
    Reviewed-by: Szymon Kłos <szymon.k...@collabora.com>

diff --git a/svx/source/tbxctrls/tbcontrl.cxx b/svx/source/tbxctrls/tbcontrl.cxx
index 03b4f4706ce3..6303bbcd7d4c 100644
--- a/svx/source/tbxctrls/tbcontrl.cxx
+++ b/svx/source/tbxctrls/tbcontrl.cxx
@@ -1607,6 +1607,9 @@ Color SvxStyleBox_Base::TestColorsVisible(const Color 
&FontCol, const Color &Bac
 
 IMPL_LINK(SvxStyleBox_Base, DumpAsPropertyTreeHdl, tools::JsonWriter&, 
rJsonWriter, void)
 {
+    if (!m_xWidget)
+        return;
+
     {
         auto entriesNode = rJsonWriter.startNode("entries");
         for (int i = 0, nEntryCount = m_xWidget->get_count(); i < nEntryCount; 
++i)
diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx 
b/vcl/inc/jsdialog/jsdialogbuilder.hxx
index f9dea1a3987d..96455be71797 100644
--- a/vcl/inc/jsdialog/jsdialogbuilder.hxx
+++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx
@@ -223,6 +223,8 @@ class JSInstanceBuilder final : public SalInstanceBuilder, 
public JSDialogSender
     bool m_bIsNotebookbar;
     /// used to detect when we have to send Full Update in container handler
     bool m_bSentInitialUpdate;
+    /// is true for tabpages, prevents from closing parent window on destroy
+    bool m_bIsNestedBuilder;
     /// When LOKNotifier is set by jsdialogs code we need to release it
     VclPtr<vcl::Window> m_aWindowToRelease;
 
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index db2481897fa3..355a4d45c45a 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -510,6 +510,7 @@ JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, 
const OUString& rUIR
     , m_bHasTopLevelDialog(false)
     , m_bIsNotebookbar(false)
     , m_bSentInitialUpdate(false)
+    , m_bIsNestedBuilder(false)
     , m_aWindowToRelease(nullptr)
 {
     // when it is a popup we initialize sender in weld_popover
@@ -543,6 +544,7 @@ JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, 
const OUString& rUIR
     , m_bHasTopLevelDialog(false)
     , m_bIsNotebookbar(false)
     , m_bSentInitialUpdate(false)
+    , m_bIsNestedBuilder(false)
     , m_aWindowToRelease(nullptr)
 {
     vcl::Window* pRoot = m_xBuilder->get_widget_root();
@@ -586,6 +588,7 @@ JSInstanceBuilder::JSInstanceBuilder(vcl::Window* pParent, 
const OUString& rUIRo
     , m_bHasTopLevelDialog(false)
     , m_bIsNotebookbar(false)
     , m_bSentInitialUpdate(false)
+    , m_bIsNestedBuilder(false)
     , m_aWindowToRelease(nullptr)
 {
     vcl::Window* pRoot = m_xBuilder->get_widget_root();
@@ -616,6 +619,7 @@ JSInstanceBuilder::JSInstanceBuilder(vcl::Window* pParent, 
const OUString& rUIRo
     , m_bHasTopLevelDialog(false)
     , m_bIsNotebookbar(false)
     , m_bSentInitialUpdate(false)
+    , m_bIsNestedBuilder(false)
     , m_aWindowToRelease(nullptr)
 {
     vcl::Window* pRoot = m_xBuilder->get_widget_root();
@@ -667,6 +671,13 @@ JSInstanceBuilder::CreateFormulabarBuilder(vcl::Window* 
pParent, const OUString&
 
 JSInstanceBuilder::~JSInstanceBuilder()
 {
+    // tab page closed -> refresh parent window
+    if (m_bIsNestedBuilder && m_sTypeOfJSON == "dialog")
+    {
+        sendFullUpdate(true);
+        flush();
+    }
+
     if (m_sTypeOfJSON == "popup")
         sendClosePopup(m_nWindowId);
 
@@ -909,15 +920,31 @@ std::unique_ptr<weld::MessageDialog> 
JSInstanceBuilder::weld_message_dialog(cons
 std::unique_ptr<weld::Container> JSInstanceBuilder::weld_container(const 
OString& id)
 {
     vcl::Window* pContainer = m_xBuilder->get<vcl::Window>(id);
-    auto pWeldWidget = std::make_unique<JSContainer>(this, pContainer, this, 
false);
+    auto pWeldWidget
+        = pContainer ? std::make_unique<JSContainer>(this, pContainer, this, 
false) : nullptr;
 
     if (pWeldWidget)
         RememberWidget(id, pWeldWidget.get());
 
-    if (!m_bSentInitialUpdate)
+    if (!m_bSentInitialUpdate && pContainer)
     {
         m_bSentInitialUpdate = true;
-        sendFullUpdate();
+
+        // use parent builder to send update - avoid multiple calls from many 
builders
+        vcl::Window* pParent = pContainer->GetParent();
+        std::string sId = std::to_string(m_nWindowId);
+        while (pParent
+               && !FindWeldWidgetsMap(
+                      sId, OUStringToOString(pParent->get_id(), 
RTL_TEXTENCODING_ASCII_US)))
+            pParent = pParent->GetParent();
+
+        if (pParent)
+            jsdialog::SendFullUpdate(
+                sId, OUStringToOString(pParent->get_id(), 
RTL_TEXTENCODING_ASCII_US));
+
+        // this is nested builder, don't close parent dialog on destroy (eg. 
single tab page is closed)
+        m_bCanClose = false;
+        m_bIsNestedBuilder = true;
     }
 
     return pWeldWidget;

Reply via email to