[Libreoffice-commits] core.git: Branch 'feature/jsdialogs' - 3 commits - desktop/source include/vcl sc/source sc/uiconfig sc/UIConfig_scalc.mk sfx2/source vcl/jsdialog vcl/source

Szymon KÅ‚os (via logerrit) logerrit at kemper.freedesktop.org
Mon Mar 9 13:30:40 UTC 2020


 desktop/source/lib/init.cxx                          |   16 +-
 include/vcl/jsdialog/jsdialogbuilder.hxx             |   13 +
 include/vcl/weld.hxx                                 |    2 
 sc/UIConfig_scalc.mk                                 |    2 
 sc/source/ui/dbgui/validate.cxx                      |   11 +
 sc/uiconfig/scalc/ui/erroralerttabpage-mobile.ui     |  151 +++++++++++++++++++
 sc/uiconfig/scalc/ui/validationhelptabpage-mobile.ui |  109 +++++++++++++
 sfx2/source/dialog/tabdlg.cxx                        |    4 
 vcl/jsdialog/jsdialogbuilder.cxx                     |  117 ++++++++++++--
 vcl/source/window/builder.cxx                        |    3 
 10 files changed, 397 insertions(+), 31 deletions(-)

New commits:
commit 9bd44f1c7bda6c9c56666225a91594aa0004b13e
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Mon Mar 9 14:11:06 2020 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Mon Mar 9 14:11:06 2020 +0100

    jsdialog: handle nested tab pages
    
    Change-Id: I04d5df55af0df18948730fcd9ee387abce77ac27

diff --git a/include/vcl/jsdialog/jsdialogbuilder.hxx b/include/vcl/jsdialog/jsdialogbuilder.hxx
index c14e4f40f2a0..107bd05c0bd4 100644
--- a/include/vcl/jsdialog/jsdialogbuilder.hxx
+++ b/include/vcl/jsdialog/jsdialogbuilder.hxx
@@ -26,8 +26,12 @@ public:
 class VCL_DLLPUBLIC JSInstanceBuilder : public SalInstanceBuilder
 {
     vcl::LOKWindowId m_nWindowId;
+    /// used in case of tab pages where dialog is not a direct top level
+    VclPtr<vcl::Window> m_aParentDialog;
+    bool m_bHasTopLevelDialog;
 
     static std::map<vcl::LOKWindowId, WidgetMap>& GetLOKWeldWidgetsMap();
+    static void InsertWindowToMap(int nWindowId);
     void RememberWidget(const OString &id, weld::Widget* pWidget);
 
 public:
@@ -103,6 +107,7 @@ public:
     virtual void insert(int pos, const OUString& rStr, const OUString* pId,
                         const OUString* pIconName, VirtualDevice* pImageSurface) override;
     virtual void remove(int pos) override;
+    virtual void set_active(int pos) override;
 };
 
 class VCL_DLLPUBLIC JSComboBox : public JSWidget<SalInstanceComboBoxWithEdit, ::ComboBox>
diff --git a/sfx2/source/dialog/tabdlg.cxx b/sfx2/source/dialog/tabdlg.cxx
index 8ef457dd31a7..dafa0432c8f8 100644
--- a/sfx2/source/dialog/tabdlg.cxx
+++ b/sfx2/source/dialog/tabdlg.cxx
@@ -39,6 +39,7 @@
 #include <vcl/IDialogRenderable.hxx>
 #include <sal/log.hxx>
 #include <comphelper/lok.hxx>
+#include <sfx2/lokhelper.hxx>
 
 #include <sfx2/strings.hrc>
 #include <helpids.h>
