avmedia/source/qt6/QtPlayer.cxx | 11 cui/uiconfig/ui/bulletandposition.ui | 3 desktop/source/deployment/gui/dp_gui_service.cxx | 2 desktop/source/deployment/gui/dp_gui_theextmgr.hxx | 4 dev/null |binary download.lst | 8 drawinglayer/source/tools/emfphelperdata.cxx | 28 drawinglayer/source/tools/emfphelperdata.hxx | 3 emfio/inc/mtftools.hxx | 2 emfio/qa/cppunit/emf/EmfImportTest.cxx | 93 ++- emfio/qa/cppunit/emf/data/TestEmfPlusSetPageTransform.emf |binary emfio/qa/cppunit/emf/data/TestExtTextOutScaleGM_COMPATIBLE.emf |binary emfio/source/reader/emfreader.cxx | 16 emfio/source/reader/mtftools.cxx | 41 + extensions/source/propctrlr/formcomponenthandler.cxx | 71 -- extensions/source/propctrlr/formcomponenthandler.hxx | 2 extensions/source/propctrlr/formstrings.hxx | 1 external/libgpg-error/ExternalPackage_libgpg-error.mk | 2 external/skia/UnpackedTarball_skia.mk | 1 external/skia/fix-xputimage-depth.patch.1 | 47 + external/zlib/UnpackedTarball_zlib.mk | 1 external/zlib/missinginclude.patch | 2 external/zlib/werror-undef.patch | 16 extras/source/templates/presnt/Blueprint_Plans/styles.xml | 96 +-- filter/source/msfilter/svdfppt.cxx | 2 i18nutil/source/utility/paper.cxx | 21 include/i18nutil/paper.hxx | 2 include/sfx2/passwd.hxx | 5 oox/source/export/drawingml.cxx | 25 sal/osl/w32/file_dirvol.cxx | 53 - sc/qa/uitest/autofilter/autofilterBugs.py | 27 sc/qa/uitest/data/autofilter/tdf160018_use_on_database_range.ods |binary sc/qa/unit/data/ods/tdf170670-Blank-width-char.ods |binary sc/qa/unit/subsequent_export_test2.cxx | 26 sc/qa/unit/subsequent_export_test4.cxx | 10 sc/source/core/data/documen3.cxx | 5 sc/source/filter/excel/xestream.cxx | 5 sc/source/filter/excel/xetable.cxx | 4 sc/source/filter/excel/xltools.cxx | 10 sc/source/filter/inc/xestream.hxx | 3 sc/source/filter/inc/xltools.hxx | 2 sc/source/ui/dbgui/PivotLayoutDialog.cxx | 12 sc/source/ui/inc/PivotLayoutDialog.hxx | 1 sc/uiconfig/scalc/ui/pivottablelayoutdialog.ui | 3 scaddins/source/analysis/analysishelper.cxx | 6 sd/qa/uitest/impress_tests2/tdf130586.py | 54 + sd/qa/uitest/impress_tests2/tdf170386.py | 3 sd/qa/unit/import-tests2.cxx | 2 sd/source/ui/dlg/BulletAndPositionDlg.cxx | 4 sd/source/ui/docshell/docshell.cxx | 8 sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx | 1 sfx2/source/dialog/StyleList.cxx | 2 sfx2/source/dialog/passwd.cxx | 52 - svtools/source/control/ctrlbox.cxx | 2 svx/source/tbxctrls/tbcontrl.cxx | 2 sw/inc/fldbas.hxx | 3 sw/qa/extras/layout/data/tdf169999.fodt | 13 sw/qa/extras/layout/data/tdf170811.fodt | 30 sw/qa/extras/layout/data/tdf170846_1.docx |binary sw/qa/extras/layout/data/tdf170846_2.docx |binary sw/qa/extras/layout/layout6.cxx | 54 + sw/qa/extras/ooxmlexport/ooxmlexport18.cxx | 22 sw/qa/uibase/fldui/fldui.cxx | 33 + sw/source/core/layout/calcmove.cxx | 3 sw/source/core/text/porexp.cxx | 9 sw/source/core/text/txtfly.cxx | 16 sw/source/filter/ww8/docxattributeoutput.cxx | 6 sw/source/uibase/fldui/fldmgr.cxx | 3 sw/source/uibase/utlui/glbltree.cxx | 10 sw/uiconfig/swriter/ui/watermarkdialog.ui | 1 vcl/inc/osx/salframe.h | 2 vcl/inc/osx/salframeview.h | 1 vcl/osx/salframe.cxx | 111 --- vcl/osx/salframeview.mm | 28 vcl/source/app/salvtables.cxx | 8 vcl/source/filter/png/PngImageReader.cxx | 301 ++++------ vcl/source/gdi/print.cxx | 20 vcl/source/pdf/pdfwriter_impl.cxx | 14 vcl/source/pdf/pdfwriterimpl_utils.cxx | 1 vcl/source/window/printdlg.cxx | 16 vcl/source/window/status.cxx | 2 vcl/win/gdi/salprn.cxx | 4 xmloff/source/style/xmlnumfi.cxx | 7 83 files changed, 899 insertions(+), 621 deletions(-)
New commits: commit 0d4ce75701f59ee0948431d7bcd3375997647613 Author: Samuel Mehrbrodt <[email protected]> AuthorDate: Thu Feb 26 09:13:05 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:32:08 2026 +0100 tdf#166030 ppt: Default indent should be 0.95cm This is the case in PowerPoint Change-Id: I74ed4f476fba0a0858fff09d10050612c4d2df3b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200388 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200559 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/filter/source/msfilter/svdfppt.cxx b/filter/source/msfilter/svdfppt.cxx index 9f5e7d1cf69a..52ef7b743a1f 100644 --- a/filter/source/msfilter/svdfppt.cxx +++ b/filter/source/msfilter/svdfppt.cxx @@ -3768,7 +3768,7 @@ void PPTNumberFormatCreator::ImplGetNumberFormat( SdrPowerPointImport const & rM // add some default indentation to match PowerPoint's behavior. if ( nIsBullet && nTextOfs == 0 && nBulletOfs == 0 ) { - nTextOfs = 288; // ~0.4 inch text indent (default PowerPoint bullet indent) + nTextOfs = 216; // 3/8 inch text indent (~0.95 cm, default PowerPoint bullet indent) nBulletOfs = 0; // bullet at left edge } sal_uInt32 nAbsLSpace = convertMasterUnitToMm100(nTextOfs); diff --git a/sd/qa/unit/import-tests2.cxx b/sd/qa/unit/import-tests2.cxx index 0a4fef8a2b44..543dcc155726 100644 --- a/sd/qa/unit/import-tests2.cxx +++ b/sd/qa/unit/import-tests2.cxx @@ -1507,7 +1507,7 @@ CPPUNIT_TEST_FIXTURE(SdImportTest2, testTdf166030) const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject(); const SvxNumBulletItem* pNumFmt = aEdit.GetParaAttribs(1).GetItem(EE_PARA_NUMBULLET); const SvxNumberFormat& rFmt = pNumFmt->GetNumRule().GetLevel(1); - CPPUNIT_ASSERT_EQUAL(sal_Int32(1270), rFmt.GetAbsLSpace()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(953), rFmt.GetAbsLSpace()); } CPPUNIT_TEST_FIXTURE(SdImportTest2, testTdf150770) commit 2aefd994b7422516ff0da46f23d57fa203ba9027 Author: Michael Weghorn <[email protected]> AuthorDate: Tue Feb 24 09:43:56 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:32:08 2026 +0100 tdf#170805 extension mgr: Don't destroy dialog while still needed commit 5a6985c124c7a0ca246fbc920ab5e024d72a5e4a Author: Michael Weghorn <[email protected]> Date: Sat Nov 8 09:42:17 2025 +0100 tdf#169318 extension mgr: Deduplicate close logic extended TheExtensionManager::Close to also reset TheExtensionManager::m_xExtMgrDialog, i.e. delete the extension manager dialog. That is fine for the callers newly added in the above commit. However, for the preexisting case in ServiceImpl::startExecuteModal, the call to TheExtensionManager::checkUpdates a few lines above the call to TheExtensionManager::Close triggers a separate update thread that still wants to use the dialog after it gets closed, causing a crash. (Can be triggered e.g. by installing older version 6.3 of the LanguageTool extension [1], then "Help" -> "Check for Updates", closing that dialog, then clicking the "Updates for extensions available" button in the menu bar; requires a build with --enable-online-update enabled.) Don't destroy the dialog there, but only close the dialog itself, by calling weld::Dialog::response instead. Make the "destructive" TheExtensionManager::Close private. [1] https://extensions.libreoffice.org/en/extensions/show/languagetool Change-Id: I370b357fe4db435489366afbf1b3003770d6a209 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200151 Reviewed-by: Michael Weghorn <[email protected]> Tested-by: Jenkins (cherry picked from commit 5f626a166ed8b7917c8acc40652a7dcc696fa137) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200271 Reviewed-by: Mike Kaganski <[email protected]> diff --git a/desktop/source/deployment/gui/dp_gui_service.cxx b/desktop/source/deployment/gui/dp_gui_service.cxx index ade7cb6fc47e..2045e4e52c4d 100644 --- a/desktop/source/deployment/gui/dp_gui_service.cxx +++ b/desktop/source/deployment/gui/dp_gui_service.cxx @@ -250,7 +250,7 @@ void ServiceImpl::startExecuteModal( { myExtMgr->checkUpdates(); if ( bCloseDialog ) - myExtMgr->Close(); + rDialog.getDialog()->response(RET_CANCEL); else myExtMgr->ToTop(); } diff --git a/desktop/source/deployment/gui/dp_gui_theextmgr.hxx b/desktop/source/deployment/gui/dp_gui_theextmgr.hxx index 8e85372344df..dbfe0b76ff3f 100644 --- a/desktop/source/deployment/gui/dp_gui_theextmgr.hxx +++ b/desktop/source/deployment/gui/dp_gui_theextmgr.hxx @@ -87,7 +87,6 @@ public: void SetText( const OUString &rTitle ); void Show(); void ToTop(); - void Close(); bool isVisible(); @@ -116,6 +115,9 @@ public: // XModifyListener virtual void SAL_CALL modified( css::lang::EventObject const & evt ) override; + +private: + void Close(); }; } // namespace dp_gui commit c83e1374893a54a8fbc776930162bc2bd3e0ee53 Author: Mike Kaganski <[email protected]> AuthorDate: Thu Feb 26 16:50:12 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:32:08 2026 +0100 tdf#171041: avoid setting mbUsePrintSetting for automatic orientation Commit a67cd7b3cf03163f87811f7080cabc49750c4fd5 (tdf#155218 sc: fix different page orientation in print dialog, 2024-02-09) introduced Printer::SetUsePrintDialogSetting, used to change print settings to use what's configured in the dialog, instead of document. It was called unconditionally in PrintDialog::updatePageSize; but for automatic orientation, that breaks autodetection of the orientation in ScModelObj::getRenderer. This change only sets mbUsePrintSetting when the orientation in the dialog is not automatic. Change-Id: I0f7be0107e39e73bea8bc37a8f160f271f3242cb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200456 Tested-by: Jenkins Reviewed-by: Mike Kaganski <[email protected]> (cherry picked from commit b7957bf31e05dc55015e41c9dfcaa7e26b533eef) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200498 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index 243d7aed1299..bbc8a7ee1e76 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -1044,7 +1044,7 @@ void PrintDialog::updatePageSize(int nOrientation) aSize = getJobPageSize(); aPrt->SetPrintPageSize(aSize); - aPrt->SetUsePrintDialogSetting(true); + aPrt->SetUsePrintDialogSetting(nOrientation != ORIENTATION_AUTOMATIC); } void PrintDialog::updateOrientationBox( const bool bAutomatic ) commit 176bd9d9d1f1417bf4d22b310aedd9679f4d7483 Author: Xisco Fauli <[email protected]> AuthorDate: Wed Feb 25 17:57:39 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:32:08 2026 +0100 tdf#168057: use RoleMapNS in PDF/UA-2 This commit reverts my previous attempt at fixing the same issue commit 5dbf35a932bfa00e17f17b1f2337de7403754b8d Author: Xisco Fauli <[email protected]> Date: Wed Feb 25 12:54:41 2026 +0100 tdf#168057: Don't use aliases in StructElem when exporting to PDF/UA-2 The unittest has been removed in the backport because the verapdf validator is only available in master Change-Id: I20ef86c780224909a7fa9414fea628415289af60 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200350 Tested-by: Jenkins Reviewed-by: Xisco Fauli <[email protected]> Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200352 Reviewed-by: Tomaž Vajngerl <[email protected]> diff --git a/vcl/source/pdf/pdfwriter_impl.cxx b/vcl/source/pdf/pdfwriter_impl.cxx index ca0a7728db04..1e2cbd327738 100644 --- a/vcl/source/pdf/pdfwriter_impl.cxx +++ b/vcl/source/pdf/pdfwriter_impl.cxx @@ -1022,11 +1022,21 @@ void PDFWriterImpl::emitNamespaces() if (!updateObject(nObject)) return; - COSWriter aWriter(m_aContext.Encryption.getParams(), m_pPDFEncryptor); + OStringBuffer aLine; + COSWriter aWriter(aLine, m_aContext.Encryption.getParams(), m_pPDFEncryptor); aWriter.startObject(nObject); aWriter.startDict(); aWriter.write("/Type", "/Namespace"); aWriter.writeKeyAndLiteral("/NS", sNamespace); + if( ! m_aRoleMap.empty() ) + { + aLine.append( "/RoleMapNS<<" ); + for (auto const& role : m_aRoleMap) + { + aLine.append( "/" + role.first + "/" + role.second + " " ); + } + aLine.append( ">> " ); + } aWriter.endDict(); aWriter.endObject(); commit 08c1ae754ecb6c1a2ff115a76229f9bd06dc62fc Author: Caolán McNamara <[email protected]> AuthorDate: Sun Feb 22 21:39:08 2026 +0000 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:32:08 2026 +0100 Resolves: tdf#134725 Don't signal for empty text The Formatter has IsEmptyFieldEnabled enabled, so empty values are intended to be no-change. Change-Id: Idb91317eda608a477ef480335665591e849a5a69 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199998 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> (cherry picked from commit 31d47a2d703a756768524b62e540019b84b9cb89) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200163 Reviewed-by: Adolfo Jayme Barrientos <[email protected]> diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 0f76bc2173f7..bc2eefd6f44f 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -5737,7 +5737,13 @@ IMPL_LINK_NOARG(SalInstanceSpinButton, ActivateHdl, Edit&, bool) IMPL_LINK_NOARG(SalInstanceSpinButton, UpDownHdl, SpinField&, void) { signal_value_changed(); } -IMPL_LINK_NOARG(SalInstanceSpinButton, LoseFocusHdl, Control&, void) { signal_value_changed(); } +IMPL_LINK_NOARG(SalInstanceSpinButton, LoseFocusHdl, Control&, void) +{ + // tdf#134725 Don't signal for empty text, the Formatter has IsEmptyFieldEnabled + // enabled, so empty values are intended to be no-change. + if (!m_xButton->GetText().isEmpty()) + signal_value_changed(); +} IMPL_LINK(SalInstanceSpinButton, OutputHdl, double, fValue, std::optional<OUString>) { commit dfa7d2eedb076b91113a62844753fc784e62a9d0 Author: Saburo Yoshida <[email protected]> AuthorDate: Mon Feb 23 16:44:53 2026 +0900 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:32:08 2026 +0100 tdf#170448 PDF property characters were XML escaped multiple times e.g. apostrophe &apos; --> ' Change-Id: I6bfedffef0244c945872438f2a9d74523bb717ac Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200027 Tested-by: Jenkins Reviewed-by: Noel Grandin <[email protected]> (cherry picked from commit e876be508061f9651a03f689fd2aea9451f7fc35) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200173 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/vcl/source/pdf/pdfwriter_impl.cxx b/vcl/source/pdf/pdfwriter_impl.cxx index cd756e0fd1bb..ca0a7728db04 100644 --- a/vcl/source/pdf/pdfwriter_impl.cxx +++ b/vcl/source/pdf/pdfwriter_impl.cxx @@ -4967,7 +4967,7 @@ static void lcl_assignMeta(std::u16string_view aValue, OString& aMeta) { if (!aValue.empty()) { - aMeta = OUStringToOString(comphelper::string::encodeForXml(aValue), RTL_TEXTENCODING_UTF8); + aMeta = OUStringToOString(aValue, RTL_TEXTENCODING_UTF8); } } commit 3319f76a70f55d382cbc98098562998457689ff7 Author: Māris Nartišs <[email protected]> AuthorDate: Wed Feb 18 21:03:54 2026 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:32:08 2026 +0100 tdf#168138 skia: fix XPutImage BadMatch on 32-bit X11 windows RasterWindowContext_xlib::onSwapBuffers() hardcoded image.depth=24, but LibreOffice's BestVisual() prefers 32-bit TrueColor visuals when available, making window drawables depth=32. XPutImage requires XImage.depth to exactly match the target drawable's depth, so a mismatch causes an asynchronous X11 BadMatch error and crash at the next X11 call. Fix by querying the actual window depth via XGetWindowAttributes in the constructor and using it instead of the hardcoded 24. Change-Id: I202a350ed1159e8322c00821df2c6c5e7391382b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199648 Reviewed-by: Xisco Fauli <[email protected]> Tested-by: Jenkins Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199852 diff --git a/external/skia/UnpackedTarball_skia.mk b/external/skia/UnpackedTarball_skia.mk index 692eba0130e5..55a3056577e5 100644 --- a/external/skia/UnpackedTarball_skia.mk +++ b/external/skia/UnpackedTarball_skia.mk @@ -44,6 +44,7 @@ skia_patches := \ 0004-loong64-Fix-the-remaining-implicit-vector-casts.patch \ msvc-unknown-attributes.patch.1 \ fix-semaphore-include.patch.1 \ + fix-xputimage-depth.patch.1 \ ifneq ($(MSYSTEM),) # use binary flag so patch from git-bash won't choke on mixed line-endings in patches diff --git a/external/skia/fix-xputimage-depth.patch.1 b/external/skia/fix-xputimage-depth.patch.1 new file mode 100644 index 000000000000..0250af76bd70 --- /dev/null +++ b/external/skia/fix-xputimage-depth.patch.1 @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: LibreOffice +Date: Wed, 18 Feb 2026 00:00:00 +0000 +Subject: [PATCH] Fix XPutImage BadMatch on 32-bit X11 windows + +RasterWindowContext_xlib::onSwapBuffers() hardcoded image.depth = 24, +but the target X11 window may have depth 32 (when BestVisual() selects +a 32-bit TrueColor visual, which is preferred for compositing). +XPutImage requires image.depth to exactly match the drawable's depth; +mismatched depth results in a BadMatch X11 error. + +Fix: query the actual window depth once during construction via +XGetWindowAttributes and store it as fDepth, then use fDepth instead of +the hardcoded 24 in onSwapBuffers. +--- + tools/window/unix/RasterWindowContext_unix.cpp | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- skia.org/tools/window/unix/RasterWindowContext_unix.cpp ++++ skia/tools/window/unix/RasterWindowContext_unix.cpp +@@ -34,6 +34,7 @@ + Display* fDisplay; + XWindow fWindow; + GC fGC; ++ int fDepth; + }; + + RasterWindowContext_xlib::RasterWindowContext_xlib(Display* display, +@@ -43,6 +44,9 @@ + std::unique_ptr<const DisplayParams> params) + : RasterWindowContext(std::move(params)), fDisplay(display), fWindow(window) { + fGC = XCreateGC(fDisplay, fWindow, 0, nullptr); ++ XWindowAttributes attrs; ++ XGetWindowAttributes(fDisplay, fWindow, &attrs); ++ fDepth = attrs.depth; + this->resize(width, height); + fWidth = width; + fHeight = height; +@@ -79,7 +83,7 @@ + image.bitmap_unit = bitsPerPixel; + image.bitmap_bit_order = LSBFirst; + image.bitmap_pad = bitsPerPixel; +- image.depth = 24; ++ image.depth = fDepth; + image.bytes_per_line = pm.rowBytes() - pm.width() * pm.info().bytesPerPixel(); + image.bits_per_pixel = bitsPerPixel; + if (!XInitImage(&image)) { commit 6a8976f207cb0fa0433a8e33232382ac7835b3a6 Author: Caolán McNamara <[email protected]> AuthorDate: Sun Feb 22 17:38:20 2026 +0000 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:31:12 2026 +0100 Resolves: tdf#130586 reset mbPageEventOccurred in observation start mbPageEventOccurred was never reset between observations, so after a undo/redo involving page insertion/deletion, another undo/redo operation (e.g. layout changes) would assume it needed to do a fresh page selection. seen as a regression at: commit 13dfaa3c3704a5a963f9e1e5d45796472f43c80e Date: Fri Dec 13 12:47:54 2019 +0000 Resolves: tdf#129346 if nothing currently selected, select something in the slidesorter but really a problem since: commit a05fe3a8cfd4ec420eb6969d98f64e4308f14230 Date: Tue Nov 21 12:38:21 2017 +0000 Resolves: tdf#100950 only update page selection if pages changed Change-Id: I86169faa9f0b2b2972dfe7065b29f94f6c6bcb85 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199990 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> (cherry picked from commit c963b8a01715f3b190d9ad38499b76fe48c4e3b1) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200035 Reviewed-by: Adolfo Jayme Barrientos <[email protected]> diff --git a/sd/qa/uitest/impress_tests2/tdf130586.py b/sd/qa/uitest/impress_tests2/tdf130586.py new file mode 100644 index 000000000000..0a8bf5e89205 --- /dev/null +++ b/sd/qa/uitest/impress_tests2/tdf130586.py @@ -0,0 +1,54 @@ +# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +from uitest.framework import UITestCase +from libreoffice.uno.propertyvalue import mkPropertyValues + +class tdf130586(UITestCase): + + def test_run(self): + with self.ui_test.create_doc_in_start_center("impress") as document: + xTemplateDlg = self.xUITest.getTopFocusWindow() + xCancelBtn = xTemplateDlg.getChild("close") + self.ui_test.close_dialog_through_button(xCancelBtn) + + xToolkit = self.xContext.ServiceManager.createInstance('com.sun.star.awt.Toolkit') + + self.assertEqual(document.CurrentController.getCurrentPage().Number, 1) + + # Insert a new slide + self.xUITest.executeCommand(".uno:InsertPage") + xToolkit.processEventsToIdle() + self.assertEqual(document.CurrentController.getCurrentPage().Number, 2) + + # Change layout on slide 2 + self.xUITest.executeCommand(".uno:AssignLayout?WhatLayout:long=1") + xToolkit.processEventsToIdle() + self.assertEqual(document.CurrentController.getCurrentPage().Number, 2) + + # Undo x2 (undo layout change, then undo insert slide) + self.xUITest.executeCommand(".uno:Undo") + xToolkit.processEventsToIdle() + self.assertEqual(document.CurrentController.getCurrentPage().Number, 2) + + self.xUITest.executeCommand(".uno:Undo") + xToolkit.processEventsToIdle() + self.assertEqual(document.CurrentController.getCurrentPage().Number, 1) + + # Redo x2 (redo insert slide, then redo layout change) + self.xUITest.executeCommand(".uno:Redo") + xToolkit.processEventsToIdle() + self.assertEqual(document.CurrentController.getCurrentPage().Number, 2) + + self.xUITest.executeCommand(".uno:Redo") + xToolkit.processEventsToIdle() + # Without the fix, this would fail with AssertionError: 2 != 1 + self.assertEqual(document.CurrentController.getCurrentPage().Number, 2) + +# vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx index ba835c23b003..e5bc5ada632f 100644 --- a/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSelectionObserver.cxx @@ -90,6 +90,7 @@ void SelectionObserver::StartObservation() OSL_ASSERT(!mbIsObservationActive); maInsertedPages.clear(); mbIsObservationActive = true; + mbPageEventOccurred = false; } void SelectionObserver::AbortObservation() commit d11a9d7aeccf3a53994064d87563e25744ba200a Author: Xisco Fauli <[email protected]> AuthorDate: Fri Feb 20 15:55:42 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:31:12 2026 +0100 tdf#167290: export CreationDate with DateTime format Otherwise, the validator fails with "The value of CreationDate entry from the document Info dictionary and its matching XMP property "xmp:CreateDate" are not equivalent (Info /CreationDate = D:20260220154049+01'00', XMP xmp:CreateDate = 2025-12-31T11:13:40.000+01) The call to osl_getDateTimeFromTimeValue was removed in commit 07ac61f2c67020ad2941462ea7081f06495bcb92 Author: Sarper Akdemir <[email protected]> Date: Mon Aug 28 11:16:34 2023 +0300 tdf#138792: PDF export: fix date of xmp:CreateDate for no apparent reason In libreoffice-26-2 and libreoffice-25-8 the test doesn't work because the verapdf validator is not implemented Change-Id: I4c6948769797a4e446239316de2857851b31565e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199886 Tested-by: Jenkins Reviewed-by: Xisco Fauli <[email protected]> Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199907 Reviewed-by: Adolfo Jayme Barrientos <[email protected]> diff --git a/vcl/source/pdf/pdfwriterimpl_utils.cxx b/vcl/source/pdf/pdfwriterimpl_utils.cxx index c553618942db..bf051f8fa44c 100644 --- a/vcl/source/pdf/pdfwriterimpl_utils.cxx +++ b/vcl/source/pdf/pdfwriterimpl_utils.cxx @@ -237,6 +237,7 @@ void computeDocumentIdentifier(std::vector<sal_uInt8>& o_rIdentifier, osl_getSystemTime(&aGMT); osl_getLocalTimeFromSystemTime(&aGMT, &aTVal); + osl_getDateTimeFromTimeValue( &aTVal, &aDT ); OStringBuffer aCreationMetaDateString(64); // i59651: we fill the Metadata date string as well, if PDF/A is requested commit 35b1839f41ef663198727f4aaa36962c395216dd Author: Bartosz Kosiorek <[email protected]> AuthorDate: Fri Feb 20 00:23:01 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:31:12 2026 +0100 tdf#138087 tdf#142548 EMF Fix font scaling and orientation in GM_COMPATIBLE When importing EMF files, certain records (like EXTTEXTOUTW) in GM_COMPATIBLE mode were not respecting non-proportional scaling or single-axis mirroring. This resulted in text that was too wide/narrow or rotated in the wrong direction. Key changes: - Added font width scaling based on the ratio between fXScale and fYScale. - Handled 180-degree rotation when both axes are negative. - Corrected font orientation for single-axis mirroring by inverting the angle (3600 - orientation) to compensate for the reversed chirality of the coordinate system. Change-Id: Ib1126c192a80b973f343f25bf20ec119d94d71a8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199770 Tested-by: Jenkins Reviewed-by: Bartosz Kosiorek <[email protected]> (cherry picked from commit b6857c1f1628caf3f2489390e84e9b5c65c3e0b1) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200034 Reviewed-by: Adolfo Jayme Barrientos <[email protected]> diff --git a/emfio/inc/mtftools.hxx b/emfio/inc/mtftools.hxx index 7d1c99923b24..8b11fb46ef9d 100644 --- a/emfio/inc/mtftools.hxx +++ b/emfio/inc/mtftools.hxx @@ -807,6 +807,8 @@ namespace emfio OUString const & rString, KernArray* pDXArry = nullptr, tools::Long* pDYArry = nullptr, + const float fXScale = 1.0, + const float fYScale = 1.0, bool bRecordPath = false, GraphicsMode nGraphicsMode = GraphicsMode::GM_COMPATIBLE); diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx index a948a2936ec5..7b41842daa0d 100644 --- a/emfio/qa/cppunit/emf/EmfImportTest.cxx +++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx @@ -1317,6 +1317,49 @@ CPPUNIT_TEST_FIXTURE(Test, testExtTextOutOpaqueAndClipTransform) u"#000000"); } +CPPUNIT_TEST_FIXTURE(Test, testExtTextOutScaleGM_COMPATIBLE) +{ + // tdf#142495 EMF records: EXTTEXTOUTW with GM_COMPATIBLE. + Primitive2DSequence aSequence + = parseEmf(u"/emfio/qa/cppunit/emf/data/TestExtTextOutScaleGM_COMPATIBLE.emf"); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); + drawinglayer::Primitive2dXmlDump dumper; + xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence)); + CPPUNIT_ASSERT(pDocument); + + assertXPath(pDocument, aXPathPrefix + "textsimpleportion", 4); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[1]", "text", u"Obliquité (ºC)"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[1]", "fontcolor", u"#202020"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[1]", "width", u"317"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[1]", "height", u"317"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[1]", "dx0", u"254"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[1]", "dx1", u"450"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[1]", "dx2", u"544"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[1]", "dx3", u"638"); + + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[2]", "text", u"23"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[2]", "fontcolor", u"#000000"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[2]", "width", u"161"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[2]", "height", u"317"); + + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[3]", "text", u"24"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[3]", "fontcolor", u"#000000"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[3]", "width", u"201"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[3]", "height", u"317"); + + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[4]", "text", u"25"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[4]", "fontcolor", u"#000000"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[4]", "width", u"268"); + assertXPath(pDocument, aXPathPrefix + "textsimpleportion[4]", "height", u"317"); + + assertXPath(pDocument, aXPathPrefix + "polygonstroke", 9); + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor", 3); + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[1]/polypolygon", "path", + u"m0 0v21589h27944v-21589z"); + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[2]/polypolygon", "path", + u"m24258 16413v264h383v-264z"); +} + CPPUNIT_TEST_FIXTURE(Test, testUnderlineTransparentBackground) { // EMF with SETBKMODE=TRANSPARENT, SETBKCOLOR=black, underlined font, and EXTTEXTOUTW "TEST". @@ -1661,13 +1704,15 @@ CPPUNIT_TEST_FIXTURE(Test, testCreatePen) assertXPath(pDocument, aXPathPrefix + "mask/polygonhairline", 10); assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion", 69); - assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[1]", "width", u"374"); + assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[1]", "height", u"374"); + assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[1]", "width", u"310"); assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[1]", "x", u"28124"); assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[1]", "y", u"16581"); assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[1]", "text", u"0.0"); assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[1]", "fontcolor", u"#000000"); - assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[10]", "width", u"266"); + assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[10]", "height", u"266"); + assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[10]", "width", u"221"); assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[10]", "x", u"28000"); assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[10]", "y", u"428"); assertXPath(pDocument, aXPathPrefix + "mask/textsimpleportion[10]", "text", u"-6"); diff --git a/emfio/qa/cppunit/emf/data/TestExtTextOutScaleGM_COMPATIBLE.emf b/emfio/qa/cppunit/emf/data/TestExtTextOutScaleGM_COMPATIBLE.emf new file mode 100644 index 000000000000..7df2e3d92077 Binary files /dev/null and b/emfio/qa/cppunit/emf/data/TestExtTextOutScaleGM_COMPATIBLE.emf differ diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx index bd5defcd1cc7..c383a3676c5a 100644 --- a/emfio/source/reader/emfreader.cxx +++ b/emfio/source/reader/emfreader.cxx @@ -1883,16 +1883,16 @@ namespace emfio { sal_Int32 ptlReferenceX, ptlReferenceY; sal_uInt32 nLen, nOptions, nGfxMode; - float nXScale, nYScale; + float fXScale, fYScale; mpInputStream->ReadInt32( ptlReferenceX ).ReadInt32( ptlReferenceY ) .ReadUInt32( nLen ).ReadUInt32( nOptions ) - .ReadUInt32( nGfxMode ).ReadFloat( nXScale ).ReadFloat( nYScale ); + .ReadUInt32( nGfxMode ).ReadFloat( fXScale ).ReadFloat( fYScale ); SAL_INFO("emfio", " Reference: (" << ptlReferenceX << ", " << ptlReferenceY << ")"); SAL_INFO("emfio", " cChars: " << nLen); SAL_INFO("emfio", " fuOptions: 0x" << std::hex << nOptions << std::dec); SAL_INFO("emfio", " iGraphicsMode: 0x" << std::hex << nGfxMode << std::dec); - SAL_INFO("emfio", " Scale: " << nXScale << " x " << nYScale); + SAL_INFO("emfio", " Scale: " << fXScale << " x " << fYScale); // Read optional bounding rectangle (present only if ETO_NO_RECT is NOT set) tools::Rectangle aRect; @@ -1946,7 +1946,7 @@ namespace emfio Push(); IntersectClipRect( aRect ); } - DrawText(aPos, aText, nullptr, nullptr, mbRecordPath, static_cast<GraphicsMode>(nGfxMode)); + DrawText(aPos, aText, nullptr, nullptr, fXScale, fYScale, mbRecordPath, static_cast<GraphicsMode>(nGfxMode)); if ( nOptions & ETO_CLIPPED ) Pop(); mnBkMode = mnBkModeBackup; @@ -1963,7 +1963,7 @@ namespace emfio { sal_Int32 nLeft, nTop, nRight, nBottom; sal_uInt32 nGfxMode; - float nXScale, nYScale; + float fXScale, fYScale; sal_uInt32 ncStrings( 1 ); sal_Int32 ptlReferenceX, ptlReferenceY; sal_uInt32 nLen, nOffString, nOptions, offDx; @@ -1972,10 +1972,10 @@ namespace emfio nCurPos = mpInputStream->Tell() - 8; mpInputStream->ReadInt32( nLeft ).ReadInt32( nTop ).ReadInt32( nRight ).ReadInt32( nBottom ) - .ReadUInt32( nGfxMode ).ReadFloat( nXScale ).ReadFloat( nYScale ); + .ReadUInt32( nGfxMode ).ReadFloat( fXScale ).ReadFloat( fYScale ); SAL_INFO("emfio", " Bounds: " << nLeft << ", " << nTop << ", " << nRight << ", " << nBottom); SAL_INFO("emfio", " iGraphicsMode: 0x" << std::hex << nGfxMode << std::dec); - SAL_INFO("emfio", " Scale: " << nXScale << " x " << nYScale); + SAL_INFO("emfio", " Scale: " << fXScale << " x " << fYScale); if ( ( nRecType == EMR_POLYTEXTOUTA ) || ( nRecType == EMR_POLYTEXTOUTW ) ) { mpInputStream->ReadUInt32( ncStrings ); @@ -2100,7 +2100,7 @@ namespace emfio Push(); // Save the current clip. It will be restored after text drawing IntersectClipRect( aRect ); } - DrawText(aPos, aText, aDXAry.empty() ? nullptr : &aDXAry, pDYAry.get(), mbRecordPath, static_cast<GraphicsMode>(nGfxMode)); + DrawText(aPos, aText, aDXAry.empty() ? nullptr : &aDXAry, pDYAry.get(), fXScale, fYScale, mbRecordPath, static_cast<GraphicsMode>(nGfxMode)); if ( nOptions & ETO_CLIPPED ) Pop(); } diff --git a/emfio/source/reader/mtftools.cxx b/emfio/source/reader/mtftools.cxx index 2fd4b5f28ae5..6043867afb78 100644 --- a/emfio/source/reader/mtftools.cxx +++ b/emfio/source/reader/mtftools.cxx @@ -1685,7 +1685,7 @@ namespace emfio } } - void MtfTools::DrawText( Point& rPosition, OUString const & rText, KernArray* pDXArry, tools::Long* pDYArry, bool bRecordPath, GraphicsMode nGfxMode ) + void MtfTools::DrawText(Point& rPosition, OUString const & rText, KernArray* pDXArry, tools::Long* pDYArry, const float fXScale, const float fYScale, bool bRecordPath, GraphicsMode nGfxMode) { UpdateClipRegion(); rPosition = ImplMap( rPosition ); @@ -1771,6 +1771,8 @@ namespace emfio bChangeFont = true; mpGDIMetaFile->AddAction( new MetaTextFillColorAction( maFont.GetFillColor(), !maFont.IsTransparent() ) ); } + // Create a local copy of the current font to apply transient modifications + // (such as color, alignment, and custom scaling) before recording it to the metafile. vcl::Font aTmp( maFont ); aTmp.SetColor( maTextColor ); @@ -1806,6 +1808,43 @@ namespace emfio aTmp.SetOrientation( aTmp.GetOrientation() + Degree10( static_cast<sal_Int16>(fOrientation) ) ); } } + else if (nGfxMode == GraphicsMode::GM_COMPATIBLE) + { + if (fXScale != 0.0) + { + // As we changing only font width, we are skippin if scales have the same values + const bool bNeedsWidthScale = (std::fabs(fYScale) != std::fabs(fXScale)); + if (bNeedsWidthScale) + { + Size aFontSize = aTmp.GetFontSize(); + const float fTestWidthScale = std::fabs(fYScale / fXScale); + + // If Width is 0, the font is scaled proportionally based on Height. + if (aFontSize.Width() == 0) + aFontSize.setWidth(basegfx::fround<tools::Long>(aFontSize.Height() * fTestWidthScale)); + else + aFontSize.setWidth(basegfx::fround<tools::Long>(aFontSize.Width() * fTestWidthScale)); + aTmp.SetFontSize(aFontSize); + bChangeFont = true; + } + } + + if ((fYScale < 0.0) && (fXScale < 0.0)) + { + // Both scales negative = 180 degree rotation. vcl::Font handles this perfectly. + aTmp.SetOrientation(aTmp.GetOrientation() + Degree10(1800)); + } + else if ((fYScale < 0.0) || (fXScale < 0.0)) + { + // Single-axis mirroring. + // In GM_COMPATIBLE, text glyphs are NOT physically mirrored. + // However, the flipped coordinate system reverses the rotation direction. + // Inverting the angle (360 degrees - current angle) fixes the text direction. + aTmp.SetOrientation(Degree10(3600) - aTmp.GetOrientation()); + + // TODO: True single-axis glyph mirroring would require a MapMode transform here + } + } if( mnTextAlign & ( TA_UPDATECP | TA_RIGHT_CENTER ) ) { commit bb88a1aba61f990c27682e71a8cae5357e980174 Author: Heiko Tietze <[email protected]> AuthorDate: Mon Jan 12 12:55:16 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:31:11 2026 +0100 Related tdf#170143 - Stylist text color should consider themed colors DialogColor is not part of the themed colors, and WindowTextColor might be better suited anyway Change-Id: Ie52cd239cf44f96b15c1e3085d70fd2de62aa676 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197094 Tested-by: Jenkins Reviewed-by: Heiko Tietze <[email protected]> (cherry picked from commit 8855e318f81651f7aff33cf12d27a37b4abe87fa) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199981 Reviewed-by: Mihai Vasiliu <[email protected]> diff --git a/sfx2/source/dialog/StyleList.cxx b/sfx2/source/dialog/StyleList.cxx index fe23f59cc1db..27a2a675302b 100644 --- a/sfx2/source/dialog/StyleList.cxx +++ b/sfx2/source/dialog/StyleList.cxx @@ -1798,7 +1798,7 @@ IMPL_LINK(StyleList, CustomRenderHdl, weld::TreeView::render_args, aPayload, voi if (bSelected) rRenderContext.SetTextColor(rStyleSettings.GetHighlightTextColor()); else - rRenderContext.SetTextColor(rStyleSettings.GetDialogTextColor()); + rRenderContext.SetTextColor(rStyleSettings.GetWindowTextColor()); bool bSuccess = false; commit f04db72c9f79f089cc2fe9e8d5de636de90a6c84 Author: Caolán McNamara <[email protected]> AuthorDate: Sun Feb 22 14:47:26 2026 +0000 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:31:11 2026 +0100 GLib-GObject-CRITICAL invalid cast from 'GtkImage' to 'GtkLabel' Change-Id: I1cb15c904a5ea69ba97301b87ab2bd345a934ea9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199987 Tested-by: Jenkins Reviewed-by: Adolfo Jayme Barrientos <[email protected]> diff --git a/sw/uiconfig/swriter/ui/watermarkdialog.ui b/sw/uiconfig/swriter/ui/watermarkdialog.ui index 904d8cde3dc0..bf7b2dafb7d1 100644 --- a/sw/uiconfig/swriter/ui/watermarkdialog.ui +++ b/sw/uiconfig/swriter/ui/watermarkdialog.ui @@ -222,6 +222,7 @@ <property name="receives-default">True</property> <property name="xalign">0</property> <property name="draw-indicator">True</property> + <property name="label" translatable="no"></property> <child> <placeholder/> </child> commit 5bb37572b3d8fbf8423debb3e4a55f92b9666f8e Author: Caolán McNamara <[email protected]> AuthorDate: Sat Feb 21 16:32:41 2026 +0000 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:31:11 2026 +0100 Resolves: tdf#166902 ensure right clicked entry is selected Change-Id: Icee19b56e750ce525674a44a109f0fd52dab509a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199952 Reviewed-by: Adolfo Jayme Barrientos <[email protected]> Tested-by: Jenkins diff --git a/sw/source/uibase/utlui/glbltree.cxx b/sw/source/uibase/utlui/glbltree.cxx index ab9aa234ccfc..27f070aa154a 100644 --- a/sw/source/uibase/utlui/glbltree.cxx +++ b/sw/source/uibase/utlui/glbltree.cxx @@ -272,6 +272,16 @@ IMPL_LINK(SwGlobalTree, CommandHdl, const CommandEvent&, rCEvt, bool) bool bPop = false; if (m_pActiveShell && !m_pActiveShell->GetView().GetDocShell()->IsReadOnly()) { + // tdf#166902 ensure right clicked entry is selected + if (std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator()); + rCEvt.IsMouseEvent() && m_xTreeView->get_dest_row_at_pos( + rCEvt.GetMousePosPixel(), xEntry.get(), false)) + { + // if clicked entry is not currently selected then clear selections and select it + if (!m_xTreeView->is_selected(*xEntry)) + m_xTreeView->set_cursor(*xEntry); + } + std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xTreeView.get(), u"modules/swriter/ui/mastercontextmenu.ui"_ustr)); std::unique_ptr<weld::Menu> xPopup = xBuilder->weld_menu(u"navmenu"_ustr); std::unique_ptr<weld::Menu> xSubPopup = xBuilder->weld_menu(u"insertmenu"_ustr); commit f9c85a55bea2b9541aea4103f96ab90eb6b3aaa0 Author: Mike Kaganski <[email protected]> AuthorDate: Fri Feb 20 16:31:14 2026 +0500 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:30:23 2026 +0100 tdf#170910: exact match can also be rotated For Microsoft XPS Document Writer printer, the paper list is very logn, and contains duplicates (e.g., two portrait Letter), as well as rotated variants (e.g., landscape Letter). The code that looks for matching paper in setPaperSizes would find all elelemts with matching Paper value, regardless of orientation; and would use the last match. It happened, that for A4 and Letter, the last matches were landscape, so the perfect portrait-oriented matches would get skipped. This change checks orientation for exact matches as well; and will prefer the first found best match. Change-Id: Iaa93292ef60b94ab1f807b21e8a3494099c0b002 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199841 Tested-by: Jenkins Reviewed-by: Mike Kaganski <[email protected]> (cherry picked from commit d8a3c74a10e70bae243162cb08572a9c2f2552a3) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199888 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index 976242be6eee..243d7aed1299 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -823,6 +823,7 @@ void PrintDialog::setPaperSizes() #endif { int nExactMatch = -1; + int nExactRotatedMatch = -1; int nSizeMatch = -1; int nRotatedSizeMatch = -1; Size aSizeOfPaper = aPrt->GetSizeOfPaper(); @@ -860,8 +861,15 @@ void PrintDialog::setPaperSizes() mxPaperSizeBox->append_text(aPaperName); + // For exact match, check that paper orientation also matches if (ePaper != PAPER_USER && ePaper == mePaper) - nExactMatch = nPaper; + { + // Only get the first match, in case there are multiple papers with the same size + if (nExactMatch == -1 && aInfo.sloppyEqual(aPaperInfo)) + nExactMatch = nPaper; + else if (nExactRotatedMatch == -1 && aInfo.sloppyEqual(aRotatedPaperInfo)) + nExactRotatedMatch = nPaper; + } if (ePaper == PAPER_USER && aInfo.sloppyEqual(aPaperInfo)) nSizeMatch = nPaper; @@ -872,6 +880,8 @@ void PrintDialog::setPaperSizes() if (nExactMatch != -1) mxPaperSizeBox->set_active(nExactMatch); + else if (nExactRotatedMatch != -1) + mxPaperSizeBox->set_active(nExactRotatedMatch); else if (nSizeMatch != -1) mxPaperSizeBox->set_active(nSizeMatch); else if (nRotatedSizeMatch != -1) commit e177459530cc055927933338772cda739f352684 Author: Mike Kaganski <[email protected]> AuthorDate: Fri Feb 20 15:49:02 2026 +0500 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:30:23 2026 +0100 tdf#162488: do not assume printer drivers only providing portrait paper This assumption is false e.g. for Microsoft XPS Document Writer, where both portrait and landscape paper are in the list. The orientation and the size of the paper must be detected from the dimensions. Change-Id: Ibcfc68f64243ec144743a385f73586ca67f0cbe5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199824 Reviewed-by: Mike Kaganski <[email protected]> Tested-by: Jenkins (cherry picked from commit 6171ccd8e6a4ee668fa526f8351e1b4e4fa0a0e2) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199876 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/i18nutil/source/utility/paper.cxx b/i18nutil/source/utility/paper.cxx index f774b1998554..ddad0b26d202 100644 --- a/i18nutil/source/utility/paper.cxx +++ b/i18nutil/source/utility/paper.cxx @@ -376,20 +376,29 @@ PaperInfo::PaperInfo(Paper eType) : m_eType(eType) m_nPaperHeight = aDinTab[m_eType].m_nHeight; } -PaperInfo::PaperInfo(tools::Long nPaperWidth, tools::Long nPaperHeight) +PaperInfo::PaperInfo(tools::Long nPaperWidth, tools::Long nPaperHeight, bool bAlsoTryRotated) : m_eType(PAPER_USER), m_nPaperWidth(nPaperWidth), m_nPaperHeight(nPaperHeight) { for ( size_t i = 0; i < nTabSize; ++i ) { - if ( - (nPaperWidth == aDinTab[i].m_nWidth) && - (nPaperHeight == aDinTab[i].m_nHeight) - ) + if (nPaperWidth == aDinTab[i].m_nWidth && nPaperHeight == aDinTab[i].m_nHeight) { m_eType = static_cast<Paper>(i); - break; + return; + } + } + if (!bAlsoTryRotated) + return; + // Only check rotated dimensions after completing the normal pass, because there are pairs like + // Tabloid (11x17) / Ledger (17x11) in aDinTab + for ( size_t i = 0; i < nTabSize; ++i ) + { + if (nPaperHeight == aDinTab[i].m_nWidth && nPaperWidth == aDinTab[i].m_nHeight) + { + m_eType = static_cast<Paper>(i); + return; } } } diff --git a/include/i18nutil/paper.hxx b/include/i18nutil/paper.hxx index c097727cfa7c..84be74be1ee3 100644 --- a/include/i18nutil/paper.hxx +++ b/include/i18nutil/paper.hxx @@ -136,7 +136,7 @@ class I18NUTIL_DLLPUBLIC PaperInfo tools::Long m_nPaperHeight; // height in 100thMM public: PaperInfo(Paper eType); - PaperInfo(tools::Long nPaperWidth, tools::Long nPaperHeight); + PaperInfo(tools::Long nPaperWidth, tools::Long nPaperHeight, bool bAlsoTryRotated = false); Paper getPaper() const { return m_eType; } tools::Long getWidth() const { return m_nPaperWidth; } diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx index 095518fda0e6..3eef89a70d51 100644 --- a/vcl/source/gdi/print.cxx +++ b/vcl/source/gdi/print.cxx @@ -58,10 +58,10 @@ int nImplSysDialog = 0; namespace { - Paper ImplGetPaperFormat( tools::Long nWidth100thMM, tools::Long nHeight100thMM ) + Paper ImplGetPaperFormat( tools::Long nWidth100thMM, tools::Long nHeight100thMM, bool bAlsoTryRotated = false ) { PaperInfo aInfo(nWidth100thMM, nHeight100thMM); - aInfo.doSloppyFit(); + aInfo.doSloppyFit(bAlsoTryRotated); return aInfo.getPaper(); } @@ -1211,15 +1211,16 @@ void Printer::ImplFindPaperFormatForUserSize( JobSetup& aJobSetup ) if ( aInfo.sloppyEqual(rPaperInfo) ) { rData.SetPaperFormat( - ImplGetPaperFormat( rPaperInfo.getWidth(), - rPaperInfo.getHeight() )); - rData.SetOrientation( Orientation::Portrait ); + ImplGetPaperFormat(rPaperInfo.getWidth(), rPaperInfo.getHeight(), true)); + rData.SetOrientation(rPaperInfo.getWidth() <= rPaperInfo.getHeight() + ? Orientation::Portrait + : Orientation::Landscape); return; } } // If the printer supports landscape orientation, check paper sizes again - // with landscape orientation. This is necessary as a printer driver provides + // with landscape orientation. This is necessary as many printer drivers provide // all paper sizes with portrait orientation only!! if ( !(rData.GetPaperFormat() == PAPER_USER && nLandscapeAngle != 0 && @@ -1237,9 +1238,10 @@ void Printer::ImplFindPaperFormatForUserSize( JobSetup& aJobSetup ) if ( aRotatedInfo.sloppyEqual( rPaperInfo ) ) { rData.SetPaperFormat( - ImplGetPaperFormat( rPaperInfo.getWidth(), - rPaperInfo.getHeight() )); - rData.SetOrientation( Orientation::Landscape ); + ImplGetPaperFormat(rPaperInfo.getWidth(), rPaperInfo.getHeight(), true)); + rData.SetOrientation(rPaperInfo.getWidth() < rPaperInfo.getHeight() + ? Orientation::Landscape + : Orientation::Portrait); return; } } diff --git a/vcl/win/gdi/salprn.cxx b/vcl/win/gdi/salprn.cxx index 07c5666a46fe..519d62f861c7 100644 --- a/vcl/win/gdi/salprn.cxx +++ b/vcl/win/gdi/salprn.cxx @@ -910,7 +910,7 @@ static void ImplJobSetupToDevMode( WinSalInfoPrinter const * pPrinter, const Imp } // If the printer supports landscape orientation, check paper sizes again - // with landscape orientation. This is necessary as a printer driver provides + // with landscape orientation. This is necessary as many printer drivers provide // all paper sizes with portrait orientation only!! if ( !nPaper && nLandscapeAngle != 0 ) { @@ -1105,7 +1105,7 @@ void WinSalInfoPrinter::InitPaperFormats( const ImplJobSetup* pSetupData ) for( DWORD i = 0; i < nCount; ++i ) { - PaperInfo aInfo(pPaperSizes[i].x * 10, pPaperSizes[i].y * 10); + PaperInfo aInfo(pPaperSizes[i].x * 10, pPaperSizes[i].y * 10, true); m_aPaperFormats.push_back( aInfo ); } std::free( pNamesBuffer ); commit 240ef30cbb7a2733b6e020377f234ab033f2dea6 Author: Jonathan Clark <[email protected]> AuthorDate: Wed Feb 18 22:55:22 2026 -0700 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:30:23 2026 +0100 tdf#83350 vcl: Fix RTL UI status bar label positioning Fixes a copy-paste error in one branch of StatusBar::ImplDrawItem. This error caused status bar labels to be rendered as LTR even with RTL UI, which in turn caused most of the labels to overflow their clip regions to the left. Change-Id: I8531bf63772b405e19474519921a8babd7cf1be2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199681 Tested-by: Jenkins Reviewed-by: Jonathan Clark <[email protected]> (cherry picked from commit 00b2fe71be4aa396c8ace272dd6266f9a9bddd2e) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199790 Reviewed-by: Adolfo Jayme Barrientos <[email protected]> diff --git a/vcl/source/window/status.cxx b/vcl/source/window/status.cxx index 16e5d6ec4e0c..5080010f91a2 100644 --- a/vcl/source/window/status.cxx +++ b/vcl/source/window/status.cxx @@ -411,11 +411,13 @@ void StatusBar::ImplDrawItem(vcl::RenderContext& rRenderContext, bool bOffScreen if (bOffScreen) { + mpImplData->mpVirDev->EnableRTL(IsRTLEnabled()); mpImplData->mpVirDev->DrawText( aTextPos, pItem->maText, 0, -1, nullptr, nullptr, pGlyphs ); + mpImplData->mpVirDev->EnableRTL(false); } else { commit 1c87ee2f9d10e52c45a74ef169f9e5bc31355b94 Author: Justin Luth <[email protected]> AuthorDate: Fri Jan 30 18:31:08 2026 -0500 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:29:45 2026 +0100 tdf#166335 followup: remove assert - gluePoint indexes are ~random I spent 6.5 hours trying to 'find something wrong'. Well, apart from 'everything', I didn't find anything that was comprehensible and clearly wrong. So I'll just document that yet another piece of this puzzle is completely unreliable. Change-Id: I53891f73d446264287600f03199b5262b7428d11 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198441 Tested-by: Jenkins Reviewed-by: Justin Luth <[email protected]> (cherry picked from commit d78b115d48156b2fd91216877f3525722683f1bb) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199775 Reviewed-by: Aron Budea <[email protected]> diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 257c3af6c863..b015885f962f 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -5025,8 +5025,14 @@ void prepareGluePoints(std::vector<Guide>& rGuideList, if (rGluePoint.First.Value >>= nIdx1) { bValidIdx1 = rGluePoint.First.Type == EnhancedCustomShapeParameterType::EQUATION; - // I would assume that any EQUATION must define a valid index value. - assert(!bValidIdx1 || (nIdx1 >= 0 && nIdx1 < aEquations.getLength())); + assert(!bValidIdx1 || nIdx1 >= 0); // It is always an index at least + // tdf#166335 + // Sadly, these equation indexes point to a (changed/enlarged) parsed collection, + // but aEquations is the un-parsed collection. + // For larger values, there is a good chance that the wrong equation is used. + // However, this is so complicated that we ignore that, + // and simply make sure we don't export corruption. Inaccuracy is fine... + bValidIdx1 = bValidIdx1 && nIdx1 < aEquations.getLength(); } else continue; @@ -5034,7 +5040,8 @@ void prepareGluePoints(std::vector<Guide>& rGuideList, if (rGluePoint.Second.Value >>= nIdx2) { bValidIdx2 = rGluePoint.Second.Type == EnhancedCustomShapeParameterType::EQUATION; - assert(!bValidIdx2 || (nIdx2 >= 0 && nIdx2 < aEquations.getLength())); + assert(!bValidIdx2 || nIdx2 >= 0); + bValidIdx2 = bValidIdx2 && nIdx2 < aEquations.getLength(); } else continue; commit b4073fddd8198dc37398caae7a5d1ced1b3324b0 Author: Mike Kaganski <[email protected]> AuthorDate: Thu Feb 19 09:07:17 2026 +0500 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:29:45 2026 +0100 tdf#170846: Use tall SwTextFly/SwFlyPortion to move floating table forward Again try to avoid InsertMovedFwdFrame for floating tables (after commit 52172dbd3e290fb92fd8169803c6df5498990466). This time, take into account that a fly frame may be shorter than its table, because SwFlyFrame::Grow_ will limit to the available space. In this case, when the table cannot split, it must move forward as a whole; but the fly's height is small enough to fit in the available space. Previously, table's MoveFwd was used to force the move - which started a complex sequence of finding the next fly; creating it on the next page by splitting the anchor; moving the table; removing the now-empty master fly; merging the split anchor (and possibly starting oscillations in the process). Then, in the commit 52172dbd3e290fb92fd8169803c6df5498990466, InsertMovedFwdFrame was used to force move of anchor forward - but that's a hack, which could prevent normal reflow. With this change, the move forward is expected to happen because last line height will calculate too high (taking into account not only the fly height itself, but also its table). For flys correctly matching their tables, nothing would change; but for too short flys, the correct height will force the normal mechanism of "line is too high -> move it forward". Change-Id: I5319b9539cbe53e776ba5a186b2df314e9fd6b0e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199678 Tested-by: Jenkins Reviewed-by: Mike Kaganski <[email protected]> Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199804 diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index 3ced1af56603..917f4461ac8c 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -3290,27 +3290,6 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext) { // Don't try to move floating table forward. It's done elsewhere moving its fly. bSkipMoveFwd = true; - // Only limit the InsertMovedFwdFrame hack to non-split floating tables for now: - // it seems that split tables don't need it. - if (!IsFollow() && !HasFollow()) - { - // This floating table doesn't fit on this page. Instead of the complex - // MoveFwd sequence (split anchor, create follow fly, move table, destroy - // old fly, merge anchor - which may oscillate), signal the anchor to move - // forward. The fly will follow. - SwTextFrame* pAnchor = pFlyFrame->FindAnchorCharFrame(); - if (pAnchor) - { - SwPageFrame* pPage = pAnchor->FindPageFrame(); - if (pPage) - { - SwLayouter::InsertMovedFwdFrame(pPage->GetFormat()->GetDoc(), - *pAnchor, - pPage->GetPhyPageNum() + 1); - pAnchor->InvalidatePos(); - } - } - } } } // don't make the effort to move fwd if its known diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx index 45df77b30b25..cd19625d5dbe 100644 --- a/sw/source/core/text/txtfly.cxx +++ b/sw/source/core/text/txtfly.cxx @@ -1376,6 +1376,22 @@ SwRect SwTextFly::AnchoredObjToRect( const SwAnchoredObject* pAnchoredObj, if( !aFly.Width() ) return aFly; + if (auto pFlyFrame = pAnchoredObj->DynCastFlyFrame()) + { + if (pFlyFrame->IsFlySplitAllowed() && pFlyFrame->Lower()) + { + // The floating table could be too tall for its fly frame at this point, because the + // fly's Grow_ would limit to only available space. Take the excessive height into + // account here, so that the line can be forced to move to next page (via SwFlyPortion). + + auto aLowerHeight = aRectFnSet.GetHeight(pFlyFrame->Lower()->getFrameArea()); + if (aLowerHeight > aRectFnSet.GetHeight(aFly)) + { + aRectFnSet.SetHeight(aFly, aLowerHeight); + } + } + } + // so the line may grow up to the lower edge of the frame SetNextTop( aRectFnSet.GetBottom(aFly) ); SwAnchoredObjList::size_type nFlyPos = GetPos( pAnchoredObj ); commit e40e0f1b182b9d5260dc164378434a485cfda749 Author: Mike Kaganski <[email protected]> AuthorDate: Tue Feb 17 11:34:00 2026 +0500 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:29:45 2026 +0100 tdf#170846: Use InsertMovedFwdFrame to move floating table forward Partially revert logic of commit 26aa5db06221ab940c65ecc27a2a52bf1ea0eb42 (tdf#170477 follow-up: reimplement the fix by cleaning up code, 2026-01-26). It turned out problematic to completely avoid InsertMovedFwdFrame. But this change does not call InsertMovedFwdFrame after MoveFwd, as in the old code; it uses InsertMovedFwdFrame instead of MoveFwd. Change-Id: If54f6cf18320d76843bb3bfad888b729f50a7a7c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199513 Reviewed-by: Mike Kaganski <[email protected]> Tested-by: Jenkins Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199803 diff --git a/sw/qa/extras/layout/data/tdf170846_1.docx b/sw/qa/extras/layout/data/tdf170846_1.docx new file mode 100644 index 000000000000..b13782ba5514 Binary files /dev/null and b/sw/qa/extras/layout/data/tdf170846_1.docx differ diff --git a/sw/qa/extras/layout/data/tdf170846_2.docx b/sw/qa/extras/layout/data/tdf170846_2.docx new file mode 100644 index 000000000000..e7af0910978e Binary files /dev/null and b/sw/qa/extras/layout/data/tdf170846_2.docx differ diff --git a/sw/qa/extras/layout/layout6.cxx b/sw/qa/extras/layout/layout6.cxx index 75abbc4fc7d5..367802968171 100644 --- a/sw/qa/extras/layout/layout6.cxx +++ b/sw/qa/extras/layout/layout6.cxx @@ -2230,6 +2230,26 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter6, testTdf169999) } } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter6, testTdf170846_1) +{ + // In this document, the whole floating table must move to page 2 + createSwDoc("tdf170846_1.docx"); + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + // Without the fix, the next test failed: + assertXPath(pXmlDoc, "//page[1]//tab", 0); // No tables on page 1 + assertXPath(pXmlDoc, "//page[2]//tab", 1); // One table on page 2 +} + +CPPUNIT_TEST_FIXTURE(SwLayoutWriter6, testTdf170846_2) +{ + // In this document, the whole floating table must move to page 2 + createSwDoc("tdf170846_2.docx"); + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + // Without the fix, the next test failed: + assertXPath(pXmlDoc, "//page[1]//tab", 0); // No tables on page 1 + assertXPath(pXmlDoc, "//page[2]//tab", 3); // Three tables on page 2 +} + } // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index 917f4461ac8c..3ced1af56603 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -3290,6 +3290,27 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext) { // Don't try to move floating table forward. It's done elsewhere moving its fly. bSkipMoveFwd = true; + // Only limit the InsertMovedFwdFrame hack to non-split floating tables for now: + // it seems that split tables don't need it. + if (!IsFollow() && !HasFollow()) + { + // This floating table doesn't fit on this page. Instead of the complex + // MoveFwd sequence (split anchor, create follow fly, move table, destroy + // old fly, merge anchor - which may oscillate), signal the anchor to move + // forward. The fly will follow. + SwTextFrame* pAnchor = pFlyFrame->FindAnchorCharFrame(); + if (pAnchor) + { + SwPageFrame* pPage = pAnchor->FindPageFrame(); + if (pPage) + { + SwLayouter::InsertMovedFwdFrame(pPage->GetFormat()->GetDoc(), + *pAnchor, + pPage->GetPhyPageNum() + 1); + pAnchor->InvalidatePos(); + } + } + } } } // don't make the effort to move fwd if its known commit 794af1456360254aa2a5f4982ca6ef52a5f6de29 Author: Xisco Fauli <[email protected]> AuthorDate: Fri Feb 20 09:29:53 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:29:20 2026 +0100 tdf#170839: Revert "tdf#56676 disable form properties when they are not available for change" This reverts commit 57352dce995c98d1282484d02c38ed2132b091f5. Reason for revert: it affects all kind of databases Change-Id: Ie852752da413553ef03ab15a0ab75ff156b5b3cf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199789 Tested-by: Jenkins Reviewed-by: Ilmari Lauhakangas <[email protected]> diff --git a/extensions/source/propctrlr/formcomponenthandler.cxx b/extensions/source/propctrlr/formcomponenthandler.cxx index d44350bd475f..a1b7ffa46d38 100644 --- a/extensions/source/propctrlr/formcomponenthandler.cxx +++ b/extensions/source/propctrlr/formcomponenthandler.cxx @@ -54,7 +54,6 @@ #include <com/sun/star/form/XGridColumnFactory.hpp> #include <com/sun/star/sdb/SQLContext.hpp> #include <com/sun/star/sdbcx/XTablesSupplier.hpp> -#include <com/sun/star/sdbcx/Privilege.hpp> #include <com/sun/star/sdb/XQueriesSupplier.hpp> #include <com/sun/star/form/ListSourceType.hpp> #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> @@ -1515,9 +1514,6 @@ namespace pcr if ( !_bFirstTimeInit && m_bHaveCommand ) lcl_rebuildAndResetCommand( _rxInspectorUI, this ); aDependentProperties.push_back( PROPERTY_ID_COMMAND ); - aDependentProperties.push_back(PROPERTY_ID_ALLOWADDITIONS); - aDependentProperties.push_back(PROPERTY_ID_ALLOWEDITS); - aDependentProperties.push_back(PROPERTY_ID_ALLOWDELETIONS); break; // case PROPERTY_ID_COMMANDTYPE // ----- DataSourceName ----- @@ -1541,9 +1537,6 @@ namespace pcr case PROPERTY_ID_COMMAND: aDependentProperties.push_back( PROPERTY_ID_FILTER ); aDependentProperties.push_back( PROPERTY_ID_SORT ); - aDependentProperties.push_back(PROPERTY_ID_ALLOWADDITIONS); - aDependentProperties.push_back(PROPERTY_ID_ALLOWEDITS); - aDependentProperties.push_back(PROPERTY_ID_ALLOWDELETIONS); if ( m_bComponentIsSubForm ) aDependentProperties.push_back( PROPERTY_ID_DETAILFIELDS ); break; @@ -1793,7 +1786,7 @@ namespace pcr } } - void FormComponentPropertyHandler::impl_updateDependentProperty_nothrow( PropertyId _nPropId, const Reference< XObjectInspectorUI >& _rxInspectorUI ) + void FormComponentPropertyHandler::impl_updateDependentProperty_nothrow( PropertyId _nPropId, const Reference< XObjectInspectorUI >& _rxInspectorUI ) const { try { @@ -1827,68 +1820,6 @@ namespace pcr } break; // case PROPERTY_ID_STRINGITEMLIST - case PROPERTY_ID_ALLOWADDITIONS: - { - bool bEnable = false; - sal_Int32 nPrivileges = 0; - if (m_xComponent->getPropertySetInfo()->hasPropertyByName(PROPERTY_PRIVILEGES)) - { - m_xComponent->getPropertyValue(PROPERTY_PRIVILEGES) >>= nPrivileges; - bEnable = (nPrivileges & css::sdbcx::Privilege::INSERT) != 0; - } - _rxInspectorUI->enablePropertyUI( - impl_getPropertyNameFromId_nothrow(PROPERTY_ID_ALLOWADDITIONS), - bEnable - ); - // Set value to false if disabled - if (!bEnable) - { - setPropertyValue(impl_getPropertyNameFromId_nothrow(PROPERTY_ID_ALLOWADDITIONS), Any(false)); - } - } - break; - - case PROPERTY_ID_ALLOWEDITS: - { - bool bEnable = false; - sal_Int32 nPrivileges = 0; - if (m_xComponent->getPropertySetInfo()->hasPropertyByName(PROPERTY_PRIVILEGES)) - { - m_xComponent->getPropertyValue(PROPERTY_PRIVILEGES) >>= nPrivileges; - bEnable = (nPrivileges & css::sdbcx::Privilege::UPDATE) != 0; - } - _rxInspectorUI->enablePropertyUI( - impl_getPropertyNameFromId_nothrow(PROPERTY_ID_ALLOWEDITS), - bEnable - ); - // Set value to false if disabled - if (!bEnable) - { - setPropertyValue(impl_getPropertyNameFromId_nothrow(PROPERTY_ID_ALLOWEDITS), Any(false)); - } - } - break; - - case PROPERTY_ID_ALLOWDELETIONS: - { - bool bEnable = false; - sal_Int32 nPrivileges = 0; - if (m_xComponent->getPropertySetInfo()->hasPropertyByName(PROPERTY_PRIVILEGES)) - { - m_xComponent->getPropertyValue(PROPERTY_PRIVILEGES) >>= nPrivileges; - bEnable = (nPrivileges & css::sdbcx::Privilege::DELETE) != 0; - } - _rxInspectorUI->enablePropertyUI( - impl_getPropertyNameFromId_nothrow(PROPERTY_ID_ALLOWDELETIONS), - bEnable - ); - // Set value to false if disabled - if (!bEnable) - { - setPropertyValue(impl_getPropertyNameFromId_nothrow(PROPERTY_ID_ALLOWDELETIONS), Any(false)); - } - } - break; // ----- TypedItemList ----- case PROPERTY_ID_TYPEDITEMLIST: { diff --git a/extensions/source/propctrlr/formcomponenthandler.hxx b/extensions/source/propctrlr/formcomponenthandler.hxx index 1596f3b2e103..d28c893f3b74 100644 --- a/extensions/source/propctrlr/formcomponenthandler.hxx +++ b/extensions/source/propctrlr/formcomponenthandler.hxx @@ -392,7 +392,7 @@ namespace pcr @param _rxInspectorUI provides access to the property browser UI. Must not be <NULL/>. */ - void impl_updateDependentProperty_nothrow( PropertyId _nPropId, const css::uno::Reference< css::inspection::XObjectInspectorUI >& _rxInspectorUI ); + void impl_updateDependentProperty_nothrow( PropertyId _nPropId, const css::uno::Reference< css::inspection::XObjectInspectorUI >& _rxInspectorUI ) const; /** determines whether the given form has a valid data source signature. diff --git a/extensions/source/propctrlr/formstrings.hxx b/extensions/source/propctrlr/formstrings.hxx index d37cc98c226c..495e178f842e 100644 --- a/extensions/source/propctrlr/formstrings.hxx +++ b/extensions/source/propctrlr/formstrings.hxx @@ -114,7 +114,6 @@ inline constexpr OUString PROPERTY_SHOW_SCROLLBARS = u"ShowScrollbars"_ustr; inline constexpr OUString PROPERTY_TABSTOP = u"Tabstop"_ustr; inline constexpr OUString PROPERTY_AUTOCOMPLETE = u"Autocomplete"_ustr; inline constexpr OUString PROPERTY_PRINTABLE = u"Printable"_ustr; -inline constexpr OUString PROPERTY_PRIVILEGES = u"Privileges"_ustr; inline constexpr OUString PROPERTY_ECHO_CHAR = u"EchoChar"_ustr; inline constexpr OUString PROPERTY_ROWHEIGHT = u"RowHeight"_ustr; inline constexpr OUString PROPERTY_HELPTEXT = u"HelpText"_ustr; commit bc2c8343e493b3dbd5648c48791c91f02c7d650d Author: Xisco Fauli <[email protected]> AuthorDate: Thu Feb 19 16:28:41 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:29:20 2026 +0100 tdf#170297: Revert "tdf#150118 check file permissions on windows if have no readonly" (26.2 only) This reverts commit 1b5d039d8b5861b5ea21ef00ff521c6e2565105f. Change-Id: I5577b131f4a8328719e93ecb1b485aafb46a0ba5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199764 Tested-by: Jenkins Reviewed-by: Xisco Fauli <[email protected]> diff --git a/sal/osl/w32/file_dirvol.cxx b/sal/osl/w32/file_dirvol.cxx index d2a87fbaac21..ad92c6f05087 100644 --- a/sal/osl/w32/file_dirvol.cxx +++ b/sal/osl/w32/file_dirvol.cxx @@ -21,7 +21,6 @@ #include <systools/win32/extended_max_path.hxx> #include <systools/win32/uwinapi.h> -#include <aclapi.h> #include "file_url.hxx" #include "filetime.hxx" @@ -1526,56 +1525,6 @@ oslFileError SAL_CALL osl_getFileStatus( // https://learn.microsoft.com/en-us/windows/desktop/FileIO/file-attribute-constants if (pStatus->uAttributes & FILE_ATTRIBUTE_DIRECTORY) pStatus->uAttributes &= ~sal_uInt64(FILE_ATTRIBUTE_READONLY); - - // tdf#150118: if there is no Read Only attribute set, lets check if the user has write access on the file - if ( (pStatus->uAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_DIRECTORY)) == 0 ) - { - HANDLE hProcessToken = nullptr; - OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hProcessToken); - - HANDLE hImpersonationToken = nullptr; - DuplicateToken(hProcessToken, SecurityImpersonation, &hImpersonationToken); - - PSECURITY_DESCRIPTOR pSD = nullptr; - // https://learn.microsoft.com/en-us/windows/win32/api/aclapi/nf-aclapi-getnamedsecurityinfow - DWORD aResult = GetNamedSecurityInfoW( - o3tl::toW(sFullPath.getStr()), SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - nullptr, nullptr, nullptr, nullptr, &pSD); - - if (aResult == ERROR_SUCCESS) - { - GENERIC_MAPPING mapping - = { FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS }; - DWORD grantedAccess = 0; - BOOL accessStatus = TRUE; - - // https://learn.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-accesscheck - BOOL bResult = AccessCheck(pSD, hImpersonationToken, FILE_GENERIC_WRITE, &mapping, - nullptr, nullptr, &grantedAccess, &accessStatus); - - if (bResult) - { - if (!accessStatus) - { - // User does NOT have write access: set Read Only attribute - pStatus->uAttributes |= sal_uInt64(FILE_ATTRIBUTE_READONLY); - } - } - else - { - SAL_WARN("AccessCheck API failed with: ", oslTranslateFileError(GetLastError())); - } - LocalFree(pSD); // free memory - } - else - { - SAL_WARN("GetNamedSecurityInfoW API failed with: ", aResult); - } - CloseHandle(hImpersonationToken); // free memory - CloseHandle(hProcessToken); // free memory - } - pStatus->uValidFields |= osl_FileStatus_Mask_Attributes; pStatus->uFileSize = static_cast<sal_uInt64>(pItemImpl->FindData.nFileSizeLow) + (static_cast<sal_uInt64>(pItemImpl->FindData.nFileSizeHigh) << 32); commit 88f6bda22a0ae4988cf345b5164197c1a847189a Author: Mike Kaganski <[email protected]> AuthorDate: Mon Feb 16 16:45:49 2026 +0500 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:29:20 2026 +0100 tdf#169999: Also hide footnotes when text frame is hidden This is similar to what MakePrtArea does in that case: call HideHidden. Change-Id: I0625c00c5ec168698feed9d34079a1e84a8fa1b9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199477 Tested-by: Jenkins Reviewed-by: Mike Kaganski <[email protected]> Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199499 diff --git a/sw/qa/extras/layout/data/tdf169999.fodt b/sw/qa/extras/layout/data/tdf169999.fodt new file mode 100644 index 000000000000..c554309a6e5b --- /dev/null +++ b/sw/qa/extras/layout/data/tdf169999.fodt @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:ooow="http://openoffice.org/2004/writer" office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:body> + <office:text> + <text:p/> + <text:section text:name="Section1" text:condition="ooow:0" text:display="condition"> + <text:p>This is a hidden section.<text:note text:id="ftn1" text:note-class="footnote"><text:note-citation>1</text:note-citation><text:note-body> + <text:p>This is a footnote in the hidden section.</text:p></text:note-body></text:note> Here are some random words in it.</text:p> + </text:section> + </office:text> + </office:body> +</office:document> \ No newline at end of file diff --git a/sw/qa/extras/layout/layout6.cxx b/sw/qa/extras/layout/layout6.cxx index f4c8cb590ffc..75abbc4fc7d5 100644 --- a/sw/qa/extras/layout/layout6.cxx +++ b/sw/qa/extras/layout/layout6.cxx @@ -2204,6 +2204,32 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter6, testTdf170811) parseLayoutDump(); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter6, testTdf169999) +{ + // Open a document with a section with a paragraph with a footnote + createSwDoc("tdf169999.fodt"); + + // Initially, the hide condition evaluates to false, so footnote is visible: + { + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "//ftn", 1); + } + + // Set hide condition to "1" + auto xTextSectionsSupplier = mxComponent.queryThrow<css::text::XTextSectionsSupplier>(); + auto xSections = xTextSectionsSupplier->getTextSections(); + CPPUNIT_ASSERT(xSections); + auto xSection = xSections->getByName(u"Section1"_ustr).queryThrow<css::beans::XPropertySet>(); + xSection->setPropertyValue(u"Condition"_ustr, css::uno::Any(u"1"_ustr)); + Scheduler::ProcessEventsToIdle(); + + // The footnote must get hidden - without the fix, the text failed, because there was a ftn + { + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "//ftn", 0); + } +} + } // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx index 1fdc0c047e5e..e7d8d4949b79 100644 --- a/sw/source/core/layout/calcmove.cxx +++ b/sw/source/core/layout/calcmove.cxx @@ -1326,11 +1326,12 @@ void SwContentFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/) bool const isHiddenNow(static_cast<SwTextFrame*>(this)->IsHiddenNowImpl()); if (isHiddenNow) { + // Similar to respective code in MakePrtArea while (HasFollow()) { static_cast<SwTextFrame&>(*this).JoinFrame(); } - HideAndShowObjects(); + static_cast<SwTextFrame*>(this)->HideHidden(); // also hides footnotes } std::optional<SwFrameDeleteGuard> oDeleteGuard(std::in_place, this); commit aef907961633efe65a6676dd8b122554c708e662 Author: Xisco Fauli <[email protected]> AuthorDate: Thu Feb 19 16:27:33 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:29:20 2026 +0100 tdf#170297: Revert "tdf#150118: fix call to AccessCheck" (26.2 only) This reverts commit 1a4f72f03b1bd49d486e52135e78971242fae649. Change-Id: I142da287cb3765cc7c6d845aefff45218104e0f3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199763 Reviewed-by: Xisco Fauli <[email protected]> Tested-by: Jenkins diff --git a/sal/osl/w32/file_dirvol.cxx b/sal/osl/w32/file_dirvol.cxx index 748a431dd4f9..d2a87fbaac21 100644 --- a/sal/osl/w32/file_dirvol.cxx +++ b/sal/osl/w32/file_dirvol.cxx @@ -1549,12 +1549,10 @@ oslFileError SAL_CALL osl_getFileStatus( = { FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS }; DWORD grantedAccess = 0; BOOL accessStatus = TRUE; - PRIVILEGE_SET privSet; - DWORD privSetSize = sizeof(privSet); // https://learn.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-accesscheck BOOL bResult = AccessCheck(pSD, hImpersonationToken, FILE_GENERIC_WRITE, &mapping, - &privSet, &privSetSize, &grantedAccess, &accessStatus); + nullptr, nullptr, &grantedAccess, &accessStatus); if (bResult) { @@ -1566,13 +1564,13 @@ oslFileError SAL_CALL osl_getFileStatus( } else { - SAL_WARN("sal.osl", "AccessCheck API failed with: " << GetLastError()); + SAL_WARN("AccessCheck API failed with: ", oslTranslateFileError(GetLastError())); } LocalFree(pSD); // free memory } else { - SAL_WARN("sal.osl", "GetNamedSecurityInfoW API failed with: " << aResult); + SAL_WARN("GetNamedSecurityInfoW API failed with: ", aResult); } CloseHandle(hImpersonationToken); // free memory CloseHandle(hProcessToken); // free memory commit 1c7e699d4dcd96804619f897b23842b56ac0298c Author: Michael Weghorn <[email protected]> AuthorDate: Fri Feb 13 17:16:29 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:29:20 2026 +0100 tdf#170681 qt avmedia: Don't fall back to QtFrameGrabber unless enabled Due to issues with QtFrameGrabber, commit 08533ca4e2526644b803c40c0c3d3c96f43762af Author: Michael Weghorn <[email protected]> Date: Fri May 2 17:52:19 2025 +0200 tdf#166055 avmedia qt: Use GStreamer frame grabber by default switched from using QtFrameGrabber by default to using the Gstreamer-based grabber by default. Since then, QtFrameGrabber is only used if either of these is true: 1) explicitly enabled by setting the SAL_VCL_QT_USE_QT_FRAME_GRABBER environment variable 2) no GStreamer-based grabber is returned by createPlatformFrameGrabber The tdf#170681 scenario of dragging and dropping an audio-only file from the gallery in Impress shows that 2) is also reached then because the preferred size of the audio-only file in Player::createFrameGrabber is empty, and thus no frame grabber is created. This apparently (at least in some configurations) results in the QtFrameGrabber problems like crashes that the above-mentioned commit was supposed to avoid, until they get addressed a different way. Therefore, adjust the logic to only create a QtFrameGrabber when explicitly enabled, i.e. for 1), but no longer for 2). Change-Id: Ic95303e812819a9c432543992773b334995ddd31 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199356 Reviewed-by: Caolán McNamara <[email protected]> Tested-by: Jenkins (cherry picked from commit d7d542b198d4edb3938b69ff31f07c1b2d0d0fb4) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199479 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/avmedia/source/qt6/QtPlayer.cxx b/avmedia/source/qt6/QtPlayer.cxx index 78ff33ca074b..5118e9bc3e42 100644 --- a/avmedia/source/qt6/QtPlayer.cxx +++ b/avmedia/source/qt6/QtPlayer.cxx @@ -287,15 +287,10 @@ uno::Reference<media::XFrameGrabber> SAL_CALL QtPlayer::createFrameGrabber() // as QtFrameGrabber has issues (see e.g. tdf#166055) static const bool bPreferQtFrameGrabber = (getenv("SAL_VCL_QT_USE_QT_FRAME_GRABBER") != nullptr); - if (!bPreferQtFrameGrabber) - { - uno::Reference<media::XFrameGrabber> xFrameGrabber - = createPlatformFrameGrabber(toOUString(m_xMediaPlayer->source().url())); - if (xFrameGrabber.is()) - return xFrameGrabber; - } + if (bPreferQtFrameGrabber) + return new QtFrameGrabber(m_xMediaPlayer->source()); - return new QtFrameGrabber(m_xMediaPlayer->source()); + return createPlatformFrameGrabber(toOUString(m_xMediaPlayer->source().url())); } OUString SAL_CALL QtPlayer::getImplementationName() commit 6318a9f0fd5d1631a663c43142338e189432c6e1 Author: Justin Luth <[email protected]> AuthorDate: Fri Feb 13 09:34:04 2026 -0500 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:29:19 2026 +0100 tdf#147724 docx export: don't export storeItemID if empty This patch is for the benefit of MS Word, which reports a document as corrupt if w:storeItemID="" It is kindof interesting, because it is not invalid if storeItemID is not provided. But if it is provided, then it must not be empty. make CppunitTest_sw_ooxmlexport18 CPPUNIT_TEST_NAME=testTdf147724 Change-Id: Iaa1de4b98e3470a3ab28fe48a46252060e70a257 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199354 Tested-by: Jenkins Reviewed-by: Justin Luth <[email protected]> (cherry picked from commit 3eb2871aefd01f2d0ce51848b7a6760b6adc9cb8) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199391 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx index f5e0b536e6cf..5e85fabb4a1c 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx @@ -614,8 +614,10 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf151912) assertXPath(pXmlDoc, "//w:sdt//w:sdtPr/w:id", "val", u"1802566103"); } -DECLARE_OOXMLEXPORT_TEST(testTdf147724, "tdf147724.docx") +CPPUNIT_TEST_FIXTURE(Test, testTdf147724) { + skipValidation(); // ERROR Attribute 'storeItemID' must appear on element 'w:dataBinding'. + createSwDoc("tdf147724.docx"); xmlDocUniquePtr pLayout = parseLayoutDump(); // Ensure we load field value from external XML correctly (it was "HERUNTERLADEN") @@ -625,6 +627,24 @@ DECLARE_OOXMLEXPORT_TEST(testTdf147724, "tdf147724.docx") // There 2 variants possible, both are acceptable OUString sFieldResult = getXPathContent(pLayout, "/root/page[1]/body/txt[2]"); CPPUNIT_ASSERT(sFieldResult == "Placeholder -> *HERUNTERLADEN*" || sFieldResult == "Placeholder -> *ABC*"); + + saveAndReload(TestFilter::DOCX); + pLayout = parseLayoutDump(); + + // Ensure we load field value from external XML correctly (it was "HERUNTERLADEN") + assertXPathContent(pLayout, "/root/page[1]/body/txt[1]", u"Placeholder -> *ABC*"); + + // This SDT has no storage id, it is not an error, but content can be taken from any suitable XML + // There 2 variants possible, both are acceptable + sFieldResult = getXPathContent(pLayout, "/root/page[1]/body/txt[2]"); + CPPUNIT_ASSERT(sFieldResult == "Placeholder -> *HERUNTERLADEN*" || sFieldResult == "Placeholder -> *ABC*"); + + xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr); + assertXPath(pXmlDoc, "//w:p/w:sdt/w:sdtPr/w:dataBinding", 2); // two w:sdt's with w:dataBinding + assertXPath(pXmlDoc, "//w:p[1]/w:sdt/w:sdtPr/w:dataBinding", "storeItemID", + u"{4E8A9591-F074-446B-902F-511FF79C122F}"); + // empty storeItemID's must not be specified: MS Word considers those document corrupt + assertXPathNoAttribute(pXmlDoc, "//w:p[2]/w:sdt/w:sdtPr/w:dataBinding", "storeItemID"); } DECLARE_OOXMLEXPORT_TEST(testTdf130782, "chart.docx") diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 9cade593cded..fac50ae76dd3 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -2724,12 +2724,14 @@ void DocxAttributeOutput::WriteContentControlStart() m_pSerializer->singleElementNS(XML_w, XML_showingPlcHdr); } - if (!m_pContentControl->GetDataBindingPrefixMappings().isEmpty() || !m_pContentControl->GetDataBindingXpath().isEmpty() || !m_pContentControl->GetDataBindingStoreItemID().isEmpty()) + const OUString sID = m_pContentControl->GetDataBindingStoreItemID(); + if (!sID.isEmpty() || !m_pContentControl->GetDataBindingPrefixMappings().isEmpty() + || !m_pContentControl->GetDataBindingXpath().isEmpty()) { m_pSerializer->singleElementNS( XML_w, XML_dataBinding, FSNS(XML_w, XML_prefixMappings), m_pContentControl->GetDataBindingPrefixMappings(), FSNS(XML_w, XML_xpath), m_pContentControl->GetDataBindingXpath(), - FSNS(XML_w, XML_storeItemID), m_pContentControl->GetDataBindingStoreItemID()); + FSNS(XML_w, XML_storeItemID), sax_fastparser::UseIf(sID, !sID.isEmpty())); } if (m_pContentControl->GetTabIndex()) commit c5927aa4a4ef94da5ed42a9207a665f030276ae6 Author: Laurent Balland <[email protected]> AuthorDate: Fri Feb 13 08:01:06 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:27:18 2026 +0100 tdf#170670 NumberFormat: fix blank width string treatment In case of 2 characters string text, with a delimiter as text and a blank width string like "-"_) the delimiter is now treated as text Add qa test with format of bug report: [>0]#,##0_);[<0](#,##0);"-"_) Change-Id: Idd4542bd186c6b6b348f6716bee2fd5055f2c83f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199314 Tested-by: Jenkins Reviewed-by: Mike Kaganski <[email protected]> (cherry picked from commit fb07ca38af165b1e367aea04aa626e073b341c8f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199416 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/sc/qa/unit/data/ods/tdf170670-Blank-width-char.ods b/sc/qa/unit/data/ods/tdf170670-Blank-width-char.ods new file mode 100644 index 000000000000..50918deb662f Binary files /dev/null and b/sc/qa/unit/data/ods/tdf170670-Blank-width-char.ods differ diff --git a/sc/qa/unit/subsequent_export_test4.cxx b/sc/qa/unit/subsequent_export_test4.cxx index bb7d8bdcf834..96d5af2fa8fd 100644 --- a/sc/qa/unit/subsequent_export_test4.cxx +++ b/sc/qa/unit/subsequent_export_test4.cxx @@ -1684,6 +1684,16 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testBlankWidthCharacter) // save to XLSX and reload saveAndReload(TestFilter::XLSX); lcl_TestNumberFormat(*getScDoc(), u"_-?0;-?0;_-?0;@"_ustr); + + createScDoc("ods/tdf170670-Blank-width-char.ods"); + + // save to ODS and reload + saveAndReload(TestFilter::ODS); + lcl_TestNumberFormat(*getScDoc(), u"[>0]#,##0_);[<0](#,##0);\"-\"_)"_ustr); + + // save to XLSX and reload + saveAndReload(TestFilter::XLSX); + lcl_TestNumberFormat(*getScDoc(), u"#,##0_);\(#,##0\);-_)"_ustr); } CPPUNIT_TEST_FIXTURE(ScExportTest4, testEmbeddedTextInDecimal) diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx index 2343e5d99e55..2ed570fb330e 100644 --- a/xmloff/source/style/xmlnumfi.cxx +++ b/xmloff/source/style/xmlnumfi.cxx @@ -527,13 +527,13 @@ static bool lcl_ValidChar( sal_Unicode cChar, const SvXMLNumFormatContext& rPare return false; } -static void lcl_EnquoteIfNecessary( OUStringBuffer& rContent, const SvXMLNumFormatContext& rParent ) +static void lcl_EnquoteIfNecessary( OUStringBuffer& rContent, const SvXMLNumFormatContext& rParent, const bool bIsBlankWidthStringEmpty = true ) { bool bQuote = true; sal_Int32 nLength = rContent.getLength(); const SvXMLStylesTokens nFormatType = rParent.GetType(); - if (nFormatType != SvXMLStylesTokens::BOOLEAN_STYLE && + if (nFormatType != SvXMLStylesTokens::BOOLEAN_STYLE && bIsBlankWidthStringEmpty && ((nLength == 1 && lcl_ValidChar( rContent[0], rParent)) || (nLength == 2 && ((rContent[0] == ' ' && rContent[1] == '-') || @@ -544,6 +544,7 @@ static void lcl_EnquoteIfNecessary( OUStringBuffer& rContent, const SvXMLNumForm // Or space followed by minus (used in currency formats) that would // lead to almost duplicated formats with built-in formats just with // the difference of quotes. + // tdf#170670: except if it is inside a blank width string bQuote = false; } else if ( nFormatType == SvXMLStylesTokens::PERCENTAGE_STYLE && nLength > 1 ) @@ -971,7 +972,7 @@ void SvXMLNumFmtElementContext::endFastElement(sal_Int32 ) } if ( !aContent.isEmpty() ) { - lcl_EnquoteIfNecessary( aContent, rParent ); + lcl_EnquoteIfNecessary( aContent, rParent, sBlankWidthString.isEmpty() ); if ( !sBlankWidthString.isEmpty() ) { lcl_InsertBlankWidthChars( sBlankWidthString, aContent ); commit b95ffc3ecb2b6cf1c783cf2cf2c898f28c623c5d Author: Laurent Balland <[email protected]> AuthorDate: Sat Feb 14 17:33:19 2026 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Mar 1 18:27:17 2026 +0100 tdf#170786 Blueprint Plans correct master slide names Previous Master slide names were containing a '-' "Blueprint Plans-4:3" and "Standard-43" This was generating numerous warning with debug build and prevents using these styles of the masters: erroneous font size were used for outlines for instance Change-Id: I9048021051c63c96c64a674ba6f5bab162944662 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199412 Tested-by: Jenkins Reviewed-by: Laurent Balland <[email protected]> (cherry picked from commit 785dba1cf27c10c2056b0e820c9fd3f8dea7d8ab) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199422 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/extras/source/templates/presnt/Blueprint_Plans/styles.xml b/extras/source/templates/presnt/Blueprint_Plans/styles.xml index 9632deba7466..2a2781d54c22 100644 --- a/extras/source/templates/presnt/Blueprint_Plans/styles.xml +++ b/extras/source/templates/presnt/Blueprint_Plans/styles.xml @@ -351,22 +351,22 @@ <style:paragraph-properties fo:text-align="center"/> <style:text-properties fo:font-variant="normal" fo:text-transform="none" fo:color="#ffffff" loext:opacity="100%" style:text-outline="false" style:text-line-through-style="none" style:text-line-through-type="none" fo:font-size="44pt" fo:font-style="normal" fo:text-shadow="none" style:text-underline-style="none" fo:font-weight="normal" style:letter-kerning="true" fo:background-color="transparent" style:font-size-asian="44pt" style:font-style-asian="normal" style:font-weight-asian="normal" style:font-size-complex="44pt" style:font-style-complex="normal" style:font-weight-complex="normal" style:text-emphasize="none" style:font-relief="none" style:text-overline-style="none" style:text-overline-color="font-color"/> </style:style> - <style:style style:name="Blueprint_20_Plans-4_3a_3-background" style:display-name="Blueprint Plans-4:3-background" style:family="presentation"> + <style:style style:name="Blueprint_20_Plans_20_4_3a_3-background" style:display-name="Blueprint Plans 4:3-background" style:family="presentation"> <style:graphic-properties draw:stroke="none" draw:fill="none"/> <style:text-properties style:letter-kerning="true"/> </style:style> - <style:style style:name="Blueprint_20_Plans-4_3a_3-backgroundobjects" style:display-name="Blueprint Plans-4:3-backgroundobjects" style:family="presentation"> + <style:style style:name="Blueprint_20_Plans_20_4_3a_3-backgroundobjects" style:display-name="Blueprint Plans 4:3-backgroundobjects" style:family="presentation"> <style:graphic-properties draw:textarea-horizontal-align="justify" draw:shadow="hidden" draw:shadow-offset-x="0.2cm" draw:shadow-offset-y="0.2cm" draw:shadow-color="#808080"/> <style:text-properties style:letter-kerning="true"/> </style:style> - <style:style style:name="Blueprint_20_Plans-4_3a_3-notes" style:display-name="Blueprint Plans-4:3-notes" style:family="presentation"> + <style:style style:name="Blueprint_20_Plans_20_4_3a_3-notes" style:display-name="Blueprint Plans 4:3-notes" style:family="presentation"> <style:graphic-properties draw:stroke="none" draw:fill="none"/> <style:paragraph-properties fo:margin-left="0.6cm" fo:margin-right="0cm" fo:text-indent="-0.6cm"/> <style:text-properties fo:font-variant="normal" fo:text-transform="none" style:use-window-font-color="true" loext:opacity="0%" style:text-outline="false" style:text-line-through-style="none" style:text-line-through-type="none" fo:font-size="20pt" fo:font-style="normal" fo:text-shadow="none" style:text-underline-style="none" fo:font-weight="normal" style:letter-kerning="true" fo:background-color="transparent" style:font-size-asian="20pt" style:font-style-asian="normal" style:font-weight-asian="normal" style:font-size-complex="20pt" style:font-style-complex="normal" style:font-weight-complex="normal" style:text-emphasize="none" style:font-relief="none" style:text-overline-style="none" style:text-overline-color="font-color"/> </style:style> - <style:style style:name="Blueprint_20_Plans-4_3a_3-outline1" style:display-name="Blueprint Plans-4:3-outline1" style:family="presentation"> + <style:style style:name="Blueprint_20_Plans_20_4_3a_3-outline1" style:display-name="Blueprint Plans 4:3-outline1" style:family="presentation"> <style:graphic-properties draw:stroke="none" draw:fill="none" draw:auto-grow-height="false" draw:fit-to-size="false" style:shrink-to-fit="true"> - <text:list-style style:name="Blueprint_20_Plans-4_3a_3-outline1" style:display-name="Blueprint Plans-4:3-outline1"> + <text:list-style style:name="Blueprint_20_Plans_20_4_3a_3-outline1" style:display-name="Blueprint Plans 4:3-outline1"> <text:list-level-style-bullet text:level="1" text:bullet-char="●"> <style:list-level-properties text:space-before="0.3cm" text:min-label-width="0.9cm"/> <style:text-properties fo:font-family="StarSymbol" fo:color="#ffffff" fo:font-size="45%"/> @@ -412,28 +412,28 @@ <style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0.499cm" fo:margin-bottom="0cm" fo:text-indent="0cm"/> -e ... etc. - the rest is truncated
