[Libreoffice-commits] core.git: desktop/source include/vcl vcl/inc vcl/jsdialog

Szymon KÅ‚os (via logerrit) logerrit at kemper.freedesktop.org
Wed Nov 25 14:47:26 UTC 2020


 desktop/source/lib/init.cxx          |   22 -------
 include/vcl/jsdialog/executor.hxx    |    6 ++
 include/vcl/weld.hxx                 |    2 
 vcl/inc/jsdialog/jsdialogbuilder.hxx |   23 +++++++
 vcl/inc/salvtables.hxx               |    2 
 vcl/jsdialog/executor.cxx            |   52 +++++++++++++++++
 vcl/jsdialog/jsdialogbuilder.cxx     |  105 +++++++++++++++++++++++++++++------
 7 files changed, 171 insertions(+), 41 deletions(-)

New commits:
commit 0de158b4eb6d48d2c1a7cfcd638a73d7b69d45a7
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Fri Oct 30 10:51:08 2020 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Nov 25 15:46:32 2020 +0100

    jsdialog: implement TreeView
    
    Change-Id: I7c1cc683e8c5d5bdc00c1e3d3d0a2c85846bbda0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106560
    Tested-by: Jenkins
    Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 06d0a1de31d2..bc8b46a94c43 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -441,24 +441,6 @@ std::vector<beans::PropertyValue> desktop::jsonToPropertyValuesVector(const char
 }
 
 
