desktop/source/lib/init.cxx | 27 +++++++++++++++++++++++++++ include/vcl/svapp.hxx | 7 +++++++ vcl/inc/salinst.hxx | 4 ++++ vcl/source/window/builder.cxx | 35 +++++++++++++++++++++++++++++++++-- 4 files changed, 71 insertions(+), 2 deletions(-)
New commits: commit b749f045bc85b59c4c21774782c6c99a5f035bb2 Author: Caolán McNamara <[email protected]> AuthorDate: Mon Dec 8 12:11:41 2025 +0000 Commit: Caolán McNamara <[email protected]> CommitDate: Wed Dec 10 16:08:55 2025 +0100 put the uicoverage into the first level json i.e. don't put json into json Change-Id: I5606c0d280e7f8c3c08cc21e1bc62689de7422bf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195226 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195315 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 4956371df9f8..ca25346f9b2a 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -5615,7 +5615,7 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma tools::JsonWriter aJson; aJson.put("commandName", aCommand); aJson.put("success", true); - aJson.put("result", Application::UICoverageReport()); + Application::UICoverageReport(aJson); pDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.finishAndGetAsOString()); } } diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx index 2bfbc02a104f..5b4e079c958e 100644 --- a/include/vcl/svapp.hxx +++ b/include/vcl/svapp.hxx @@ -45,6 +45,7 @@ class Bitmap; +namespace tools { class JsonWriter; } namespace weld { class Builder; @@ -1241,7 +1242,7 @@ public: static void EnableUICoverage(bool bEnable); /** Report on what .ui files were used*/ - static OString UICoverageReport(); + static void UICoverageReport(tools::JsonWriter& rJson); ///@} diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx index f73a8b444653..30e881eacb07 100644 --- a/vcl/source/window/builder.cxx +++ b/vcl/source/window/builder.cxx @@ -194,18 +194,16 @@ void Application::EnableUICoverage(bool bEnable) ImplGetSVData()->mpDefInst->getUsedUIList().clear(); } -OString Application::UICoverageReport() +void Application::UICoverageReport(tools::JsonWriter& rJson) { - tools::JsonWriter aJson; + auto resultNode = rJson.startNode("result"); const auto& entries = ImplGetSVData()->mpDefInst->getUsedUIList(); { - auto childrenNode = aJson.startArray("used"); + auto childrenNode = rJson.startArray("used"); for (const auto& entry : entries) - aJson.putSimpleValue(entry); + rJson.putSimpleValue(entry); } - - return aJson.finishAndGetAsOString(); } std::unique_ptr<weld::Builder> Application::CreateBuilder(weld::Widget* pParent, const OUString &rUIFile, bool bMobile, sal_uInt64 nLOKWindowId) commit be0e1382a6964a3edc62d9b3317eef9170eb588a Author: Caolán McNamara <[email protected]> AuthorDate: Fri Dec 5 20:22:22 2025 +0000 Commit: Caolán McNamara <[email protected]> CommitDate: Wed Dec 10 16:08:46 2025 +0100 Collect .ui use coverage information bootstrap reporting of what .ui files were used in a session. Change-Id: I19b004482a3892898a9738e5e98ee084ab8cdcec Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195113 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195314 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 47b4e4e56cbd..4956371df9f8 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -5602,6 +5602,33 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma hideSidebar(); return; } + else if (gImpl && aCommand == ".uno:UICoverage") + { + for (const beans::PropertyValue& rPropValue : aPropertyValuesVector) + { + if (rPropValue.Name == "Report") + { + bool report(true); + rPropValue.Value >>= report; + if (report) + { + tools::JsonWriter aJson; + aJson.put("commandName", aCommand); + aJson.put("success", true); + aJson.put("result", Application::UICoverageReport()); + pDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.finishAndGetAsOString()); + } + } + else if (rPropValue.Name == "Track") + { + bool track(false); + rPropValue.Value >>= track; + Application::EnableUICoverage(track); + } + } + + return; + } if (aCommand != ".uno:Save") { diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx index 43cb3f9535b0..2bfbc02a104f 100644 --- a/include/vcl/svapp.hxx +++ b/include/vcl/svapp.hxx @@ -1237,6 +1237,12 @@ public: /** Determines if safe mode is enabled */ static bool IsSafeModeEnabled(); + /** Collect what .ui files are used*/ + static void EnableUICoverage(bool bEnable); + + /** Report on what .ui files were used*/ + static OString UICoverageReport(); + ///@} /** Get the desktop environment the process is currently running in diff --git a/vcl/inc/salinst.hxx b/vcl/inc/salinst.hxx index 359cf21226be..65b64125697b 100644 --- a/vcl/inc/salinst.hxx +++ b/vcl/inc/salinst.hxx @@ -20,6 +20,7 @@ #pragma once #include <sal/types.h> +#include <o3tl/sorted_vector.hxx> #include <rtl/ref.hxx> #include <vcl/ColorDialog.hxx> #include <vcl/dllapi.h> @@ -81,6 +82,7 @@ private: rtl::Reference< vcl::DisplayConnectionDispatch > m_pEventInst; const std::unique_ptr<comphelper::SolarMutex> m_pYieldMutex; css::uno::Reference<css::datatransfer::clipboard::XClipboard> m_clipboard; + o3tl::sorted_vector<OUString> m_usedUI; protected: bool m_bSupportsOpenGL = false; @@ -95,6 +97,8 @@ public: bool supportsOpenGL() const { return m_bSupportsOpenGL; } + o3tl::sorted_vector<OUString>& getUsedUIList() { return m_usedUI; } + //called directly after Application::Init virtual void AfterAppInit() {} virtual bool SVMainHook(int*) { return false; } diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx index df072d404ca3..f73a8b444653 100644 --- a/vcl/source/window/builder.cxx +++ b/vcl/source/window/builder.cxx @@ -185,8 +185,36 @@ namespace } +static bool bEnableUICoverage = false; + +void Application::EnableUICoverage(bool bEnable) +{ + bEnableUICoverage = bEnable; + if (!bEnableUICoverage) + ImplGetSVData()->mpDefInst->getUsedUIList().clear(); +} + +OString Application::UICoverageReport() +{ + tools::JsonWriter aJson; + + const auto& entries = ImplGetSVData()->mpDefInst->getUsedUIList(); + { + auto childrenNode = aJson.startArray("used"); + for (const auto& entry : entries) + aJson.putSimpleValue(entry); + } + + return aJson.finishAndGetAsOString(); +} + std::unique_ptr<weld::Builder> Application::CreateBuilder(weld::Widget* pParent, const OUString &rUIFile, bool bMobile, sal_uInt64 nLOKWindowId) { + ImplSVData* pSVData = ImplGetSVData(); + + if (bEnableUICoverage) + pSVData->mpDefInst->getUsedUIList().insert(rUIFile); + if (comphelper::LibreOfficeKit::isActive() && !jsdialog::isIgnored(rUIFile)) { if (jsdialog::isBuilderEnabledForSidebar(rUIFile)) @@ -208,11 +236,16 @@ std::unique_ptr<weld::Builder> Application::CreateBuilder(weld::Widget* pParent, SAL_WARN("vcl", "UI file not enabled for JSDialogs: " << rUIFile); } - return ImplGetSVData()->mpDefInst->CreateBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile); + return pSVData->mpDefInst->CreateBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile); } std::unique_ptr<weld::Builder> Application::CreateInterimBuilder(vcl::Window* pParent, const OUString &rUIFile, bool bAllowCycleFocusOut, sal_uInt64 nLOKWindowId) { + ImplSVData* pSVData = ImplGetSVData(); + + if (bEnableUICoverage) + pSVData->mpDefInst->getUsedUIList().insert(rUIFile); + if (comphelper::LibreOfficeKit::isActive() && !jsdialog::isIgnored(rUIFile)) { // Notebookbar sub controls @@ -228,7 +261,7 @@ std::unique_ptr<weld::Builder> Application::CreateInterimBuilder(vcl::Window* pP SAL_WARN("vcl", "UI file not enabled for JSDialogs: " << rUIFile); } - return ImplGetSVData()->mpDefInst->CreateInterimBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile, bAllowCycleFocusOut, nLOKWindowId); + return pSVData->mpDefInst->CreateInterimBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile, bAllowCycleFocusOut, nLOKWindowId); } weld::MessageDialog* Application::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType,