@@ -187,7 +188,8 @@ SfxTabPage::SfxTabPage(TabPageParent pParent, const OUString& rUIXMLDescription,
     , pSet                ( rAttrSet )
     , bHasExchangeSupport ( false )
     , pImpl               ( new TabPageImpl )
-    , m_xBuilder(pParent.pPage ? Application::CreateBuilder(pParent.pPage, rUIXMLDescription)
+    , m_xBuilder(pParent.pPage ? Application::CreateBuilder(pParent.pPage, rUIXMLDescription, comphelper::LibreOfficeKit::isActive()
+                                    && comphelper::LibreOfficeKit::isMobile(SfxLokHelper::getView()))
                                : Application::CreateInterimBuilder(this, rUIXMLDescription))
     , m_xContainer(m_xBuilder->weld_container(rID))
 {
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index 6f714c360c1f..2fae6e6ac172 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -30,12 +30,21 @@ JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIR
                 dynamic_cast<SalInstanceWidget*>(pParent)->getWidget() : nullptr,
             rUIRoot, rUIFile)
         , m_nWindowId(0)
+        , m_aParentDialog(nullptr)
+        , m_bHasTopLevelDialog(false)
 {
+    vcl::Window* pRoot = get_builder().get_widget_root();
+    if (pRoot && pRoot->GetParent())
+    {
+        m_aParentDialog = pRoot->GetParent()->GetParentWithLOKNotifier();
+        m_nWindowId = m_aParentDialog->GetLOKWindowId();
+        InsertWindowToMap(m_nWindowId);
+    }
 }
 
 JSInstanceBuilder::~JSInstanceBuilder()
 {
-    if (m_nWindowId)
+    if (m_nWindowId && m_bHasTopLevelDialog)
         GetLOKWeldWidgetsMap().erase(m_nWindowId);
 }
 
@@ -50,6 +59,7 @@ std::map<vcl::LOKWindowId, WidgetMap>& JSInstanceBuilder::GetLOKWeldWidgetsMap()
 weld::Widget* JSInstanceBuilder::FindWeldWidgetsMap(vcl::LOKWindowId nWindowId, const OString& rWidget)
 {
     const auto it = GetLOKWeldWidgetsMap().find(nWindowId);
+
     if (it != GetLOKWeldWidgetsMap().end())
     {
         auto widgetIt = it->second.find(rWidget);
@@ -60,6 +70,15 @@ weld::Widget* JSInstanceBuilder::FindWeldWidgetsMap(vcl::LOKWindowId nWindowId,
     return nullptr;
 }
 
+void JSInstanceBuilder::InsertWindowToMap(int nWindowId)
+{
+    WidgetMap map;
+    auto it = GetLOKWeldWidgetsMap().find(nWindowId);
+    if (it == GetLOKWeldWidgetsMap().end())
+        GetLOKWeldWidgetsMap().insert(
+            std::map<vcl::LOKWindowId, WidgetMap>::value_type(nWindowId, map));
+}
+
 void JSInstanceBuilder::RememberWidget(const OString &id, weld::Widget* pWidget)
 {
     auto it = GetLOKWeldWidgetsMap().find(m_nWindowId);
@@ -74,8 +93,7 @@ std::unique_ptr<weld::Dialog> JSInstanceBuilder::weld_dialog(const OString& id,
     ::Dialog* pDialog = m_xBuilder->get<::Dialog>(id);
     m_nWindowId = pDialog->GetLOKWindowId();
 
-    WidgetMap map;
-    GetLOKWeldWidgetsMap().insert(std::map<vcl::LOKWindowId, WidgetMap>::value_type(m_nWindowId, map));
+    InsertWindowToMap(m_nWindowId);
 
     std::unique_ptr<weld::Dialog> pRet(pDialog ? new SalInstanceDialog(pDialog, this, false) : nullptr);
     if (bTakeOwnership && pDialog)
@@ -83,6 +101,7 @@ std::unique_ptr<weld::Dialog> JSInstanceBuilder::weld_dialog(const OString& id,
         assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
         m_aOwnedToplevel.set(pDialog);
         m_xBuilder->drop_ownership(pDialog);
+        m_bHasTopLevelDialog = true;
     }
 
     const vcl::ILibreOfficeKitNotifier* pNotifier = pDialog->GetLOKNotifier();
@@ -102,9 +121,12 @@ std::unique_ptr<weld::Dialog> JSInstanceBuilder::weld_dialog(const OString& id,
 std::unique_ptr<weld::Label> JSInstanceBuilder::weld_label(const OString &id, bool bTakeOwnership)
 {
     ::FixedText* pLabel = m_xBuilder->get<FixedText>(id);
-    auto pWeldWidget = std::make_unique<JSLabel>(m_aOwnedToplevel, pLabel, this, bTakeOwnership);
+    auto pWeldWidget = std::make_unique<JSLabel>(m_bHasTopLevelDialog ? m_aOwnedToplevel : m_aParentDialog,
+                                                    pLabel, this, bTakeOwnership);
+
+    if (pWeldWidget)
+        RememberWidget(id, pWeldWidget.get());
 
-    RememberWidget(id, pWeldWidget.get());
     return pWeldWidget;
 }
 
@@ -112,9 +134,12 @@ std::unique_ptr<weld::Button> JSInstanceBuilder::weld_button(const OString &id,
 {
     ::Button* pButton = m_xBuilder->get<::Button>(id);
     auto pWeldWidget = pButton ?
-        std::make_unique<JSButton>(m_aOwnedToplevel, pButton, this, bTakeOwnership) : nullptr;
+        std::make_unique<JSButton>(m_bHasTopLevelDialog ? m_aOwnedToplevel : m_aParentDialog,
+                                        pButton, this, bTakeOwnership) : nullptr;
+
+    if (pWeldWidget)
+        RememberWidget(id, pWeldWidget.get());
 
-    RememberWidget(id, pWeldWidget.get());
     return pWeldWidget;
 }
 
@@ -122,9 +147,12 @@ std::unique_ptr<weld::Entry> JSInstanceBuilder::weld_entry(const OString& id, bo
 {
     Edit* pEntry = m_xBuilder->get<Edit>(id);
     auto pWeldWidget = pEntry ?
-        std::make_unique<JSEntry>(m_aOwnedToplevel, pEntry, this, bTakeOwnership) : nullptr;
+        std::make_unique<JSEntry>(m_bHasTopLevelDialog ? m_aOwnedToplevel : m_aParentDialog,
+                                    pEntry, this, bTakeOwnership) : nullptr;
+
+    if (pWeldWidget)
+        RememberWidget(id, pWeldWidget.get());
 
-    RememberWidget(id, pWeldWidget.get());
     return pWeldWidget;
 }
 
@@ -137,17 +165,21 @@ std::unique_ptr<weld::ComboBox> JSInstanceBuilder::weld_combo_box(const OString&
 
     if (pComboBox)
     {
-        pWeldWidget = std::make_unique<JSComboBox>(m_aOwnedToplevel, pComboBox, this, bTakeOwnership);
+        pWeldWidget = std::make_unique<JSComboBox>(m_bHasTopLevelDialog ? m_aOwnedToplevel : m_aParentDialog,
+                                                    pComboBox, this, bTakeOwnership);
     }
     else
     {
         ListBox* pListBox = dynamic_cast<ListBox*>(pWidget);
         pWeldWidget = pListBox
-               ? std::make_unique<JSListBox>(m_aOwnedToplevel, pListBox, this, bTakeOwnership)
+               ? std::make_unique<JSListBox>(m_bHasTopLevelDialog ? m_aOwnedToplevel : m_aParentDialog,
+                                                pListBox, this, bTakeOwnership)
                : nullptr;
     }
 
-    RememberWidget(id, pWeldWidget.get());
+    if (pWeldWidget)
+        RememberWidget(id, pWeldWidget.get());
+
     return pWeldWidget;
 }
 
@@ -155,9 +187,12 @@ std::unique_ptr<weld::Notebook> JSInstanceBuilder::weld_notebook(const OString &
 {
     TabControl* pNotebook = m_xBuilder->get<TabControl>(id);
     auto pWeldWidget = pNotebook ?
-        std::make_unique<JSNotebook>(m_aOwnedToplevel, pNotebook, this, bTakeOwnership) : nullptr;
+        std::make_unique<JSNotebook>(m_bHasTopLevelDialog ? m_aOwnedToplevel : m_aParentDialog,
+                                        pNotebook, this, bTakeOwnership) : nullptr;
+
+    if (pWeldWidget)
+        RememberWidget(id, pWeldWidget.get());
 
-    RememberWidget(id, pWeldWidget.get());
     return pWeldWidget;
 }
 
@@ -211,6 +246,12 @@ void JSListBox::remove(int pos)
     notifyDialogState();
 }
 
+void JSListBox::set_active(int pos)
+{
+    SalInstanceComboBoxWithoutEdit::set_active(pos);
+    notifyDialogState();
+}
+
 JSComboBox::JSComboBox(VclPtr<vcl::Window> aOwnedToplevel, ::ComboBox* pComboBox,
                 SalInstanceBuilder* pBuilder, bool bTakeOwnership)
 : JSWidget<SalInstanceComboBoxWithEdit, ::ComboBox>(aOwnedToplevel, pComboBox, pBuilder, bTakeOwnership)
commit f47d9cb7bc231d8fefc69208f34f258d2a198d86
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Fri Mar 6 12:24:01 2020 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Fri Mar 6 12:24:01 2020 +0100

    jsdialog: Add mobile version of data validation dialog
    
    Change-Id: I8c59892196ae015852fff6004c72e1990b35c1af

diff --git a/sc/UIConfig_scalc.mk b/sc/UIConfig_scalc.mk
index e91e9c35959b..58a9eb5942ab 100644
--- a/sc/UIConfig_scalc.mk
+++ b/sc/UIConfig_scalc.mk
@@ -125,6 +125,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/scalc,\
 	sc/uiconfig/scalc/ui/dropmenu \
 	sc/uiconfig/scalc/ui/doubledialog \
 	sc/uiconfig/scalc/ui/erroralerttabpage \
+	sc/uiconfig/scalc/ui/erroralerttabpage-mobile \
 	sc/uiconfig/scalc/ui/externaldata \
 	sc/uiconfig/scalc/ui/exponentialsmoothingdialog \
 	sc/uiconfig/scalc/ui/filldlg \
@@ -241,6 +242,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/scalc,\
 	sc/uiconfig/scalc/ui/validationdialog \
 	sc/uiconfig/scalc/ui/validationcriteriapage \
 	sc/uiconfig/scalc/ui/validationhelptabpage \
+	sc/uiconfig/scalc/ui/validationhelptabpage-mobile \
 	sc/uiconfig/scalc/ui/xmlsourcedialog \
 	sc/uiconfig/scalc/ui/ztestdialog \
 ))
diff --git a/sc/source/ui/dbgui/validate.cxx b/sc/source/ui/dbgui/validate.cxx
index c38de3295786..9cfd99fc80af 100644
--- a/sc/source/ui/dbgui/validate.cxx
+++ b/sc/source/ui/dbgui/validate.cxx
@@ -48,6 +48,11 @@
 #include <sfx2/viewfrm.hxx>
 #include <sfx2/childwin.hxx>
 #include <reffact.hxx>
+#include <comphelper/lok.hxx>
+#include <sfx2/lokhelper.hxx>
+
+
+#define IS_MOBILE (comphelper::LibreOfficeKit::isActive() && comphelper::LibreOfficeKit::isMobile(SfxLokHelper::getView()))
 
 /*  Position indexes for "Allow" list box.
     They do not map directly to ScValidationMode and can safely be modified to
@@ -688,7 +693,8 @@ IMPL_LINK_NOARG(ScTPValidationValue, CheckHdl, weld::Button&, void)
 // Input Help Page
 
 ScTPValidationHelp::ScTPValidationHelp(TabPageParent pParent, const SfxItemSet& rArgSet)
-    : SfxTabPage(pParent, "modules/scalc/ui/validationhelptabpage.ui", "ValidationHelpTabPage", &rArgSet)
+    : SfxTabPage(pParent, IS_MOBILE ? OUString("modules/scalc/ui/validationhelptabpage-mobile.ui")
+            : OUString("modules/scalc/ui/validationhelptabpage.ui"), "ValidationHelpTabPage", &rArgSet)
     , m_xTsbHelp(m_xBuilder->weld_check_button("tsbhelp"))
     , m_xEdtTitle(m_xBuilder->weld_entry("title"))
     , m_xEdInputHelp(m_xBuilder->weld_text_view("inputhelp"))
@@ -742,7 +748,8 @@ ScTPValidationError::ScTPValidationError(TabPageParent pParent,
                                          const SfxItemSet& rArgSet)
 
     :   SfxTabPage      ( pParent,
-                          "modules/scalc/ui/erroralerttabpage.ui", "ErrorAlertTabPage",
+                          IS_MOBILE ? OUString("modules/scalc/ui/erroralerttabpage-mobile.ui")
+                                : OUString("modules/scalc/ui/erroralerttabpage.ui"), "ErrorAlertTabPage",
                           &rArgSet )
     , m_xTsbShow(m_xBuilder->weld_check_button("tsbshow"))
     , m_xLbAction(m_xBuilder->weld_combo_box("actionCB"))
diff --git a/sc/uiconfig/scalc/ui/erroralerttabpage-mobile.ui b/sc/uiconfig/scalc/ui/erroralerttabpage-mobile.ui
new file mode 100644
index 000000000000..2faa72dba83d
--- /dev/null
+++ b/sc/uiconfig/scalc/ui/erroralerttabpage-mobile.ui
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.4 -->
+<interface domain="sc">
+  <requires lib="gtk+" version="3.18"/>
+  <object class="GtkBox" id="ErrorAlertTabPage">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="hexpand">True</property>
+    <property name="vexpand">True</property>
+    <property name="border_width">6</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">12</property>
+    <child>
+      <object class="GtkCheckButton" id="tsbshow">
+        <property name="label" translatable="yes" context="erroralerttabpage|tsbshow">Show error _message when invalid values are entered</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="hexpand">True</property>
+        <property name="use_underline">True</property>
+        <property name="xalign">0</property>
+        <property name="inconsistent">True</property>
+        <property name="draw_indicator">True</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkGrid" id="grid1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
+        <property name="row_spacing">6</property>
+        <property name="column_spacing">12</property>
+        <child>
+          <object class="GtkLabel" id="action_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes" context="erroralerttabpage|action_label">_Action:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">actionCB</property>
+            <property name="xalign">0</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="title_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes" context="erroralerttabpage|title_label">_Title:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">erroralert_title</property>
+            <property name="xalign">0</property>
+            <property name="yalign">0</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="scrolledwindow1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="vexpand">True</property>
+            <property name="shadow_type">in</property>
+            <child>
+              <object class="GtkTextView" id="errorMsg">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="vexpand">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">2</property>
+            <property name="width">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="erroralert_title">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">1</property>
+            <property name="width">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="errormsg_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes" context="erroralerttabpage|errormsg_label">_Error message:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">errorMsg</property>
+            <property name="xalign">0</property>
+            <property name="yalign">0</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="browseBtn">
+            <property name="label" translatable="yes" context="erroralerttabpage|browseBtn">_Browse...</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="use_underline">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">2</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBoxText" id="actionCB">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="hexpand">True</property>
+            <items>
+              <item translatable="yes" context="erroralerttabpage|actionCB">Stop</item>
+              <item translatable="yes" context="erroralerttabpage|actionCB">Warning</item>
+              <item translatable="yes" context="erroralerttabpage|actionCB">Information</item>
+            </items>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/sc/uiconfig/scalc/ui/validationhelptabpage-mobile.ui b/sc/uiconfig/scalc/ui/validationhelptabpage-mobile.ui
new file mode 100644
index 000000000000..ea5146be8f1f
--- /dev/null
+++ b/sc/uiconfig/scalc/ui/validationhelptabpage-mobile.ui
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.4 -->
+<interface domain="sc">
+  <requires lib="gtk+" version="3.18"/>
+  <object class="GtkBox" id="ValidationHelpTabPage">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="hexpand">True</property>
+    <property name="vexpand">True</property>
+    <property name="border_width">6</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">12</property>
+    <child>
+      <object class="GtkCheckButton" id="tsbhelp">
+        <property name="label" translatable="yes" context="validationhelptabpage|tsbhelp">_Show input help when cell is selected</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="hexpand">True</property>
+        <property name="use_underline">True</property>
+        <property name="xalign">0</property>
+        <property name="inconsistent">True</property>
+        <property name="draw_indicator">True</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkGrid" id="grid1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
+        <property name="row_spacing">6</property>
+        <property name="column_spacing">12</property>
+        <child>
+          <object class="GtkEntry" id="title">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hexpand">True</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="title_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes" context="validationhelptabpage|title_label">_Title:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">title</property>
+            <property name="xalign">0</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="inputhelp_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes" context="validationhelptabpage|inputhelp_label">_Input help:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">inputhelp</property>
+            <property name="xalign">0</property>
+            <property name="yalign">0</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="scrolledwindow1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hexpand">True</property>
+            <property name="vexpand">True</property>
+            <property name="shadow_type">in</property>
+            <child>
+              <object class="GtkTextView" id="inputhelp">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index bc1f903081bc..b51ed407f432 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -149,7 +149,8 @@ weld::Builder* Application::CreateBuilder(weld::Widget* pParent, const OUString
     if (bMobile)
     {
         if (rUIFile == "modules/swriter/ui/wordcount-mobile.ui" ||
-            rUIFile == "svx/ui/findreplacedialog-mobile.ui")
+            rUIFile == "svx/ui/findreplacedialog-mobile.ui" ||
+            rUIFile == "modules/scalc/ui/validationdialog.ui")
             bUseJSBuilder = true;
     }
 
commit b487a4e175e1c18a8daf6ee950e45e97a3ca659b
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Fri Mar 6 11:11:57 2020 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Fri Mar 6 11:19:03 2020 +0100

    jsdialog: remember weld instances
    
    Change-Id: Ie55e0fcd2307679aee52751b2d2e434393850418

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 690b441b591d..fcfc27ddd23d 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -3535,7 +3535,6 @@ static void doc_sendDialogEvent(LibreOfficeKitDocument* /*pThis*/, unsigned nWin
 
     StringMap aMap(jsonToStringMap(pArguments));
     VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nWindowId);
-    JSInstanceBuilder* pBuilder = JSInstanceBuilder::FindLOKWeldBuilder(nWindowId);
 
     if (!pWindow && nWindowId >= 1000000000 /* why unsigned? */)
         pWindow = getSidebarWindow();
@@ -3556,18 +3555,20 @@ static void doc_sendDialogEvent(LibreOfficeKitDocument* /*pThis*/, unsigned nWin
 
         try
         {
-            bool bIsWeldedDialog = pBuilder != nullptr;
+            OString sControlId = OUStringToOString(aMap["id"], RTL_TEXTENCODING_ASCII_US);
+            weld::Widget* pWidget = JSInstanceBuilder::FindWeldWidgetsMap(nWindowId, sControlId);
+
+            bool bIsWeldedDialog = pWidget != nullptr;
             bool bContinueWithLOKWindow = false;
 
             if (bIsWeldedDialog)
             {
-                OString sControlId = OUStringToOString(aMap["id"], RTL_TEXTENCODING_ASCII_US);
                 OUString sControlType = aMap["type"];
                 OUString sAction = aMap["cmd"];
 
                 if (sControlType == "tabcontrol")
                 {
-                    auto pNotebook = pBuilder->weld_notebook(sControlId, false);
+                    auto pNotebook = dynamic_cast<weld::Notebook*>(pWidget);
                     if (pNotebook)
                     {
                         if (sAction == "selecttab")
@@ -3583,7 +3584,7 @@ static void doc_sendDialogEvent(LibreOfficeKitDocument* /*pThis*/, unsigned nWin
                 }
                 else if (sControlType == "combobox")
                 {
-                    auto pCombobox = pBuilder->weld_combo_box(sControlId, false);
+                    auto pCombobox = dynamic_cast<weld::ComboBox*>(pWidget);
                     if (pCombobox)
                     {
                         if (sAction == "selected")
@@ -3597,6 +3598,11 @@ static void doc_sendDialogEvent(LibreOfficeKitDocument* /*pThis*/, unsigned nWin
                                 pCombobox->set_active(pos);
                             }
                         }
+                        else if (sAction == "change")
+                        {
+                            pCombobox->set_entry_text(aMap["data"]);
+                            pCombobox->signal_changed();
+                        }
                         else
                             bContinueWithLOKWindow = true;
                     }
diff --git a/include/vcl/jsdialog/jsdialogbuilder.hxx b/include/vcl/jsdialog/jsdialogbuilder.hxx
index 7d76fba4d68b..c14e4f40f2a0 100644
--- a/include/vcl/jsdialog/jsdialogbuilder.hxx
+++ b/include/vcl/jsdialog/jsdialogbuilder.hxx
@@ -10,6 +10,8 @@
 #include <vcl/combobox.hxx>
 #include <vcl/button.hxx>
 
+typedef std::map<OString, weld::Widget*> WidgetMap;
+
 class JSDialogSender
 {
     VclPtr<vcl::Window> m_aOwnedToplevel;
@@ -25,6 +27,9 @@ class VCL_DLLPUBLIC JSInstanceBuilder : public SalInstanceBuilder
 {
     vcl::LOKWindowId m_nWindowId;
 
+    static std::map<vcl::LOKWindowId, WidgetMap>& GetLOKWeldWidgetsMap();
+    void RememberWidget(const OString &id, weld::Widget* pWidget);
+
 public:
     JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile);
     virtual ~JSInstanceBuilder() override;
@@ -35,8 +40,7 @@ public:
     virtual std::unique_ptr<weld::ComboBox> weld_combo_box(const OString& id, bool bTakeOwnership = false) override;
     virtual std::unique_ptr<weld::Notebook> weld_notebook(const OString &id, bool bTakeOwnership = false) override;
 
-    static std::map<vcl::LOKWindowId, JSInstanceBuilder*>& GetLOKWeldBuilderMap();
-    static JSInstanceBuilder* FindLOKWeldBuilder(vcl::LOKWindowId nWindowId);
+    static weld::Widget* FindWeldWidgetsMap(vcl::LOKWindowId nWindowId, const OString& rWidget);
 };
 
 template<class BaseInstanceClass, class VclClass>
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index bdea15fb9cd9..6c207e59cc13 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -335,9 +335,9 @@ protected:
     Link<ComboBox&, bool> m_aEntryActivateHdl;
     Link<OUString&, bool> m_aEntryInsertTextHdl;
 
+public:
     void signal_changed() { m_aChangeHdl.Call(*this); }
 
-public:
     virtual void insert(int pos, const OUString& rStr, const OUString* pId,
                         const OUString* pIconName, VirtualDevice* pImageSurface)
         = 0;
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index bb10fd7d6927..6f714c360c1f 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -36,33 +36,46 @@ JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIR
 JSInstanceBuilder::~JSInstanceBuilder()
 {
     if (m_nWindowId)
-        GetLOKWeldBuilderMap().erase(m_nWindowId);
+        GetLOKWeldWidgetsMap().erase(m_nWindowId);
 }
 
-std::map<vcl::LOKWindowId, JSInstanceBuilder*>& JSInstanceBuilder::GetLOKWeldBuilderMap()
+std::map<vcl::LOKWindowId, WidgetMap>& JSInstanceBuilder::GetLOKWeldWidgetsMap()
 {
-    // Map to remember the LOKWindowId <-> Builder binding.
-    static std::map<vcl::LOKWindowId, JSInstanceBuilder*> s_aLOKWeldBuildersMap;
+    // Map to remember the LOKWindowId <-> weld widgets binding.
+    static std::map<vcl::LOKWindowId, WidgetMap> s_aLOKWeldBuildersMap;
 
     return s_aLOKWeldBuildersMap;
 }
 
-JSInstanceBuilder* JSInstanceBuilder::FindLOKWeldBuilder(vcl::LOKWindowId nWindowId)
+weld::Widget* JSInstanceBuilder::FindWeldWidgetsMap(vcl::LOKWindowId nWindowId, const OString& rWidget)
 {
-    const auto it = GetLOKWeldBuilderMap().find(nWindowId);
-    if (it != GetLOKWeldBuilderMap().end())
-        return it->second;
+    const auto it = GetLOKWeldWidgetsMap().find(nWindowId);
+    if (it != GetLOKWeldWidgetsMap().end())
+    {
+        auto widgetIt = it->second.find(rWidget);
+        if (widgetIt != it->second.end())
+            return widgetIt->second;
+    }
 
     return nullptr;
 }
 
+void JSInstanceBuilder::RememberWidget(const OString &id, weld::Widget* pWidget)
+{
+    auto it = GetLOKWeldWidgetsMap().find(m_nWindowId);
+    if (it != GetLOKWeldWidgetsMap().end())
+    {
+        it->second.insert(WidgetMap::value_type(id, pWidget));
+    }
+}
+
 std::unique_ptr<weld::Dialog> JSInstanceBuilder::weld_dialog(const OString& id, bool bTakeOwnership)
 {
     ::Dialog* pDialog = m_xBuilder->get<::Dialog>(id);
     m_nWindowId = pDialog->GetLOKWindowId();
 
-    GetLOKWeldBuilderMap().insert(
-        std::map<vcl::LOKWindowId, JSInstanceBuilder*>::value_type(m_nWindowId, this));
+    WidgetMap map;
+    GetLOKWeldWidgetsMap().insert(std::map<vcl::LOKWindowId, WidgetMap>::value_type(m_nWindowId, map));
 
     std::unique_ptr<weld::Dialog> pRet(pDialog ? new SalInstanceDialog(pDialog, this, false) : nullptr);
     if (bTakeOwnership && pDialog)
@@ -89,19 +102,30 @@ std::unique_ptr<weld::Dialog> JSInstanceBuilder::weld_dialog(const OString& id,
 std::unique_ptr<weld::Label> JSInstanceBuilder::weld_label(const OString &id, bool bTakeOwnership)
 {
     ::FixedText* pLabel = m_xBuilder->get<FixedText>(id);
-    return std::make_unique<JSLabel>(m_aOwnedToplevel, pLabel, this, bTakeOwnership);
+    auto pWeldWidget = std::make_unique<JSLabel>(m_aOwnedToplevel, pLabel, this, bTakeOwnership);
+
+    RememberWidget(id, pWeldWidget.get());
+    return pWeldWidget;
 }
 
 std::unique_ptr<weld::Button> JSInstanceBuilder::weld_button(const OString &id, bool bTakeOwnership)
 {
     ::Button* pButton = m_xBuilder->get<::Button>(id);
-    return pButton ? std::make_unique<JSButton>(m_aOwnedToplevel, pButton, this, bTakeOwnership) : nullptr;
+    auto pWeldWidget = pButton ?
+        std::make_unique<JSButton>(m_aOwnedToplevel, pButton, this, bTakeOwnership) : nullptr;
+
+    RememberWidget(id, pWeldWidget.get());
+    return pWeldWidget;
 }
 
 std::unique_ptr<weld::Entry> JSInstanceBuilder::weld_entry(const OString& id, bool bTakeOwnership)
 {
     Edit* pEntry = m_xBuilder->get<Edit>(id);
-    return pEntry ? std::make_unique<JSEntry>(m_aOwnedToplevel, pEntry, this, bTakeOwnership) : nullptr;
+    auto pWeldWidget = pEntry ?
+        std::make_unique<JSEntry>(m_aOwnedToplevel, pEntry, this, bTakeOwnership) : nullptr;
+
+    RememberWidget(id, pWeldWidget.get());
+    return pWeldWidget;
 }
 
 std::unique_ptr<weld::ComboBox> JSInstanceBuilder::weld_combo_box(const OString& id,
@@ -109,18 +133,32 @@ std::unique_ptr<weld::ComboBox> JSInstanceBuilder::weld_combo_box(const OString&
 {
     vcl::Window* pWidget = m_xBuilder->get<vcl::Window>(id);
     ::ComboBox* pComboBox = dynamic_cast<::ComboBox*>(pWidget);
+    std::unique_ptr<weld::ComboBox> pWeldWidget;
+
     if (pComboBox)
-        return std::make_unique<JSComboBox>(m_aOwnedToplevel, pComboBox, this, bTakeOwnership);
-    ListBox* pListBox = dynamic_cast<ListBox*>(pWidget);
-    return pListBox
+    {
+        pWeldWidget = std::make_unique<JSComboBox>(m_aOwnedToplevel, pComboBox, this, bTakeOwnership);
+    }
+    else
+    {
+        ListBox* pListBox = dynamic_cast<ListBox*>(pWidget);
+        pWeldWidget = pListBox
                ? std::make_unique<JSListBox>(m_aOwnedToplevel, pListBox, this, bTakeOwnership)
                : nullptr;
+    }
+
+    RememberWidget(id, pWeldWidget.get());
+    return pWeldWidget;
 }
 
 std::unique_ptr<weld::Notebook> JSInstanceBuilder::weld_notebook(const OString &id, bool bTakeOwnership)
 {
     TabControl* pNotebook = m_xBuilder->get<TabControl>(id);
-    return pNotebook ? std::make_unique<JSNotebook>(m_aOwnedToplevel, pNotebook, this, bTakeOwnership) : nullptr;
+    auto pWeldWidget = pNotebook ?
+        std::make_unique<JSNotebook>(m_aOwnedToplevel, pNotebook, this, bTakeOwnership) : nullptr;
+
+    RememberWidget(id, pWeldWidget.get());
+    return pWeldWidget;
 }
 
 JSLabel::JSLabel(VclPtr<vcl::Window> aOwnedToplevel, FixedText* pLabel,


More information about the Libreoffice-commits mailing list