include/tools/json_writer.hxx | 2 - include/vcl/weld.hxx | 14 ++++++++---- svx/source/inc/StylesPreviewWindow.hxx | 4 +-- svx/source/tbxctrls/StylesPreviewWindow.cxx | 31 ++++++++++++++-------------- vcl/inc/iconview.hxx | 6 +++-- vcl/inc/salvtables.hxx | 5 +++- vcl/source/app/salvtables.cxx | 20 ++++++++++++++++-- vcl/source/treelist/iconview.cxx | 7 ++---- vcl/unx/gtk3/gtkinst.cxx | 8 ++++++- 9 files changed, 63 insertions(+), 34 deletions(-)
New commits: commit c9d92e3a33e5f21ac2c72c58d49eeb138cece109 Author: Caolán McNamara <caolan.mcnam...@collabora.com> AuthorDate: Tue Jun 6 11:57:16 2023 +0100 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Tue Jun 6 20:39:47 2023 +0200 perf: we don't need to 'really' insert a preview when providing json if we have intercepting 'image' when generating the json, then we don't need to really insert the image into the server side TreeView at all, we just need to provide it in the client json payload. so we generate each bitmap once, and its base64 png representation once. Change-Id: I1b6916b036a0b84ef4346ebf2141240c4ae5b706 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152675 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/include/tools/json_writer.hxx b/include/tools/json_writer.hxx index 7c9b5b96a4b4..12b3eea25a8c 100644 --- a/include/tools/json_writer.hxx +++ b/include/tools/json_writer.hxx @@ -166,7 +166,5 @@ class ScopedJsonWriterStruct public: ~ScopedJsonWriterStruct() { mrWriter.endStruct(); } }; - -typedef std::tuple<JsonWriter&, const OUString&, std::string_view> json_prop_query; } /* 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 38df3cb5ea19..8d1b5cf7722f 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -70,7 +70,6 @@ typedef OutputDevice RenderContext; namespace tools { class JsonWriter; -typedef std::tuple<tools::JsonWriter&, const OUString&, std::string_view> json_prop_query; } class LOKTrigger; @@ -1383,6 +1382,8 @@ public: using Widget::get_sensitive; }; +typedef std::tuple<tools::JsonWriter&, const TreeIter&, std::string_view> json_prop_query; + class VCL_DLLPUBLIC IconView : virtual public Widget { friend class ::LOKTrigger; @@ -1395,6 +1396,7 @@ protected: Link<IconView&, bool> m_aItemActivatedHdl; Link<const CommandEvent&, bool> m_aCommandHdl; Link<const TreeIter&, OUString> m_aQueryTooltipHdl; + Link<const json_prop_query&, bool> m_aGetPropertyTreeElemHdl; void signal_selection_changed() { m_aSelectionChangeHdl.Call(*this); } bool signal_item_activated() { return m_aItemActivatedHdl.Call(*this); } @@ -1449,10 +1451,11 @@ public: m_aQueryTooltipHdl = rLink; } - // 0: json writer, 1: id, 2: property. returns true if supported - virtual void - connect_get_property_tree_elem(const Link<const tools::json_prop_query&, bool>& rLink) - = 0; + // 0: json writer, 1: TreeIter, 2: property. returns true if supported + virtual void connect_get_property_tree_elem(const Link<const json_prop_query&, bool>& rLink) + { + m_aGetPropertyTreeElemHdl = rLink; + } virtual OUString get_selected_id() const = 0; @@ -1473,6 +1476,7 @@ public: virtual void set_cursor(const TreeIter& rIter) = 0; virtual bool get_iter_first(TreeIter& rIter) const = 0; virtual OUString get_id(const TreeIter& rIter) const = 0; + virtual OUString get_text(const TreeIter& rIter) const = 0; virtual void scroll_to_item(const TreeIter& rIter) = 0; // call func on each selected element until func returns true or we run out of elements diff --git a/svx/source/inc/StylesPreviewWindow.hxx b/svx/source/inc/StylesPreviewWindow.hxx index 1d59c574bfbe..1e9b01a6df1b 100644 --- a/svx/source/inc/StylesPreviewWindow.hxx +++ b/svx/source/inc/StylesPreviewWindow.hxx @@ -112,7 +112,7 @@ protected: DECL_LINK(Selected, weld::IconView&, void); DECL_LINK(DoubleClick, weld::IconView&, bool); DECL_LINK(DoCommand, const CommandEvent&, bool); - DECL_STATIC_LINK(StylesPreviewWindow_Base, DoJsonProperty, const tools::json_prop_query&, bool); + DECL_LINK(DoJsonProperty, const weld::json_prop_query&, bool); public: StylesPreviewWindow_Base( @@ -123,7 +123,7 @@ public: void Select(const OUString& rStyleName); void RequestStylesListUpdate(); static VclPtr<VirtualDevice> GetCachedPreview(const std::pair<OUString, OUString>& rStyle); - static OString GetCachedPreviewJson(const OUString& rStyle); + static OString GetCachedPreviewJson(const std::pair<OUString, OUString>& rStyle); private: void UpdateStylesList(); diff --git a/svx/source/tbxctrls/StylesPreviewWindow.cxx b/svx/source/tbxctrls/StylesPreviewWindow.cxx index eeca3db49840..53a8f14511a9 100644 --- a/svx/source/tbxctrls/StylesPreviewWindow.cxx +++ b/svx/source/tbxctrls/StylesPreviewWindow.cxx @@ -20,6 +20,7 @@ #include <StylesPreviewWindow.hxx> #include <comphelper/base64.hxx> +#include <comphelper/lok.hxx> #include <comphelper/propertyvalue.hxx> #include <utility> #include <vcl/svapp.hxx> @@ -527,14 +528,16 @@ static OString extractPngString(const BitmapEx& rBitmap) return ""; } -// 0: json writer, 1: id, 2: property. returns true if supported -IMPL_STATIC_LINK(StylesPreviewWindow_Base, DoJsonProperty, const tools::json_prop_query&, rQuery, - bool) +// 0: json writer, 1: TreeIter, 2: property. returns true if supported +IMPL_LINK(StylesPreviewWindow_Base, DoJsonProperty, const weld::json_prop_query&, rQuery, bool) { if (std::get<2>(rQuery) != "image") return false; - OString sBase64Png(GetCachedPreviewJson(std::get<1>(rQuery))); + const weld::TreeIter& rIter = std::get<1>(rQuery); + OUString sStyleId(m_xStylesView->get_id(rIter)); + OUString sStyleName(m_xStylesView->get_text(rIter)); + OString sBase64Png(GetCachedPreviewJson(std::pair<OUString, OUString>(sStyleId, sStyleName))); if (sBase64Png.isEmpty()) return false; @@ -564,20 +567,16 @@ StylesPreviewWindow_Base::GetCachedPreview(const std::pair<OUString, OUString>& } } -OString StylesPreviewWindow_Base::GetCachedPreviewJson(const OUString& rStyle) +OString StylesPreviewWindow_Base::GetCachedPreviewJson(const std::pair<OUString, OUString>& rStyle) { - auto aJsonFound = StylePreviewCache::GetJson().find(rStyle); + auto aJsonFound = StylePreviewCache::GetJson().find(rStyle.second); if (aJsonFound != StylePreviewCache::GetJson().end()) - return StylePreviewCache::GetJson()[rStyle]; + return StylePreviewCache::GetJson()[rStyle.second]; - auto aFound = StylePreviewCache::Get().find(rStyle); - if (aFound == StylePreviewCache::Get().end()) - return ""; - - VclPtr<VirtualDevice> xDev = aFound->second; + VclPtr<VirtualDevice> xDev = GetCachedPreview(rStyle); BitmapEx aBitmap(xDev->GetBitmapEx(Point(0, 0), xDev->GetOutputSize())); OString sResult = extractPngString(aBitmap); - StylePreviewCache::GetJson()[rStyle] = sResult; + StylePreviewCache::GetJson()[rStyle.second] = sResult; return sResult; } @@ -608,10 +607,12 @@ void StylesPreviewWindow_Base::UpdateStylesList() m_xStylesView->freeze(); m_xStylesView->clear(); + // for online we can skip inserting the preview into the IconView and rely + // on DoJsonProperty to provide the image to clients + const bool bNeedInsertPreview = !comphelper::LibreOfficeKit::isActive(); for (const auto& rStyle : m_aAllStyles) { - VclPtr<VirtualDevice> pImg = GetCachedPreview(rStyle); - + VclPtr<VirtualDevice> pImg = bNeedInsertPreview ? GetCachedPreview(rStyle) : nullptr; m_xStylesView->append(rStyle.first, rStyle.second, pImg); } m_xStylesView->thaw(); diff --git a/vcl/inc/iconview.hxx b/vcl/inc/iconview.hxx index bc84a6ea436d..54c2681a9e79 100644 --- a/vcl/inc/iconview.hxx +++ b/vcl/inc/iconview.hxx @@ -48,7 +48,9 @@ public: virtual FactoryFunction GetUITestFactory() const override; virtual void DumpAsPropertyTree(tools::JsonWriter& rJsonWriter) override; - void SetDumpElemToPropertyTreeHdl(const Link<const tools::json_prop_query&, bool>& rLink) + typedef std::tuple<tools::JsonWriter&, SvTreeListEntry*, std::string_view> json_prop_query; + + void SetDumpElemToPropertyTreeHdl(const Link<const json_prop_query&, bool>& rLink) { maDumpElemToPropertyTreeHdl = rLink; } @@ -58,7 +60,7 @@ protected: private: Link<SvTreeListEntry*, OUString> maEntryAccessibleDescriptionHdl; - Link<const tools::json_prop_query&, bool> maDumpElemToPropertyTreeHdl; + Link<const json_prop_query&, bool> maDumpElemToPropertyTreeHdl; void DumpEntryAndSiblings(tools::JsonWriter& rJsonWriter, SvTreeListEntry* pEntry); }; diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index 65d9b4cb1a47..7ac28808ce3d 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -1921,6 +1921,7 @@ private: DECL_LINK(CommandHdl, const CommandEvent&, bool); DECL_LINK(TooltipHdl, SvTreeListEntry*, OUString); DECL_LINK(EntryAccessibleDescriptionHdl, SvTreeListEntry*, OUString); + DECL_LINK(DumpElemToPropertyTreeHdl, const ::IconView::json_prop_query&, bool); public: SalInstanceIconView(::IconView* pIconView, SalInstanceBuilder* pBuilder, bool bTakeOwnership); @@ -1943,7 +1944,7 @@ public: virtual void connect_query_tooltip(const Link<const weld::TreeIter&, OUString>& rLink) override; virtual void - connect_get_property_tree_elem(const Link<const tools::json_prop_query&, bool>& rLink) override; + connect_get_property_tree_elem(const Link<const weld::json_prop_query&, bool>& rLink) override; virtual OUString get_selected_id() const override; @@ -1974,6 +1975,8 @@ public: virtual OUString get_id(const weld::TreeIter& rIter) const override; + virtual OUString get_text(const weld::TreeIter& rIter) const override; + virtual void clear() override; virtual ~SalInstanceIconView() override; diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 1ea5c985ecc2..71308484ed63 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -5532,10 +5532,20 @@ void SalInstanceIconView::connect_query_tooltip(const Link<const weld::TreeIter& m_xIconView->SetTooltipHdl(LINK(this, SalInstanceIconView, TooltipHdl)); } +IMPL_LINK(SalInstanceIconView, DumpElemToPropertyTreeHdl, const ::IconView::json_prop_query&, + rQuery, bool) +{ + SvTreeListEntry* pEntry = std::get<1>(rQuery); + return m_aGetPropertyTreeElemHdl.Call(weld::json_prop_query( + std::get<0>(rQuery), SalInstanceTreeIter(pEntry), std::get<2>(rQuery))); +} + void SalInstanceIconView::connect_get_property_tree_elem( - const Link<const tools::json_prop_query&, bool>& rLink) + const Link<const weld::json_prop_query&, bool>& rLink) { - m_xIconView->SetDumpElemToPropertyTreeHdl(rLink); + weld::IconView::connect_get_property_tree_elem(rLink); + m_xIconView->SetDumpElemToPropertyTreeHdl( + LINK(this, SalInstanceIconView, DumpElemToPropertyTreeHdl)); } OUString SalInstanceIconView::get_selected_id() const @@ -5668,6 +5678,12 @@ OUString SalInstanceIconView::get_id(const weld::TreeIter& rIter) const return OUString(); } +OUString SalInstanceIconView::get_text(const weld::TreeIter& rIter) const +{ + const SalInstanceTreeIter& rVclIter = static_cast<const SalInstanceTreeIter&>(rIter); + return SvTabListBox::GetEntryText(rVclIter.iter, 0); +} + void SalInstanceIconView::clear() { disable_notify_events(); diff --git a/vcl/source/treelist/iconview.cxx b/vcl/source/treelist/iconview.cxx index 6ff3a3556967..bd4368e9a998 100644 --- a/vcl/source/treelist/iconview.cxx +++ b/vcl/source/treelist/iconview.cxx @@ -289,10 +289,9 @@ void IconView::DumpEntryAndSiblings(tools::JsonWriter& rJsonWriter, SvTreeListEn if (pIt) rJsonWriter.put("text", static_cast<const SvLBoxString*>(pIt)->GetText()); - const OUString* pId = static_cast<const OUString*>(pEntry->GetUserData()); - const bool bHandled = pId && maDumpElemToPropertyTreeHdl.IsSet() - && maDumpElemToPropertyTreeHdl.Call( - tools::json_prop_query(rJsonWriter, *pId, "image")); + const bool bHandled + = maDumpElemToPropertyTreeHdl.IsSet() + && maDumpElemToPropertyTreeHdl.Call(json_prop_query(rJsonWriter, pEntry, "image")); if (!bHandled) { pIt = pEntry->GetFirstItem(SvLBoxItemType::ContextBmp); diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index 9ba8d6caa8f8..60d6c6b12b3b 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -17035,7 +17035,7 @@ public: gtk_widget_set_has_tooltip(GTK_WIDGET(m_pIconView), true); } - virtual void connect_get_property_tree_elem(const Link<const tools::json_prop_query&, bool>& /*rLink*/) override + virtual void connect_get_property_tree_elem(const Link<const weld::json_prop_query&, bool>& /*rLink*/) override { //not implemented for the gtk variant } @@ -17255,6 +17255,12 @@ public: return get(rGtkIter.iter, m_nIdCol); } + virtual OUString get_text(const weld::TreeIter& rIter) const override + { + const GtkInstanceTreeIter& rGtkIter = static_cast<const GtkInstanceTreeIter&>(rIter); + return get(rGtkIter.iter, m_nTextCol); + } + virtual void disable_notify_events() override { g_signal_handler_block(m_pIconView, m_nSelectionChangedSignalId);