desktop/source/lib/init.cxx | 58 +++++++++++--------------------------- include/tools/json_writer.hxx | 2 + tools/source/misc/json_writer.cxx | 26 +++++++++++++++++ vcl/jsdialog/jsdialogbuilder.cxx | 3 - 4 files changed, 46 insertions(+), 43 deletions(-)
New commits: commit 178b15672b0e8b7f3a0ea1d6b2d46739b3c87f0e Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Fri May 19 13:45:22 2023 +0200 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Tue May 23 09:10:16 2023 +0200 jsdialog: lazy json generation when closing tab in dialog After profiling Writer -> Format -> Character dialog I found that full dialog update happens while creating the dialog as some of the tabs are destroyed. Instead of instant JSON generation we should add the message to the queue and send it in idle time. Problem is that we are closing the tab and it's builder so we will not be able to do it later. So using jsdialog::SendFullUpdate trigger update in parent dialog which shares the same WINDOW_ID. This behaviour can be tested in Highlight tab when switching between "Color" and "None". As previous solution was introduced for it in: commit 41a1a2f04301dc22b156b4e11767859e40473897 jsdialog: don't close dialog on tab page destroy Change-Id: I916250cf08d87c1109dc2db6dbbc1fbff7f48c07 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152008 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Szymon Kłos <szymon.k...@collabora.com> diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx index 359368f2a702..6944cc817af7 100644 --- a/vcl/jsdialog/jsdialogbuilder.cxx +++ b/vcl/jsdialog/jsdialogbuilder.cxx @@ -677,8 +677,7 @@ JSInstanceBuilder::~JSInstanceBuilder() // tab page closed -> refresh parent window if (m_bIsNestedBuilder && m_sTypeOfJSON == "dialog") { - sendFullUpdate(true); - flush(); + jsdialog::SendFullUpdate(std::to_string(m_nWindowId), "__DIALOG__"); } if (m_sTypeOfJSON == "popup") commit 9a8c2106aede982007e15bdb1d0f2764a5610dde Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Thu May 18 15:00:38 2023 +0200 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Tue May 23 09:07:48 2023 +0200 linking: api: use JsonWriter Change-Id: If5bf1897f1aef8db1672789cbee14b90cb96dc08 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151959 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Szymon Kłos <szymon.k...@collabora.com> diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 7da7aaad7444..1472bbeb6747 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -411,7 +411,7 @@ std::vector<beans::PropertyValue> desktop::jsonToPropertyValuesVector(const char return aArguments; } -static bool extractLinks(const uno::Reference< container::XNameAccess >& xLinks, bool subcontent, OUStringBuffer& jsonText) +static void extractLinks(const uno::Reference< container::XNameAccess >& xLinks, bool subcontent, tools::JsonWriter& aJson) { const uno::Sequence< OUString > aNames( xLinks->getElementNames() ); @@ -452,47 +452,27 @@ static bool extractLinks(const uno::Reference< container::XNameAccess >& xLinks, if (subcontent) { - jsonText.append("\""); - jsonText.append(aStrDisplayname); - jsonText.append("\": \""); - jsonText.append(aLink); - jsonText.append("\""); - if (i < nLinks-1) - { - jsonText.append(", "); - } + aJson.put(aStrDisplayname, aLink); } else { uno::Reference< lang::XServiceInfo > xSI( xTarget, uno::UNO_QUERY ); bIsTarget = xSI->supportsService( aProp_LinkTarget ); - if (i != 0) - { - if (!bIsTarget) - jsonText.append("}"); - if (i < nLinks) - { - jsonText.append(", "); - } - } - jsonText.append("\""); - jsonText.append(aStrDisplayname); - jsonText.append("\": "); if (bIsTarget) { - jsonText.append("\""); - jsonText.append(aLink); - jsonText.append("\""); + aJson.put(aStrDisplayname, aLink); continue; } - jsonText.append("{"); - } + else + { + std::unique_ptr<char[], o3tl::free_delete> pName(convertOUString(aStrDisplayname)); + auto aNode = aJson.startNode(pName.get()); - uno::Reference< document::XLinkTargetSupplier > xLTS( xTarget, uno::UNO_QUERY ); - if( xLTS.is() ) - { - extractLinks(xLTS->getLinks(), true, jsonText); + uno::Reference< document::XLinkTargetSupplier > xLTS( xTarget, uno::UNO_QUERY ); + if( xLTS.is() ) + extractLinks(xLTS->getLinks(), true, aJson); + } } } catch(...) @@ -501,7 +481,6 @@ static bool extractLinks(const uno::Reference< container::XNameAccess >& xLinks, } } } - return bIsTarget; } static void unoAnyToJson(tools::JsonWriter& rJson, const char * pNodeName, const uno::Any& anyItem) @@ -3144,15 +3123,12 @@ static char* lo_extractRequest(LibreOfficeKit* /*pThis*/, const char* pFilePath) if( xLTS.is() ) { - OUStringBuffer jsonText; - jsonText.append("{ \"Targets\": { "); - bool lastParentheses = extractLinks(xLTS->getLinks(), false, jsonText); - jsonText.append("} }"); - if (!lastParentheses) - jsonText.append(" }"); - - OUString res(jsonText.makeStringAndClear()); - return convertOUString(res); + tools::JsonWriter aJson; + { + auto aNode = aJson.startNode("Targets"); + extractLinks(xLTS->getLinks(), false, aJson); + } + return aJson.extractData(); } xComp->dispose(); } diff --git a/include/tools/json_writer.hxx b/include/tools/json_writer.hxx index 700e82b9a2c6..b8b47ddb2ef8 100644 --- a/include/tools/json_writer.hxx +++ b/include/tools/json_writer.hxx @@ -51,6 +51,8 @@ public: [[nodiscard]] ScopedJsonWriterArray startArray(const char*); [[nodiscard]] ScopedJsonWriterStruct startStruct(); + void put(const OUString& pPropName, const OUString& rPropValue); + void put(const char* pPropName, const OUString& rPropValue); // Assumes utf-8 property value encoding void put(const char* pPropName, std::string_view rPropValue); diff --git a/tools/source/misc/json_writer.cxx b/tools/source/misc/json_writer.cxx index aea89a15d421..5bc718608d6a 100644 --- a/tools/source/misc/json_writer.cxx +++ b/tools/source/misc/json_writer.cxx @@ -231,6 +231,32 @@ void JsonWriter::writeEscapedOUString(const OUString& rPropVal) validate(); } +void JsonWriter::put(const OUString& pPropName, const OUString& rPropVal) +{ + auto nPropNameLength = pPropName.getLength(); + // But values can be any UTF-8, + // if the string only contains of 0x2028, it will be expanded 6 times (see writeEscapedSequence) + auto nWorstCasePropValLength = rPropVal.getLength() * 6; + ensureSpace(nPropNameLength + nWorstCasePropValLength + 8); + + addCommaBeforeField(); + + *mPos = '"'; + ++mPos; + + writeEscapedOUString(pPropName); + + memcpy(mPos, "\": \"", 4); + mPos += 4; + + writeEscapedOUString(rPropVal); + + *mPos = '"'; + ++mPos; + + validate(); +} + void JsonWriter::put(const char* pPropName, const OUString& rPropVal) { auto nPropNameLength = strlen(pPropName);