summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorSzymon Kłos <szymon.klos@collabora.com>2020-10-30 10:51:08 +0100
committerSzymon Kłos <szymon.klos@collabora.com>2020-11-25 15:46:32 +0100
commit0de158b4eb6d48d2c1a7cfcd638a73d7b69d45a7 (patch)
tree73277f49af609d2e052992c484a6890297c7bb8e /vcl
parentadb2e4e192392faef628f9c6b7e21e1cd63f2fcc (diff)
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@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/jsdialog/jsdialogbuilder.hxx23
-rw-r--r--vcl/inc/salvtables.hxx2
-rw-r--r--vcl/jsdialog/executor.cxx52
-rw-r--r--vcl/jsdialog/jsdialogbuilder.cxx105
4 files changed, 161 insertions, 21 deletions
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: */