download.lst | 4 filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu | 2 include/sfx2/sidebar/ResourceManager.hxx | 9 readlicense_oo/license/license.xml | 28 +- sc/qa/unit/data/ods/tdf123225_pivotTable_empty_row_col_items.ods |binary sc/qa/unit/data/ods/tdf123225_pivotTable_no_col_items.ods |binary sc/qa/unit/pivottable_filters_test.cxx | 99 +++++++++- sc/source/filter/excel/xepivotxml.cxx | 53 ++++- sc/source/ui/inc/viewfunc.hxx | 3 sc/source/ui/view/formatsh.cxx | 9 sc/source/ui/view/viewfunc.cxx | 10 - sfx2/source/sidebar/ResourceManager.cxx | 24 ++ sfx2/source/sidebar/SidebarController.cxx | 33 ++- svl/source/crypto/cryptosign.cxx | 54 +++-- svx/uiconfig/ui/themecoloreditdialog.ui | 3 sw/inc/ndtxt.hxx | 5 sw/inc/node.hxx | 2 sw/qa/core/txtnode/data/node-split-style-list-level.odt |binary sw/qa/core/txtnode/txtnode.cxx | 24 ++ sw/qa/extras/ooxmlexport/data/tdf165059_broken.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport21.cxx | 23 +- sw/source/core/docnode/node.cxx | 2 sw/source/core/txtnode/ndtxt.cxx | 45 +++- sw/source/filter/ww8/docxattributeoutput.cxx | 15 + vcl/source/control/combobox.cxx | 10 - vcl/source/control/listbox.cxx | 10 - 26 files changed, 362 insertions(+), 105 deletions(-)
New commits: commit d98a3785f907976eba985f95757a4010f1fbca4b Author: Andras Timar <andras.ti...@collabora.com> AuthorDate: Sun Mar 23 09:13:56 2025 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 24 13:50:54 2025 +0100 Update license text of Python (see https://docs.python.org/3/license.html) Change-Id: I8963b4d88ae6bbdf0e31aca12a0803f249778b42 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183234 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/readlicense_oo/license/license.xml b/readlicense_oo/license/license.xml index 74b070a1e696..07b0d25ede4a 100644 --- a/readlicense_oo/license/license.xml +++ b/readlicense_oo/license/license.xml @@ -1740,25 +1740,25 @@ <h2>Python</h2> <p>The following software may be included in this product: Python. Use of any of this software is governed by the terms of the license below:</p> - <h3>PSF LICENSE AGREEMENT FOR PYTHON 2.3</h3> + <h3>PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2</h3> <p>1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or - Organization ("Licensee") accessing and otherwise using Python 2.3 software in source or binary form and its - associated documentation.</p> + Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and + its associated documentation.</p> <p>2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare - derivative works, distribute, and otherwise use Python 2.3 alone or in any derivative version, provided, - however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, - 2004 Python Software Foundation; All Rights Reserved" are retained in Python 2.3 alone or in any derivative - version prepared by Licensee.</p> - <p>3. In the event Licensee prepares a derivative work that is based on or incorporates Python 2.3 or any part + derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, + however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright © 2001-2024 Python + Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared + by Licensee.</p> + <p>3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby - agrees to include in any such work a brief summary of the changes made to Python 2.3.</p> - <p>4. PSF is making Python 2.3 available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR + agrees to include in any such work a brief summary of the changes made to Python.</p> + <p>4. PSF is making Python available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON - 2.3 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.</p> - <p>5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.3 FOR ANY INCIDENTAL, SPECIAL, OR - CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3, OR ANY + WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.</p> + <p>5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON FOR ANY INCIDENTAL, SPECIAL, OR + CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.</p> <p>6. This License Agreement will automatically terminate upon a material breach of its terms and conditions.</p> @@ -1766,7 +1766,7 @@ joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party.</p> - <p>8. By copying, installing or otherwise using Python 2.3, Licensee agrees to be bound by the terms and + <p>8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this License Agreement.</p> <p>BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0</p> <p>BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1</p> commit f094f6a17695b0a7884d4acaa8d350eaaa9fc3d8 Author: Justin Luth <jl...@mail.com> AuthorDate: Sat Mar 22 13:15:10 2025 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 24 13:50:54 2025 +0100 Revert "tdf#164201 docx convert-to: prefer Word 2010–365 Document, not 2007" This reverts 24.04 commit 858c452e5e6b7acad6932df7d1cd2f0950d47f33 on the 24.04 branch only. It is fine to remain on 25.04. Reason for revert: There is a follow-up commit in bug 164201 that is necessary for Microsoft to be able to fully read the document. That necessary piece is only in 25.04. Making this seemingly simple change has a lot more implications than expected (primarily by Microsoft not being able to read files created according to their own specs). So I am not comfortable recommending that it be backported to our stable 24.04. It was originally backported primarily to benefit mso-test - not a compelling reason to hang on to it. The specific problem that lead to the follow-up commit was the loss of create/modified date/time fields (seen only in MS Word). The specific problem that lead to this revert is content controls only showing the placeholder text, and not the real text (seen only in MS Word). Change-Id: I2e3d0e835282938dff86d80b17b8bb22958a0622 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183223 Reviewed-by: Justin Luth <jl...@mail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu b/filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu index e163be7cafa2..11396057a026 100644 --- a/filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu +++ b/filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu @@ -20,7 +20,7 @@ <prop oor:name="URLPattern"/> <prop oor:name="Extensions"><value>docx</value></prop> <prop oor:name="MediaType"><value>application/msword</value></prop> - <prop oor:name="Preferred"><value>false</value></prop> + <prop oor:name="Preferred"><value>true</value></prop> <prop oor:name="PreferredFilter"><value>MS Word 2007 XML</value></prop> <prop oor:name="UIName"><value xml:lang="en-US">Word 2007</value></prop> <prop oor:name="ClipboardFormat"><value>MSWordDoc</value></prop> commit 4bd3bdff9e4cc5397bc1302b662bf744854f994f Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Wed Mar 12 17:30:33 2025 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 24 13:50:54 2025 +0100 lok: sidebar: do not remember last active It is done in lok client, do not introduce additional state in core part. Also config modification is costly so good to avoid. There was rule to always open ElementsDeck in Formula context. Move it to a dedicated map with overrides. We need to not skip context updates when enters OLE second time. Introduced in commit 81055959e06848c917c4df1e4f19e1e5c6e70684 lok: Avoid redundant call to UpdateConfigurations But it has negative performance impact - causing to switch decks on every key press when 2 users are typing. Signed-off-by: Szymon Kłos <szymon.k...@collabora.com> Change-Id: Ie20181db013a2b7ea1cbb8245b301e55260b8c0d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183035 Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/include/sfx2/sidebar/ResourceManager.hxx b/include/sfx2/sidebar/ResourceManager.hxx index 9ac1130cc29b..c3ea9abbc940 100644 --- a/include/sfx2/sidebar/ResourceManager.hxx +++ b/include/sfx2/sidebar/ResourceManager.hxx @@ -20,6 +20,7 @@ #include <unotools/confignode.hxx> #include <map> +#include <vcl/EnumContext.hxx> #include <vector> #include <set> @@ -89,6 +90,11 @@ public: const css::uno::Reference<css::frame::XController>& rxController); const OUString& GetLastActiveDeck( const Context& rContext ); + const std::map<OUString, OUString>& GetDeckOverrides() { + if (maApplicationDeckOverrides.empty()) + SetupOverrides(); + return maApplicationDeckOverrides; + } void SetLastActiveDeck( const Context& rContext, const OUString& rsDeckId ); /** Remember the expansions state per panel and context. @@ -107,10 +113,13 @@ private: PanelContainer maPanels; mutable std::set<OUString> maProcessedApplications; std::map<OUString, OUString> maLastActiveDecks; + // always jump to Deck on Application type, override last used + std::map<OUString, OUString> maApplicationDeckOverrides; void ReadDeckList(); void ReadPanelList(); void ReadLastActive(); + void SetupOverrides(); static void ReadContextList(const utl::OConfigurationNode& rNode, ContextList& rContextList, const OUString& rsDefaultMenuCommand); diff --git a/sfx2/source/sidebar/ResourceManager.cxx b/sfx2/source/sidebar/ResourceManager.cxx index 433cd5091f31..9260438ad62c 100644 --- a/sfx2/source/sidebar/ResourceManager.cxx +++ b/sfx2/source/sidebar/ResourceManager.cxx @@ -33,7 +33,6 @@ #include <comphelper/diagnose_ex.hxx> #include <sal/log.hxx> -#include <vcl/EnumContext.hxx> #include <o3tl/string_view.hxx> #include <com/sun/star/frame/ModuleManager.hpp> @@ -237,6 +236,7 @@ const ResourceManager::PanelContextDescriptorContainer& ResourceManager::GetMatc const OUString& ResourceManager::GetLastActiveDeck( const Context& rContext ) { + assert(!comphelper::LibreOfficeKit::isActive()); if( maLastActiveDecks.find( rContext.msApplication ) == maLastActiveDecks.end()) return maLastActiveDecks["any"]; else @@ -245,6 +245,7 @@ const OUString& ResourceManager::GetLastActiveDeck( const Context& rContext ) void ResourceManager::SetLastActiveDeck( const Context& rContext, const OUString &rsDeckId ) { + assert(!comphelper::LibreOfficeKit::isActive()); maLastActiveDecks[rContext.msApplication] = rsDeckId; } @@ -299,6 +300,9 @@ void ResourceManager::ReadDeckList() void ResourceManager::SaveDecksSettings(const Context& rContext) { + if (comphelper::LibreOfficeKit::isActive()) + return; + for (auto const& deck : maDecks) { const ContextList::Entry* pMatchingEntry = deck->maContextList.GetMatch(rContext); @@ -403,6 +407,9 @@ void ResourceManager::SaveDeckSettings(const DeckDescriptor* pDeckDesc) void ResourceManager::SaveLastActiveDeck(const Context& rContext, const OUString& rActiveDeck) { + if (comphelper::LibreOfficeKit::isActive()) + return; + maLastActiveDecks[rContext.msApplication] = rActiveDeck; std::set<OUString> aLastActiveDecks; @@ -467,6 +474,9 @@ void ResourceManager::ReadPanelList() void ResourceManager::ReadLastActive() { + if (comphelper::LibreOfficeKit::isActive()) + return; + const Sequence <OUString> aLastActive (officecfg::Office::UI::Sidebar::Content::LastActiveDeck::get()); for (const auto& rDeckInfo : aLastActive) @@ -488,9 +498,15 @@ void ResourceManager::ReadLastActive() } // Set up a default for Math - will do nothing if already set - maLastActiveDecks.emplace( - vcl::EnumContext::GetApplicationName(vcl::EnumContext::Application::Formula), - "ElementsDeck"); + for (const auto& aOverrideDeck : GetDeckOverrides()) + maLastActiveDecks.emplace(aOverrideDeck.first, aOverrideDeck.second); +} + +void ResourceManager::SetupOverrides() +{ + maApplicationDeckOverrides = { + { vcl::EnumContext::GetApplicationName(vcl::EnumContext::Application::Formula), "ElementsDeck" } + }; } void ResourceManager::ReadContextList ( diff --git a/sfx2/source/sidebar/SidebarController.cxx b/sfx2/source/sidebar/SidebarController.cxx index 805514a7871f..313a7323e665 100644 --- a/sfx2/source/sidebar/SidebarController.cxx +++ b/sfx2/source/sidebar/SidebarController.cxx @@ -361,8 +361,12 @@ void SAL_CALL SidebarController::notifyContextChangeEvent (const css::ui::Contex maContextChangeUpdate.RequestCall(); // async call, not a prob // calling with held // solarmutex - // TODO: this call is redundant but mandatory for unit test to update context on document loading - if (!comphelper::LibreOfficeKit::isActive()) + + bool bSwitchedApp = maRequestedContext.msApplication != maCurrentContext.msApplication; + // Happens on reattach of sidebar to frame or context change + // LOK performance impact: prevents to switch sidebar on every keypress in multi user case + // Allow when enters embedded OLE (eg. Math formula editor second time) + if (!comphelper::LibreOfficeKit::isActive() || bSwitchedApp) UpdateConfigurations(); } } @@ -549,8 +553,10 @@ void SidebarController::UpdateConfigurations() && mnRequestedForceFlags == SwitchFlag_NoForce) return; - if ((maCurrentContext.msApplication != "none") && - !maCurrentContext.msApplication.isEmpty()) + bool bIsLOK = comphelper::LibreOfficeKit::isActive(); + + if (!bIsLOK && maCurrentContext.msApplication != "none" && + !maCurrentContext.msApplication.isEmpty()) { mpResourceManager->SaveDecksSettings(maCurrentContext); mpResourceManager->SetLastActiveDeck(maCurrentContext, msCurrentDeckId); @@ -558,11 +564,22 @@ void SidebarController::UpdateConfigurations() // get last active deck for this application on first update if (!maRequestedContext.msApplication.isEmpty() && - (maCurrentContext.msApplication != maRequestedContext.msApplication)) + (maCurrentContext.msApplication != maRequestedContext.msApplication)) { - OUString sLastActiveDeck = mpResourceManager->GetLastActiveDeck( maRequestedContext ); - if (!sLastActiveDeck.isEmpty()) - msCurrentDeckId = sLastActiveDeck; + if (bIsLOK) + { + // LOK has no last-used memory + const auto& rOverrides = mpResourceManager->GetDeckOverrides(); + const auto aOverride = rOverrides.find(maRequestedContext.msApplication); + if (aOverride != rOverrides.end()) + msCurrentDeckId = aOverride->second; + } + else + { + OUString sLastActiveDeck = mpResourceManager->GetLastActiveDeck( maRequestedContext ); + if (!sLastActiveDeck.isEmpty()) + msCurrentDeckId = sLastActiveDeck; + } } maCurrentContext = maRequestedContext; commit 39b7a37bbd55a1ea954f2d4155ac285116b55ce9 Author: Heiko Tietze <tietze.he...@gmail.com> AuthorDate: Tue Apr 23 15:45:20 2024 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 24 13:50:54 2025 +0100 Resolves tdf#160050 - Overlapping controls in 'add themes' dialog (cherry picked from commit 8f3a19ce3a2dea548f644a8925bfe0718424ac21) Change-Id: I196ef4b445dcae5d6fc9891c8f9c0d0b2976d583 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183112 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/svx/uiconfig/ui/themecoloreditdialog.ui b/svx/uiconfig/ui/themecoloreditdialog.ui index 96276093a75a..ac0114ab4be1 100644 --- a/svx/uiconfig/ui/themecoloreditdialog.ui +++ b/svx/uiconfig/ui/themecoloreditdialog.ui @@ -3,13 +3,12 @@ <interface domain="svx"> <requires lib="gtk+" version="3.20"/> <object class="GtkDialog" id="ThemeColorEditDialog"> - <property name="width-request">400</property> - <property name="height-request">300</property> <property name="can-focus">False</property> <property name="hexpand">True</property> <property name="vexpand">True</property> <property name="border-width">6</property> <property name="title" translatable="yes" context="themedialog|Title">Theme Color Edit</property> + <property name="resizable">False</property> <property name="modal">True</property> <property name="type-hint">dialog</property> <child internal-child="vbox"> commit 59cd8ce02ce5a1c1d847591fa52fdc9d58306130 Author: Juraj Šarinay <ju...@sarinay.com> AuthorDate: Thu Mar 6 16:44:01 2025 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 24 13:50:54 2025 +0100 Improve adbe.pkcs7.sha1 signature verification For PDF signatures with SubFilter == adbe.pkcs7.sha1, we only compared hash values and never actually checked SignatureValue within SignerInfo. Fix bugs introduced by 055fd58711d57af4d96214aebd71b713303d5527 and e58ed17e35989350afe3e9fd77b24515df782eac by verifying the actual (public-key) signature after the hash values compare equal. Change-Id: I5fa3d60df214cc5efedd1c0eba6cf1b9faf05360 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183059 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins (cherry picked from commit 9f687b06fc25156a2a3f4d688b56542612995aa9) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183082 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/svl/source/crypto/cryptosign.cxx b/svl/source/crypto/cryptosign.cxx index 5af0fb2e033a..747abd1af99c 100644 --- a/svl/source/crypto/cryptosign.cxx +++ b/svl/source/crypto/cryptosign.cxx @@ -2109,23 +2109,30 @@ bool Signing::Verify(const std::vector<unsigned char>& aData, if (pAttribute) rInformation.bHasSigningCertificate = true; + SECItem aSignedDigestItem {siBuffer, nullptr, 0}; + SECItem* pContentInfoContentData = pCMSSignedData->contentInfo.content.data; if (bNonDetached && pContentInfoContentData && pContentInfoContentData->data) { // Not a detached signature. - if (!std::memcmp(pActualResultBuffer, pContentInfoContentData->data, nMaxResultLen) && nActualResultLen == pContentInfoContentData->len) - rInformation.nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED; + if (nActualResultLen == pContentInfoContentData->len && + !std::memcmp(pActualResultBuffer, pContentInfoContentData->data, nMaxResultLen) && + HASH_HashBuf(eHashType, pActualResultBuffer, pContentInfoContentData->data, nActualResultLen) == SECSuccess) + { + aSignedDigestItem.data = pActualResultBuffer; + aSignedDigestItem.len = nActualResultLen; + } } else { // Detached, the usual case. - SECItem aActualResultItem; - aActualResultItem.data = pActualResultBuffer; - aActualResultItem.len = nActualResultLen; - if (NSS_CMSSignerInfo_Verify(pCMSSignerInfo, &aActualResultItem, nullptr) == SECSuccess) - rInformation.nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED; + aSignedDigestItem.data = pActualResultBuffer; + aSignedDigestItem.len = nActualResultLen; } + if (aSignedDigestItem.data && NSS_CMSSignerInfo_Verify(pCMSSignerInfo, &aSignedDigestItem, nullptr) == SECSuccess) + rInformation.nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED; + // Everything went fine SECITEM_FreeItem(&aOidData.oid, false); PORT_Free(pActualResultBuffer); @@ -2158,19 +2165,21 @@ bool Signing::Verify(const std::vector<unsigned char>& aData, return false; } - // Update the message with the content blob. - if (!CryptMsgUpdate(hMsg, aData.data(), aData.size(), FALSE)) + if (!bNonDetached) { - SAL_WARN("svl.crypto", "ValidateSignature, CryptMsgUpdate() for the content failed: " << WindowsErrorString(GetLastError())); - return false; - } + // Update the message with the content blob. + if (!CryptMsgUpdate(hMsg, aData.data(), aData.size(), FALSE)) + { + SAL_WARN("svl.crypto", "ValidateSignature, CryptMsgUpdate() for the content failed: " << WindowsErrorString(GetLastError())); + return false; + } - if (!CryptMsgUpdate(hMsg, nullptr, 0, TRUE)) - { - SAL_WARN("svl.crypto", "ValidateSignature, CryptMsgUpdate() for the last content failed: " << WindowsErrorString(GetLastError())); - return false; + if (!CryptMsgUpdate(hMsg, nullptr, 0, TRUE)) + { + SAL_WARN("svl.crypto", "ValidateSignature, CryptMsgUpdate() for the last content failed: " << WindowsErrorString(GetLastError())); + return false; + } } - // Get the CRYPT_ALGORITHM_IDENTIFIER from the message. DWORD nDigestID = 0; if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_HASH_ALGORITHM_PARAM, 0, nullptr, &nDigestID)) @@ -2246,6 +2255,8 @@ bool Signing::Verify(const std::vector<unsigned char>& aData, rInformation.X509Datas.emplace_back(temp); } + std::vector<BYTE> aContentParam; + if (bNonDetached) { // Not a detached signature. @@ -2256,19 +2267,16 @@ bool Signing::Verify(const std::vector<unsigned char>& aData, return false; } - std::vector<BYTE> aContentParam(nContentParam); + aContentParam.resize(nContentParam); if (!CryptMsgGetParam(hMsg, CMSG_CONTENT_PARAM, 0, aContentParam.data(), &nContentParam)) { SAL_WARN("svl.crypto", "ValidateSignature: CryptMsgGetParam() failed"); return false; } - - if (VerifyNonDetachedSignature(aData, aContentParam)) - rInformation.nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED; } - else + + if (!bNonDetached || VerifyNonDetachedSignature(aData, aContentParam)) { - // Detached, the usual case. // Use the CERT_INFO from the signer certificate to verify the signature. if (CryptMsgControl(hMsg, 0, CMSG_CTRL_VERIFY_SIGNATURE, pSignerCertContext->pCertInfo)) rInformation.nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED; commit 65b8ecef9aaefa87882018d66793fd0c1a0f5fc0 Author: Bayram Çiçek <bayram.ci...@collabora.com> AuthorDate: Wed Mar 5 13:40:08 2025 +0300 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 24 13:50:54 2025 +0100 tdf#123225 - calculate count attribute correctly in xl/pivotTables/pivotTable*.xml we have e.g. <location ref="A3:B6" firstHeaderRow="1" firstDataRow="1" firstDataCol="1" rowPageCount="1" colPageCount="1"/> - the 'ref' attribute indicates the cell range of a pivot table. - 'firstDataRow' specifies the first row of the PivotTable data, relative to the top left cell in the ref value. - 'firstDataCol' specifies the first column of the PivotTable data, relative to the top left cell in the ref value. if we get the number of rows and cols in the pivot table (using <location ref="..."), and substract 'firstDataRow' & 'firstDataCol' from it, we get the correct count attr. value of <row/colItems> during export from ODS -> XLSX. - added testTdf123225PivotTableEmptyRowColItems Cppunit test to make sure that export works with empty row/col items. Signed-off-by: Bayram Çiçek <bayram.ci...@collabora.com> Change-Id: Ia85a89e429d95492f0f753af3fbf46771d1a2a0f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182529 Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> (cherry picked from commit 765bf4bff2b8d4ed9569e735dc663ac55ae7a424) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183063 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sc/qa/unit/data/ods/tdf123225_pivotTable_empty_row_col_items.ods b/sc/qa/unit/data/ods/tdf123225_pivotTable_empty_row_col_items.ods new file mode 100644 index 000000000000..fba4bc00d3ab Binary files /dev/null and b/sc/qa/unit/data/ods/tdf123225_pivotTable_empty_row_col_items.ods differ diff --git a/sc/qa/unit/pivottable_filters_test.cxx b/sc/qa/unit/pivottable_filters_test.cxx index 9c710bcd5324..1baaca95568e 100644 --- a/sc/qa/unit/pivottable_filters_test.cxx +++ b/sc/qa/unit/pivottable_filters_test.cxx @@ -234,6 +234,29 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testTdf123225PivotTableNoColItems) assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i/x:x"_ostr, "v"_ostr, "0"); } +CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testTdf123225PivotTableEmptyRowColItems) +{ + // this doc contains blank row/col items + // <sharedItems containsBlank="1" count="..."> (xl/pivotCache/pivotCacheDefinition1.xml) + createScDoc("ods/tdf123225_pivotTable_empty_row_col_items.ods"); + save(u"Calc Office Open XML"_ustr); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + // Row items <rowItems> + + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems"_ostr, 1); + // check if <rowItems count="4"> + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems"_ostr, "count"_ostr, "4"); + + // Column items <colItems> + + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems"_ostr, 1); + // check if <colItems count="5"> + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems"_ostr, "count"_ostr, "5"); +} + CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testPivotTableNamedRangeSourceODS) { createScDoc("ods/pivot-table-named-range-source.ods"); diff --git a/sc/source/filter/excel/xepivotxml.cxx b/sc/source/filter/excel/xepivotxml.cxx index 66bebb04865a..41ec742a7fa1 100644 --- a/sc/source/filter/excel/xepivotxml.cxx +++ b/sc/source/filter/excel/xepivotxml.cxx @@ -861,6 +861,12 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP // NB: Excel's range does not include page field area (if any). ScRange aOutRange = rDPObj.GetOutputRangeByType(sheet::DataPilotOutputRangeType::TABLE); + // normalize the order to prevent negative row/col counts - just in case. + aOutRange.PutInOrder(); + // both start and end cells are included. subtraction excludes the start cells, therefore add +1. + SCROW pivotTableRowCount = aOutRange.aEnd.Row() - aOutRange.aStart.Row() + 1; + SCCOL pivotTableColCount = aOutRange.aEnd.Col() - aOutRange.aStart.Col() + 1; + sal_Int32 nFirstHeaderRow = rDPObj.GetHideHeader() ? 0 : (rDPObj.GetHeaderLayout() ? 2 : 1); sal_Int32 nFirstDataRow = rDPObj.GetHideHeader() ? 1 : 2; sal_Int32 nFirstDataCol = 1; @@ -1058,15 +1064,8 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP pAttList->add( XML_outline, ToPsz10(false)); pPivotStrm->startElement(XML_pivotField, pAttList); - tools::Long nItemsCount - = static_cast<tools::Long>(aMemberSequence.size() + aSubtotalSequence.size()); pPivotStrm->startElement(XML_items, - XML_count, OString::number(nItemsCount)); - - if (strcmp(toOOXMLAxisType(eOrient), "axisCol") == 0) - nColItemsCount = nItemsCount; - else if (strcmp(toOOXMLAxisType(eOrient), "axisRow") == 0) - nRowItemsCount = nItemsCount; + XML_count, OString::number(static_cast<tools::Long>(aMemberSequence.size() + aSubtotalSequence.size()))); for (const auto & nMember : aMemberSequence) { @@ -1077,6 +1076,11 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP pPivotStrm->singleElement(XML_item, pItemAttList); } + if (strcmp(toOOXMLAxisType(eOrient), "axisCol") == 0) + nColItemsCount = pivotTableColCount - nFirstDataCol; + else if (strcmp(toOOXMLAxisType(eOrient), "axisRow") == 0) + nRowItemsCount = pivotTableRowCount - nFirstDataRow; + for (const OString& sSubtotal : aSubtotalSequence) { pPivotStrm->singleElement(XML_item, XML_t, sSubtotal); commit 642132f5cdd58fea5c8c22e41a2945b9c8a29e1b Author: Bayram Çiçek <bayram.ci...@collabora.com> AuthorDate: Wed Feb 26 18:33:06 2025 +0300 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 24 13:50:53 2025 +0100 tdf#123225 - export <i t="grand"> of row/colItems in xl/pivotTables/pivotTable*.xml. - we should always export (.ods to .xlsx) <rowItems> and <colItems>, even if the pivot table does not contain col/row items. Otherwise: 1) Excel will fail to open the xlsx document, you will get an error message. 2) Excel will open the file without any errors but: 2.1) context menu -by right clicking on the pivot table- will have less or more items than it should have after "refresh". 2.2) if e.g. trying to sort the items you will get "Cannot determine which PivotTable field to sort by" warning. - we should add t="grand" to the last <i> element. Otherwise, Excel will not have all functions in the context menu of the pivot table. Especially for the "Grand Total" column/row cells. we shouldn't need "refresh" to use all functions/items in the context menu. - note: it is not completely clear that the last <i> element always gets t="grand". however, testing on the some docs indicate that t="grand" should be in the last <i> element. - added testTdf123225PivotTableNoColItems unit test to check if <i t="grand"> exported. also, added some useful information in the comment section for future tests/issues. Signed-off-by: Bayram Çiçek <bayram.ci...@collabora.com> Change-Id: I22b42ddb4a27c4b7b88ad8a71376c2c82d5a735a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182242 Tested-by: Jenkins Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> (cherry picked from commit 3b3ba9c329b691ef600ad9ecc419e818b385ce0e) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182892 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sc/qa/unit/data/ods/tdf123225_pivotTable_no_col_items.ods b/sc/qa/unit/data/ods/tdf123225_pivotTable_no_col_items.ods new file mode 100644 index 000000000000..0e2b601efa44 Binary files /dev/null and b/sc/qa/unit/data/ods/tdf123225_pivotTable_no_col_items.ods differ diff --git a/sc/qa/unit/pivottable_filters_test.cxx b/sc/qa/unit/pivottable_filters_test.cxx index 3cb8eabd743a..9c710bcd5324 100644 --- a/sc/qa/unit/pivottable_filters_test.cxx +++ b/sc/qa/unit/pivottable_filters_test.cxx @@ -134,8 +134,24 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testTdf123225PivotTableRowColItems xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); CPPUNIT_ASSERT(pSheet); - // be sure that we have <rowItems> and <colItems> element - // under <pivotTableDefinition> after export of the .ods to .xlsx + /* + - be sure that we have <rowItems> and <colItems> element + under <pivotTableDefinition> after export of the .ods to .xlsx + + otherwise: + 1) Excel will fail to open the xlsx document, you will get an error message. + 2) Excel will open the file without any errors but: + 2.1) context menu -by right clicking on the pivot table- will have + less or more items than it should have after "refresh". + 2.2) if e.g. trying to sort the items you will get "Cannot determine + which PivotTable field to sort by" warning. + + - after exporting the .ods as .xlsx and opening the .xlsx document in Excel: + the count attribute of rowItems(or colItems) should have the expected value. + otherwise, context menu on the pivot table will have less/more items + than it should have after "refresh". we shouldn't need "refresh" to use all + functions/items in the context menu. + */ // Row items <rowItems> @@ -162,6 +178,62 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testTdf123225PivotTableRowColItems assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i[1]/x:x"_ostr, "v"_ostr, "0"); } +CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testTdf123225PivotTableNoColItems) +{ + createScDoc("ods/tdf123225_pivotTable_no_col_items.ods"); + save(u"Calc Office Open XML"_ustr); + + xmlDocUniquePtr pSheet = parseExport(u"xl/pivotTables/pivotTable1.xml"_ustr); + CPPUNIT_ASSERT(pSheet); + + /* + - after exporting the .ods to .xlsx, we should have t="grand" in the + last <i> element of the <rowItems> and <colItems>. Otherwise, Excel will not + have all functions in the context menu of the pivot table. Especially for the + "Grand Total" column/row cells. + + - additionally, we should always export a single <rowItems> and <colItems> regardless of + whether the document has row/col items. Otherwise, in Excel, context menu on some + cells of the pivot table, will not have the expected context menu items. + + - this tdf123225_pivotTable_no_col_items.ods document does not have + axisCol (DataPilotFieldOrientation_COLUMN) and that means <colItems> should not exist + during export. But in Excel, if pivot table refreshed, there will be + + <colItems count="1"> + <i/> + </colItems> + + in the xl/pivotTables/pivotTable1.xml. So, that means we should export <colItems> + without checking the existence of it. + For the sake of completeness, <colItems> exported as: + + <colItems count="1"> + <i t="grand"> + <x v="0"/> + </i> + </colItems> + */ + + // Row items <rowItems> + + // check if <rowItems count="3"> + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems"_ostr, "count"_ostr, "3"); + // check if last <i> element, has t="grand" + assertXPath(pSheet, "/x:pivotTableDefinition/x:rowItems/x:i[last()]"_ostr, "t"_ostr, "grand"); + + // Column items <colItems> + + // check if <colItems count="1"> + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems"_ostr, "count"_ostr, "1"); + // check if <colItems> has only a single <i> element + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i"_ostr, 1); + // check if <i> element has t="grand" + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i"_ostr, "t"_ostr, "grand"); + // check if <i> has <x v="0"/> + assertXPath(pSheet, "/x:pivotTableDefinition/x:colItems/x:i/x:x"_ostr, "v"_ostr, "0"); +} + CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest, testPivotTableNamedRangeSourceODS) { createScDoc("ods/pivot-table-named-range-source.ods"); diff --git a/sc/source/filter/excel/xepivotxml.cxx b/sc/source/filter/excel/xepivotxml.cxx index 8a0ef118b4cc..66bebb04865a 100644 --- a/sc/source/filter/excel/xepivotxml.cxx +++ b/sc/source/filter/excel/xepivotxml.cxx @@ -774,8 +774,11 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP std::vector<tools::Long> aPageFields; std::vector<DataField> aDataFields; - tools::Long nRowItemsCount = 0; // for <rowItems count="..."> of pivotTable*.xml - tools::Long nColItemsCount = 0; // for <colItems count="..."> of pivotTable*.xml + // we should always export <rowItems> and <colItems>, even if the pivot table + // does not contain col/row items. otherwise, in Excel, pivot table will not + // have all context menu items. + tools::Long nRowItemsCount = 1; // for <rowItems count="..."> of pivotTable*.xml + tools::Long nColItemsCount = 1; // for <colItems count="..."> of pivotTable*.xml tools::Long nDataDimCount = rSaveData.GetDataDimensionCount(); // Use dimensions in the save data to get their correct ordering. // Dimension order here is significant as they specify the order of @@ -1062,7 +1065,7 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP if (strcmp(toOOXMLAxisType(eOrient), "axisCol") == 0) nColItemsCount = nItemsCount; - else + else if (strcmp(toOOXMLAxisType(eOrient), "axisRow") == 0) nRowItemsCount = nItemsCount; for (const auto & nMember : aMemberSequence) @@ -1108,7 +1111,18 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP // export nRowItemsCount times <i> and <x> elements for (tools::Long nCount = 0; nCount < nRowItemsCount; ++nCount) { - pPivotStrm->startElement(XML_i); + /* we should add t="grand" to the last <i> element. Otherwise, Excel will not + have all functions in the context menu of the pivot table. Especially for the + "Grand Total" column/row cells. + + note: it is not completely clear that the last <i> element always gets t="grand". + however, testing on the some docs indicate that t="grand" should be + in the last element, so let's try this here. */ + if (nCount == nRowItemsCount - 1) + pPivotStrm->startElement(XML_i, XML_t, "grand"); + else + pPivotStrm->startElement(XML_i); + pPivotStrm->singleElement(XML_x, XML_v, OString::number(nCount)); pPivotStrm->endElement(XML_i); } @@ -1139,7 +1153,18 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP // export nColItemsCount times <i> and <x> elements for (tools::Long nCount = 0; nCount < nColItemsCount; ++nCount) { - pPivotStrm->startElement(XML_i); + /* we should add t="grand" to the last <i> element. Otherwise, Excel will not + have all functions in the context menu of the pivot table. Especially for the + "Grand Total" column/row cells. + + note: it is not completely clear that the last <i> element always gets t="grand". + however, testing on the some docs indicate that t="grand" should be + in the last element, so let's try this here. */ + if (nCount == nColItemsCount - 1) + pPivotStrm->startElement(XML_i, XML_t, "grand"); + else + pPivotStrm->startElement(XML_i); + pPivotStrm->singleElement(XML_x, XML_v, OString::number(nCount)); pPivotStrm->endElement(XML_i); } commit 747e34729ab3d3826ff665e08fd5011476018e10 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Mon Mar 17 19:40:03 2025 +0500 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 24 13:50:53 2025 +0100 tdf#144151: do not adjust row height for font / style preview In commit bcc51fb2ebdf77a1cc089857775fd742085b45b6 (add support for in-place style preview, 2013-08-29), a feature of live preview was introduced, to see the effect of not-yet-applied font currently hovered in the font list. While doing this, it could recalculate row heights (e.g., for auto-wrapped cells). For large selection, this recalculation may take several seconds. Also, this may mark document modified, and also result in following UI operations slowdown. This change prevents this recalculation for the preview. The cost is that now the preview could be not 100% correct, but hopefully this is much less problematic, than the problems it resolves. SID_ATTR_CHAR_FONTHEIGHT (.uno:CharFontName) does the height adjust anyway. Change-Id: If347aa7222cb700d8969dd546727ae437f787d14 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183034 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Jenkins (cherry picked from commit 950cbe4ccf2a95981e40f2a9589b22a403784557) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183045 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index a49941e7052e..22b97957b3ea 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -339,7 +339,8 @@ public: SCROW nEndRow , SCCOL nEndCol , std::vector<std::unique_ptr<ScDataFormFragment>>& rEdits, sal_uInt16 aColLength); - void UpdateSelectionArea( const ScMarkData& rSel, ScPatternAttr* pAttr = nullptr ); + void UpdateSelectionArea(const ScMarkData& rSel, ScPatternAttr* pAttr = nullptr, + bool adjustHeight = true); void OnLOKInsertDeleteColumn(SCCOL nStartCol, tools::Long nOffset); void OnLOKInsertDeleteRow(SCROW nStartRow, tools::Long nOffset); diff --git a/sc/source/ui/view/formatsh.cxx b/sc/source/ui/view/formatsh.cxx index 8381209e7c72..539f2f08df16 100644 --- a/sc/source/ui/view/formatsh.cxx +++ b/sc/source/ui/view/formatsh.cxx @@ -196,7 +196,7 @@ void ScFormatShell::ExecuteStyle( SfxRequest& rReq ) rNewSet.Put( aItemSet, false ); rDoc.ApplySelectionPattern( aNewAttrs, rDoc.GetPreviewSelection() ); - pTabViewShell->UpdateSelectionArea( aFuncMark, &aAttr ); + pTabViewShell->UpdateSelectionArea(aFuncMark, &aAttr, /*adjustHeight*/ false); } } else @@ -218,7 +218,7 @@ void ScFormatShell::ExecuteStyle( SfxRequest& rReq ) SfxItemSet& rNewSet = aNewAttrs.GetItemSet(); rNewSet.Put( aItemSet, false ); rDoc.ApplySelectionPattern( aNewAttrs, aPreviewMark ); - pTabViewShell->UpdateSelectionArea( aPreviewMark, &aAttr ); + pTabViewShell->UpdateSelectionArea(aPreviewMark, &aAttr, /*adjustHeight*/ false); } } } @@ -945,7 +945,8 @@ void ScFormatShell::ExecuteAttr( SfxRequest& rReq ) case SID_ATTR_CHAR_ENDPREVIEW_FONT: { rDoc.SetPreviewFont(nullptr); - pTabViewShell->UpdateSelectionArea( rDoc.GetPreviewSelection() ); + pTabViewShell->UpdateSelectionArea(rDoc.GetPreviewSelection(), nullptr, + /*adjustHeight*/ false); break; } case SID_ATTR_CHAR_COLOR: @@ -1026,7 +1027,7 @@ void ScFormatShell::ExecuteAttr( SfxRequest& rReq ) aFuncMark.SetMarkArea( aRange ); } rDoc.SetPreviewSelection( aFuncMark ); - pTabViewShell->UpdateSelectionArea( aFuncMark ); + pTabViewShell->UpdateSelectionArea(aFuncMark, nullptr, /*adjustHeight*/ false); break; } case SID_ATTR_CHAR_OVERLINE: diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index 20f3795400b9..7c2b221ba5e7 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -3247,7 +3247,8 @@ void ScViewFunc::InsertNameList() pDocSh->UpdateOle(GetViewData()); } -void ScViewFunc::UpdateSelectionArea( const ScMarkData& rSel, ScPatternAttr* pAttr ) +void ScViewFunc::UpdateSelectionArea(const ScMarkData& rSel, ScPatternAttr* pAttr, + bool adjustHeight) { ScDocShell* pDocShell = GetViewData().GetDocShell(); ScRange aMarkRange; @@ -3281,8 +3282,11 @@ void ScViewFunc::UpdateSelectionArea( const ScMarkData& rSel, ScPatternAttr* pAt pDocShell->PostPaint( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab, PaintPartFlags::Grid, nExtFlags | SC_PF_TESTMERGE ); - ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); - pTabViewShell->AdjustBlockHeight(false, const_cast<ScMarkData*>(&rSel)); + if (adjustHeight) + { + ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); + pTabViewShell->AdjustBlockHeight(false, const_cast<ScMarkData*>(&rSel)); + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 2a83dcf080461981bdcf40bf6fe1838e4089d024 Author: Caolán McNamara <caolan.mcnam...@collabora.com> AuthorDate: Fri Mar 14 16:17:49 2025 +0000 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 24 13:50:53 2025 +0100 lokit: don't double-buffer combo/list box dropdowns we don't need them and they take up a noticeable amount of dead memory .e.g. before: 57140k, after 56732k for a blank writer document. Change-Id: I50b378989c01e5e2a94e06c8e78a08dfb3829ef8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182929 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx index 82520cc765f4..4625a0b21d4a 100644 --- a/vcl/source/control/combobox.cxx +++ b/vcl/source/control/combobox.cxx @@ -199,8 +199,14 @@ void ComboBox::ImplInit( vcl::Window* pParent, WinBits nStyle ) if( nStyle & WB_DROPDOWN ) { m_pImpl->m_pFloatWin = VclPtr<ImplListBoxFloatingWindow>::Create( this ); - if (!IsNativeControlSupported(ControlType::Pushbutton, ControlPart::Focus)) - m_pImpl->m_pFloatWin->RequestDoubleBuffering(true); + // For Kit jsdialogs we don't need or want a buffer the size of + // the ComboBox dropdown taking up memory which is unnecessary + // in that case. + if (!comphelper::LibreOfficeKit::isActive()) + { + if (!IsNativeControlSupported(ControlType::Pushbutton, ControlPart::Focus)) + m_pImpl->m_pFloatWin->RequestDoubleBuffering(true); + } m_pImpl->m_pFloatWin->SetAutoWidth( true ); m_pImpl->m_pFloatWin->SetPopupModeEndHdl( LINK(m_pImpl.get(), ComboBox::Impl, ImplPopupModeEndHdl) ); diff --git a/vcl/source/control/listbox.cxx b/vcl/source/control/listbox.cxx index e189c8480f05..818ddd1e40b5 100644 --- a/vcl/source/control/listbox.cxx +++ b/vcl/source/control/listbox.cxx @@ -109,8 +109,14 @@ void ListBox::ImplInit( vcl::Window* pParent, WinBits nStyle ) } mpFloatWin = VclPtr<ImplListBoxFloatingWindow>::Create( this ); - if (!IsNativeControlSupported(ControlType::Pushbutton, ControlPart::Focus)) - mpFloatWin->RequestDoubleBuffering(true); + // For Kit jsdialogs we don't need or want a buffer the size of + // the ListBox dropdown taking up memory which is unnecessary + // in that case. + if (!comphelper::LibreOfficeKit::isActive()) + { + if (!IsNativeControlSupported(ControlType::Pushbutton, ControlPart::Focus)) + mpFloatWin->RequestDoubleBuffering(true); + } mpFloatWin->SetAutoWidth( true ); mpFloatWin->SetPopupModeEndHdl( LINK( this, ListBox, ImplPopupModeEndHdl ) ); mpFloatWin->GetDropTarget()->addDropTargetListener(xDrop); commit 908f773072e604e8480ab8ae113aa01c20e4e688 Author: Xisco Fauli <xiscofa...@libreoffice.org> AuthorDate: Fri Mar 14 08:54:38 2025 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 24 13:50:53 2025 +0100 expat: upgrade to 2.7.0 Downloaded from https://github.com/libexpat/libexpat/releases/download/R_2_7_0/expat-2.7.0.tar.xz Change-Id: I714d00fe5e1b3073ec3034065057ae9795060eec Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182894 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> (cherry picked from commit 82c0b78f16dc4a5969b130c0d2519cf9d05e4794) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182898 Reviewed-by: Taichi Haradaguchi <20001...@protonmail.com> diff --git a/download.lst b/download.lst index 85cec46a2641..854233ab395b 100644 --- a/download.lst +++ b/download.lst @@ -111,8 +111,8 @@ ETONYEK_TARBALL := libetonyek-0.1.$(ETONYEK_VERSION_MICRO).tar.xz # three static lines # so that git cherry-pick # will not run into conflicts -EXPAT_SHA256SUM := a695629dae047055b37d50a0ff4776d1d45d0a4c842cf4ccee158441f55ff7ee -EXPAT_TARBALL := expat-2.6.4.tar.xz +EXPAT_SHA256SUM := 25df13dd2819e85fb27a1ce0431772b7047d72af81ae78dc26b4c6e0805f48d1 +EXPAT_TARBALL := expat-2.7.0.tar.xz # three static lines # so that git cherry-pick # will not run into conflicts commit 947c63c396faa3918daafa38bf08eb89810e5930 Author: Jaume Pujantell <jaume.pujant...@collabora.com> AuthorDate: Thu Mar 13 15:01:24 2025 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 24 13:50:53 2025 +0100 tdf#165059 sw use delText inside all del tags Continuation of commit 624de66a2aeee92c0d2cadc8de3740167ec09062 "sw fix not valid moveFrom/moveTo tag". Make sure to us w:delText instead of w:t inside the w:del tags now used because of that change. Change-Id: Ic5bac1865e5c12a71bd15306249c2624eb1149f9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182870 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/qa/extras/ooxmlexport/data/tdf165059_broken.docx b/sw/qa/extras/ooxmlexport/data/tdf165059_broken.docx index 548d4d9c7414..6a81afd69e15 100644 Binary files a/sw/qa/extras/ooxmlexport/data/tdf165059_broken.docx and b/sw/qa/extras/ooxmlexport/data/tdf165059_broken.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx index a97720dc69d4..8fa2e7ef14bc 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx @@ -494,19 +494,18 @@ CPPUNIT_TEST_FIXTURE(Test, testMsWordUlTrailSpace) assertXPath(pXmlSettings, "/w:settings/w:compat/w:ulTrailSpace"_ostr); } -DECLARE_OOXMLEXPORT_TEST(testTdf165059_moveFromTo, "tdf165059_broken.docx") +CPPUNIT_TEST_FIXTURE(Test, testTdf165059_moveFromTo) { - if (isExported()) - { - // Without the fix, exported contains w:move* ouside of move ranges - // Outside move range tags ins/del are valid - xmlDocUniquePtr p_XmlDoc = parseExport("word/document.xml"); - CPPUNIT_ASSERT(p_XmlDoc); - assertXPath(p_XmlDoc, "//w:moveTo"_ostr, 0); - assertXPath(p_XmlDoc, "//w:ins"_ostr, 1); - assertXPath(p_XmlDoc, "//w:moveFrom"_ostr, 0); - assertXPath(p_XmlDoc, "//w:del"_ostr, 1); - } + loadAndSave("tdf165059_broken.docx"); + // Without the fix, exported contains w:move* ouside of move ranges + // Outside move range tags ins/del are valid + xmlDocUniquePtr p_XmlDoc = parseExport("word/document.xml"); + CPPUNIT_ASSERT(p_XmlDoc); + assertXPath(p_XmlDoc, "//w:moveTo"_ostr, 0); + assertXPath(p_XmlDoc, "//w:ins"_ostr, 1); + assertXPath(p_XmlDoc, "//w:moveFrom"_ostr, 0); + assertXPath(p_XmlDoc, "//w:del"_ostr, 1); + assertXPath(p_XmlDoc, "//w:delText"_ostr, 1); } } // end of anonymous namespace diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index ed2273925059..770da84aabc3 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -3803,9 +3803,18 @@ void DocxAttributeOutput::RunText( const OUString& rText, rtl_TextEncoding /*eCh // the text run is usually XML_t, with the exception of the deleted (and not moved) text sal_Int32 nTextToken = XML_t; - bool bMoved = m_pRedlineData && m_pRedlineData->IsMoved() && - // tdf#150166 save tracked moving around TOC as w:ins, w:del - SwDoc::GetCurTOX(*m_rExport.m_pCurPam->GetPoint()) == nullptr; + bool isInMoveBookmark = false; + for (const auto& openedBookmark : m_rOpenedBookmarksIds) + { + if (openedBookmark.first.startsWith(u"__RefMove")) + { + isInMoveBookmark = true; + break; + } + } + bool bMoved = isInMoveBookmark && m_pRedlineData && m_pRedlineData->IsMoved() && + // tdf#150166 save tracked moving around TOC as w:ins, w:del + SwDoc::GetCurTOX(*m_rExport.m_pCurPam->GetPoint()) == nullptr; if ( m_pRedlineData && m_pRedlineData->GetType() == RedlineType::Delete && !bMoved ) { commit 8ebec402806a04c0e83a390507112cd35a117915 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Mar 13 12:10:41 2025 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Mar 24 13:50:53 2025 +0100 tdf#165701 sw: fix unexpected list level change on inserting new bullet Go to the end of the 3rd paragraph of the bugdoc, press Enter, list level of both the old and new paragraphs change from 5 to 4, unexpectedly. It seems what happens is that the paragraph in question has a style which has its outline level set to 4. So once the node is split, the newly inserted node will host the old text (so need to set the style on it to the old style, which sets list level to the outline level from the style as a side effect) and the old node will host what looks like a new bullet point on the UI, so there we need to set the paragraph style to the follow style. This second set-style also drops the list level direct formatting and takes the outline level from the style. Fix the problem by keeping the old scenario (paragraph style with a different follow style) unchanged, since a different list level on an actual paragraph style change can be expected -- but avoid setting a list level when this is a simple node split with just the same style on both nodes. That's not seen as an explicit "set style" by the user, so changing the list level there is confusing. In fact the list level is fine after copying the text node's item set from the old node to the new node, just make sure that SwTextNode::ChgTextCollUpdateNum() doesn't set a new list level in the "effectively no style change" case. Make sure to not set a new list level at both places (SwTextNode::MakeNewTextNode() does this for the previous node, SwTextNode::ChgFormatColl() does this for the next node). Change-Id: Ifdf9048f01fef7bb8e99098ebeb5d1ec339fdaa6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182861 Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx index 1024974c60b6..9d6b03ab6aa1 100644 --- a/sw/inc/ndtxt.hxx +++ b/sw/inc/ndtxt.hxx @@ -464,9 +464,10 @@ public: bool Convert( SwConversionArgs & ); inline SwTextFormatColl *GetTextColl() const; - virtual SwFormatColl *ChgFormatColl( SwFormatColl* ) override; + virtual SwFormatColl *ChgFormatColl( SwFormatColl*, bool bSetListLevel = true ) override; void ChgTextCollUpdateNum( const SwTextFormatColl* pOld, - const SwTextFormatColl* pNew ); + const SwTextFormatColl* pNew, + bool bSetListLevel = true ); /** Copy collection with all auto formats to dest-node. The latter might be in another document! diff --git a/sw/inc/node.hxx b/sw/inc/node.hxx index e42b6e80e53c..3708209b78f9 100644 --- a/sw/inc/node.hxx +++ b/sw/inc/node.hxx @@ -493,7 +493,7 @@ public: const SwAttrSet *GetpSwAttrSet() const { return mpAttrSet.get(); } bool HasSwAttrSet() const { return mpAttrSet != nullptr; } - virtual SwFormatColl* ChgFormatColl( SwFormatColl* ); + virtual SwFormatColl* ChgFormatColl( SwFormatColl*, bool bSetListLevel = true ); SwFormatColl* GetFormatColl() const { return const_cast<SwFormatColl*>(static_cast<const SwFormatColl*>(GetRegisteredIn())); } inline SwFormatColl& GetAnyFormatColl() const; diff --git a/sw/qa/core/txtnode/data/node-split-style-list-level.odt b/sw/qa/core/txtnode/data/node-split-style-list-level.odt new file mode 100644 index 000000000000..f2535bb69b9c Binary files /dev/null and b/sw/qa/core/txtnode/data/node-split-style-list-level.odt differ diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx index e967e58436d6..428b7561d852 100644 --- a/sw/qa/core/txtnode/txtnode.cxx +++ b/sw/qa/core/txtnode/txtnode.cxx @@ -598,6 +598,30 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testCopyCommentsWithReplies) CPPUNIT_ASSERT_EQUAL(comments[2]->GetName(), comments[3]->GetParentName()); } +CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testNodeSplitStyleListLevel) +{ + // Given a document with a 3rd paragraph where the list level as direct formatting differs from + // the list level from style: + createSwDoc("node-split-style-list-level.odt"); + SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell(); + pWrtShell->Down(/*bSelect=*/false, /*nCount=*/2); + pWrtShell->EndPara(); + + // When pressing enter at the end of the paragraph: + pWrtShell->SplitNode(); + + SwTextNode* pNext = pWrtShell->GetCursor()->GetPointNode().GetTextNode(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 4 + // - Actual : 3 + // i.e. the list level for the new paragraph changed on a simple node split. + CPPUNIT_ASSERT_EQUAL(4, pNext->GetAttrListLevel()); + pWrtShell->Up(/*bSelect=*/false, /*nCount=*/1); + SwTextNode* pPrevious = pWrtShell->GetCursor()->GetPointNode().GetTextNode(); + // Same happened for the old paragraph. + CPPUNIT_ASSERT_EQUAL(4, pPrevious->GetAttrListLevel()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx index ca38e625a0e4..957d6a2cb10f 100644 --- a/sw/source/core/docnode/node.cxx +++ b/sw/source/core/docnode/node.cxx @@ -1258,7 +1258,7 @@ SwRect SwContentNode::FindPageFrameRect() const sal_Int32 SwContentNode::Len() const { return 0; } -SwFormatColl *SwContentNode::ChgFormatColl( SwFormatColl *pNewColl ) +SwFormatColl *SwContentNode::ChgFormatColl( SwFormatColl *pNewColl, bool /*bSetListLevel*/ ) { OSL_ENSURE( pNewColl, "Collectionpointer is 0." ); SwFormatColl *pOldColl = GetFormatColl(); diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index 458d1e99f637..ec2ad33d28c5 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -1666,7 +1666,8 @@ void SwTextNode::Update( } void SwTextNode::ChgTextCollUpdateNum( const SwTextFormatColl *pOldColl, - const SwTextFormatColl *pNewColl) + const SwTextFormatColl *pNewColl, + bool bSetListLevel) { SwDoc& rDoc = GetDoc(); // query the OutlineLevel and if it changed, notify the Nodes-Array! @@ -1675,7 +1676,7 @@ void SwTextNode::ChgTextCollUpdateNum( const SwTextFormatColl *pOldColl, const int nNewLevel = pNewColl && pNewColl->IsAssignedToListLevelOfOutlineStyle() ? pNewColl->GetAssignedOutlineStyleLevel() : MAXLEVEL; - if ( MAXLEVEL != nNewLevel && -1 != nNewLevel ) + if ( MAXLEVEL != nNewLevel && -1 != nNewLevel && bSetListLevel ) { SetAttrListLevel(nNewLevel); } @@ -3075,6 +3076,36 @@ bool SwTextNode::HasMarkedLabel() const } // <- #i27615# +namespace +{ +/// Decides if a list level direct formatting on a paragraph needs copying to a next, new paragraph. +bool CopyDirectListLevel(SwTextNode* pTextNode) +{ + SwTextFormatColl* pColl = pTextNode->GetTextColl(); + if (!pColl) + { + // No style, so can't have a conflict with a direct formatting. + return false; + } + + if (&pColl->GetNextTextFormatColl() != pColl) + { + // Style has a custom follow style, changing list level is OK. + return false; + } + + if (!pColl->IsAssignedToListLevelOfOutlineStyle()) + { + // Paragraph style has no own list level, no conflict. + return false; + } + + // Copy is needed if the old paragraph had a direct formatting, which may be different and has + // to be kept during the paragraph split. + return pTextNode->HasAttrListLevel(); +} +} + SwTextNode* SwTextNode::MakeNewTextNode( SwNode& rPosNd, bool bNext, bool bChgFollow ) { @@ -3173,7 +3204,9 @@ SwTextNode* SwTextNode::MakeNewTextNode( SwNode& rPosNd, bool bNext, ( bChgFollow && pColl != GetTextColl() )) return pNode; // that ought to be enough? - pNode->ChgTextCollUpdateNum( nullptr, pColl ); // for numbering/outline + bool bSetListLevel = !CopyDirectListLevel(this); + + pNode->ChgTextCollUpdateNum( nullptr, pColl, bSetListLevel ); // for numbering/outline if( bNext || !bChgFollow ) return pNode; @@ -3191,7 +3224,7 @@ SwTextNode* SwTextNode::MakeNewTextNode( SwNode& rPosNd, bool bNext, } } } - ChgFormatColl( pNextColl ); + ChgFormatColl( pNextColl, bSetListLevel ); return pNode; } @@ -4135,7 +4168,7 @@ namespace { // End of method <HandleModifyAtTextNode> } -SwFormatColl* SwTextNode::ChgFormatColl( SwFormatColl *pNewColl ) +SwFormatColl* SwTextNode::ChgFormatColl( SwFormatColl *pNewColl, bool bSetListLevel ) { OSL_ENSURE( pNewColl,"ChgFormatColl: Collectionpointer has value 0." ); assert( dynamic_cast<const SwTextFormatColl *>(pNewColl) && "ChgFormatColl: is not a Text Collection pointer." ); @@ -4164,7 +4197,7 @@ SwFormatColl* SwTextNode::ChgFormatColl( SwFormatColl *pNewColl ) // only for real nodes-array if( GetNodes().IsDocNodes() ) { - ChgTextCollUpdateNum( pOldColl, static_cast<SwTextFormatColl *>(pNewColl) ); + ChgTextCollUpdateNum( pOldColl, static_cast<SwTextFormatColl *>(pNewColl), bSetListLevel ); } return pOldColl;