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 bc44bc450df0826aa1e7257fbc42ec8ff9466c56 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 14:57:12 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/+/152674 Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/include/tools/json_writer.hxx b/include/tools/json_writer.hxx index fd19e933e093..ae9664b2da67 100644 --- a/include/tools/json_writer.hxx +++ b/include/tools/json_writer.hxx @@ -164,7 +164,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 07e12dff294d..618f9a518a8e 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; @@ -1371,6 +1370,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; @@ -1383,6 +1384,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); } @@ -1437,10 +1439,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; @@ -1461,6 +1464,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 8eb16ba3901e..76a085bce5c2 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 4f4be2ee5dff..f4dd77dd4fb5 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 7e33cbdbbd5b..bfd3259e48fc 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -1912,6 +1912,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); @@ -1934,7 +1935,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; @@ -1965,6 +1966,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 87a6722ca168..103a266361c5 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -5518,10 +5518,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 @@ -5654,6 +5664,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 1b5b87c26c0f..acdad73a9505 100644 --- a/vcl/source/treelist/iconview.cxx +++ b/vcl/source/treelist/iconview.cxx @@ -293,10 +293,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 9e38d781d204..428f0f5ae357 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -16978,7 +16978,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 } @@ -17206,6 +17206,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);