-static StringMap jsonToStringMap(const char* pJSON)
-{
-    StringMap aArgs;
-    if (pJSON && pJSON[0] != '\0')
-    {
-        std::stringstream aStream(pJSON);
-        boost::property_tree::ptree aTree;
-        boost::property_tree::read_json(aStream, aTree);
-
-        for (const auto& rPair : aTree)
-        {
-            aArgs[OUString::fromUtf8(rPair.first.c_str())] = OUString::fromUtf8(rPair.second.get_value<std::string>(".").c_str());
-        }
-    }
-    return aArgs;
-}
-
-
 static boost::property_tree::ptree unoAnyToPropertyTree(const uno::Any& anyItem)
 {
     boost::property_tree::ptree aTree;
@@ -3710,7 +3692,7 @@ static void doc_sendDialogEvent(LibreOfficeKitDocument* /*pThis*/, unsigned long
 {
     SolarMutexGuard aGuard;
 
-    StringMap aMap(jsonToStringMap(pArguments));
+    StringMap aMap(jsdialog::jsonToStringMap(pArguments));
     VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nWindowId);
 
     if (!pWindow && nWindowId >= 1000000000 /* why unsigned? */)
@@ -5686,7 +5668,7 @@ static void doc_sendFormFieldEvent(LibreOfficeKitDocument* pThis, const char* pA
     if (doc_getDocumentType(pThis) != LOK_DOCTYPE_TEXT)
             return;
 
-    StringMap aMap(jsonToStringMap(pArguments));
+    StringMap aMap(jsdialog::jsonToStringMap(pArguments));
     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     if (!pDoc)
     {
diff --git a/include/vcl/jsdialog/executor.hxx b/include/vcl/jsdialog/executor.hxx
index 1cfa24c28a8a..e49190f31e5f 100644
--- a/include/vcl/jsdialog/executor.hxx
+++ b/include/vcl/jsdialog/executor.hxx
@@ -22,6 +22,11 @@ public:
 
     static void trigger_changed(weld::ComboBox& rComboBox) { rComboBox.signal_changed(); }
 
+    static void trigger_row_activated(weld::TreeView& rTreeView)
+    {
+        rTreeView.signal_row_activated();
+    }
+
     static void trigger_clicked(weld::Toolbar& rToolbar, const OString& rIdent)
     {
         rToolbar.signal_clicked(rIdent);
@@ -36,6 +41,7 @@ public:
 namespace jsdialog
 {
 VCL_DLLPUBLIC bool ExecuteAction(sal_uInt64 nWindowId, const OString& rWidget, StringMap& rData);
+VCL_DLLPUBLIC StringMap jsonToStringMap(const char* pJSON);
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 10686ffe705e..04285ee63778 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -782,6 +782,8 @@ public:
 */
 class VCL_DLLPUBLIC TreeView : virtual public Container
 {
+    friend class ::LOKTrigger;
+
 public:
     typedef std::pair<const TreeIter&, int> iter_col;
     typedef std::pair<const TreeIter&, OUString> iter_string;
diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx
index 91640f7a4ccd..8c379857e4b3 100644
--- a/vcl/inc/jsdialog/jsdialogbuilder.hxx
+++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx
@@ -22,6 +22,7 @@
 class ToolBox;
 class ComboBox;
 class VclMultiLineEdit;
+class SvTabListBox;
 
 typedef std::map<OString, weld::Widget*> WidgetMap;
 
@@ -108,8 +109,9 @@ public:
     weld_drawing_area(const OString& id, const a11yref& rA11yImpl = nullptr,
                       FactoryFunction pUITestFactoryFunction = nullptr,
                       void* pUserData = nullptr) override;
-    std::unique_ptr<weld::Toolbar> weld_toolbar(const OString& id) override;
-    std::unique_ptr<weld::TextView> weld_text_view(const OString& id) override;
+    virtual std::unique_ptr<weld::Toolbar> weld_toolbar(const OString& id) override;
+    virtual std::unique_ptr<weld::TextView> weld_text_view(const OString& id) override;
+    virtual std::unique_ptr<weld::TreeView> weld_tree_view(const OString& id) override;
 
     static weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent,
                                                     VclMessageType eMessageType,
@@ -145,6 +147,7 @@ public:
         notifyDialogState();
     }
 
+    using BaseInstanceClass::set_sensitive;
     virtual void set_sensitive(bool sensitive) override
     {
         BaseInstanceClass::set_sensitive(sensitive);
@@ -290,4 +293,20 @@ public:
     virtual void set_text(const OUString& rText) override;
 };
 
+class JSTreeView : public JSWidget<SalInstanceTreeView, ::SvTabListBox>
+{
+public:
+    JSTreeView(VclPtr<vcl::Window> aNotifierWindow, VclPtr<vcl::Window> aContentWindow,
+               ::SvTabListBox* pTextView, SalInstanceBuilder* pBuilder, bool bTakeOwnership,
+               std::string sTypeOfJSON);
+
+    using SalInstanceTreeView::set_toggle;
+    /// pos is used differently here, it defines how many steps of iterator we need to perform to take entry
+    virtual void set_toggle(int pos, TriState eState, int col = -1) override;
+
+    using SalInstanceTreeView::select;
+    /// pos is used differently here, it defines how many steps of iterator we need to perform to take entry
+    virtual void select(int pos) override;
+};
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index cb7ccc7b12e3..343da9cf79f0 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -1302,7 +1302,7 @@ public:
 
 class SalInstanceTreeView : public SalInstanceContainer, public virtual weld::TreeView
 {
-private:
+protected:
     // owner for UserData
     std::vector<std::unique_ptr<OUString>> m_aUserData;
     VclPtr<SvTabListBox> m_xTreeView;
diff --git a/vcl/jsdialog/executor.cxx b/vcl/jsdialog/executor.cxx
index 53fded14e1c1..9863d0c2edb9 100644
--- a/vcl/jsdialog/executor.cxx
+++ b/vcl/jsdialog/executor.cxx
@@ -11,9 +11,29 @@
 #include <vcl/weld.hxx>
 #include <vcl/jsdialog/executor.hxx>
 #include <sal/log.hxx>
+#include <rtl/uri.hxx>
+#include <boost/property_tree/json_parser.hpp>
 
 namespace jsdialog
 {
+StringMap jsonToStringMap(const char* pJSON)
+{
+    StringMap aArgs;
+    if (pJSON && pJSON[0] != '\0')
+    {
+        std::stringstream aStream(pJSON);
+        boost::property_tree::ptree aTree;
+        boost::property_tree::read_json(aStream, aTree);
+
+        for (const auto& rPair : aTree)
+        {
+            aArgs[OUString::fromUtf8(rPair.first.c_str())]
+                = OUString::fromUtf8(rPair.second.get_value<std::string>(".").c_str());
+        }
+    }
+    return aArgs;
+}
+
 bool ExecuteAction(sal_uInt64 nWindowId, const OString& rWidget, StringMap& rData)
 {
     weld::Widget* pWidget = JSInstanceBuilder::FindWeldWidgetsMap(nWindowId, rWidget);
@@ -143,6 +163,38 @@ bool ExecuteAction(sal_uInt64 nWindowId, const OString& rWidget, StringMap& rDat
                 }
             }
         }
+        else if (sControlType == "treeview")
+        {
+            auto pTreeView = dynamic_cast<weld::TreeView*>(pWidget);
+            if (pTreeView)
+            {
+                if (sAction == "change")
+                {
+                    OUString sDataJSON = rtl::Uri::decode(
+                        rData["data"], rtl_UriDecodeMechanism::rtl_UriDecodeWithCharset,
+                        RTL_TEXTENCODING_UTF8);
+                    StringMap aMap(jsonToStringMap(
+                        OUStringToOString(sDataJSON, RTL_TEXTENCODING_ASCII_US).getStr()));
+
+                    OString nRowString = OUStringToOString(aMap["row"], RTL_TEXTENCODING_ASCII_US);
+                    int nRow = std::atoi(nRowString.getStr());
+                    bool bValue = aMap["value"] == "true";
+
+                    pTreeView->set_toggle(nRow, bValue ? TRISTATE_TRUE : TRISTATE_FALSE);
+
+                    return true;
+                }
+                else if (sAction == "select")
+                {
+                    OString nRowString
+                        = OUStringToOString(rData["data"], RTL_TEXTENCODING_ASCII_US);
+                    int nRow = std::atoi(nRowString.getStr());
+
+                    pTreeView->select(nRow);
+                    LOKTrigger::trigger_row_activated(*pTreeView);
+                }
+            }
+        }
     }
 
     return false;
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index 88e2b9cc6eee..f2bc205d8b88 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -22,6 +22,8 @@
 #include <vcl/toolbox.hxx>
 #include <vcl/toolkit/vclmedit.hxx>
 #include <boost/property_tree/json_parser.hpp>
+#include <vcl/toolkit/treelistentry.hxx>
+#include <vcl/jsdialog/executor.hxx>
 
 JSDialogNotifyIdle::JSDialogNotifyIdle(VclPtr<vcl::Window> aNotifierWindow,
                                        VclPtr<vcl::Window> aContentWindow, std::string sTypeOfJSON)
@@ -39,30 +41,42 @@ void JSDialogNotifyIdle::ForceUpdate() { m_bForce = true; }
 
 void JSDialogNotifyIdle::Invoke()
 {
-    try
+    if (!m_aNotifierWindow)
+        return;
+
+    const vcl::ILibreOfficeKitNotifier* pNotifier = m_aNotifierWindow->GetLOKNotifier();
+    if (pNotifier)
     {
-        if (!m_aNotifierWindow)
-            return;
+        tools::JsonWriter aJsonWriter;
+        m_aContentWindow->DumpAsPropertyTree(aJsonWriter);
+        aJsonWriter.put("id", m_aNotifierWindow->GetLOKWindowId());
+        aJsonWriter.put("jsontype", m_sTypeOfJSON);
 
-        const vcl::ILibreOfficeKitNotifier* pNotifier = m_aNotifierWindow->GetLOKNotifier();
-        if (pNotifier)
+        if (m_sTypeOfJSON == "autofilter")
         {
-            tools::JsonWriter aJsonWriter;
-            m_aContentWindow->DumpAsPropertyTree(aJsonWriter);
-            aJsonWriter.put("id", m_aNotifierWindow->GetLOKWindowId());
-            aJsonWriter.put("jsontype", m_sTypeOfJSON);
-            if (m_bForce || !aJsonWriter.isDataEquals(m_LastNotificationMessage))
+            vcl::Window* pWindow = m_aContentWindow.get();
+            DockingWindow* pDockingWIndow = dynamic_cast<DockingWindow*>(pWindow);
+            while (pWindow && !pDockingWIndow)
+            {
+                pWindow = pWindow->GetParent();
+                pDockingWIndow = dynamic_cast<DockingWindow*>(pWindow);
+            }
+
+            if (pDockingWIndow)
             {
-                m_bForce = false;
-                m_LastNotificationMessage = aJsonWriter.extractAsStdString();
-                pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG,
-                                                      m_LastNotificationMessage.c_str());
+                Point aPos = pDockingWIndow->GetFloatingPos();
+                aJsonWriter.put("posx", aPos.getX());
+                aJsonWriter.put("posy", aPos.getY());
             }
         }
-    }
-    catch (boost::property_tree::json_parser::json_parser_error& rError)
-    {
-        SAL_WARN("vcl", rError.message());
+
+        if (m_bForce || !aJsonWriter.isDataEquals(m_LastNotificationMessage))
+        {
+            m_bForce = false;
+            m_LastNotificationMessage = aJsonWriter.extractAsStdString();
+            pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG,
+                                                  m_LastNotificationMessage.c_str());
+        }
     }
 }
 
@@ -412,6 +426,20 @@ std::unique_ptr<weld::TextView> JSInstanceBuilder::weld_text_view(const OString&
     return pWeldWidget;
 }
 
+std::unique_ptr<weld::TreeView> JSInstanceBuilder::weld_tree_view(const OString& id)
+{
+    SvTabListBox* pTreeView = m_xBuilder->get<SvTabListBox>(id);
+    auto pWeldWidget = pTreeView
+                           ? std::make_unique<JSTreeView>(GetNotifierWindow(), GetContentWindow(),
+                                                          pTreeView, this, false, m_sTypeOfJSON)
+                           : nullptr;
+
+    if (pWeldWidget)
+        RememberWidget(id, pWeldWidget.get());
+
+    return pWeldWidget;
+}
+
 weld::MessageDialog* JSInstanceBuilder::CreateMessageDialog(weld::Widget* pParent,
                                                             VclMessageType eMessageType,
                                                             VclButtonsType eButtonType,
@@ -693,4 +721,45 @@ void JSTextView::set_text(const OUString& rText)
     notifyDialogState();
 }
 
+JSTreeView::JSTreeView(VclPtr<vcl::Window> aNotifierWindow, VclPtr<vcl::Window> aContentWindow,
+                       ::SvTabListBox* pTreeView, SalInstanceBuilder* pBuilder, bool bTakeOwnership,
+                       std::string sTypeOfJSON)
+    : JSWidget<SalInstanceTreeView, ::SvTabListBox>(aNotifierWindow, aContentWindow, pTreeView,
+                                                    pBuilder, bTakeOwnership, sTypeOfJSON)
+{
+}
+
+void JSTreeView::set_toggle(int pos, TriState eState, int col)
+{
+    SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, 0);
+
+    while (pEntry && pos--)
+        pEntry = m_xTreeView->Next(pEntry);
+
+    if (pEntry)
+        SalInstanceTreeView::set_toggle(pEntry, eState, col);
+}
+
+void JSTreeView::select(int pos)
+{
+    assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
+    disable_notify_events();
+    if (pos == -1 || (pos == 0 && n_children() == 0))
+        m_xTreeView->SelectAll(false);
+    else
+    {
+        SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, 0);
+
+        while (pEntry && pos--)
+            pEntry = m_xTreeView->Next(pEntry);
+
+        if (pEntry)
+        {
+            m_xTreeView->Select(pEntry, true);
+            m_xTreeView->MakeVisible(pEntry);
+        }
+    }
+    enable_notify_events();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */


More information about the Libreoffice-commits mailing list