android/source/src/main/play/listings/en-US/graphics/icon.png | 1 android/source/src/main/play/listings/en-US/graphics/icon/icon.png | 1 comphelper/source/misc/storagehelper.cxx | 13 configure.ac | 2 cui/source/dialogs/AdditionsDialog.cxx | 10 cui/source/tabpages/autocdlg.cxx | 4 desktop/source/lib/init.cxx | 2 distro-configs/LibreOfficeFlatpak.conf | 1 download.lst | 4 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx | 6 editeng/source/misc/svxacorr.cxx | 2 extras/source/autocorr/lang/el/DocumentList.xml | 4 extras/source/autocorr/lang/nl-BE/DocumentList.xml | 4 extras/source/autocorr/lang/nl/DocumentList.xml | 4 extras/source/autotext/lang/pl/standard/PODDOK/PODDOK.xml | 2 filter/source/graphicfilter/icgm/cgm.cxx | 2 helpcontent2 | 2 i18npool/qa/cppunit/test_breakiterator.cxx | 60 + i18npool/qa/cppunit/test_textsearch.cxx | 88 ++ i18npool/source/breakiterator/data/dict_word.txt | 2 i18npool/source/breakiterator/data/dict_word_hu.txt | 2 i18npool/source/breakiterator/data/edit_word.txt | 8 i18npool/source/breakiterator/data/edit_word_hu.txt | 8 i18npool/source/search/textsearch.cxx | 40 - icon-themes/colibre/res/donate.png |binary include/oox/ppt/comments.hxx | 1 include/oox/ppt/slidepersist.hxx | 4 include/sfx2/AccessibilityIssue.hxx | 1 include/sfx2/shell.hxx | 2 include/svx/EnhancedCustomShape2d.hxx | 1 include/svx/strings.hrc | 2 include/unotools/ucbstreamhelper.hxx | 11 lingucomponent/Library_LanguageTool.mk | 1 lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx | 76 + lingucomponent/source/spellcheck/languagetool/languagetoolimp.hxx | 5 officecfg/registry/data/org/openoffice/Office/Common.xcu | 3 officecfg/registry/schema/org/openoffice/Office/Common.xcs | 6 oovbaapi/ooo/vba/word/XTable.idl | 8 oox/qa/unit/data/connectorConnection.pptx |binary oox/qa/unit/data/curvedConnectors.pptx |binary oox/qa/unit/data/elbowConnectors.pptx |binary oox/qa/unit/shape.cxx | 109 ++ oox/source/drawingml/customshapepresetdata.cxx | 81 ++ oox/source/drawingml/customshapes/oox-drawingml-cs-presets | 78 - oox/source/ppt/comments.cxx | 11 oox/source/ppt/presentationfragmenthandler.cxx | 1 oox/source/ppt/slidepersist.cxx | 391 +++------- package/inc/ZipFile.hxx | 3 package/source/zipapi/MemoryByteGrabber.hxx | 8 package/source/zipapi/ZipFile.cxx | 53 + package/source/zippackage/ZipPackage.cxx | 6 readlicense_oo/license/license.xml | 12 sc/inc/document.hxx | 5 sc/inc/queryevaluator.hxx | 3 sc/inc/queryiter.hxx | 2 sc/inc/rangecache.hxx | 2 sc/inc/table.hxx | 1 sc/qa/uitest/pasteSpecial/tdf158110.py | 38 sc/qa/unit/data/functions/spreadsheet/fods/xlookup.fods | 375 +++++---- sc/qa/unit/data/functions/spreadsheet/fods/xmatch.fods | 38 sc/qa/unit/data/xlsx/cell-note.xlsx |binary sc/qa/unit/data/xlsx/change-tracking.xlsx |binary sc/qa/unit/subsequent_export_test4.cxx | 46 + sc/source/core/data/documen2.cxx | 5 sc/source/core/data/document.cxx | 9 sc/source/core/data/queryevaluator.cxx | 4 sc/source/core/data/queryiter.cxx | 20 sc/source/core/data/table2.cxx | 14 sc/source/core/tool/address.cxx | 7 sc/source/core/tool/rangecache.cxx | 10 sc/source/filter/excel/xeescher.cxx | 12 sc/source/filter/inc/XclExpChangeTrack.hxx | 5 sc/source/filter/inc/xeescher.hxx | 3 sc/source/filter/xcl97/XclExpChangeTrack.cxx | 13 sc/source/ui/view/viewfun3.cxx | 9 sd/qa/unit/data/pptx/glue_point_leaving_directions.pptx |binary sd/qa/unit/data/pptx/tdf157216.pptx |binary sd/qa/unit/data/xml/n820786_0.xml | 2 sd/qa/unit/import-tests.cxx | 87 +- sd/sdi/NotesPanelView.sdi | 9 sd/sdi/drviewsh.sdi | 6 sd/source/filter/eppt/eppt.cxx | 38 sd/source/filter/eppt/epptooxml.hxx | 3 sd/source/filter/eppt/pptx-epptbase.cxx | 1 sd/source/filter/eppt/pptx-epptooxml.cxx | 32 sd/source/ui/framework/module/ToolBarModule.cxx | 118 ++- sd/source/ui/framework/module/ToolBarModule.hxx | 29 sd/source/ui/func/fuolbull.cxx | 2 sd/source/ui/func/fusearch.cxx | 14 sd/source/ui/inc/EventMultiplexer.hxx | 12 sd/source/ui/inc/OutlinerIteratorImpl.hxx | 61 - sd/source/ui/inc/ToolBarManager.hxx | 5 sd/source/ui/inc/ViewShell.hxx | 1 sd/source/ui/inc/ViewShellManager.hxx | 4 sd/source/ui/tools/EventMultiplexer.cxx | 24 sd/source/ui/view/NotesPanelView.cxx | 6 sd/source/ui/view/NotesPanelViewShell.cxx | 47 - sd/source/ui/view/Outliner.cxx | 150 +++ sd/source/ui/view/OutlinerIterator.cxx | 318 +++----- sd/source/ui/view/ToolBarManager.cxx | 38 sd/source/ui/view/ViewShellManager.cxx | 51 + sd/source/ui/view/drtxtob.cxx | 5 sd/source/ui/view/drviews6.cxx | 5 sd/source/ui/view/drviews7.cxx | 7 sd/source/ui/view/outlnvsh.cxx | 2 sd/source/ui/view/viewshel.cxx | 65 + sfx2/inc/bitmaps.hlst | 2 sfx2/source/dialog/backingwindow.cxx | 11 sfx2/source/dialog/infobar.cxx | 6 sfx2/source/doc/objmisc.cxx | 6 sfx2/source/doc/objserv.cxx | 7 sfx2/source/doc/objstor.cxx | 2 solenv/flatpak-manifest.in | 8 svx/source/customshapes/EnhancedCustomShape2d.cxx | 34 svx/source/form/filtnav.cxx | 2 svx/uiconfig/ui/filternavigator.ui | 13 sw/inc/AccessibilityCheckStrings.hrc | 2 sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx | 40 - sw/qa/core/data/docm/testTables.docm |binary sw/qa/core/macros-test.cxx | 5 sw/qa/extras/layout/data/tdf107209-vert-ltr.fodt | 313 ++++++++ sw/qa/extras/layout/data/tdf107209-vert-rtl.fodt | 310 +++++++ sw/qa/extras/layout/layout3.cxx | 32 sw/qa/filter/ww8/ww8.cxx | 44 + sw/source/core/access/AccessibilityCheck.cxx | 46 + sw/source/core/access/AccessibilityIssue.cxx | 32 sw/source/core/inc/AccessibilityIssue.hxx | 1 sw/source/core/text/atrstck.cxx | 2 sw/source/core/text/frmform.cxx | 9 sw/source/core/text/txthyph.cxx | 29 sw/source/filter/ww8/docxattributeoutput.cxx | 13 sw/source/filter/ww8/rtfexport.cxx | 10 sw/source/filter/ww8/wrtw8nds.cxx | 12 sw/source/filter/ww8/wrtw8sty.cxx | 31 sw/source/filter/ww8/wrtww8.cxx | 9 sw/source/filter/ww8/wrtww8.hxx | 8 sw/source/ui/frmdlg/column.cxx | 1 sw/source/ui/index/swuiidxmrk.cxx | 2 sw/source/ui/misc/glossary.cxx | 2 sw/source/ui/vba/vbatable.cxx | 24 sw/source/ui/vba/vbatable.hxx | 16 sw/source/uibase/docvw/edtwin.cxx | 2 sw/source/uibase/ribbar/workctrl.cxx | 2 sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx | 1 sw/source/uibase/sidebar/QuickFindPanel.cxx | 80 +- sw/source/uibase/sidebar/QuickFindPanel.hxx | 2 sw/source/uibase/uno/unotxdoc.cxx | 6 sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx | 22 toolkit/source/awt/vclxtoolkit.cxx | 4 translations | 2 ucb/source/ucp/webdav-curl/webdavcontent.cxx | 13 unotools/source/ucbhelper/ucbstreamhelper.cxx | 19 vcl/inc/skia/osx/gdiimpl.hxx | 4 vcl/osx/DataFlavorMapping.cxx | 4 vcl/osx/salgdiutils.cxx | 98 +- vcl/osx/salmacos.cxx | 7 vcl/quartz/CoreTextFontFace.cxx | 53 - vcl/skia/osx/gdiimpl.cxx | 142 ++- vcl/source/bitmap/BitmapEx.cxx | 11 vcl/source/filter/ieps/ieps.cxx | 12 wizards/source/sfdocuments/SF_Document.xba | 4 xmloff/source/text/XMLTextFrameContext.cxx | 27 162 files changed, 3347 insertions(+), 1161 deletions(-)
New commits: commit f6f00606282f36b206ced9857b378e399d00dc65 Author: Noel Grandin <[email protected]> AuthorDate: Tue Jul 9 21:38:05 2024 +0200 Commit: Xisco Fauli <[email protected]> CommitDate: Wed Jul 10 10:43:07 2024 +0200 Revert "tdf#158556 speedup docx load" This reverts commit ab29c857c669bcca3d8eea8a5a9e6ad5eae622d7. As jluth points out, my logic here is wrong. Change-Id: I8887526a0a96070ad615aa07ef0e77e36214d0d5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170252 Reviewed-by: Justin Luth <[email protected]> Reviewed-by: Noel Grandin <[email protected]> Tested-by: Jenkins (cherry picked from commit 6f96e7720f765d4e5e8fdef6a2a2b8cbb75c81ef) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170241 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx index 8bb8da5b1db1..efcf9987347a 100644 --- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx @@ -3774,14 +3774,26 @@ void DomainMapper_Impl::ConvertHeaderFooterToTextFrame(bool bDynamicHeightTop, b namespace { // Determines if the XText content is empty (no text, no shapes, no tables) -bool isContentEmpty(uno::Reference<text::XText> const& xText) +bool isContentEmpty(uno::Reference<text::XText> const& xText, uno::Reference<text::XTextDocument> const& xTextDocument) { if (!xText.is()) return true; // no XText means it's empty - uno::Reference<css::lang::XServiceInfo> xTextServiceInfo(xText, uno::UNO_QUERY); - if (xTextServiceInfo && xTextServiceInfo->getImplementationName() == "SwXHeadFootText") - return false; + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xTextDocument, uno::UNO_QUERY); + auto xDrawPage = xDrawPageSupplier->getDrawPage(); + if (xDrawPage && xDrawPage->hasElements()) + { + for (sal_Int32 i = 0; i < xDrawPage->getCount(); ++i) + { + uno::Reference<text::XTextContent> xShape(xDrawPage->getByIndex(i), uno::UNO_QUERY); + if (xShape.is()) + { + uno::Reference<text::XTextRange> xAnchor = xShape->getAnchor(); + if (xAnchor.is() && xAnchor->getText() == xText) + return false; + } + } + } uno::Reference<container::XEnumerationAccess> xEnumAccess(xText->getText(), uno::UNO_QUERY); uno::Reference<container::XEnumeration> xEnum = xEnumAccess->createEnumeration(); @@ -3928,7 +3940,7 @@ void DomainMapper_Impl::checkIfHeaderFooterIsEmpty(PagePartType ePagePartType, P if (!xPageStyle.is()) return; - bool bEmpty = isContentEmpty(m_aTextAppendStack.top().xTextAppend); + bool bEmpty = isContentEmpty(m_aTextAppendStack.top().xTextAppend, GetTextDocument()); if (eType == PageType::FIRST && bEmpty) { commit 9ac896c5367bd37d820f859b3af9b8c02bcd5594 Author: Caolán McNamara <[email protected]> AuthorDate: Tue Jul 9 13:08:23 2024 +0100 Commit: Michael Stahl <[email protected]> CommitDate: Wed Jul 10 10:15:53 2024 +0200 use a throwaway TMPDIR for ghostscript-using helpers Change-Id: Iba5a475399589c9e2c4fd485d613f0dedfe0dc44 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170123 Reviewed-by: Michael Stahl <[email protected]> Tested-by: Jenkins diff --git a/vcl/source/filter/ieps/ieps.cxx b/vcl/source/filter/ieps/ieps.cxx index d9d233ed77bf..8ec84cd9ba8e 100644 --- a/vcl/source/filter/ieps/ieps.cxx +++ b/vcl/source/filter/ieps/ieps.cxx @@ -152,6 +152,14 @@ static oslProcessError runProcessWithPathSearch(const OUString &rProgName, rtl_uString* pArgs[], sal_uInt32 nArgs, oslProcess *pProcess, oslFileHandle *pIn, oslFileHandle *pOut, oslFileHandle *pErr) { + // run things that directly or indirectly might call gs in a tmpdir of their own + utl::TempFileNamed aTMPDirectory(nullptr, true); + aTMPDirectory.EnableKillingFile(true); + OUString sTmpDirEnv = u"TMPDIR="_ustr + aTMPDirectory.GetFileName(); + + rtl_uString* ustrEnvironment[1]; + ustrEnvironment[0] = sTmpDirEnv.pData; + oslProcessError result = osl_Process_E_None; oslSecurity pSecurity = osl_getCurrentSecurity(); #ifdef _WIN32 @@ -179,11 +187,11 @@ static oslProcessError runProcessWithPathSearch(const OUString &rProgName, else result = osl_executeProcess_WithRedirectedIO(url.pData, pArgs, nArgs, osl_Process_HIDDEN, - pSecurity, nullptr, nullptr, 0, pProcess, pIn, pOut, pErr); + pSecurity, nullptr, ustrEnvironment, 1, pProcess, pIn, pOut, pErr); #else result = osl_executeProcess_WithRedirectedIO(rProgName.pData, pArgs, nArgs, osl_Process_SEARCHPATH | osl_Process_HIDDEN, - pSecurity, nullptr, nullptr, 0, pProcess, pIn, pOut, pErr); + pSecurity, nullptr, ustrEnvironment, 1, pProcess, pIn, pOut, pErr); #endif osl_freeSecurityHandle( pSecurity ); return result; commit 42e3bb7cde89db579d5a42a18b7a7a93c6aad059 Author: Jean-Pierre Ledure <[email protected]> AuthorDate: Mon Jul 8 16:04:04 2024 +0200 Commit: Xisco Fauli <[email protected]> CommitDate: Tue Jul 9 17:59:44 2024 +0200 ScriptForge (Document) tdf#161946 Fix CreateMenu() / Before A too strict validity check of the Before argument prevents the use of numeric values. String values work fine. Fix the arguments of the call to SF_Utils.Validate() in SFDocuments.Document.xba Change-Id: Id1d21cef1c3f056078b0208a8e15c503e1ecb201 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170165 Reviewed-by: Jean-Pierre Ledure <[email protected]> Tested-by: Jenkins (cherry picked from commit b2b29283c21640d02b12c031963dbd50a646552c) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170225 diff --git a/wizards/source/sfdocuments/SF_Document.xba b/wizards/source/sfdocuments/SF_Document.xba index 6382b7c62827..43e143f30a59 100644 --- a/wizards/source/sfdocuments/SF_Document.xba +++ b/wizards/source/sfdocuments/SF_Document.xba @@ -572,7 +572,7 @@ Check: If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then If Not _IsStillAlive() Then GoTo Finally If Not ScriptForge.SF_Utils._Validate(MenuHeader, "MenuHeader", V_STRING) Then GoTo Finally - If Not ScriptForge.SF_Utils._Validate(Before, "Before", V_STRING) Then GoTo Finally + If Not ScriptForge.SF_Utils._Validate(Before, "Before", Array(V_STRING, ScriptForge.V_NUMERIC)) Then GoTo Finally If Not ScriptForge.SF_Utils._Validate(SubmenuChar, "SubmenuChar", V_STRING) Then GoTo Finally End If @@ -2138,4 +2138,4 @@ Private Function _Repr() As String End Function ' SFDocuments.SF_Document._Repr REM ============================================ END OF SFDOCUMENTS.SF_DOCUMENT -</script:module> +</script:module> \ No newline at end of file commit f14b64fd7e2b4f134489d5a444eccdc101cb69bd Author: Miklos Vajna <[email protected]> AuthorDate: Mon Jul 8 10:46:03 2024 +0200 Commit: Xisco Fauli <[email protected]> CommitDate: Tue Jul 9 16:18:27 2024 +0200 tdf#161771 sw content controls: fix DOCX export of empty dropdown list item Open the bugdoc, save as DOCX, try to open in Word: Word refuses to open, saying that the file is corrupted. Each dropdown item has a value and a display text, it seems it's OK to omit the display text, but the value really should not be empty. Fix the problem by first trying to copy the display text to the value if the value would be empty; and if both are empty, then just omit the dropdown item. Note that the trick used at display text won't work here, omitting the value attribute (instead of writing an empty one) is still invalid DOCX. Change-Id: I4ae86aaf1a11cc8fd7c276634647f5737a9b04e4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170142 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins (cherry picked from commit 62fb52cd43d7c0d41dd4e35a1c128947b6a14918) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170111 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/sw/qa/filter/ww8/ww8.cxx b/sw/qa/filter/ww8/ww8.cxx index 070565345a2d..d52055e40ae9 100644 --- a/sw/qa/filter/ww8/ww8.cxx +++ b/sw/qa/filter/ww8/ww8.cxx @@ -14,6 +14,8 @@ #include <com/sun/star/text/XTextDocument.hpp> #include <com/sun/star/text/WrapTextMode.hpp> +#include <comphelper/propertyvalue.hxx> + #include <docsh.hxx> #include <formatcontentcontrol.hxx> #include <wrtsh.hxx> @@ -594,6 +596,48 @@ CPPUNIT_TEST_FIXTURE(Test, testEndnotesAtSectEnd) // i.e. the default position was used: document end. CPPUNIT_ASSERT_EQUAL(OUString("sectEnd"), aPos); } + +CPPUNIT_TEST_FIXTURE(Test, testContentControlPDFDropDownEmptyItem) +{ + // Given a document with a dropdown content control, one item is empty, which can't be saved to + // a valid DOCX: + createSwDoc(); + uno::Reference<lang::XMultiServiceFactory> xMSF(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XText> xText = xTextDocument->getText(); + uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor(); + xText->insertString(xCursor, u"test"_ustr, /*bAbsorb=*/false); + xCursor->gotoStart(/*bExpand=*/false); + xCursor->gotoEnd(/*bExpand=*/true); + uno::Reference<text::XTextContent> xContentControl( + xMSF->createInstance(u"com.sun.star.text.ContentControl"_ustr), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY); + { + uno::Sequence<beans::PropertyValues> aListItems = { + { + comphelper::makePropertyValue(u"DisplayText"_ustr, uno::Any(u"red"_ustr)), + comphelper::makePropertyValue(u"Value"_ustr, uno::Any(u"R"_ustr)), + }, + { + comphelper::makePropertyValue(u"DisplayText"_ustr, uno::Any(u""_ustr)), + comphelper::makePropertyValue(u"Value"_ustr, uno::Any(u""_ustr)), + }, + }; + xContentControlProps->setPropertyValue(u"ListItems"_ustr, uno::Any(aListItems)); + } + xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true); + + // When saving to DOCX: + save(u"Office Open XML Text"_ustr); + + // Then make sure we only emit 1 list item: + xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1 + // - Actual : 2 + // i.e. we emitted an empty list item, so the result can't be opened in Word. + assertXPath(pXmlDoc, "//w:dropDownList/w:listItem"_ostr, 1); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index e8854b62ceba..ca66bb289ac0 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -2717,12 +2717,25 @@ void DocxAttributeOutput::WriteContentControlStart() } for (const auto& rItem : m_pContentControl->GetListItems()) { + if (rItem.m_aDisplayText.isEmpty() && rItem.m_aValue.isEmpty()) + { + // Empty display text & value would be invalid DOCX, skip the item. + continue; + } + rtl::Reference<FastAttributeList> xAttributes = FastSerializerHelper::createAttrList(); if (!rItem.m_aDisplayText.isEmpty()) { // If there is no display text, need to omit the attribute, not write an empty one. xAttributes->add(FSNS(XML_w, XML_displayText), rItem.m_aDisplayText); } + + OUString aValue = rItem.m_aValue; + if (aValue.isEmpty()) + { + // Empty value would be invalid DOCX, default to the display text. + aValue = rItem.m_aDisplayText; + } xAttributes->add(FSNS(XML_w, XML_value), rItem.m_aValue); m_pSerializer->singleElementNS(XML_w, XML_listItem, xAttributes); } commit 371e574ffb938a45578c2ecda85343383fca5c23 Author: Stephan Bergmann <[email protected]> AuthorDate: Tue Jul 9 08:04:57 2024 +0200 Commit: Stephan Bergmann <[email protected]> CommitDate: Tue Jul 9 15:19:44 2024 +0200 Adapt flatpak build to upstream changes <https://github.com/flathub/org.libreoffice.LibreOffice/commit/4bed50e14d9d106093b027bc8bb780023fb42b55> "gvfs: Update gvfs-1.54.1.tar.xz to 1.54.2 (#295)" <https://github.com/flathub/org.libreoffice.LibreOffice/commit/88a0d0718a9ddcd75a0842b5173e6d6ecd4d3bde> "--enable-ext-nlpsolver (#297)" Change-Id: Ie39c22c2611a31a8e2a82ae200b7a3836393dff3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170177 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <[email protected]> (cherry picked from commit 6b80e0554e4b11f9c1eb955c2d26445bc6855371) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170121 diff --git a/distro-configs/LibreOfficeFlatpak.conf b/distro-configs/LibreOfficeFlatpak.conf index 77cb65f6d76e..6a296fd696e4 100644 --- a/distro-configs/LibreOfficeFlatpak.conf +++ b/distro-configs/LibreOfficeFlatpak.conf @@ -1,4 +1,5 @@ --disable-odk +--enable-ext-nlpsolver --enable-release-build --with-ant-home=/run/build/libreoffice/ant --with-extra-buildid=Flatpak diff --git a/solenv/flatpak-manifest.in b/solenv/flatpak-manifest.in index c6e9d4f8e874..3aef4468fa0d 100644 --- a/solenv/flatpak-manifest.in +++ b/solenv/flatpak-manifest.in @@ -51,8 +51,8 @@ "sources": [ { "type": "archive", - "url": "https://download.gnome.org/sources/gvfs/1.54/gvfs-1.54.1.tar.xz", - "sha256": "ac4a3bccb7fe1502158ef0fde5c979ab44712557d028a8e4f30a29f0fbd9d19f", + "url": "https://download.gnome.org/sources/gvfs/1.54/gvfs-1.54.2.tar.xz", + "sha256": "54908f4e10b5f1c231e90330c8c15b7f21f2bb610f194c034b338e379c508e3c", "x-checker-data": { "type": "gnome", "name": "gvfs", commit 0cbb17b4cc2af9cdebebb20126a3459be70f09d2 Author: Christian Lohmaier <[email protected]> AuthorDate: Mon Jul 8 20:02:47 2024 +0200 Commit: Christian Lohmaier <[email protected]> CommitDate: Mon Jul 8 20:02:47 2024 +0200 bump product version to 24.8.0.1.0+ Change-Id: I251f327d209e5ebda174dc7ee3b9244b7e2957cd diff --git a/configure.ac b/configure.ac index 6b981058e1f6..866d54c27f76 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl in order to create a configure script. # several non-alphanumeric characters, those are split off and used only for the # ABOUTBOXPRODUCTVERSIONSUFFIX in openoffice.lst. Why that is necessary, no idea. -AC_INIT([LibreOffice],[24.8.0.0.beta1+],[],[],[http://documentfoundation.org/]) +AC_INIT([LibreOffice],[24.8.0.1.0+],[],[],[http://documentfoundation.org/]) dnl libnumbertext needs autoconf 2.68, but that can pick up autoconf268 just fine if it is installed dnl whereas aclocal (as run by autogen.sh) insists on using autoconf and fails hard commit 4924908d99194c9541b7791c0e7413a5af332e09 Author: Heiko Tietze <[email protected]> AuthorDate: Mon Jul 8 13:58:33 2024 +0200 Commit: Christian Lohmaier <[email protected]> CommitDate: Mon Jul 8 19:57:27 2024 +0200 Resolves tdf#161421 - Keep soft hyphen always visible Soft hyphen is now visible as printable character unless the non-printable is switched on together with the respective option; and soft hyphens are always black in the printout Change-Id: Ief84f986e3d1fa5b11eed827d1a94cf0aef46d10 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170158 Reviewed-by: Heiko Tietze <[email protected]> Tested-by: Jenkins (cherry picked from commit 3d0411ef53ccd6bb0af21b69aa557f1f40beffd0) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170112 Reviewed-by: Christian Lohmaier <[email protected]> diff --git a/sw/source/core/text/txthyph.cxx b/sw/source/core/text/txthyph.cxx index f1dd3acc5b75..bf8751d6cea5 100644 --- a/sw/source/core/text/txthyph.cxx +++ b/sw/source/core/text/txthyph.cxx @@ -431,23 +431,26 @@ SwTwips SwSoftHyphPortion::GetViewWidth(const SwTextSizeInfo& rInf) const */ void SwSoftHyphPortion::Paint( const SwTextPaintInfo &rInf ) const { - if ( Width() && rInf.GetOpt().IsViewMetaChars()) + if ( Width() ) { rInf.DrawViewOpt( *this, PortionType::SoftHyphen ); SwExpandPortion::Paint( rInf ); - OUString aMarker = u"-"_ustr; - SwTextPaintInfo aInf(rInf, &aMarker); - SwTextPortion aMarkerPor; - SwPosSize aMarkerSize(rInf.GetTextSize(aMarker)); - aMarkerPor.Width(aMarkerSize.Width()); - aMarkerPor.Height(aMarkerSize.Height()); - aMarkerPor.SetAscent(GetAscent()); - - Color colorBackup = aInf.GetFont()->GetColor(); - aInf.GetFont()->SetColor(NON_PRINTING_CHARACTER_COLOR); - aInf.DrawText(aMarkerPor, TextFrameIndex(aMarker.getLength()), true); - aInf.GetFont()->SetColor(colorBackup); + if (rInf.GetOpt().IsViewMetaChars() && !rInf.GetOpt().IsPrinting()) + { + OUString aMarker = u"-"_ustr; + SwTextPaintInfo aInf(rInf, &aMarker); + SwTextPortion aMarkerPor; + SwPosSize aMarkerSize(rInf.GetTextSize(aMarker)); + aMarkerPor.Width(aMarkerSize.Width()); + aMarkerPor.Height(aMarkerSize.Height()); + aMarkerPor.SetAscent(GetAscent()); + + Color colorBackup = aInf.GetFont()->GetColor(); + aInf.GetFont()->SetColor(NON_PRINTING_CHARACTER_COLOR); + aInf.DrawText(aMarkerPor, TextFrameIndex(aMarker.getLength()), true); + aInf.GetFont()->SetColor(colorBackup); + } } } commit e2b45e8fab139e9f51fee44a218ec8ec79d28bf2 Author: Christian Lohmaier <[email protected]> AuthorDate: Mon Jul 8 18:27:16 2024 +0200 Commit: Gerrit Code Review <[email protected]> CommitDate: Mon Jul 8 18:27:16 2024 +0200 Update git submodules * Update translations from branch 'libreoffice-24-8' to d8b21faf49eb9131634ab258d39a73427cbf7d26 - update translations for 24.8.0 rc1/master and force-fix errors using pocheck Change-Id: I696fda5336e4c075c43ebbdddc1974e5f1c6fe65 (cherry picked from commit a9266fc54a66142dba20625f94d196898070ca0d) diff --git a/translations b/translations index 9c4940d11cc6..d8b21faf49eb 160000 --- a/translations +++ b/translations @@ -1 +1 @@ -Subproject commit 9c4940d11cc69f95cbe67f01635ebab908685e24 +Subproject commit d8b21faf49eb9131634ab258d39a73427cbf7d26 commit eb815bdee64f9eb9527cb58e6b75f0bd69184c71 Author: László Németh <[email protected]> AuthorDate: Thu Jun 27 11:06:35 2024 +0200 Commit: Christian Lohmaier <[email protected]> CommitDate: Mon Jul 8 17:09:10 2024 +0200 tdf#161737 i18npool: fix bad word selection with NNBSP Fix word breaking rules also for editing. Previously the word was selected with the following narrow no-break space, e.g. at French words before exclamation and question marks (where narrow no-break space allows to get correct typography, if the OpenType/Graphite font doesn't have this feature). Add this and the previous fixes for Hungarian, which handled by extra word-breaking rule files. Follow-up to commit 6e002da1615b52cda4e9331e87878458b1fe9677 "tdf#161737 i18npool: fix fake spelling alarms with NNBSP". Change-Id: I7230bd356e5f0360172b652e615a61d96131d336 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169624 Tested-by: Jenkins Reviewed-by: László Németh <[email protected]> (cherry picked from commit 2b9fee5a3e9d1eae65932fb0f08f0216f8a30cf7) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169594 Reviewed-by: Christian Lohmaier <[email protected]> diff --git a/i18npool/qa/cppunit/test_breakiterator.cxx b/i18npool/qa/cppunit/test_breakiterator.cxx index 6fbde026f565..7e9f47ad22f1 100644 --- a/i18npool/qa/cppunit/test_breakiterator.cxx +++ b/i18npool/qa/cppunit/test_breakiterator.cxx @@ -1022,6 +1022,36 @@ void TestBreakIterator::testWordBoundaries() // This was 8 (word + NNBSP) CPPUNIT_ASSERT_EQUAL(sal_Int32(5), aBounds.endPos); } + + // tdf#161737: narrow no-break space at the end of words resulted spelling mistakes + { + aLocale.Language = "hu"; + aLocale.Country = "HU"; + + OUString aTest(u"L’espace fine insécable\u202F!"_ustr); + aBounds + = m_xBreak->getWordBoundary(aTest, 14, aLocale, i18n::WordType::DICTIONARY_WORD, false); + CPPUNIT_ASSERT_EQUAL(sal_Int32(14), aBounds.startPos); + // This was 24 (word + NNBSP) + CPPUNIT_ASSERT_EQUAL(sal_Int32(23), aBounds.endPos); + } + + // tdf#161737: narrow no-break space between digits resulted spelling mistakes + // as a quick fix, limit NBSP as word-part character only for editing, and not for spell checking + // TODO: remove NBSP by the linguistic module or by the spell checking dictionaries to allow + // to check numbers with thousand separators and with correct suffix + { + aLocale.Language = "hu"; + aLocale.Country = "HU"; + + OUString aTest(u"1\u202F000\u202F000"_ustr); + aBounds + = m_xBreak->getWordBoundary(aTest, 2, aLocale, i18n::WordType::DICTIONARY_WORD, false); + // This was 0 (word + NNBSP) + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aBounds.startPos); + // This was 8 (word + NNBSP) + CPPUNIT_ASSERT_EQUAL(sal_Int32(5), aBounds.endPos); + } } void TestBreakIterator::testSentenceBoundaries() diff --git a/i18npool/source/breakiterator/data/dict_word_hu.txt b/i18npool/source/breakiterator/data/dict_word_hu.txt index 88648e6e5716..4ba426c8c7db 100644 --- a/i18npool/source/breakiterator/data/dict_word_hu.txt +++ b/i18npool/source/breakiterator/data/dict_word_hu.txt @@ -53,7 +53,7 @@ $Double_Quote = [\p{Word_Break = Double_Quote}]; $MidNumLet = [\p{Word_Break = MidNumLet}]; $MidNum = [\p{Word_Break = MidNum}]; $Numeric = [\p{Word_Break = Numeric}]; -$ExtendNumLet = [\p{Word_Break = ExtendNumLet}]; +$ExtendNumLet = [\p{Word_Break = ExtendNumLet}-[:name = NARROW NO-BREAK SPACE:]]; $WSegSpace = [\p{Word_Break = WSegSpace}]; $Extended_Pict = [\p{Extended_Pictographic}]; diff --git a/i18npool/source/breakiterator/data/edit_word.txt b/i18npool/source/breakiterator/data/edit_word.txt index 14fc221aa96e..1e3bcd15b20d 100644 --- a/i18npool/source/breakiterator/data/edit_word.txt +++ b/i18npool/source/breakiterator/data/edit_word.txt @@ -65,7 +65,7 @@ $Extended_Pict = [\p{Extended_Pictographic}]; $MidNumLet = [\p{Word_Break = MidNumLet}-[:name= FULL STOP:]]; # $ExtendNumLet = [\p{Word_Break = ExtendNumLet}]; -$ExtendNumLet = [\p{Word_Break = ExtendNumLet}-[:name= LOW LINE:]]; +$ExtendNumLet = [\p{Word_Break = ExtendNumLet}-[:name= LOW LINE:]-[:name = NARROW NO-BREAK SPACE:]]; ### END CUSTOMIZATION @@ -164,16 +164,18 @@ $Numeric $ExFm* ($MidNum | $MidNumLet | $Single_Quote) $ExFm* $Numeric; $Katakana $ExFm* $Katakana {400}; # rule 13a/b +# allow to select numbers with narrow no-break spaces as thousand separators +$ExtendNumLetNNBSP = [\p{Word_Break = ExtendNumLet}]; $ALetterPlus $ExFm* $ExtendNumLet {200}; # (13a) $Hebrew_Letter $ExFm* $ExtendNumLet {200}; # (13a) -$Numeric $ExFm* $ExtendNumLet {100}; # (13a) +$Numeric $ExFm* $ExtendNumLetNNBSP {100}; # (13a) $Katakana $ExFm* $ExtendNumLet {400}; # (13a) $ExtendNumLet $ExFm* $ExtendNumLet {200}; # (13a) $ExtendNumLet $ExFm* $ALetterPlus {200}; # (13b) $ExtendNumLet $ExFm* $Hebrew_Letter {200}; # (13b) -$ExtendNumLet $ExFm* $Numeric {100}; # (13b) +$ExtendNumLetNNBSP $ExFm* $Numeric {100}; # (13b) $ExtendNumLet $ExFm* $Katakana {400}; # (13b) # rules 15 - 17 diff --git a/i18npool/source/breakiterator/data/edit_word_hu.txt b/i18npool/source/breakiterator/data/edit_word_hu.txt index 389ad2bacc13..a5e44d2732d9 100644 --- a/i18npool/source/breakiterator/data/edit_word_hu.txt +++ b/i18npool/source/breakiterator/data/edit_word_hu.txt @@ -81,7 +81,7 @@ $MidLetter = [\p{Word_Break = MidLetter} $Symbols_hu]; $MidNumLet = [\p{Word_Break = MidNumLet}-[:name= FULL STOP:]]; # $ExtendNumLet = [\p{Word_Break = ExtendNumLet}]; -$ExtendNumLet = [\p{Word_Break = ExtendNumLet}-[:name= LOW LINE:]]; +$ExtendNumLet = [\p{Word_Break = ExtendNumLet}-[:name= LOW LINE:]-[:name = NARROW NO-BREAK SPACE:]]; ### END CUSTOMIZATION @@ -180,16 +180,18 @@ $Numeric $ExFm* ($MidNum | $MidNumLet | $Single_Quote) $ExFm* $Numeric; $Katakana $ExFm* $Katakana {400}; # rule 13a/b +# allow to select numbers with narrow no-break spaces as thousand separators +$ExtendNumLetNNBSP = [\p{Word_Break = ExtendNumLet}]; $ALetterPlus $ExFm* $ExtendNumLet {200}; # (13a) $Hebrew_Letter $ExFm* $ExtendNumLet {200}; # (13a) -$Numeric $ExFm* $ExtendNumLet {100}; # (13a) +$Numeric $ExFm* $ExtendNumLetNNBSP {100}; # (13a) $Katakana $ExFm* $ExtendNumLet {400}; # (13a) $ExtendNumLet $ExFm* $ExtendNumLet {200}; # (13a) $ExtendNumLet $ExFm* $ALetterPlus {200}; # (13b) $ExtendNumLet $ExFm* $Hebrew_Letter {200}; # (13b) -$ExtendNumLet $ExFm* $Numeric {100}; # (13b) +$ExtendNumLetNNBSP $ExFm* $Numeric {100}; # (13b) $ExtendNumLet $ExFm* $Katakana {400}; # (13b) # rules 15 - 17 commit fc2bba731459b5ba2ed88fc8212f90b6ae08c15a Author: László Németh <[email protected]> AuthorDate: Thu Jun 27 10:06:03 2024 +0200 Commit: Christian Lohmaier <[email protected]> CommitDate: Mon Jul 8 17:09:02 2024 +0200 tdf#161737 i18npool: fix fake spelling alarms with NNBSP Fix word break by excluding narrow no-break space at the end of the words for spell checking. This was a problem e.g. for French, where (automatically? or manually) inserted narrow no-break space is used to get correct typography before exclamation and question marks, also after and before guillemets, if the OpenType/Graphite font doesn't have this feature). Regression from commit 44699b3de37f07090ac6fee1cd97aa76036e9700 "tdf#49885 BreakIterator rule upgrades". Note: this fixes also the problem, when digits separated by NNBSP thousand separator weren't handled by spell checking, alarming fake spelling mistakes, when "Check words with numbers" was enabled in Tools->Options->Languages and Locales->Writing Aids. (TODO: at the case of thousand separators, remove NBSP by the linguistic module or by the spell checking dictionaries to allow to check numbers with thousand separators and with correct suffix.) Change-Id: I36e10add7e0ba840f207a375ccc8668dbfef9572 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169618 Tested-by: Jenkins Reviewed-by: László Németh <[email protected]> (cherry picked from commit 6e002da1615b52cda4e9331e87878458b1fe9677) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169593 Reviewed-by: Christian Lohmaier <[email protected]> diff --git a/i18npool/qa/cppunit/test_breakiterator.cxx b/i18npool/qa/cppunit/test_breakiterator.cxx index e790c17e1155..6fbde026f565 100644 --- a/i18npool/qa/cppunit/test_breakiterator.cxx +++ b/i18npool/qa/cppunit/test_breakiterator.cxx @@ -992,6 +992,36 @@ void TestBreakIterator::testWordBoundaries() CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aBounds.startPos); CPPUNIT_ASSERT_EQUAL(sal_Int32(11), aBounds.endPos); } + + // tdf#161737: narrow no-break space at the end of words resulted spelling mistakes + { + aLocale.Language = "en"; + aLocale.Country = "US"; + + OUString aTest(u"L’espace fine insécable\u202F!"_ustr); + aBounds + = m_xBreak->getWordBoundary(aTest, 14, aLocale, i18n::WordType::DICTIONARY_WORD, false); + CPPUNIT_ASSERT_EQUAL(sal_Int32(14), aBounds.startPos); + // This was 24 (word + NNBSP) + CPPUNIT_ASSERT_EQUAL(sal_Int32(23), aBounds.endPos); + } + + // tdf#161737: narrow no-break space between digits resulted spelling mistakes + // as a quick fix, limit NBSP as word-part character only for editing, and not for spell checking + // TODO: remove NBSP by the linguistic module or by the spell checking dictionaries to allow + // to check numbers with thousand separators and with correct suffix + { + aLocale.Language = "en"; + aLocale.Country = "US"; + + OUString aTest(u"1\u202F000\u202F000"_ustr); + aBounds + = m_xBreak->getWordBoundary(aTest, 2, aLocale, i18n::WordType::DICTIONARY_WORD, false); + // This was 0 (word + NNBSP) + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), aBounds.startPos); + // This was 8 (word + NNBSP) + CPPUNIT_ASSERT_EQUAL(sal_Int32(5), aBounds.endPos); + } } void TestBreakIterator::testSentenceBoundaries() diff --git a/i18npool/source/breakiterator/data/dict_word.txt b/i18npool/source/breakiterator/data/dict_word.txt index f804b0eec214..deeec7dd659e 100644 --- a/i18npool/source/breakiterator/data/dict_word.txt +++ b/i18npool/source/breakiterator/data/dict_word.txt @@ -54,7 +54,7 @@ $Double_Quote = [\p{Word_Break = Double_Quote}]; $MidNumLet = [\p{Word_Break = MidNumLet}]; $MidNum = [\p{Word_Break = MidNum}]; $Numeric = [\p{Word_Break = Numeric}]; -$ExtendNumLet = [\p{Word_Break = ExtendNumLet}]; +$ExtendNumLet = [\p{Word_Break = ExtendNumLet}-[:name = NARROW NO-BREAK SPACE:]]; $WSegSpace = [\p{Word_Break = WSegSpace}]; $Extended_Pict = [\p{Extended_Pictographic}]; commit 0c3b1fec87b1d1f32832e2265918f68f93e2aca7 Author: Andreas Heinisch <[email protected]> AuthorDate: Sun Jun 23 14:57:34 2024 +0200 Commit: Christian Lohmaier <[email protected]> CommitDate: Mon Jul 8 16:32:14 2024 +0200 tdf#158110 - Paste special: improve check for cells with notes Change-Id: Ia18d8f91ee2d4493174255424ce7e3b7310c369d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169355 Reviewed-by: Andreas Heinisch <[email protected]> Tested-by: Jenkins (cherry picked from commit 8cf0bc36a8baa1d53b0a5fb169c6a9d5d8455289) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170039 Reviewed-by: Christian Lohmaier <[email protected]> diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 2f67225bf8ec..15f1720142fb 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -1359,6 +1359,8 @@ public: // This also includes e.g. notes. Use IsEmptyData() for cell data only. bool IsBlockEmpty( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab ) const; + bool IsNotesBlockEmpty( SCCOL nStartCol, SCROW nStartRow, + SCCOL nEndCol, SCROW nEndRow, SCTAB nTab ) const; bool IsPrintEmpty( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, bool bLeftIsEmpty = false, diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 08f2fbce3015..ca43636e57b9 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -426,6 +426,7 @@ public: // This also includes e.g. notes. Use IsEmptyData() for cell data only. bool IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const; + bool IsNotesBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const; bool SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString& rString, const ScSetStringParam * pParam = nullptr ); diff --git a/sc/qa/uitest/pasteSpecial/tdf158110.py b/sc/qa/uitest/pasteSpecial/tdf158110.py index 9b0dba6ed8cd..9d775226c030 100644 --- a/sc/qa/uitest/pasteSpecial/tdf158110.py +++ b/sc/qa/uitest/pasteSpecial/tdf158110.py @@ -12,6 +12,7 @@ from uitest.framework import UITestCase from libreoffice.calc.document import get_cell_by_position from libreoffice.uno.propertyvalue import mkPropertyValues from libreoffice.calc.paste_special import reset_default_values +from uitest.uihelper.common import get_state_as_dict class tdf158110(UITestCase): def test_tdf158110_paste_special_multiple_cells(self): @@ -45,4 +46,41 @@ class tdf158110(UITestCase): # i.e., the comment was not copied self.assertEqual("Comment 1", get_cell_by_position(document, 0, 1, 0).Annotation.String) + def test_tdf158110_paste_special_overwrite_comments(self): + with self.ui_test.create_doc_in_start_center("calc") as document: + xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window") + + # Insert a comments + targetCells = ["A1", "A2", "B3", "D2"] + for targetCell in targetCells: + xGridWin.executeAction("SELECT", mkPropertyValues({"CELL": targetCell})) + xArgs = mkPropertyValues({"Text": "Comment 1"}) + self.xUITest.executeCommandWithParameters(".uno:InsertAnnotation", xArgs) + + # Copy cell range A1:B3 to clipboard + xGridWin.executeAction("SELECT", mkPropertyValues({"RANGE": "A1:B3"})) + self.xUITest.executeCommand(".uno:Copy") + + # Paste data using special options (check only comments), i.e., overwrite comment in D2 + xGridWin.executeAction("SELECT", mkPropertyValues({"CELL": "D1"})) + with self.ui_test.execute_dialog_through_command(".uno:PasteSpecial") as xPasteSpecialDlg: + reset_default_values(self, xPasteSpecialDlg) + xDateTimeChkBox = xPasteSpecialDlg.getChild("datetime") + xDateTimeChkBox.executeAction("CLICK", tuple()) + xTextChkBox = xPasteSpecialDlg.getChild("text") + xTextChkBox.executeAction("CLICK", tuple()) + xNumbersChkBox = xPasteSpecialDlg.getChild("numbers") + xNumbersChkBox.executeAction("CLICK", tuple()) + xCommentsChkBox = xPasteSpecialDlg.getChild("comments") + xCommentsChkBox.executeAction("CLICK", tuple()) + + # Without the fix in place, this test would have failed with + # AssertionError: 'CheckWarningDialog' != '' + # i.e., the warning dialog was not shown + xCheckWarningDlg = self.xUITest.getTopFocusWindow() + self.assertEqual("CheckWarningDialog", get_state_as_dict(xCheckWarningDlg)["ID"]) + if get_state_as_dict(xCheckWarningDlg)["ID"] == "CheckWarningDialog": + xYesBtn = xCheckWarningDlg.getChild("yes") + xYesBtn.executeAction("CLICK", tuple()) + # vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 51d636c588af..78f36e0bc462 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -5308,6 +5308,15 @@ void ScDocument::GetBorderLines( SCCOL nCol, SCROW nRow, SCTAB nTab, *ppBottom = pBottomLine; } +bool ScDocument::IsNotesBlockEmpty(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, + SCTAB nTab) const +{ + if (HasTable(nTab)) + return maTabs[nTab]->IsNotesBlockEmpty(nStartCol, nStartRow, nEndCol, nEndRow); + OSL_FAIL("wrong table number"); + return false; +} + bool ScDocument::IsBlockEmpty(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const { diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index aa51bec2d727..4629ce8036d1 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -2396,6 +2396,20 @@ void ScTable::SetMergedCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ApplyFlags(nCol1+1, nRow1+1, nCol2, nRow2, ScMF::Hor | ScMF::Ver); } +bool ScTable::IsNotesBlockEmpty(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const +{ + if (!(ValidCol(nCol1) && ValidCol(nCol2))) + { + OSL_FAIL("ScTable::IsBlockEmptyNotes: invalid column number"); + return false; + } + nCol2 = ClampToAllocatedColumns(nCol2); + bool bEmpty = true; + for (SCCOL i = nCol1; i <= nCol2 && bEmpty; i++) + bEmpty = aCol[i].IsNotesEmptyBlock(nRow1, nRow2); + return bEmpty; +} + bool ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const { if (!(ValidCol(nCol1) && ValidCol(nCol2))) diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index f9ded7171687..d3e40076187a 100644 --- a/sc/source/ui/view/viewfun3.cxx +++ b/sc/source/ui/view/viewfun3.cxx @@ -852,13 +852,18 @@ bool checkDestRangeForOverwrite(InsertDeleteFlags nFlags, const ScRangeList& rDe { bool bIsEmpty = true; size_t nRangeSize = rDestRanges.size(); + for (const auto& rTab : rMark) { for (size_t i = 0; i < nRangeSize && bIsEmpty; ++i) { const ScRange& rRange = rDestRanges[i]; - if (nFlags & InsertDeleteFlags::ADDNOTES) - bIsEmpty = !rDoc.HasNote(rRange.aStart) && !rDoc.HasNote(rRange.aEnd); + // tdf#158110 - check if just the ADDNOTES flag is present without any other content + if ((nFlags & InsertDeleteFlags::ADDNOTES) == InsertDeleteFlags::ADDNOTES + && (nFlags & (InsertDeleteFlags::CONTENTS & ~InsertDeleteFlags::NOTE)) + == InsertDeleteFlags::NONE) + bIsEmpty = rDoc.IsNotesBlockEmpty(rRange.aStart.Col(), rRange.aStart.Row(), + rRange.aEnd.Col(), rRange.aEnd.Row(), rTab); else bIsEmpty = rDoc.IsBlockEmpty(rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rTab); commit 8cb56a69c27a60f111e920aff22068b1abc0251e Author: Heiko Tietze <[email protected]> AuthorDate: Tue Jul 2 16:13:34 2024 +0200 Commit: Christian Lohmaier <[email protected]> CommitDate: Mon Jul 8 16:29:52 2024 +0200 Resolves tdf#161796 - Donate button at start center Cherry-picks the patches I83d10d7230722d38914934d59d70ece471e62599 I9042bd1573e97164233ae9289193301ed01fc3c4 Ib9716b5ca18727eb50e637decc008a80089875cf I0a591cc1ec8c3c506ece47dc89f368096f6c8e51 Change-Id: I0ff0d650b09e5231aa8f8fa1baee16336481592b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169885 Tested-by: Jenkins Reviewed-by: Christian Lohmaier <[email protected]> diff --git a/icon-themes/colibre/res/donate.png b/icon-themes/colibre/res/donate.png new file mode 100644 index 000000000000..570309eb85c8 Binary files /dev/null and b/icon-themes/colibre/res/donate.png differ diff --git a/officecfg/registry/data/org/openoffice/Office/Common.xcu b/officecfg/registry/data/org/openoffice/Office/Common.xcu index de1eae2ce767..f146d5a82769 100644 --- a/officecfg/registry/data/org/openoffice/Office/Common.xcu +++ b/officecfg/registry/data/org/openoffice/Office/Common.xcu @@ -457,6 +457,9 @@ <prop oor:name="PerformFileExtCheck"> <value install:module="wnt">true</value> </prop> + <prop oor:name="ShowDonation"> + <value>true</value> + </prop> </node> <node oor:name="Save"> <node oor:name="ODF"> diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs index 15b3a481195c..c2e0e97159d1 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs @@ -5367,6 +5367,12 @@ </info> <value>false</value> </prop> + <prop oor:name="ShowDonation" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc>Determines whether to show a donation button in the start center or extension.</desc> + </info> + <value>true</value> + </prop> <prop oor:name="UseOpenCL" oor:type="xs:boolean" oor:nillable="false"> <info> <desc>Determines whether OpenCL can be used, when available, to speed up diff --git a/sfx2/inc/bitmaps.hlst b/sfx2/inc/bitmaps.hlst index 0484bb7e18e9..04169c38d2db 100644 --- a/sfx2/inc/bitmaps.hlst +++ b/sfx2/inc/bitmaps.hlst @@ -95,4 +95,6 @@ inline constexpr OUString BMP_MENU_RENAME = u"cmd/sc_editdoc.png"_ustr; inline constexpr OUString BMP_MENU_DELETE = u"cmd/sc_delete.png"_ustr; inline constexpr OUString BMP_MENU_EXPORT = u"cmd/sc_exportto.png"_ustr; +inline constexpr OUString BMP_DONATE = u"res/donate.png"_ustr; + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sfx2/source/dialog/backingwindow.cxx b/sfx2/source/dialog/backingwindow.cxx index e3761327ee60..323f5ae554ed 100644 --- a/sfx2/source/dialog/backingwindow.cxx +++ b/sfx2/source/dialog/backingwindow.cxx @@ -56,6 +56,10 @@ #include <com/sun/star/util/URLTransformer.hpp> #include <com/sun/star/task/InteractionHandler.hpp> +#include <sfx2/strings.hrc> +#include <sfx2/sfxresid.hxx> +#include <bitmaps.hlst> + using namespace ::com::sun::star; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::frame; @@ -189,6 +193,13 @@ BackingWindow::BackingWindow(vcl::Window* i_pParent) mxHelpButton->set_label(mxAltHelpLabel->get_label()); mxHelpButton->connect_clicked(LINK(this, BackingWindow, ClickHelpHdl)); + // tdf#161796 make the extension button show the donation page + if (officecfg::Office::Common::Misc::ShowDonation::get()) + { + mxExtensionsButton->set_from_icon_name(BMP_DONATE); + mxExtensionsButton->set_label(SfxResId(STR_DONATE_BUTTON)); + } + mxDropTarget = mxAllRecentThumbnails->GetDropTarget(); try commit 41a704f51b748388c6795afb563177fa680f7931 Author: Samuel Mehrbrodt <[email protected]> AuthorDate: Mon Jul 1 23:43:01 2024 +0200 Commit: Xisco Fauli <[email protected]> CommitDate: Mon Jul 8 16:27:41 2024 +0200 pptx export: Respect user defined initials instead of generating new ones. Change-Id: I8979eaa694642cebd552534eeddcff5483831e6e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169846 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <[email protected]> Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170093 diff --git a/sd/source/filter/eppt/epptbase.hxx b/sd/source/filter/eppt/epptbase.hxx index 18199210cc6b..70bcd3a4b6ce 100644 --- a/sd/source/filter/eppt/epptbase.hxx +++ b/sd/source/filter/eppt/epptbase.hxx @@ -379,7 +379,6 @@ protected: ::tools::Rectangle MapRectangle( const css::awt::Rectangle& ); bool ContainsOtherShapeThanPlaceholders(); - static OUString GetInitials(std::u16string_view sName); public: PPTWriterBase(); diff --git a/sd/source/filter/eppt/epptooxml.hxx b/sd/source/filter/eppt/epptooxml.hxx index 9646afb865d8..7d1fa57f11d3 100644 --- a/sd/source/filter/eppt/epptooxml.hxx +++ b/sd/source/filter/eppt/epptooxml.hxx @@ -109,7 +109,7 @@ private: sal_uInt32 GetNewSlideId() { return mnSlideIdMax ++; } sal_uInt32 GetNewSlideMasterId() { return mnSlideMasterIdMax ++; } - sal_Int32 GetAuthorIdAndLastIndex( const OUString& sAuthor, sal_Int32& nLastIndex ); + sal_Int32 GetAuthorIdAndLastIndex( const OUString& sAuthor, const OUString& sInitials, sal_Int32& nLastIndex ); // Write docProps/core.xml and docprops/custom.xml and docprops/app.xml void writeDocumentProperties(); @@ -165,6 +165,7 @@ private: struct AuthorComments { sal_Int32 nId; sal_Int32 nLastIndex; + OUString sInitials; }; typedef std::unordered_map< OUString, struct AuthorComments > AuthorsMap; AuthorsMap maAuthors; diff --git a/sd/source/filter/eppt/pptx-epptbase.cxx b/sd/source/filter/eppt/pptx-epptbase.cxx index fe9444865797..eebf01410c15 100644 --- a/sd/source/filter/eppt/pptx-epptbase.cxx +++ b/sd/source/filter/eppt/pptx-epptbase.cxx @@ -998,24 +998,4 @@ bool PPTWriterBase::ContainsOtherShapeThanPlaceholders() return bOtherThanPlaceHolders; } -OUString PPTWriterBase::GetInitials(std::u16string_view sName) -{ - OUStringBuffer sRet; - - if (!sName.empty()) - { - sRet.append(sName[0]); - size_t nStart = 0, nOffset; - - while ((nOffset = sName.find(' ', nStart)) != std::u16string_view::npos) - { - if (nOffset + 1 < sName.size()) - sRet.append(sName[ nOffset + 1 ]); - nStart = nOffset + 1; - } - } - - return sRet.makeStringAndClear(); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx b/sd/source/filter/eppt/pptx-epptooxml.cxx index f7379a3cd68e..6c1b8c466e01 100644 --- a/sd/source/filter/eppt/pptx-epptooxml.cxx +++ b/sd/source/filter/eppt/pptx-epptooxml.cxx @@ -1036,7 +1036,7 @@ void PowerPointExport::WriteAuthors() pFS->singleElementNS(XML_p, XML_cmAuthor, XML_id, OString::number(i.second.nId), XML_name, i.first, - XML_initials, GetInitials(i.first), + XML_initials, i.second.sInitials, XML_lastIdx, OString::number(i.second.nLastIndex), XML_clrIdx, OString::number(i.second.nId)); } @@ -1046,7 +1046,9 @@ void PowerPointExport::WriteAuthors() pFS->endDocument(); } -sal_Int32 PowerPointExport::GetAuthorIdAndLastIndex(const OUString& sAuthor, sal_Int32& nLastIndex) +sal_Int32 PowerPointExport::GetAuthorIdAndLastIndex(const OUString& sAuthor, + const OUString& sInitials, + sal_Int32& nLastIndex) { if (maAuthors.count(sAuthor) <= 0) { @@ -1054,6 +1056,7 @@ sal_Int32 PowerPointExport::GetAuthorIdAndLastIndex(const OUString& sAuthor, sal aAuthorComments.nId = maAuthors.size(); aAuthorComments.nLastIndex = 0; + aAuthorComments.sInitials = sInitials; maAuthors[ sAuthor ] = aAuthorComments; } @@ -1172,7 +1175,10 @@ bool PowerPointExport::WriteComments(sal_uInt32 nPageNum) ? "Author" + OUString::number(GetInfoID(xAnnotation->getAuthor())) : xAnnotation->getAuthor()); - sal_Int32 nId = GetAuthorIdAndLastIndex(sAuthor, nLastIndex); + OUString sInitials(bRemoveCommentAuthorDates + ? "A" + OUString::number(GetInfoID(xAnnotation->getAuthor())) + : xAnnotation->getInitials()); + sal_Int32 nId = GetAuthorIdAndLastIndex(sAuthor, sInitials, nLastIndex); char cDateTime[sizeof("-32768-65535-65535T65535:65535:65535.4294967295")]; // reserve enough space for hypothetical max length commit 80ad887134d0a253aaf60f66fcd980e2b3c92743 Author: László Németh <[email protected]> AuthorDate: Wed Jun 26 17:53:21 2024 +0200 Commit: Christian Lohmaier <[email protected]> CommitDate: Mon Jul 8 16:24:04 2024 +0200 tdf#138258 i18npool: allow ASCII double quote to match typographic quote Similar to the straight (typewriter or ASCII) apostrophe, straight double quotation mark (") matches its typographic variants now, like other word processors do. Note: regex search doesn't use this matching, similar to the apostrophe search. Follow-up to commit d40f2d02df26e216f367b5da3f9546b73f250469 "tdf#117643 Writer: fix apostrophe search regression". Change-Id: If6a3ee00750828583cd0cfc4aa7f7b656ea9bd1e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169605 Reviewed-by: László Németh <[email protected]> Tested-by: Jenkins (cherry picked from commit 3a02490e1a04c32e18ce5bad5f3c3cb70501a7a4) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169590 Reviewed-by: Christian Lohmaier <[email protected]> diff --git a/i18npool/qa/cppunit/test_textsearch.cxx b/i18npool/qa/cppunit/test_textsearch.cxx index 269380a90910..38cc099b7c95 100644 --- a/i18npool/qa/cppunit/test_textsearch.cxx +++ b/i18npool/qa/cppunit/test_textsearch.cxx @@ -38,6 +38,7 @@ public: void testSearches(); void testWildcardSearch(); void testApostropheSearch(); + void testQuotationMarkSearch(); void testTdf138410(); CPPUNIT_TEST_SUITE(TestTextSearch); @@ -45,6 +46,7 @@ public: CPPUNIT_TEST(testSearches); CPPUNIT_TEST(testWildcardSearch); CPPUNIT_TEST(testApostropheSearch); + CPPUNIT_TEST(testQuotationMarkSearch); CPPUNIT_TEST(testTdf138410); CPPUNIT_TEST_SUITE_END(); private: @@ -404,6 +406,92 @@ void TestTextSearch::testApostropheSearch() CPPUNIT_ASSERT( aRes.subRegExpressions > 0 ); } +void TestTextSearch::testQuotationMarkSearch() +{ + // A) find typographic quotation marks also by using ASCII ones + OUString str( u"“x”, „y‟, ‘z’, ‚a‛"_ustr ); + sal_Int32 startPos = 0, endPos = str.getLength(); + + // set options + util::SearchOptions aOptions; + aOptions.algorithmType = util::SearchAlgorithms_ABSOLUTE; + aOptions.searchFlag = util::SearchFlags::ALL_IGNORE_CASE; + aOptions.searchString = "\"x\""; + aOptions.transliterateFlags = static_cast<int>(TransliterationFlags::IGNORE_CASE + | TransliterationFlags::IGNORE_WIDTH); + m_xSearch->setOptions( aOptions ); + + util::SearchResult aRes; + + // search forward + aRes = m_xSearch->searchForward( str, startPos, endPos ); + // This was 0. + CPPUNIT_ASSERT( aRes.subRegExpressions > 0 ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(0), aRes.startOffset[0] ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(3), aRes.endOffset[0] ); + + // search backwards + aRes = m_xSearch->searchBackward( str, endPos, startPos ); + // This was 0. + CPPUNIT_ASSERT( aRes.subRegExpressions > 0 ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(3), aRes.startOffset[0] ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(0), aRes.endOffset[0] ); + + // B) + aOptions.searchString = "\"y\""; + m_xSearch->setOptions( aOptions ); + + // search forward + aRes = m_xSearch->searchForward( str, startPos, endPos ); + // This was 0. + CPPUNIT_ASSERT( aRes.subRegExpressions > 0 ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(5), aRes.startOffset[0] ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(8), aRes.endOffset[0] ); + + // search backwards + aRes = m_xSearch->searchBackward( str, endPos, startPos ); + // This was 0. + CPPUNIT_ASSERT( aRes.subRegExpressions > 0 ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(8), aRes.startOffset[0] ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(5), aRes.endOffset[0] ); + + // C) + aOptions.searchString = "'z'"; + m_xSearch->setOptions( aOptions ); + + // search forward + aRes = m_xSearch->searchForward( str, startPos, endPos ); + // This was 0. + CPPUNIT_ASSERT( aRes.subRegExpressions > 0 ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(10), aRes.startOffset[0] ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(13), aRes.endOffset[0] ); + + // search backwards + aRes = m_xSearch->searchBackward( str, endPos, startPos ); + // This was 0. + CPPUNIT_ASSERT( aRes.subRegExpressions > 0 ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(13), aRes.startOffset[0] ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(10), aRes.endOffset[0] ); + + // D) + aOptions.searchString = "'a'"; + m_xSearch->setOptions( aOptions ); + + // search forward + aRes = m_xSearch->searchForward( str, startPos, endPos ); + // This was 0. + CPPUNIT_ASSERT( aRes.subRegExpressions > 0 ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(15), aRes.startOffset[0] ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(18), aRes.endOffset[0] ); + + // search backwards + aRes = m_xSearch->searchBackward( str, endPos, startPos ); + // This was 0. + CPPUNIT_ASSERT( aRes.subRegExpressions > 0 ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(18), aRes.startOffset[0] ); + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(15), aRes.endOffset[0] ); +} + void TestTextSearch::testTdf138410() { OUString str(u"\u0643\u064f\u062a\u064f\u0628 \u0643\u062a\u0628"_ustr); diff --git a/i18npool/source/search/textsearch.cxx b/i18npool/source/search/textsearch.cxx index 816e162c1e6e..dbb49f494781 100644 --- a/i18npool/source/search/textsearch.cxx +++ b/i18npool/source/search/textsearch.cxx @@ -93,6 +93,30 @@ bool isSimpleRegexTrans( TransliterationFlags n ) { return bool(maskSimpleRegexTrans(n)); } + +bool isReplacePunctuation( OUString &rStr ) +{ + return rStr.indexOf(u'\u2018') > -1 || + rStr.indexOf(u'\u2019') > -1 || + rStr.indexOf(u'\u201A') > -1 || + rStr.indexOf(u'\u201B') > -1 || + rStr.indexOf(u'\u201C') > -1 || + rStr.indexOf(u'\u201D') > -1 || + rStr.indexOf(u'\u201E') > -1 || + rStr.indexOf(u'\u201F') > -1; +} + +OUString replacePunctuation( OUString &rStr ) +{ + return rStr.replace(u'\u2018', '\'') + .replace(u'\u2019', '\'') + .replace(u'\u201A', '\'') + .replace(u'\u201B', '\'') + .replace(u'\u201C', '"') + .replace(u'\u201D', '"') + .replace(u'\u201E', '"') + .replace(u'\u201F', '"'); +} }; TextSearch::TextSearch(const Reference < XComponentContext > & rxContext) @@ -139,10 +163,10 @@ void TextSearch::setOptions2( const SearchOptions2& rOptions ) // match is not case-altered, leave case-(in)sensitive to regex engine. transliterateFlags &= ~TransliterationFlags::IGNORE_CASE; } - else if ( aSrchPara.searchString.indexOf('\'') > - 1 ) + else if ( aSrchPara.searchString.indexOf('\'') > - 1 || aSrchPara.searchString.indexOf('"') > - 1 ) { bSearchApostrophe = true; - bReplaceApostrophe = aSrchPara.searchString.indexOf(u'\u2019') > -1; + bReplaceApostrophe = isReplacePunctuation(aSrchPara.searchString); } // Create Transliteration class @@ -215,7 +239,7 @@ void TextSearch::setOptions2( const SearchOptions2& rOptions ) } if ( bReplaceApostrophe ) - sSrchStr = sSrchStr.replace(u'\u2019', '\''); + sSrchStr = replacePunctuation(sSrchStr); // Take the new SearchOptions2::AlgorithmType2 field and ignore // SearchOptions::algorithmType @@ -308,7 +332,7 @@ SearchResult TextSearch::searchForward( const OUString& searchStr, sal_Int32 sta // in non-regex mode, allow searching typographical apostrophe with the ASCII one // to avoid regression after using automatic conversion to U+2019 during typing in Writer - bool bReplaceApostrophe = bSearchApostrophe && in_str.indexOf(u'\u2019') > -1; + bool bReplaceApostrophe = bSearchApostrophe && isReplacePunctuation(in_str); bUsePrimarySrchStr = true; @@ -340,7 +364,7 @@ SearchResult TextSearch::searchForward( const OUString& searchStr, sal_Int32 sta in_str = xTranslit->transliterate(searchStr, nInStartPos, nInEndPos - nInStartPos, offset); if ( bReplaceApostrophe ) - in_str = in_str.replace(u'\u2019', '\''); + in_str = replacePunctuation(in_str); // JP 20.6.2001: also the start and end positions must be corrected! sal_Int32 newStartPos = @@ -447,7 +471,7 @@ SearchResult TextSearch::searchBackward( const OUString& searchStr, sal_Int32 st // in non-regex mode, allow searching typographical apostrophe with the ASCII one // to avoid regression after using automatic conversion to U+2019 during typing in Writer - bool bReplaceApostrophe = bSearchApostrophe && in_str.indexOf(u'\u2019') > -1; + bool bReplaceApostrophe = bSearchApostrophe && isReplacePunctuation(in_str); bUsePrimarySrchStr = true; @@ -458,7 +482,7 @@ SearchResult TextSearch::searchBackward( const OUString& searchStr, sal_Int32 st in_str = xTranslit->transliterate( searchStr, endPos, startPos - endPos, offset ); if ( bReplaceApostrophe ) - in_str = in_str.replace(u'\u2019', '\''); + in_str = replacePunctuation(in_str); // JP 20.6.2001: also the start and end positions must be corrected! sal_Int32 const newStartPos = (startPos < searchStr.getLength()) @@ -508,7 +532,7 @@ SearchResult TextSearch::searchBackward( const OUString& searchStr, sal_Int32 st else { if ( bReplaceApostrophe ) - in_str = in_str.replace(u'\u2019', '\''); + in_str = replacePunctuation(in_str); sres = (this->*fnBackward)( in_str, startPos, endPos ); } commit 281749bd9684dd979cb57064ad3fc9dd4d464bce Author: Jim Raykowski <[email protected]> AuthorDate: Wed Jun 12 12:59:05 2024 -0800 Commit: Christian Lohmaier <[email protected]> CommitDate: Mon Jul 8 16:22:22 2024 +0200 tdf#160541 Resolves Quickfind sidebar: present results with some indication of location in document Change-Id: I9262511c46b9a89fd7c5d7fe93551fecbd21cecf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168832 Reviewed-by: Jim Raykowski <[email protected]> Tested-by: Jenkins (cherry picked from commit 6fb5e52479b0a3e6f63ae96886884b3653abddaf) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169487 Reviewed-by: Christian Lohmaier <[email protected]> diff --git a/sw/source/uibase/sidebar/QuickFindPanel.cxx b/sw/source/uibase/sidebar/QuickFindPanel.cxx index cffca4511ef2..753888702587 100644 --- a/sw/source/uibase/sidebar/QuickFindPanel.cxx +++ b/sw/source/uibase/sidebar/QuickFindPanel.cxx @@ -21,6 +21,8 @@ #include <edtwin.hxx> #include <fmtanchr.hxx> #include <cntfrm.hxx> +#include <strings.hrc> +#include <vcl/event.hxx> const int MinimumPanelWidth = 250; @@ -60,7 +62,6 @@ QuickFindPanel::QuickFindPanel(weld::Widget* pParent) , m_xSearchFindsList(m_xBuilder->weld_tree_view(u"searchfinds"_ustr)) , m_nRowHeight(m_xSearchFindsList->get_height_rows(4)) , m_pWrtShell(::GetActiveWrtShell()) - { m_xContainer->set_size_request(MinimumPanelWidth, -1); m_xSearchFindsList->set_size_request(1, m_nRowHeight); @@ -75,6 +76,7 @@ QuickFindPanel::QuickFindPanel(weld::Widget* pParent) LINK(this, QuickFindPanel, SearchFindsListSelectionChangedHandler)); m_xSearchFindsList->connect_row_activated( LINK(this, QuickFindPanel, SearchFindsListRowActivatedHandler)); + m_xSearchFindsList->connect_mouse_press(LINK(this, QuickFindPanel, MousePressHandler)); } QuickFindPanel::~QuickFindPanel() @@ -83,6 +85,16 @@ QuickFindPanel::~QuickFindPanel() m_xSearchFindsList.reset(); } +IMPL_LINK(QuickFindPanel, MousePressHandler, const MouseEvent&, rMEvt, bool) +{ + if (std::unique_ptr<weld::TreeIter> xEntry(m_xSearchFindsList->make_iterator()); + m_xSearchFindsList->get_dest_row_at_pos(rMEvt.GetPosPixel(), xEntry.get(), false, false)) + { + return m_xSearchFindsList->get_id(*xEntry)[0] == '-'; + } + return false; +} + IMPL_LINK_NOARG(QuickFindPanel, SearchFindEntryActivateHandler, weld::Entry&, bool) { FillSearchFindsList(); @@ -100,19 +112,55 @@ IMPL_LINK(QuickFindPanel, SearchFindsListRender, weld::TreeView::render_args, aP vcl::RenderContext& rRenderContext = std::get<0>(aPayload); const ::tools::Rectangle& rRect = std::get<1>(aPayload); const OUString& rId = std::get<3>(aPayload); - int nIndex = m_xSearchFindsList->find_id(rId); - OUString aEntry(m_xSearchFindsList->get_text(nIndex)); - DrawTextFlags const nTextStyle = DrawTextFlags::Left | DrawTextFlags::VCenter - | DrawTextFlags::MultiLine | DrawTextFlags::WordBreak; + tools::Rectangle aRect( rRect.TopLeft(), Size(rRenderContext.GetOutputSize().Width() - rRect.Left(), rRect.GetHeight())); - rRenderContext.DrawText(aRect, aEntry, nTextStyle); + + int nIndex = m_xSearchFindsList->find_id(rId); + OUString aEntry(m_xSearchFindsList->get_text(nIndex)); + + const bool bPageEntry = rId[0] == '-'; + if (!bPageEntry) + { + rRenderContext.DrawText(aRect, aEntry, + DrawTextFlags::VCenter | DrawTextFlags::MultiLine + | DrawTextFlags::WordBreak); + } + else + { + aEntry = aEntry.copy(1); // remove '-' + tools::Long aTextWidth = rRenderContext.GetTextWidth(aEntry); + tools::Long aTextHeight = rRenderContext.GetTextHeight(); + + rRenderContext.Push(); + rRenderContext.SetLineColor(COL_BLACK); + rRenderContext.DrawLine( + aRect.LeftCenter(), + Point(aRect.Center().AdjustX(-(aTextWidth / 2)) - 4, aRect.Center().getY())); + rRenderContext.DrawText(Point(aRect.Center().AdjustX(-(aTextWidth / 2)), + aRect.Center().AdjustY(-(aTextHeight / 2) - 1)), + aEntry); + rRenderContext.DrawLine( + Point(aRect.Center().AdjustX(aTextWidth / 2) + 5, aRect.Center().getY()), + aRect.RightCenter()); + rRenderContext.Pop(); + } } IMPL_LINK_NOARG(QuickFindPanel, SearchFindsListSelectionChangedHandler, weld::TreeView&, void) { - std::unique_ptr<SwPaM>& rxPaM = m_vPaMs[m_xSearchFindsList->get_cursor_index()]; + std::unique_ptr<weld::TreeIter> xEntry(m_xSearchFindsList->make_iterator()); + if (!m_xSearchFindsList->get_cursor(xEntry.get())) + return; + + OUString sId = m_xSearchFindsList->get_id(*xEntry); + + // check for page number entry + if (sId[0] == '-') + return; + + std::unique_ptr<SwPaM>& rxPaM = m_vPaMs[sId.toInt64()]; m_pWrtShell->StartAction(); bool bFound = false; @@ -144,6 +192,14 @@ IMPL_LINK_NOARG(QuickFindPanel, SearchFindsListSelectionChangedHandler, weld::Tr IMPL_LINK_NOARG(QuickFindPanel, SearchFindsListRowActivatedHandler, weld::TreeView&, bool) { + std::unique_ptr<weld::TreeIter> xEntry(m_xSearchFindsList->make_iterator()); + if (!m_xSearchFindsList->get_cursor(xEntry.get())) + return false; + + // check for page number entry + if (m_xSearchFindsList->get_id(*xEntry)[0] == '-') + return false; + m_pWrtShell->GetView().GetEditWin().GrabFocus(); return true; } @@ -216,7 +272,7 @@ void QuickFindPanel::FillSearchFindsList() }); // fill list - for (int i = 0; std::unique_ptr<SwPaM> & xPaM : m_vPaMs) + for (sal_uInt16 nPage = 0, i = 0; std::unique_ptr<SwPaM> & xPaM : m_vPaMs) { SwPosition* pMarkPosition = xPaM->GetMark(); SwPosition* pPointPosition = xPaM->GetPoint(); @@ -282,6 +338,14 @@ void QuickFindPanel::FillSearchFindsList() } } + // tdf#161291 indicate page of search finds + if (xPaM->GetPageNum() != nPage) + { + nPage = xPaM->GetPageNum(); + OUString sPageEntry(u"-"_ustr + SwResId(ST_PGE) + u" "_ustr + OUString::number(nPage)); + m_xSearchFindsList->append(sPageEntry, sPageEntry); + } + auto nCount = nMarkIndex - nStartIndex; OUString sTextBeforeFind = OUString::Concat(sNodeText.subView(nStartIndex, nCount)); auto nCount1 = nPointIndex - nMarkIndex; diff --git a/sw/source/uibase/sidebar/QuickFindPanel.hxx b/sw/source/uibase/sidebar/QuickFindPanel.hxx index af95bd18fb44..1cf241554662 100644 --- a/sw/source/uibase/sidebar/QuickFindPanel.hxx +++ b/sw/source/uibase/sidebar/QuickFindPanel.hxx @@ -36,6 +36,8 @@ private: DECL_LINK(SearchFindsListSelectionChangedHandler, weld::TreeView&, void); DECL_LINK(SearchFindEntryChangedHandler, weld::Entry&, void); DECL_LINK(SearchFindsListRowActivatedHandler, weld::TreeView&, bool); + DECL_LINK(MousePressHandler, const MouseEvent&, bool); + void FillSearchFindsList(); }; } commit f9c31bf18461d9d713929d74623d964dab8ae1f9 Author: Jim Raykowski <[email protected]> AuthorDate: Thu Jun 20 17:04:11 2024 -0800 Commit: Christian Lohmaier <[email protected]> CommitDate: Mon Jul 8 15:48:30 2024 +0200 tdf#161537 fix Filter Navigator no longer shows the name of the field Change-Id: I3dae3458ac5795b217743b1e6897345a22f1bf61 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169310 Reviewed-by: Jim Raykowski <[email protected]> Tested-by: Jenkins (cherry picked from commit c5bbbe987321d8f9e101fab9d67ddbf3d4f8dfca) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169486 Reviewed-by: Christian Lohmaier <[email protected]> diff --git a/svx/source/form/filtnav.cxx b/svx/source/form/filtnav.cxx index 722deefaca35..fe633e9fdd20 100644 --- a/svx/source/form/filtnav.cxx +++ b/svx/source/form/filtnav.cxx @@ -1061,7 +1061,7 @@ FmFilterNavigator::FmFilterNavigator(vcl::Window* pTopLevel, std::unique_ptr<wel m_xTreeView->connect_custom_get_size(LINK(this, FmFilterNavigator, CustomGetSizeHdl)); m_xTreeView->connect_custom_render(LINK(this, FmFilterNavigator, CustomRenderHdl)); - m_xTreeView->set_column_custom_renderer(0, true); + m_xTreeView->set_column_custom_renderer(1, true); m_xTreeView->connect_changed(LINK(this, FmFilterNavigator, SelectHdl)); m_xTreeView->connect_key_press(LINK(this, FmFilterNavigator, KeyInputHdl)); diff --git a/svx/uiconfig/ui/filternavigator.ui b/svx/uiconfig/ui/filternavigator.ui index 99297b0dc10f..5b7512f0376b 100644 --- a/svx/uiconfig/ui/filternavigator.ui +++ b/svx/uiconfig/ui/filternavigator.ui @@ -4,7 +4,7 @@ <requires lib="gtk+" version="3.20"/> <object class="GtkTreeStore" id="liststore1"> <columns> - <!-- column-name expander --> + <!-- column-name icon --> <column type="GdkPixbuf"/> <!-- column-name text --> <column type="gchararray"/> @@ -43,16 +43,21 @@ <object class="GtkTreeSelection"/> </child> <child> - <object class="GtkTreeViewColumn" id="treeviewcolumn2"> + <object class="GtkTreeViewColumn" id="treeviewcolumn0"> + <property name="visible">False</property> + </object> + </child> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn1"> <property name="spacing">6</property> <child> - <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/> + <object class="GtkCellRendererPixbuf" id="cellrendererpixbuf"/> <attributes> <attribute name="pixbuf">0</attribute> </attributes> </child> <child> - <object class="GtkCellRendererText" id="cellrenderertext2"> + <object class="GtkCellRendererText" id="cellrenderertext"> <property name="editable">True</property> </object> <attributes> commit 2b995b4b069843aafe2bea353c0138b8a8aca237 Author: László Németh <[email protected]> AuthorDate: Fri Jun 28 15:49:22 2024 +0200 Commit: Christian Lohmaier <[email protected]> CommitDate: Mon Jul 8 15:43:12 2024 +0200 tdf#96787 AutoCorrect: find item with ".*" and between :colons: It was very hard to disable autocorrection of (c)->© and other AutoCorrect items, because the searched Replace string "(c)" etc. didn't jump the list cursor to the corresponding ".*(c)" item. Now skip ".*" pattern matching marks, also colon (emoji replacement) characters, so the list cursor jumps to the line ".*(c)"->© typing only "(c" etc., allowing users to press Delete to disable its autocorrection without knowing about the special AutoCorrect patterns. Follow-up to commit 50be3fa1f0f3b8870af5bda88b65f835ef37d77e "tdf#141773 AutoCorrect: fix broken [All] dictionaries". Change-Id: I72be1ecb2fdc5ae67c72727ce7fbd70b28a4125b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169714 Tested-by: Jenkins Reviewed-by: László Németh <[email protected]> (cherry picked from commit e5507c8a003328f629ae924fbba14155c13e7a12) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169733 Reviewed-by: Christian Lohmaier <[email protected]> diff --git a/cui/source/tabpages/autocdlg.cxx b/cui/source/tabpages/autocdlg.cxx index 87e803f677b4..393f9f79d872 100644 --- a/cui/source/tabpages/autocdlg.cxx +++ b/cui/source/tabpages/autocdlg.cxx @@ -1145,7 +1145,9 @@ IMPL_LINK(OfaAutocorrReplacePage, ModifyHdl, weld::Entry&, rEdt, void) else { aTestStr = pCharClass->lowercase( aTestStr ); - if( aTestStr.startsWith(aWordStr) && !bTmpSelEntry ) + if( !bTmpSelEntry && ( aTestStr.startsWith(aWordStr) + // find also with ".*" and between :colons: + || aTestStr.replaceAll(".*","").replaceAll(":", "").startsWith(aWordStr) ) ) { m_xReplaceTLB->scroll_to_row(rIter); bTmpSelEntry = true; commit bacc00112dde35ba4bbdfad3850aed19619b191c Author: Caolán McNamara <[email protected]> AuthorDate: Wed Jul 3 09:46:07 2024 +0100 Commit: Xisco Fauli <[email protected]> CommitDate: Mon Jul 8 11:26:49 2024 +0200 cid#1606556 Overflowed constant Change-Id: I7748094d226b8201cfbdf43d6ae7df0cd776f9e7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169923 Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> (cherry picked from commit cd91074bc087b0f85293c2756cdb96f53024c489) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170041 Tested-by: Jenkins Reviewed-by: Xisco Fauli <[email protected]> diff --git a/sw/source/ui/index/swuiidxmrk.cxx b/sw/source/ui/index/swuiidxmrk.cxx index 2d3ab98cd0e5..0d30104f9e41 100644 --- a/sw/source/ui/index/swuiidxmrk.cxx +++ b/sw/source/ui/index/swuiidxmrk.cxx @@ -526,7 +526,7 @@ void SwIndexMarkPane::InsertMark() SwTOXMarkDescription aDesc(eType); - const int nLevel = m_xLevelNF->denormalize(m_xLevelNF->get_value()); + const auto nLevel = m_xLevelNF->denormalize(m_xLevelNF->get_value()); switch( nPos) { case POS_CONTENT : break; commit 40efa54267668c8bbb0bcdd338fa872c84b6800b Author: Samuel Mehrbrodt <[email protected]> AuthorDate: Mon Jul 1 23:44:30 2024 +0200 Commit: Xisco Fauli <[email protected]> CommitDate: Mon Jul 8 11:11:22 2024 +0200 pptx: Import comment author initials Change-Id: Ic5838c929db9c08d6d9c6e1c87160dc2530105e1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169847 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <[email protected]> Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170094 diff --git a/include/oox/ppt/comments.hxx b/include/oox/ppt/comments.hxx index 10cad1270a1c..fb858e83d021 100644 --- a/include/oox/ppt/comments.hxx +++ b/include/oox/ppt/comments.hxx @@ -97,6 +97,7 @@ class Comment return y.toInt32(); } OUString getAuthor ( const CommentAuthorList& list ); + OUString getInitials ( const CommentAuthorList& list ); }; class CommentList diff --git a/oox/source/ppt/comments.cxx b/oox/source/ppt/comments.cxx index b85d95b4a692..179370f05873 100644 --- a/oox/source/ppt/comments.cxx +++ b/oox/source/ppt/comments.cxx @@ -77,6 +77,17 @@ OUString Comment::getAuthor(const CommentAuthorList& list) return u"Anonymous"_ustr; } +OUString Comment::getInitials(const CommentAuthorList& list) +{ + const sal_Int32 nId = authorId.toInt32(); + for (auto const& author : list.cmAuthorLst) + { + if (author.id.toInt32() == nId) + return author.initials; + } + return u"A"_ustr; +} + const Comment& CommentList::getCommentAtIndex(int index) { if (index < 0 || o3tl::make_unsigned(index) >= cmLst.size()) diff --git a/oox/source/ppt/presentationfragmenthandler.cxx b/oox/source/ppt/presentationfragmenthandler.cxx index c8783a7da976..9a1ea8679cef 100644 --- a/oox/source/ppt/presentationfragmenthandler.cxx +++ b/oox/source/ppt/presentationfragmenthandler.cxx @@ -595,6 +595,7 @@ void PresentationFragmentHandler::importSlide(sal_uInt32 nSlide, bool bFirstPage ::oox::drawingml::convertEmuToHmm( nPosX ) * 15.87, ::oox::drawingml::convertEmuToHmm( nPosY ) * 15.87 ) ); xAnnotation->setAuthor( aComment.getAuthor(maAuthorList) ); + xAnnotation->setInitials( aComment.getInitials(maAuthorList) ); xAnnotation->setDateTime( aComment.getDateTime() ); uno::Reference< text::XText > xText( xAnnotation->getTextRange() ); xText->setString( aComment.get_text()); commit 4fe0b058d3173c2b8decee324989eef5ede30ca5 Author: Samuel Mehrbrodt <[email protected]> AuthorDate: Mon Jul 1 23:03:47 2024 +0200 Commit: Xisco Fauli <[email protected]> CommitDate: Mon Jul 8 11:10:59 2024 +0200 ppt export: Respect user defined initials instead of generating new ones. Change-Id: If64690ac2aa22542e6b3939f3ed9cdc3c9f3be84 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169844 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <[email protected]> Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170092 diff --git a/sd/source/filter/eppt/eppt.cxx b/sd/source/filter/eppt/eppt.cxx index 1d0f242c20b1..1d7d564de8f6 100644 --- a/sd/source/filter/eppt/eppt.cxx +++ b/sd/source/filter/eppt/eppt.cxx @@ -1054,7 +1054,10 @@ void PPTWriter::ImplExportComments( const uno::Reference< drawing::XDrawPage >& : xAnnotation->getAuthor() ); uno::Reference< text::XText > xText( xAnnotation->getTextRange() ); OUString sText( xText->getString() ); - OUString sInitials( GetInitials( sAuthor ) ); + OUString sInitials( + bRemoveCommentAuthorDates + ? "A" + OUString::number(mpAuthorIDs->GetInfoID(xAnnotation->getAuthor())) + : xAnnotation->getInitials()); util::DateTime aEmptyDateTime; util::DateTime aDateTime(bRemoveCommentAuthorDates ? aEmptyDateTime : xAnnotation->getDateTime()); commit bfc49355d472cd41399b7d68ede1e7c3f2ebdcdc Author: Samuel Mehrbrodt <[email protected]> AuthorDate: Thu Jun 13 19:31:48 2024 +0200 Commit: Xisco Fauli <[email protected]> CommitDate: Mon Jul 8 11:10:45 2024 +0200 Move duplicate code into shared method Change-Id: I3859c3a491abbe74d12f08d86948196dddb462ef Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168822 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <[email protected]> Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170091 diff --git a/sd/source/filter/eppt/eppt.cxx b/sd/source/filter/eppt/eppt.cxx index bb0544c5d068..1d0f242c20b1 100644 --- a/sd/source/filter/eppt/eppt.cxx +++ b/sd/source/filter/eppt/eppt.cxx @@ -1024,39 +1024,6 @@ bool PPTWriter::ImplCreateMainNotes() return true; } -static OUString getInitials( const OUString& rName ) -{ - OUStringBuffer sInitials; - - const sal_Unicode * pStr = rName.getStr(); - sal_Int32 nLength = rName.getLength(); - - while( nLength ) - { - // skip whitespace - while( nLength && (*pStr <= ' ') ) - { - nLength--; pStr++; - } - - // take letter - if( nLength ) - { - sInitials.append( *pStr ); - nLength--; pStr++; - } - - // skip letters until whitespace - while( nLength && (*pStr > ' ') ) - { - nLength--; pStr++; - } - } - - return sInitials.makeStringAndClear(); -} - - void PPTWriter::ImplExportComments( const uno::Reference< drawing::XDrawPage >& xPage, SvMemoryStream& rBinaryTagData10Atom ) { try @@ -1087,7 +1054,7 @@ void PPTWriter::ImplExportComments( const uno::Reference< drawing::XDrawPage >& : xAnnotation->getAuthor() ); uno::Reference< text::XText > xText( xAnnotation->getTextRange() ); OUString sText( xText->getString() ); - OUString sInitials( getInitials( sAuthor ) ); + OUString sInitials( GetInitials( sAuthor ) ); util::DateTime aEmptyDateTime; util::DateTime aDateTime(bRemoveCommentAuthorDates ? aEmptyDateTime : xAnnotation->getDateTime()); diff --git a/sd/source/filter/eppt/epptbase.hxx b/sd/source/filter/eppt/epptbase.hxx index 70bcd3a4b6ce..18199210cc6b 100644 --- a/sd/source/filter/eppt/epptbase.hxx +++ b/sd/source/filter/eppt/epptbase.hxx @@ -379,6 +379,7 @@ protected: ::tools::Rectangle MapRectangle( const css::awt::Rectangle& ); bool ContainsOtherShapeThanPlaceholders(); + static OUString GetInitials(std::u16string_view sName); public: PPTWriterBase(); diff --git a/sd/source/filter/eppt/pptx-epptbase.cxx b/sd/source/filter/eppt/pptx-epptbase.cxx index 1e2137cb8057..fe9444865797 100644 --- a/sd/source/filter/eppt/pptx-epptbase.cxx +++ b/sd/source/filter/eppt/pptx-epptbase.cxx @@ -25,6 +25,7 @@ #include <vcl/outdev.hxx> #include <rtl/ustring.hxx> #include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> #include <sal/log.hxx> #include <tools/UnitConversion.hxx> #include <com/sun/star/awt/Rectangle.hpp> @@ -997,4 +998,24 @@ bool PPTWriterBase::ContainsOtherShapeThanPlaceholders() return bOtherThanPlaceHolders; } +OUString PPTWriterBase::GetInitials(std::u16string_view sName) +{ + OUStringBuffer sRet; + + if (!sName.empty()) + { + sRet.append(sName[0]); + size_t nStart = 0, nOffset; + + while ((nOffset = sName.find(' ', nStart)) != std::u16string_view::npos) + { + if (nOffset + 1 < sName.size()) + sRet.append(sName[ nOffset + 1 ]); + nStart = nOffset + 1; + } + } + + return sRet.makeStringAndClear(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx b/sd/source/filter/eppt/pptx-epptooxml.cxx index 728682f955d6..f7379a3cd68e 100644 --- a/sd/source/filter/eppt/pptx-epptooxml.cxx +++ b/sd/source/filter/eppt/pptx-epptooxml.cxx @@ -1017,26 +1017,6 @@ void PowerPointExport::WriteTransition(const FSHelperPtr& pFS) } } -static OUString lcl_GetInitials(std::u16string_view sName) -{ - OUStringBuffer sRet; - - if (!sName.empty()) - { - sRet.append(sName[0]); - size_t nStart = 0, nOffset; - - while ((nOffset = sName.find(' ', nStart)) != std::u16string_view::npos) - { - if (nOffset + 1 < sName.size()) - sRet.append(sName[ nOffset + 1 ]); - nStart = nOffset + 1; - } - } - - return sRet.makeStringAndClear(); -} - void PowerPointExport::WriteAuthors() { if (maAuthors.empty()) @@ -1056,7 +1036,7 @@ void PowerPointExport::WriteAuthors() pFS->singleElementNS(XML_p, XML_cmAuthor, XML_id, OString::number(i.second.nId), XML_name, i.first, - XML_initials, lcl_GetInitials(i.first), + XML_initials, GetInitials(i.first), XML_lastIdx, OString::number(i.second.nLastIndex), XML_clrIdx, OString::number(i.second.nId)); } commit 56a3bb29b1451233118204159b7861a23ace5d23 Author: Michael Stahl <[email protected]> AuthorDate: Fri Jul 5 13:55:31 2024 +0200 Commit: Xisco Fauli <[email protected]> CommitDate: Mon Jul 8 10:53:11 2024 +0200 package: avoid throwing RuntimeException in getZipFileContents() Translate it to ZipIOException. Change-Id: I7a07a59c0ba301b92f31696355c73ccbdf119ff8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170013 Tested-by: Jenkins Reviewed-by: Michael Stahl <[email protected]> (cherry picked from commit c409c83d777fdb6291c7cd03186b69fe4e7fd902) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170029 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx index 907ed1b4112e..2cb267734b9f 100644 --- a/package/source/zippackage/ZipPackage.cxx +++ b/package/source/zippackage/ZipPackage.cxx @@ -626,7 +626,11 @@ void ZipPackage::getZipFileContents() if ( !pCurrent->hasByName( sTemp ) ) { rtl::Reference<ZipPackageFolder> pPkgFolder = new ZipPackageFolder(m_xContext, m_nFormat, m_bAllowRemoveOnInsert); - pPkgFolder->setName( sTemp ); + try { + pPkgFolder->setName( sTemp ); + } catch (uno::RuntimeException const& e) { + throw css::packages::zip::ZipIOException(e.Message); + } pPkgFolder->doSetParent( pCurrent ); pCurrent = pPkgFolder.get(); } commit 74dbd40aa9f60197455f4dcef13c76826b934b93 Author: Caolán McNamara <[email protected]> AuthorDate: Fri Jul 5 14:06:13 2024 +0100 Commit: Xisco Fauli <[email protected]> CommitDate: Mon Jul 8 10:52:16 2024 +0200 cid#1609595 Dereference null return value Change-Id: I6ae93f46c50e0fe4a29d03fdf02797f808d4d1c3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170022 Reviewed-by: Caolán McNamara <[email protected]> Tested-by: Jenkins Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170090 diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx index ed0045b3c8a2..8f33f1edbde7 100644 --- a/sd/source/ui/view/Outliner.cxx +++ b/sd/source/ui/view/Outliner.cxx @@ -1845,13 +1845,13 @@ SdrObject* SdOutliner::SetObject ( if(rPosition.meEditMode == EditMode::Page && rPosition.mePageKind == PageKind::Notes) { std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock()); - std::shared_ptr<sd::DrawViewShell> pDrawViewShell( - std::dynamic_pointer_cast<sd::DrawViewShell>(pViewShell)); - - if (pDrawViewShell->GetEditMode() != EditMode::Page - || pDrawViewShell->GetCurPagePos() != rPosition.mnPageIndex) - SetPage(EditMode::Page, static_cast<sal_uInt16>(rPosition.mnPageIndex)); - + if (std::shared_ptr<sd::DrawViewShell> pDrawViewShell = + std::dynamic_pointer_cast<sd::DrawViewShell>(pViewShell)) + { + if (pDrawViewShell->GetEditMode() != EditMode::Page + || pDrawViewShell->GetCurPagePos() != rPosition.mnPageIndex) + SetPage(EditMode::Page, static_cast<sal_uInt16>(rPosition.mnPageIndex)); + } mnText = rPosition.mnText; return rPosition.mxObject.get().get(); } commit 7911041df4692d68f115c853689174f265d74820 Author: Tibor Nagy <[email protected]> AuthorDate: Fri Jul 5 07:19:15 2024 +0200 Commit: Xisco Fauli <[email protected]> CommitDate: Mon Jul 8 10:52:03 2024 +0200 Add escape direction support for glue points in the preset shapes Change-Id: I6727def5dd42ecd5dae3ddd27d2af733b5883e09 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170006 Tested-by: Jenkins Reviewed-by: Nagy Tibor <[email protected]> Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170089 diff --git a/include/svx/EnhancedCustomShape2d.hxx b/include/svx/EnhancedCustomShape2d.hxx index bed4fa9d75f8..3947da9c31c4 100644 --- a/include/svx/EnhancedCustomShape2d.hxx +++ b/include/svx/EnhancedCustomShape2d.hxx @@ -118,6 +118,7 @@ class SVXCORE_DLLPUBLIC EnhancedCustomShape2d final : public SfxItemSet css::uno::Sequence< css::drawing::EnhancedCustomShapeAdjustmentValue > m_seqAdjustmentValues; css::uno::Sequence< css::beans::PropertyValues > m_seqHandles; css::uno::Sequence< css::awt::Size > m_seqSubViewSize; + css::uno::Sequence< double > m_seqGluePointLeavingDirections; bool m_bFilled : 1; bool m_bStroked : 1; diff --git a/oox/source/drawingml/customshapepresetdata.cxx b/oox/source/drawingml/customshapepresetdata.cxx index 597f19b5943e..b03d583a8cdf 100644 --- a/oox/source/drawingml/customshapepresetdata.cxx +++ b/oox/source/drawingml/customshapepresetdata.cxx @@ -162,6 +162,18 @@ awt::Rectangle lcl_parseRectangle(std::string_view rValue) return aRectangle; } +sal_Int32 lcl_parseDirection(std::string_view rValue) +{ + sal_Int32 aDirection; + // We expect the following here: Direction + static const char aExpectedWidthPrefix[] = "Dir = (long) "; + assert(o3tl::starts_with(rValue, aExpectedWidthPrefix)); + sal_Int32 nIndex = strlen(aExpectedWidthPrefix); + aDirection = o3tl::toInt32(rValue.substr(nIndex)); + + return aDirection; +} + awt::Size lcl_parseSize(std::string_view rValue) { awt::Size aSize; @@ -582,6 +594,73 @@ void lcl_parsePathGluePoints(std::vector<beans::PropertyValue>& rPath, std::stri } } +void lcl_parsePathGluePointLeavingDirectionsValues(std::vector<beans::PropertyValue>& rPath, + std::string_view rValue) +{ + std::vector<double> aDirection; + sal_Int32 nLevel = 0; + sal_Int32 nStart = 0; + for (size_t i = 0; i < rValue.size(); ++i) + { + if (rValue[i] == '{') + { + if (!nLevel) + nStart = i; + nLevel++; + } + else if (rValue[i] == '}') + { + nLevel--; + if (!nLevel) + aDirection.push_back(lcl_parseDirection( + rValue.substr(nStart + strlen("{ "), i - nStart - strlen(" },")))); + } + } + + beans::PropertyValue aPropertyValue; + aPropertyValue.Name = "GluePointLeavingDirections"; + aPropertyValue.Value <<= comphelper::containerToSequence(aDirection); + rPath.push_back(aPropertyValue); +} + +void lcl_parsePathGluePointLeavingDirections(std::vector<beans::PropertyValue>& rPath, + std::string_view rValue) +{ + sal_Int32 nLevel = 0; + bool bIgnore = false; + sal_Int32 nStart = 0; + for (size_t i = 0; i < rValue.size(); ++i) + { + if (rValue[i] == '{') + { + if (!nLevel) + bIgnore = true; + nLevel++; + } + else if (rValue[i] == '}') + { + nLevel--; + if (!nLevel) + bIgnore = false; + } + else if (rValue[i] == ',' && !bIgnore) + { + std::string_view aToken = rValue.substr(nStart, i - nStart); + static const char aExpectedPrefix[] = "Value = (any) { ([]long) { "; + if (o3tl::starts_with(aToken, aExpectedPrefix)) + { + aToken = aToken.substr(strlen(aExpectedPrefix), + aToken.size() - strlen(aExpectedPrefix) - strlen(" } }")); + lcl_parsePathGluePointLeavingDirectionsValues(rPath, aToken); + } + else if (!o3tl::starts_with(aToken, "Name =") && !o3tl::starts_with(aToken, "Handle =")) + SAL_WARN("oox", + "lcl_parsePathGluePointLeavingDirections: unexpected token: " << aToken); + nStart = i + strlen(", "); + } + } +} + void lcl_parsePathSegmentValues(std::vector<beans::PropertyValue>& rPath, std::string_view rValue) { std::vector<drawing::EnhancedCustomShapeSegment> aSegments; @@ -804,6 +883,8 @@ void lcl_parsePath(std::vector<beans::PropertyValue>& rPath, std::string_view rV lcl_parsePathCoordinates(rPath, aToken); else if (o3tl::starts_with(aToken, "Name = \"GluePoints\"")) lcl_parsePathGluePoints(rPath, aToken); + else if (o3tl::starts_with(aToken, "Name = \"GluePointLeavingDirections\"")) + lcl_parsePathGluePointLeavingDirections(rPath, aToken); else if (o3tl::starts_with(aToken, "Name = \"Segments\"")) lcl_parsePathSegments(rPath, aToken); else if (o3tl::starts_with(aToken, "Name = \"TextFrames\"")) diff --git a/oox/source/drawingml/customshapes/oox-drawingml-cs-presets b/oox/source/drawingml/customshapes/oox-drawingml-cs-presets index 004bf6abfadd..4ef1ccf5d9dd 100644 --- a/oox/source/drawingml/customshapes/oox-drawingml-cs-presets +++ b/oox/source/drawingml/customshapes/oox-drawingml-cs-presets @@ -979,7 +979,7 @@ false MirroredY false Path -([]com.sun.star.beans.PropertyValue) { { Name = "Coordinates", Handle = (long) 0, Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 0 }, Type = (short) 0 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 3 }, Type = (short) 1 } }, { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 2 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 0 }, Type = (short) 0 } }, { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 5 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 3 }, Type = (short) 1 } }, { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 2 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapePa rameter) { Value = (any) { (long) 4 }, Type = (short) 1 } } } }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE }, { Name = "GluePoints", Handle = (long) 0, Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 2 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 0 }, Type = (short) 0 } }, { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 0 }, Type = (short) 0 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 3 }, Type = (short) 1 } }, { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 2 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 4 }, Type = (short) 1 } }, { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 5 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 3 }, Type = (short) 1 } } } }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE }, { Name = "Segments", Handle = (long) 0, Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeSegment) { { Command = (short) 1, Count = (short) 1 }, { Command = (short) 2, Count = (short) 3 }, { Command = (short) 4, Count = (short) 0 }, { Command = (short) 5, Count = (short) 0 } } }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE }, { Name = "TextFrames", Handle = (long) 0, Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeTextFrame) { { TopLeft = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 6 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 7 }, Type = (short) 1 } }, BottomRight = (com.sun.star.drawi ng.EnhancedCustomShapeParameterPair) { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 0 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 1 }, Type = (short) 1 } } } } }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE } } +([]com.sun.star.beans.PropertyValue) { { Name = "Coordinates", Handle = (long) 0, Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 0 }, Type = (short) 0 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 3 }, Type = (short) 1 } }, { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 2 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 0 }, Type = (short) 0 } }, { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 5 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 3 }, Type = (short) 1 } }, { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 2 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapePa rameter) { Value = (any) { (long) 4 }, Type = (short) 1 } } } }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE }, { Name = "GluePoints", Handle = (long) 0, Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 2 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 0 }, Type = (short) 0 } }, { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 0 }, Type = (short) 0 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 3 }, Type = (short) 1 } }, { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 2 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 4 }, Type = (short) 1 } }, { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 5 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 3 }, Type = (short) 1 } } } }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE }, { Name = "GluePointLeavingDirections", Handle = (long) 0, Value = (any) { ([]long) { { Dir = (long) 3 }, { Dir = (long) 1 }, { Dir = (long) 4 }, { Dir = (long) 2 } } }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE }, { Name = "Segments", Handle = (long) 0, Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeSegment) { { Command = (short) 1, Count = (short) 1 }, { Command = (short) 2, Count = (short) 3 }, { Command = (short) 4, Count = (short) 0 }, { Command = (short) 5, Count = (short) 0 } } }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE }, { Name = "TextFrames", Handle = (long) 0, Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeTextFrame) { { TopLeft = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { First = (com.sun.star.drawin g.EnhancedCustomShapeParameter) { Value = (any) { (long) 6 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 7 }, Type = (short) 1 } }, BottomRight = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 0 }, Type = (short) 1 }, Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) 1 }, Type = (short) 1 } } } } }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE } } Type "ooxml-non-primitive" ViewBox @@ -1081,7 +1081,7 @@ false MirroredY false Path -e ... etc. - the rest is truncated
