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>
This commit is contained in:
parent
adb2e4e192
commit
0de158b4eb
@ -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)
|
||||
{
|
||||
|
@ -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: */
|
||||
|
@ -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;
|
||||
|
@ -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: */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
if (!m_aNotifierWindow)
|
||||
return;
|
||||
|
||||
const vcl::ILibreOfficeKitNotifier* pNotifier = m_aNotifierWindow->GetLOKNotifier();
|
||||
if (pNotifier)
|
||||
const vcl::ILibreOfficeKitNotifier* pNotifier = m_aNotifierWindow->GetLOKNotifier();
|
||||
if (pNotifier)
|
||||
{
|
||||
tools::JsonWriter aJsonWriter;
|
||||
m_aContentWindow->DumpAsPropertyTree(aJsonWriter);
|
||||
aJsonWriter.put("id", m_aNotifierWindow->GetLOKWindowId());
|
||||
aJsonWriter.put("jsontype", m_sTypeOfJSON);
|
||||
|
||||
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)
|
||||
{
|
||||
m_bForce = false;
|
||||
m_LastNotificationMessage = aJsonWriter.extractAsStdString();
|
||||
pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG,
|
||||
m_LastNotificationMessage.c_str());
|
||||
pWindow = pWindow->GetParent();
|
||||
pDockingWIndow = dynamic_cast<DockingWindow*>(pWindow);
|
||||
}
|
||||
|
||||
if (pDockingWIndow)
|
||||
{
|
||||
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: */
|
||||
|
Loading…
x
Reference in New Issue
Block a user