basic/source/inc/rtlproto.hxx | 1 basic/source/runtime/methods.cxx | 19 +++ basic/source/runtime/stdobj.cxx | 7 + compilerplugins/clang/redundantfcast.cxx | 3 drawinglayer/source/tools/emfpcustomlinecap.cxx | 9 - drawinglayer/source/tools/emfpcustomlinecap.hxx | 2 drawinglayer/source/tools/emfphelperdata.cxx | 68 ++---------- drawinglayer/source/tools/emfphelperdata.hxx | 5 drawinglayer/source/tools/emfppen.cxx | 70 ++++++++++-- drawinglayer/source/tools/emfppen.hxx | 5 drawinglayer/source/tools/primitive2dxmldump.cxx | 32 +++-- emfio/qa/cppunit/emf/EmfImportTest.cxx | 44 +++++++- emfio/qa/cppunit/emf/data/TestEmfPlusDrawLineWithDash.emf |binary fpicker/source/office/autocmpledit.cxx | 25 ++++ fpicker/source/office/autocmpledit.hxx | 2 oox/source/drawingml/textcharacterproperties.cxx | 6 + sd/qa/uitest/impress_tests/tdf148620.py | 77 ++++++++++++++ sd/qa/unit/data/pptx/tdf148685.pptx |binary sd/qa/unit/import-tests2.cxx | 43 +++++++ sfx2/source/appl/newhelp.cxx | 1 sfx2/source/view/viewfrm.cxx | 3 svx/qa/unit/svdraw.cxx | 3 svx/source/svdraw/sdrhittesthelper.cxx | 7 - sw/source/core/doc/docbm.cxx | 5 sw/source/core/inc/layfrm.hxx | 1 sw/source/core/layout/findfrm.cxx | 21 +++ sw/source/core/layout/pagechg.cxx | 2 ucb/CppunitTest_ucb_webdav_core.mk | 1 ucb/Library_ucpdav1.mk | 1 ucb/source/ucp/webdav-curl/CurlSession.cxx | 7 - ucb/source/ucp/webdav-curl/webdavcontent.cxx | 8 + ucb/source/ucp/webdav-curl/webdavresponseparser.cxx | 22 +++- vcl/inc/qt5/QtInstance.hxx | 6 + vcl/inc/qt5/QtWidget.hxx | 8 + vcl/qt5/QtInstance.cxx | 7 + vcl/qt5/QtWidget.cxx | 55 +++++++++- vcl/unx/gtk3/gtkinst.cxx | 2 37 files changed, 462 insertions(+), 116 deletions(-)
New commits: commit c6fab8b3c25de948372f13e1faf59f71724bff6b Author: Bartosz Kosiorek <gan...@poczta.onet.pl> AuthorDate: Fri Apr 22 16:46:39 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:13:56 2022 +0200 tdf#55058 tdf#143875 EMF+ Don't change line weight while rotating Previously when TranfromationMatrix was used with rotation, the line weight and dashed line shapes were changed. In worst case if angle was larger than 90 degrees, the lines just disappear. This patch fixes that. The line looks exactly after rotation (with TranfromationMatrix). The tests were updated (added some additional rotation), to prove that now it is working correctly. Change-Id: Ic2382fa8d1b711a6bf06c94b2d0b9da9e7d396f0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133329 Tested-by: Jenkins Reviewed-by: Bartosz Kosiorek <gan...@poczta.onet.pl> (cherry picked from commit abe3a06c45c0803a5c8bcf16e0e586fd72781c93) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133285 Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com> diff --git a/drawinglayer/source/tools/emfphelperdata.cxx b/drawinglayer/source/tools/emfphelperdata.cxx index 79ced761e8a2..7a64f8ad4dac 100644 --- a/drawinglayer/source/tools/emfphelperdata.cxx +++ b/drawinglayer/source/tools/emfphelperdata.cxx @@ -442,6 +442,10 @@ namespace emfplushelper maMapTransform *= basegfx::utils::createScaleTranslateB2DHomMatrix(100.0 * mnMmX / mnPixX, 100.0 * mnMmY / mnPixY, double(-mnFrameLeft), double(-mnFrameTop)); maMapTransform *= maBaseTransform; + + // Used only for performance optimization, to do not calculate it every line draw + mdExtractedXScale = std::hypot(maMapTransform.a(), maMapTransform.b()); + mdExtractedYScale = std::hypot(maMapTransform.c(), maMapTransform.d()); } ::basegfx::B2DPoint EmfPlusHelperData::Map(double ix, double iy) const @@ -517,7 +521,7 @@ namespace emfplushelper SAL_WARN_IF(pen->startCap != pen->endCap, "drawinglayer.emf", "emf+ pen uses different start and end cap"); } - const double transformedPenWidth = maMapTransform.get(0, 0) * pen->penWidth; + const double transformedPenWidth = mdExtractedYScale * pen->penWidth; drawinglayer::attribute::LineAttribute lineAttribute(pen->GetColor().getBColor(), transformedPenWidth, pen->GetLineJoinType(), @@ -529,7 +533,7 @@ namespace emfplushelper new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D( polygon, lineAttribute, - pen->GetStrokeAttribute(maMapTransform.get(1, 1)))); + pen->GetStrokeAttribute(mdExtractedXScale))); } else { @@ -537,7 +541,7 @@ namespace emfplushelper new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D( polygon, lineAttribute, - pen->GetStrokeAttribute(maMapTransform.get(1, 1)))); + pen->GetStrokeAttribute(mdExtractedXScale))); mrTargetHolders.Current().append( new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( diff --git a/drawinglayer/source/tools/emfphelperdata.hxx b/drawinglayer/source/tools/emfphelperdata.hxx index cf3474b5b1a7..3d8244b6f208 100644 --- a/drawinglayer/source/tools/emfphelperdata.hxx +++ b/drawinglayer/source/tools/emfphelperdata.hxx @@ -210,6 +210,11 @@ namespace emfplushelper GraphicStateMap mGSStack; GraphicStateMap mGSContainerStack; + /* Performance optimizators */ + /* Extracted Scale values from Transformation Matrix */ + double mdExtractedXScale; + double mdExtractedYScale; + /// data holders wmfemfhelper::TargetHolders& mrTargetHolders; wmfemfhelper::PropertyHolders& mrPropertyHolders; diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx b/drawinglayer/source/tools/primitive2dxmldump.cxx index a1fddf900543..27a8adf1b5e3 100644 --- a/drawinglayer/source/tools/primitive2dxmldump.cxx +++ b/drawinglayer/source/tools/primitive2dxmldump.cxx @@ -143,7 +143,7 @@ void writeStrokeAttribute(::tools::XmlWriter& rWriter, OUString sDotDash; for (double fDotDash : rStrokeAttribute.getDotDashArray()) { - sDotDash += OUString::number(round(100.0 * fDotDash)) + " "; + sDotDash += OUString::number(lround(fDotDash)) + " "; } rWriter.attribute("dotDashArray", sDotDash); rWriter.attribute("fullDotDashLength", rStrokeAttribute.getFullDotDashLen()); diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx index 63661c9c73c2..a734010e0dac 100644 --- a/emfio/qa/cppunit/emf/EmfImportTest.cxx +++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx @@ -389,13 +389,13 @@ void Test::TestDrawLine() // check correct import of the DrawLine: color and width of the line assertXPath(pDocument, aXPathPrefix + "polypolygonstroke/line", "color", "#000000"); - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke/line", "width", "33"); + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke/line", "width", "23"); } void Test::TestDrawLineWithDash() { - // EMF+ with records: DrawLine - // The lines with different dash styles + // EMF+ with records: DrawLine, ScaleWorldTransform, RotateWorldTransform + // Test lines with different dash styles and different World Rotation Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestEmfPlusDrawLineWithDash.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); @@ -405,23 +405,31 @@ void Test::TestDrawLineWithDash() CPPUNIT_ASSERT(pDocument); // check correct import of the DrawLine: color and width of the line - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke", 10); - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", "color", "#000000"); - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", "width", "132"); - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/stroke", 0); - - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", "width", "132"); - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/stroke", "dotDashArray", - "13225 13225 "); - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[3]/stroke", "dotDashArray", - "39674 13225 "); - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[4]/stroke", "dotDashArray", - "39674 13225 13225 13225 "); - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[5]/stroke", "dotDashArray", - "39674 13225 13225 13225 13225 13225 "); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke", 12); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[1]/line", "color", "#000000"); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[1]/line", "width", "185"); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[1]/stroke", 0); + + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[2]/line", "width", "185"); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[2]/stroke", "dotDashArray", + "185 185 "); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[3]/line", "width", "185"); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[3]/stroke", "dotDashArray", + "556 185 "); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[4]/line", "width", "185"); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[4]/stroke", "dotDashArray", + "556 185 185 185 "); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[5]/line", "width", "370"); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[5]/stroke", "dotDashArray", + "556 185 185 185 185 185 "); //TODO polypolygonstroke[6-9]/stroke add support for PenDataDashedLineOffset - assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[10]/stroke", "dotDashArray", - "66124 26450 198372 52899 "); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[10]/line", "width", "370"); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[10]/stroke", "dotDashArray", + "1851 741 5554 1481 "); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[11]/line", "width", "370"); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[11]/stroke", "dotDashArray", + "1851 741 5554 1481 "); + assertXPath(pDocument, aXPathPrefix + "mask/polypolygonstroke[12]/line", "width", "370"); } void Test::TestLinearGradient() diff --git a/emfio/qa/cppunit/emf/data/TestEmfPlusDrawLineWithDash.emf b/emfio/qa/cppunit/emf/data/TestEmfPlusDrawLineWithDash.emf index dc5af59e3f66..547cfca3fcad 100644 Binary files a/emfio/qa/cppunit/emf/data/TestEmfPlusDrawLineWithDash.emf and b/emfio/qa/cppunit/emf/data/TestEmfPlusDrawLineWithDash.emf differ commit 4e833598f83aedec6aec46be8acf178e6b051638 Author: Xisco Fauli <xiscofa...@libreoffice.org> AuthorDate: Wed Apr 20 17:58:15 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:13:51 2022 +0200 tdf#148685: Unset CharUnderlineColor and CharUnderlineHasColor properties Change-Id: Iebf482434cd393f55ae3e4690580b573624d78b1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133219 Tested-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> (cherry picked from commit 1c924efe1f80207a5e104d755615b1eb9a91d418) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133282 Tested-by: Jenkins Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com> diff --git a/oox/source/drawingml/textcharacterproperties.cxx b/oox/source/drawingml/textcharacterproperties.cxx index 7ffeaeba8da2..be2409f5795c 100644 --- a/oox/source/drawingml/textcharacterproperties.cxx +++ b/oox/source/drawingml/textcharacterproperties.cxx @@ -195,6 +195,12 @@ void TextCharacterProperties::pushToPropMap( PropertyMap& rPropMap, const XmlFil rPropMap.setProperty( PROP_CharUnderlineHasColor, true); rPropMap.setProperty( PROP_CharUnderlineColor, maUnderlineColor.getColor( rFilter.getGraphicHelper() )); } + else + { + rPropMap.setProperty( PROP_CharUnderlineHasColor, false); + rPropMap.setProperty( PROP_CharUnderlineColor, sal_Int32(-1)); + } + // TODO If bUnderlineFillFollowText uFillTx (CT_TextUnderlineFillFollowText) is set, fill color of the underline should be the same color as the text if (maHighlightColor.isUsed() && maHighlightColor.getTransparency() != 100) diff --git a/sd/qa/unit/data/pptx/tdf148685.pptx b/sd/qa/unit/data/pptx/tdf148685.pptx new file mode 100644 index 000000000000..80af5a9bbf46 Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf148685.pptx differ diff --git a/sd/qa/unit/import-tests2.cxx b/sd/qa/unit/import-tests2.cxx index 3ecbec200c6e..ee0d110df24d 100644 --- a/sd/qa/unit/import-tests2.cxx +++ b/sd/qa/unit/import-tests2.cxx @@ -116,6 +116,7 @@ public: void testAoo124143(); void testTdf103567(); void testTdf103792(); + void testTdf148685(); void testTdf103876(); void testTdf79007(); void testTdf118776(); @@ -184,6 +185,7 @@ public: CPPUNIT_TEST(testAoo124143); CPPUNIT_TEST(testTdf103567); CPPUNIT_TEST(testTdf103792); + CPPUNIT_TEST(testTdf148685); CPPUNIT_TEST(testTdf103876); CPPUNIT_TEST(testTdf79007); CPPUNIT_TEST(testTdf118776); @@ -476,6 +478,47 @@ void SdImportTest2::testTdf103792() xDocShRef->DoClose(); } +void SdImportTest2::testTdf148685() +{ + sd::DrawDocShellRef xDocShRef + = loadURL(m_directories.getURLFromSrc(u"/sd/qa/unit/data/pptx/tdf148685.pptx"), PPTX); + uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(1, 0, xDocShRef)); + + uno::Reference<text::XTextRange> const xParagraph(getParagraphFromShape(0, xShape)); + + uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph)); + CPPUNIT_ASSERT_EQUAL(OUString("TEXT "), xRun->getString()); + + uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY_THROW); + + Color nCharUnderlineColor; + xPropSet->getPropertyValue("CharUnderlineColor") >>= nCharUnderlineColor; + CPPUNIT_ASSERT_EQUAL(Color(0xA1467E), nCharUnderlineColor); + + xRun.set(getRunFromParagraph(1, xParagraph)); + + CPPUNIT_ASSERT_EQUAL(OUString("TE"), xRun->getString()); + + xPropSet.set(xRun, uno::UNO_QUERY_THROW); + + xPropSet->getPropertyValue("CharUnderlineColor") >>= nCharUnderlineColor; + + // Without the fix in place, this test would have failed with + // - Expected: Color: R:255 G:255 B:255 A:255 + // - Actual : Color: R:161 G:70 B:126 A:0 + CPPUNIT_ASSERT_EQUAL(COL_AUTO, nCharUnderlineColor); + + xRun.set(getRunFromParagraph(2, xParagraph)); + CPPUNIT_ASSERT_EQUAL(OUString("XT"), xRun->getString()); + + xPropSet.set(xRun, uno::UNO_QUERY_THROW); + + xPropSet->getPropertyValue("CharUnderlineColor") >>= nCharUnderlineColor; + CPPUNIT_ASSERT_EQUAL(COL_AUTO, nCharUnderlineColor); + + xDocShRef->DoClose(); +} + void SdImportTest2::testTdf103876() { // Title text shape's placeholder text did not inherit the corresponding text properties commit 65d679e6f78a819e3f4a60143782308b0a8b19f4 Author: Xisco Fauli <xiscofa...@libreoffice.org> AuthorDate: Tue Apr 19 16:25:14 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:13:46 2022 +0200 tdf#148620: sd: add UItest I tried to implement this test as a CppUnittest but '.uno:OutlineUp' and '.uno:OutlineDown' do nothing there Change-Id: Ie0d35abcc423999891d6a5dac07ec55d4ca8ee71 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133176 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> (cherry picked from commit e9dbbf0f184e4f742d5f0e1a6bc9adcd9d765739) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133283 diff --git a/sd/qa/uitest/impress_tests/tdf148620.py b/sd/qa/uitest/impress_tests/tdf148620.py new file mode 100644 index 000000000000..a703d722d8dd --- /dev/null +++ b/sd/qa/uitest/impress_tests/tdf148620.py @@ -0,0 +1,77 @@ +# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +from uitest.uihelper.common import get_state_as_dict +from libreoffice.uno.propertyvalue import mkPropertyValues +from uitest.framework import UITestCase + +class Tdf148620(UITestCase): + + def test_Tdf148620(self): + with self.ui_test.create_doc_in_start_center("impress") as document: + + xTemplateDlg = self.xUITest.getTopFocusWindow() + xCancelBtn = xTemplateDlg.getChild("close") + self.ui_test.close_dialog_through_button(xCancelBtn) + + xDoc = self.xUITest.getTopFocusWindow() + xEditWin = xDoc.getChild("impress_win") + + xEditWin.executeAction("SELECT", mkPropertyValues({"OBJECT":"Unnamed Drawinglayer object 1"})) + self.assertEqual("com.sun.star.drawing.SvxShapeCollection", document.CurrentSelection.getImplementationName()) + + xEditWin.executeAction("TYPE", mkPropertyValues({"TEXT":"one"})) + xEditWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "RETURN"})) + xEditWin.executeAction("TYPE", mkPropertyValues({"TEXT":"two"})) + xEditWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "RETURN"})) + xEditWin.executeAction("TYPE", mkPropertyValues({"TEXT":"three"})) + xEditWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "RETURN"})) + xEditWin.executeAction("TYPE", mkPropertyValues({"TEXT":"four"})) + xEditWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "RETURN"})) + xEditWin.executeAction("TYPE", mkPropertyValues({"TEXT":"five"})) + xEditWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "RETURN"})) + xEditWin.executeAction("TYPE", mkPropertyValues({"TEXT":"six"})) + + self.assertEqual("One\nTwo\nThree\nFour\nFive\nsix", document.DrawPages[0].getByIndex(1).String) + + xArgs = mkPropertyValues({"KeyModifier": 0}) + self.xUITest.executeCommandWithParameters(".uno:OutlineUp", xArgs) + self.assertEqual("One\nTwo\nThree\nFour\nsix\nFive", document.DrawPages[0].getByIndex(1).String) + + self.xUITest.executeCommandWithParameters(".uno:OutlineUp", xArgs) + self.assertEqual("One\nTwo\nThree\nsix\nFour\nFive", document.DrawPages[0].getByIndex(1).String) + + self.xUITest.executeCommandWithParameters(".uno:OutlineUp", xArgs) + self.assertEqual("One\nTwo\nsix\nThree\nFour\nFive", document.DrawPages[0].getByIndex(1).String) + + self.xUITest.executeCommandWithParameters(".uno:OutlineUp", xArgs) + self.assertEqual("One\nsix\nTwo\nThree\nFour\nFive", document.DrawPages[0].getByIndex(1).String) + + self.xUITest.executeCommandWithParameters(".uno:OutlineUp", xArgs) + self.assertEqual("six\nOne\nTwo\nThree\nFour\nFive", document.DrawPages[0].getByIndex(1).String) + + self.xUITest.executeCommandWithParameters(".uno:OutlineDown", xArgs) + + # Without the fix in place, this test would have failed with + # AssertionError: 'One\nsix\nTwo\nThree\nFour\nFive' != 'One\nTwo\nsix\nThree\nFour\nFive' + self.assertEqual("One\nsix\nTwo\nThree\nFour\nFive", document.DrawPages[0].getByIndex(1).String) + + self.xUITest.executeCommandWithParameters(".uno:OutlineDown", xArgs) + self.assertEqual("One\nTwo\nsix\nThree\nFour\nFive", document.DrawPages[0].getByIndex(1).String) + + self.xUITest.executeCommandWithParameters(".uno:OutlineDown", xArgs) + self.assertEqual("One\nTwo\nThree\nsix\nFour\nFive", document.DrawPages[0].getByIndex(1).String) + + self.xUITest.executeCommandWithParameters(".uno:OutlineDown", xArgs) + self.assertEqual("One\nTwo\nThree\nFour\nsix\nFive", document.DrawPages[0].getByIndex(1).String) + + self.xUITest.executeCommandWithParameters(".uno:OutlineDown", xArgs) + self.assertEqual("One\nTwo\nThree\nFour\nFive\nsix", document.DrawPages[0].getByIndex(1).String) + +# vim: set shiftwidth=4 softtabstop=4 expandtab: commit 101e8309188581594bdfe1c77e0c81218a991124 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Tue Apr 19 18:01:37 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:13:41 2022 +0200 ucb: webdav-curl: put user name from config into LOCK request ... so that the dialog in SfxMedium::LockOrigFileOnDemand() can show something more useful than hard-coded URL, which has been used since commit 99bdd887a6141883878978bad9beb35e7b326cd1 in 2009 when locking was added. This is half of the user info that is put into LO's own lock files (see svt::LockFileCommon::GenerateOwnEntry()). Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133186 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 70bea73ffbe815c2d5b7067f20d3eebbb98df61f) ucb: webdav-curl: check UseUserData before sending user name Hope this should be acceptable. Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133188 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 6d7c3848560883034a4ff12ac1ef52d2d1d28606) Change-Id: Iefac724644a536fc37c3c79ce862e25bd9be38af Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133143 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> diff --git a/ucb/CppunitTest_ucb_webdav_core.mk b/ucb/CppunitTest_ucb_webdav_core.mk index fbd3f59f55f6..0df1feefff21 100644 --- a/ucb/CppunitTest_ucb_webdav_core.mk +++ b/ucb/CppunitTest_ucb_webdav_core.mk @@ -19,6 +19,7 @@ $(eval $(call gb_CppunitTest_use_libraries,ucb_webdav_core, \ cppuhelper \ sal \ salhelper \ + svl \ test \ ucbhelper \ tl \ diff --git a/ucb/Library_ucpdav1.mk b/ucb/Library_ucpdav1.mk index b8cbb2be48e1..8574c6ff47a4 100644 --- a/ucb/Library_ucpdav1.mk +++ b/ucb/Library_ucpdav1.mk @@ -23,6 +23,7 @@ $(eval $(call gb_Library_use_libraries,ucpdav1,\ cppuhelper \ sal \ salhelper \ + svl \ ucbhelper \ tl \ )) diff --git a/ucb/source/ucp/webdav-curl/webdavcontent.cxx b/ucb/source/ucp/webdav-curl/webdavcontent.cxx index 1eb069a3480e..513626b8d73b 100644 --- a/ucb/source/ucp/webdav-curl/webdavcontent.cxx +++ b/ucb/source/ucp/webdav-curl/webdavcontent.cxx @@ -22,12 +22,14 @@ #include <cppuhelper/queryinterface.hxx> #include <rtl/uri.hxx> #include <sal/log.hxx> +#include <officecfg/Office/Common.hxx> #include <officecfg/Inet.hxx> #include <ucbhelper/contentidentifier.hxx> #include <ucbhelper/macros.hxx> #include <ucbhelper/propertyvalueset.hxx> #include <ucbhelper/simpleinteractionrequest.hxx> #include <ucbhelper/cancelcommandexecution.hxx> +#include <svl/lockfilecommon.hxx> #include <com/sun/star/beans/IllegalTypeException.hpp> #include <com/sun/star/beans/NotRemoveableException.hpp> @@ -3236,8 +3238,10 @@ void Content::lock( } uno::Any aOwnerAny; - aOwnerAny - <<= OUString("LibreOffice - http://www.libreoffice.org/"); + OUString const user(officecfg::Office::Common::Save::Document::UseUserData::get() + ? " - " + ::svt::LockFileCommon::GetOOOUserName() + : OUString()); + aOwnerAny <<= OUString("LibreOffice" + user); ucb::Lock aLock( ucb::LockScope_EXCLUSIVE, commit 17de89f167a26d8d1cb560f61e92b5aef7ef3fb7 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Tue Apr 19 17:34:52 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:13:35 2022 +0200 ucb: webdav-curl: fix getting DAV:lockdiscovery property commit b4576f3da4d90139fc5140962d13cb91dab98797 "tdf#82744: fix WebDAV lock/unlock behaviour - part 3" added a call to get the DAV:lockdiscovery property. But WebDAVResponseParser puts lock related properties into a separate return value maResult_Lock that is only returned for LOCK requests. Just add it as a normal property too, then PROPFIND can get it, and the dialog in SfxMedium::LockOrigFileOnDemand() no longer displays "Unknown user". Change-Id: Icee920588ea40b6e203b18287d75484528cfdebb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133185 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 68f41f4e2dcec65e8885cdfa658c0568a26182a9) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133142 Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> diff --git a/ucb/source/ucp/webdav-curl/webdavresponseparser.cxx b/ucb/source/ucp/webdav-curl/webdavresponseparser.cxx index a236957c096e..8b7d0473585c 100644 --- a/ucb/source/ucp/webdav-curl/webdavresponseparser.cxx +++ b/ucb/source/ucp/webdav-curl/webdavresponseparser.cxx @@ -22,11 +22,13 @@ #include "DAVProperties.hxx" #include "UCBDeadPropertyValue.hxx" -#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <comphelper/processfactory.hxx> +#include <comphelper/sequence.hxx> + #include <cppuhelper/implbase.hxx> #include <com/sun/star/xml/sax/Parser.hpp> #include <com/sun/star/xml/sax/InputSource.hpp> -#include <comphelper/processfactory.hxx> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> #include <com/sun/star/ucb/LockEntry.hpp> #include <com/sun/star/ucb/LockScope.hpp> #include <com/sun/star/ucb/LockType.hpp> @@ -75,6 +77,7 @@ namespace { WebDAVName_unknown = 0, WebDAVName_activelock, + WebDAVName_lockdiscovery, WebDAVName_multistatus, WebDAVName_response, WebDAVName_href, @@ -114,6 +117,7 @@ namespace if(aWebDAVNameMapperList.empty()) { aWebDAVNameMapperList.insert(WebDAVNameValueType(OUString("activelock"), WebDAVName_activelock)); + aWebDAVNameMapperList.insert(WebDAVNameValueType(OUString("lockdiscovery"), WebDAVName_lockdiscovery)); aWebDAVNameMapperList.insert(WebDAVNameValueType(OUString("multistatus"), WebDAVName_multistatus)); aWebDAVNameMapperList.insert(WebDAVNameValueType(OUString("response"), WebDAVName_response)); aWebDAVNameMapperList.insert(WebDAVNameValueType(OUString("href"), WebDAVName_href)); @@ -751,6 +755,20 @@ namespace maResult_Lock.push_back(maLock); break; } + case WebDAVName_lockdiscovery: + { + // lockdiscovery may be requested via PROPFIND, + // in addition to LOCK! so return it 2 ways + if (isCollectingProperties()) + { + http_dav_ucp::DAVPropertyValue aDAVPropertyValue; + + aDAVPropertyValue.Name = "DAV:lockdiscovery"; + aDAVPropertyValue.Value <<= ::comphelper::containerToSequence(maResult_Lock); + maPropStatProperties.push_back(aDAVPropertyValue); + } + break; + } case WebDAVName_propstat: { // propstat end, check status commit 89c2dfcbb749b9b8d9d6e29e92b0d1086f2abf1d Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Tue Apr 19 14:09:08 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:13:30 2022 +0200 sfx2: do reload on SID_EDITDOC in SfxViewFrame::ExecReload_Impl() commit b505ca5b9c31b3d9c639406d03a25bea4e914242 "Switch to read-only mode: do not force reload document if possible" replaced "true" with "bNeedsReload" here - but this is a problem when switching from read-only to editable. 1. Start LO and load a document from WebDAV editable 2. Start other LO and load the same document from WebDAV read-only 3. In first LO, edit document, store it and close it 4. In second LO, click "Edit Document" button 5. LO doesn't reload the document and shows stale content It's not clear what problem that commit was trying to solve, but let's assume that it intended to change only what happens when switching from editable to read-only. Change-Id: I69c779c5c0c5c2ccda677ea8cb353c8716916861 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133171 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit c929c563e2029bbb969dc417a688cca8934e69b0) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133141 Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index fd66caabd0d4..f8940b3ae8b4 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -599,7 +599,8 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) } } - rReq.AppendItem( SfxBoolItem( SID_FORCERELOAD, bNeedsReload) ); + rReq.AppendItem( SfxBoolItem(SID_FORCERELOAD, + rReq.GetSlot() == SID_EDITDOC || bNeedsReload) ); rReq.AppendItem( SfxBoolItem( SID_SILENT, true )); [[fallthrough]]; //TODO ??? commit 608ddfdd8bc3640b36ee632691c16015fad3451d Author: Julien Nabet <serval2...@yahoo.fr> AuthorDate: Mon Apr 18 19:37:10 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:13:24 2022 +0200 tdf#148651: implement VBA.FormatPercent I started from a copy/paste of FormatNumber. Then I deduplicated the code (it saved about 99% of it). Change-Id: Ibcb9ffbf8cebf45d5ffac4713e3d220b8499ba11 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133133 Tested-by: Jenkins Reviewed-by: Julien Nabet <serval2...@yahoo.fr> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133246 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/basic/source/inc/rtlproto.hxx b/basic/source/inc/rtlproto.hxx index 65efa4f0a746..f73de17ba3a4 100644 --- a/basic/source/inc/rtlproto.hxx +++ b/basic/source/inc/rtlproto.hxx @@ -233,6 +233,7 @@ extern void SbRtl_IsUnoStruct(StarBASIC * pBasic, SbxArray & rPar, bool bWrite); extern void SbRtl_FileDateTime(StarBASIC * pBasic, SbxArray & rPar, bool bWrite); extern void SbRtl_Format(StarBASIC * pBasic, SbxArray & rPar, bool bWrite); extern void SbRtl_FormatNumber(StarBASIC* pBasic, SbxArray& rPar, bool bWrite); +extern void SbRtl_FormatPercent(StarBASIC* pBasic, SbxArray& rPar, bool bWrite); extern void SbRtl_GetAttr(StarBASIC * pBasic, SbxArray & rPar, bool bWrite); extern void SbRtl_Randomize(StarBASIC * pBasic, SbxArray & rPar, bool bWrite); // JSM extern void SbRtl_Round(StarBASIC * pBasic, SbxArray & rPar, bool bWrite); diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx index e678b8852838..851584b6db79 100644 --- a/basic/source/runtime/methods.cxx +++ b/basic/source/runtime/methods.cxx @@ -3337,8 +3337,7 @@ void SbRtl_Format(StarBASIC *, SbxArray & rPar, bool) } } -// https://msdn.microsoft.com/en-us/vba/language-reference-vba/articles/formatnumber-function -void SbRtl_FormatNumber(StarBASIC*, SbxArray& rPar, bool) +static void lcl_FormatNumberPercent(SbxArray& rPar, bool isPercent) { const sal_uInt32 nArgCount = rPar.Count(); if (nArgCount < 2 || nArgCount > 6) @@ -3421,6 +3420,8 @@ void SbRtl_FormatNumber(StarBASIC*, SbxArray& rPar, bool) } double fVal = rPar.Get(1)->GetDouble(); + if (isPercent) + fVal *= 100; const bool bNegative = fVal < 0; if (bNegative) fVal = fabs(fVal); // Always work with non-negatives, to easily handle leading zero @@ -3462,6 +3463,20 @@ void SbRtl_FormatNumber(StarBASIC*, SbxArray& rPar, bool) } rPar.Get(0)->PutString(aResult); + if (isPercent) + aResult += "%"; +} + +// https://docs.microsoft.com/en-us/office/vba/Language/Reference/User-Interface-Help/formatnumber-function +void SbRtl_FormatNumber(StarBASIC*, SbxArray& rPar, bool) +{ + return lcl_FormatNumberPercent(rPar, false); +} + +// https://docs.microsoft.com/en-us/office/vba/Language/Reference/User-Interface-Help/formatpercent-function +void SbRtl_FormatPercent(StarBASIC*, SbxArray& rPar, bool) +{ + return lcl_FormatNumberPercent(rPar, true); } namespace { diff --git a/basic/source/runtime/stdobj.cxx b/basic/source/runtime/stdobj.cxx index dcbc0ec05983..810f53ad4912 100644 --- a/basic/source/runtime/stdobj.cxx +++ b/basic/source/runtime/stdobj.cxx @@ -401,6 +401,13 @@ constexpr Method aMethods[] = { arg(u"useParensForNegativeNumbers", SbxINTEGER, OPT_), // vbTriState arg(u"groupDigits", SbxINTEGER, OPT_), // vbTriState +{ u"FormatPercent", SbxSTRING, 5 | FUNCTION_ | COMPATONLY_, SbRtl_FormatPercent }, + arg(u"expression", SbxDOUBLE), + arg(u"numDigitsAfterDecimal", SbxINTEGER, OPT_), + arg(u"includeLeadingDigit", SbxINTEGER, OPT_), // vbTriState + arg(u"useParensForNegativeNumbers", SbxINTEGER, OPT_), // vbTriState + arg(u"groupDigits", SbxINTEGER, OPT_), // vbTriState + { u"Frac", SbxDOUBLE, 1 | FUNCTION_, SbRtl_Frac }, arg(u"number", SbxDOUBLE), commit 960a4aefde91746b0fde69b04ba67793797aab9b Author: Bartosz Kosiorek <gan...@poczta.onet.pl> AuthorDate: Wed Apr 20 19:44:05 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:13:17 2022 +0200 tdf#55058 tdf#143875 EMF+ Fix display of dashed lines and line joints With previous implementation, empty spaces between dashes were too long. Additionally line joints were not working correctly, after EMF+ reworking: tdf#111486 This commit fixes all these issues and additionally it is covering it with tests. Change-Id: I9404e566d2d7d3405ab817268ad9b1f538c200eb Change-Id: I523f92a928ab592ff175d0d01c1ad1a3bc22e324 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133207 Tested-by: Jenkins Reviewed-by: Bartosz Kosiorek <gan...@poczta.onet.pl> (cherry picked from commit 80c856336668e35837667323957fa3ad4172f3c0) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133152 diff --git a/compilerplugins/clang/redundantfcast.cxx b/compilerplugins/clang/redundantfcast.cxx index 2cfe5183ed46..f09b5b92c46f 100644 --- a/compilerplugins/clang/redundantfcast.cxx +++ b/compilerplugins/clang/redundantfcast.cxx @@ -335,6 +335,9 @@ public: // tdf#145203: FIREBIRD cannot create a table if (fn == SRCDIR "/connectivity/source/drivers/firebird/DatabaseMetaData.cxx") return false; + // false positive during using contructor drawinglayer::attribute::StrokeAttribute({ 3 * pw, pw }) + if (fn == SRCDIR "/drawinglayer/source/tools/emfppen.cxx") + return false; return true; } diff --git a/drawinglayer/source/tools/emfpcustomlinecap.cxx b/drawinglayer/source/tools/emfpcustomlinecap.cxx index e24cbcc32cb1..49cc912ed33c 100644 --- a/drawinglayer/source/tools/emfpcustomlinecap.cxx +++ b/drawinglayer/source/tools/emfpcustomlinecap.cxx @@ -43,15 +43,6 @@ namespace emfplushelper { } - void EMFPCustomLineCap::SetAttributes(rendering::StrokeAttributes& aAttributes) - { - aAttributes.StartCapType = EMFPPen::lcl_convertStrokeCap(strokeStartCap); - aAttributes.EndCapType = EMFPPen::lcl_convertStrokeCap(strokeEndCap); - aAttributes.JoinType = EMFPPen::lcl_convertLineJoinType(strokeJoin); - - aAttributes.MiterLimit = miterLimit; - } - void EMFPCustomLineCap::ReadPath(SvStream& s, EmfPlusHelperData const & rR, bool bFill) { sal_Int32 pathLength; diff --git a/drawinglayer/source/tools/emfpcustomlinecap.hxx b/drawinglayer/source/tools/emfpcustomlinecap.hxx index a42e0ab4ef46..e6202ae98179 100644 --- a/drawinglayer/source/tools/emfpcustomlinecap.hxx +++ b/drawinglayer/source/tools/emfpcustomlinecap.hxx @@ -19,7 +19,6 @@ #pragma once -#include <com/sun/star/rendering/StrokeAttributes.hpp> #include "emfphelperdata.hxx" namespace emfplushelper @@ -34,7 +33,6 @@ namespace emfplushelper EMFPCustomLineCap(); - void SetAttributes(com::sun::star::rendering::StrokeAttributes& aAttributes); void ReadPath(SvStream& s, EmfPlusHelperData const & rR, bool bFill); void Read(SvStream& s, EmfPlusHelperData const & rR); }; diff --git a/drawinglayer/source/tools/emfphelperdata.cxx b/drawinglayer/source/tools/emfphelperdata.cxx index 447686167837..79ced761e8a2 100644 --- a/drawinglayer/source/tools/emfphelperdata.cxx +++ b/drawinglayer/source/tools/emfphelperdata.cxx @@ -509,13 +509,6 @@ namespace emfplushelper if (!(pen && polygon.count())) return; - // we need a line join attribute - basegfx::B2DLineJoin lineJoin = basegfx::B2DLineJoin::Round; - if (pen->penDataFlags & EmfPlusPenDataJoin) // additional line join information - { - lineJoin = static_cast<basegfx::B2DLineJoin>(EMFPPen::lcl_convertLineJoinType(pen->lineJoin)); - } - // we need a line cap attribute css::drawing::LineCap lineCap = css::drawing::LineCap_BUTT; if (pen->penDataFlags & EmfPlusPenDataStartCap) // additional line cap information @@ -527,57 +520,16 @@ namespace emfplushelper const double transformedPenWidth = maMapTransform.get(0, 0) * pen->penWidth; drawinglayer::attribute::LineAttribute lineAttribute(pen->GetColor().getBColor(), transformedPenWidth, - lineJoin, - lineCap); - - drawinglayer::attribute::StrokeAttribute aStrokeAttribute; - if (pen->penDataFlags & EmfPlusPenDataLineStyle && pen->dashStyle != EmfPlusLineStyleCustom) // pen has a predefined line style - { - // short writing - const double pw = maMapTransform.get(1, 1) * pen->penWidth; - // taken from the old cppcanvas implementation and multiplied with pen width - const std::vector<double> dash = { 3*pw, 3*pw }; - const std::vector<double> dot = { pw, 3*pw }; - const std::vector<double> dashdot = { 3*pw, 3*pw, pw, 3*pw }; - const std::vector<double> dashdotdot = { 3*pw, 3*pw, pw, 3*pw, pw, 3*pw }; - - switch (pen->dashStyle) - { - case EmfPlusLineStyleSolid: // do nothing special, use default stroke attribute - break; - case EmfPlusLineStyleDash: - aStrokeAttribute = drawinglayer::attribute::StrokeAttribute(std::vector(dash)); - break; - case EmfPlusLineStyleDot: - aStrokeAttribute = drawinglayer::attribute::StrokeAttribute(std::vector(dot)); - break; - case EmfPlusLineStyleDashDot: - aStrokeAttribute = drawinglayer::attribute::StrokeAttribute(std::vector(dashdot)); - break; - case EmfPlusLineStyleDashDotDot: - aStrokeAttribute = drawinglayer::attribute::StrokeAttribute(std::vector(dashdotdot)); - break; - } - } - else if (pen->penDataFlags & EmfPlusPenDataDashedLine) // pen has a custom dash line - { - // StrokeAttribute needs a double vector while the pen provides a float vector - std::vector<double> aPattern(pen->dashPattern.size()); - for (size_t i=0; i<aPattern.size(); i++) - { - // convert from float to double and multiply with the adjusted pen width - aPattern[i] = maMapTransform.get(1, 1) * pen->penWidth * pen->dashPattern[i]; - } - aStrokeAttribute = drawinglayer::attribute::StrokeAttribute(std::move(aPattern)); - } - + pen->GetLineJoinType(), + lineCap, + basegfx::deg2rad(15.0)); // TODO Add MiterLimit support if (!pen->GetColor().IsTransparent()) { mrTargetHolders.Current().append( new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D( polygon, lineAttribute, - aStrokeAttribute)); + pen->GetStrokeAttribute(maMapTransform.get(1, 1)))); } else { @@ -585,7 +537,7 @@ namespace emfplushelper new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D( polygon, lineAttribute, - aStrokeAttribute)); + pen->GetStrokeAttribute(maMapTransform.get(1, 1)))); mrTargetHolders.Current().append( new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( @@ -634,7 +586,7 @@ namespace emfplushelper new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D( startCapPolygon, lineAttribute, - aStrokeAttribute)); + pen->GetStrokeAttribute(maMapTransform.get(1, 1)))); } } @@ -679,7 +631,7 @@ namespace emfplushelper new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D( endCapPolygon, lineAttribute, - aStrokeAttribute)); + pen->GetStrokeAttribute(maMapTransform.get(1, 1)))); } } diff --git a/drawinglayer/source/tools/emfppen.cxx b/drawinglayer/source/tools/emfppen.cxx index d41dca676d4e..f348391b0519 100644 --- a/drawinglayer/source/tools/emfppen.cxx +++ b/drawinglayer/source/tools/emfppen.cxx @@ -18,7 +18,6 @@ */ #include <com/sun/star/rendering/PathCapType.hpp> -#include <com/sun/star/rendering/PathJoinType.hpp> #include <o3tl/safeint.hxx> #include <sal/log.hxx> #include <rtl/ustrbuf.hxx> @@ -179,27 +178,70 @@ namespace emfplushelper { switch (nEmfStroke) { - case EmfPlusLineCapTypeSquare: return rendering::PathCapType::SQUARE; - case EmfPlusLineCapTypeRound: return rendering::PathCapType::ROUND; + case EmfPlusLineCapTypeSquare: + return rendering::PathCapType::SQUARE; + // we have no mapping for EmfPlusLineCapTypeTriangle, + // but it is similar to Round + case EmfPlusLineCapTypeTriangle: // fall-through + case EmfPlusLineCapTypeRound: + return rendering::PathCapType::ROUND; } - // we have no mapping for EmfPlusLineCapTypeTriangle = 0x00000003, - // so return BUTT always return rendering::PathCapType::BUTT; } - sal_Int8 EMFPPen::lcl_convertLineJoinType(sal_uInt32 nEmfLineJoin) + basegfx::B2DLineJoin EMFPPen::GetLineJoinType() const { - switch (nEmfLineJoin) + if (penDataFlags & EmfPlusPenDataJoin) // additional line join information { - case EmfPlusLineJoinTypeMiter: // fall-through - case EmfPlusLineJoinTypeMiterClipped: return rendering::PathJoinType::MITER; - case EmfPlusLineJoinTypeBevel: return rendering::PathJoinType::BEVEL; - case EmfPlusLineJoinTypeRound: return rendering::PathJoinType::ROUND; + switch (lineJoin) + { + case EmfPlusLineJoinTypeMiter: // fall-through + case EmfPlusLineJoinTypeMiterClipped: + return basegfx::B2DLineJoin::Miter; + case EmfPlusLineJoinTypeBevel: + return basegfx::B2DLineJoin::Bevel; + case EmfPlusLineJoinTypeRound: + return basegfx::B2DLineJoin::Round; + } } + // If nothing set, then miter applied with no limit + return basegfx::B2DLineJoin::Miter; + } - assert(false); // Line Join type isn't in specification. - return 0; + drawinglayer::attribute::StrokeAttribute + EMFPPen::GetStrokeAttribute(const double aTransformation) const + { + if (penDataFlags & EmfPlusPenDataLineStyle // pen has a predefined line style + && dashStyle != EmfPlusLineStyleCustom) + { + const double pw = aTransformation * penWidth; + switch (dashStyle) + { + case EmfPlusLineStyleDash: + return drawinglayer::attribute::StrokeAttribute({ 3 * pw, pw }); + case EmfPlusLineStyleDot: + return drawinglayer::attribute::StrokeAttribute({ pw, pw }); + case EmfPlusLineStyleDashDot: + return drawinglayer::attribute::StrokeAttribute({ 3 * pw, pw, pw, pw }); + case EmfPlusLineStyleDashDotDot: + return drawinglayer::attribute::StrokeAttribute({ 3 * pw, pw, pw, pw, pw, pw }); + } + } + else if (penDataFlags & EmfPlusPenDataDashedLine) // pen has a custom dash line + { + const double pw = aTransformation * penWidth; + // StrokeAttribute needs a double vector while the pen provides a float vector + std::vector<double> aPattern(dashPattern.size()); + for (size_t i = 0; i < aPattern.size(); i++) + { + // convert from float to double and multiply with the adjusted pen width + aPattern[i] = pw * dashPattern[i]; + } + return drawinglayer::attribute::StrokeAttribute(std::move(aPattern)); + } + // EmfPlusLineStyleSolid: - do nothing special, use default stroke attribute + return drawinglayer::attribute::StrokeAttribute(); } void EMFPPen::Read(SvStream& s, EmfPlusHelperData const & rR) @@ -249,7 +291,7 @@ namespace emfplushelper if (penDataFlags & PenDataJoin) { s.ReadInt32(lineJoin); - SAL_WARN("drawinglayer.emf", "EMF+\t\tTODO PenDataJoin: " << LineJoinTypeToString(lineJoin) << " (0x" << std::hex << lineJoin << ")"); + SAL_WARN("drawinglayer.emf", "EMF+\t\t LineJoin: " << LineJoinTypeToString(lineJoin) << " (0x" << std::hex << lineJoin << ")"); } else { diff --git a/drawinglayer/source/tools/emfppen.hxx b/drawinglayer/source/tools/emfppen.hxx index 05b2fc376d7d..29ece63ecf5d 100644 --- a/drawinglayer/source/tools/emfppen.hxx +++ b/drawinglayer/source/tools/emfppen.hxx @@ -19,6 +19,7 @@ #pragma once +#include <drawinglayer/attribute/strokeattribute.hxx> #include "emfpbrush.hxx" #include <vector> @@ -26,6 +27,7 @@ namespace emfplushelper { const sal_uInt32 EmfPlusLineCapTypeSquare = 0x00000001; const sal_uInt32 EmfPlusLineCapTypeRound = 0x00000002; + const sal_uInt32 EmfPlusLineCapTypeTriangle = 0x00000003; const sal_uInt32 EmfPlusLineJoinTypeMiter = 0x00000000; const sal_uInt32 EmfPlusLineJoinTypeBevel = 0x00000001; @@ -122,7 +124,8 @@ namespace emfplushelper void Read(SvStream& s, EmfPlusHelperData const & rR); static sal_Int8 lcl_convertStrokeCap(sal_uInt32 nEmfStroke); - static sal_Int8 lcl_convertLineJoinType(sal_uInt32 nEmfLineJoin); + drawinglayer::attribute::StrokeAttribute GetStrokeAttribute(const double aTransformation) const; + basegfx::B2DLineJoin GetLineJoinType() const; }; } diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx b/drawinglayer/source/tools/primitive2dxmldump.cxx index 2e2bb887a3d4..a1fddf900543 100644 --- a/drawinglayer/source/tools/primitive2dxmldump.cxx +++ b/drawinglayer/source/tools/primitive2dxmldump.cxx @@ -13,6 +13,7 @@ #include <tools/stream.hxx> #include <tools/XmlWriter.hxx> +#include <math.h> #include <memory> #include <sal/log.hxx> @@ -132,6 +133,24 @@ void writePolyPolygon(::tools::XmlWriter& rWriter, const basegfx::B2DPolyPolygon rWriter.endElement(); } +void writeStrokeAttribute(::tools::XmlWriter& rWriter, + const drawinglayer::attribute::StrokeAttribute& rStrokeAttribute) +{ + if (!rStrokeAttribute.getDotDashArray().empty()) + { + rWriter.startElement("stroke"); + + OUString sDotDash; + for (double fDotDash : rStrokeAttribute.getDotDashArray()) + { + sDotDash += OUString::number(round(100.0 * fDotDash)) + " "; + } + rWriter.attribute("dotDashArray", sDotDash); + rWriter.attribute("fullDotDashLength", rStrokeAttribute.getFullDotDashLen()); + rWriter.endElement(); + } +} + void writeLineAttribute(::tools::XmlWriter& rWriter, const drawinglayer::attribute::LineAttribute& rLineAttribute) { @@ -718,14 +737,7 @@ void Primitive2dXmlDump::decomposeAndWrite( rWriter.endElement(); writeLineAttribute(rWriter, rPolygonStrokePrimitive2D.getLineAttribute()); - - rWriter.startElement("stroke"); - const drawinglayer::attribute::StrokeAttribute& aStrokeAttribute - = rPolygonStrokePrimitive2D.getStrokeAttribute(); - rWriter.attribute("fulldotdashlen", aStrokeAttribute.getFullDotDashLen()); - //rWriter.attribute("dotdasharray", aStrokeAttribute.getDotDashArray()); - rWriter.endElement(); - + writeStrokeAttribute(rWriter, rPolygonStrokePrimitive2D.getStrokeAttribute()); rWriter.endElement(); } break; @@ -736,9 +748,7 @@ void Primitive2dXmlDump::decomposeAndWrite( rWriter.startElement("polypolygonstroke"); writeLineAttribute(rWriter, rPolyPolygonStrokePrimitive2D.getLineAttribute()); - - //getStrokeAttribute() - + writeStrokeAttribute(rWriter, rPolyPolygonStrokePrimitive2D.getStrokeAttribute()); writePolyPolygon(rWriter, rPolyPolygonStrokePrimitive2D.getB2DPolyPolygon()); rWriter.endElement(); diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx index 799f8eef9c46..63661c9c73c2 100644 --- a/emfio/qa/cppunit/emf/EmfImportTest.cxx +++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx @@ -52,6 +52,7 @@ class Test : public test::BootstrapFixture, public XmlTestTools, public unotest: void TestDrawStringTransparent(); void TestDrawStringWithBrush(); void TestDrawLine(); + void TestDrawLineWithDash(); void TestLinearGradient(); void TestTextMapMode(); void TestEnglishMapMode(); @@ -95,6 +96,7 @@ public: CPPUNIT_TEST(TestDrawStringTransparent); CPPUNIT_TEST(TestDrawStringWithBrush); CPPUNIT_TEST(TestDrawLine); + CPPUNIT_TEST(TestDrawLineWithDash); CPPUNIT_TEST(TestLinearGradient); CPPUNIT_TEST(TestTextMapMode); CPPUNIT_TEST(TestEnglishMapMode); @@ -390,6 +392,38 @@ void Test::TestDrawLine() assertXPath(pDocument, aXPathPrefix + "polypolygonstroke/line", "width", "33"); } +void Test::TestDrawLineWithDash() +{ + // EMF+ with records: DrawLine + // The lines with different dash styles + Primitive2DSequence aSequence + = parseEmf(u"/emfio/qa/cppunit/emf/data/TestEmfPlusDrawLineWithDash.emf"); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); + drawinglayer::Primitive2dXmlDump dumper; + xmlDocUniquePtr pDocument + = dumper.dumpAndParse(comphelper::sequenceToContainer<Primitive2DContainer>(aSequence)); + CPPUNIT_ASSERT(pDocument); + + // check correct import of the DrawLine: color and width of the line + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke", 10); + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", "color", "#000000"); + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", "width", "132"); + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/stroke", 0); + + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", "width", "132"); + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/stroke", "dotDashArray", + "13225 13225 "); + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[3]/stroke", "dotDashArray", + "39674 13225 "); + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[4]/stroke", "dotDashArray", + "39674 13225 13225 13225 "); + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[5]/stroke", "dotDashArray", + "39674 13225 13225 13225 13225 13225 "); + //TODO polypolygonstroke[6-9]/stroke add support for PenDataDashedLineOffset + assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[10]/stroke", "dotDashArray", + "66124 26450 198372 52899 "); +} + void Test::TestLinearGradient() { // EMF+ file with LinearGradient brush diff --git a/emfio/qa/cppunit/emf/data/TestEmfPlusDrawLineWithDash.emf b/emfio/qa/cppunit/emf/data/TestEmfPlusDrawLineWithDash.emf new file mode 100644 index 000000000000..dc5af59e3f66 Binary files /dev/null and b/emfio/qa/cppunit/emf/data/TestEmfPlusDrawLineWithDash.emf differ diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx index cab6b56b0ae7..ae673af298b3 100644 --- a/svx/qa/unit/svdraw.cxx +++ b/svx/qa/unit/svdraw.cxx @@ -338,7 +338,8 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testRectangleObject) assertXPathContent(pXmlDoc, aBasePath + "/polygon", "49.5,99 0,99 0,0 99,0 99,99"); - assertXPath(pXmlDoc, aBasePath + "/stroke", "fulldotdashlen", "0"); + // If solid line, then there is no line stroke information + assertXPath(pXmlDoc, aBasePath + "/stroke", 0); pPage->RemoveObject(0); commit 2a05d1aaf31686babd75d80316639e625ca5ea81 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Wed Apr 20 18:48:30 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:13:12 2022 +0200 sw: layout: fix crash when deleting page with section being formatted This crashes only when calling storeToURL() with writer_pdf_Export? There is a text frame 112, followed by section frame 126, which contains table frame 127. The section frame 126 is being formatted, which in SwFrame::PrepareMake() formats its prev, text frame 112. This does MoveBwd() and in SwContentFrame::MakeAll() formats its next, tab frame 127. This also does MoveBwd() and then there is this really odd condition in SwTabFrame::Paste() where it calls SwFrame::CheckPageDescs() if it *doesn't* have a RES_PAGEDESC item and the page has a non-default page style - this condition remains inexplicable since initial CVS import. Then CheckPageDesc() sees the (next) page is empty and deletes it. So check in sw::IsPageFrameEmpty() that there aren't any sections with IsDeleteForbidden() set. (regression from commit b9ef71476fd70bc13f50ebe80390e0730d1b7afb) Change-Id: I3c64fe40fabffc255c4146a35c678ce6a1cc09c9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133222 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 85aa57359befd7a21b3fdf36f2b362f50495f77c) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133150 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sw/source/core/inc/layfrm.hxx b/sw/source/core/inc/layfrm.hxx index 3f73602e6bfa..b0f981477499 100644 --- a/sw/source/core/inc/layfrm.hxx +++ b/sw/source/core/inc/layfrm.hxx @@ -100,6 +100,7 @@ public: SwPrintData const*const pPrintData = nullptr ) const override; const SwFrame *Lower() const { return m_pLower; } SwFrame *Lower() { return m_pLower; } + bool ContainsDeleteForbiddenLayFrame() const; const SwContentFrame *ContainsContent() const; inline SwContentFrame *ContainsContent(); const SwCellFrame *FirstCell() const; diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx index d100e24526a4..3d92f2a9ce0e 100644 --- a/sw/source/core/layout/findfrm.cxx +++ b/sw/source/core/layout/findfrm.cxx @@ -165,6 +165,27 @@ const SwFrame *SwLayoutFrame::ContainsAny( const bool _bInvestigateFootnoteForSe return nullptr; } +bool SwLayoutFrame::ContainsDeleteForbiddenLayFrame() const +{ + if (IsDeleteForbidden()) + { + return true; + } + for (SwFrame const* pFrame = Lower(); pFrame; pFrame = pFrame->GetNext()) + { + if (!pFrame->IsLayoutFrame()) + { + continue; + } + SwLayoutFrame const*const pLay(static_cast<SwLayoutFrame const*>(pFrame)); + if (pLay->ContainsDeleteForbiddenLayFrame()) + { + return true; + } + } + return false; +} + const SwFrame* SwFrame::GetLower() const { return IsLayoutFrame() ? static_cast<const SwLayoutFrame*>(this)->Lower() : nullptr; diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx index fe84f956a35c..e7a458737d30 100644 --- a/sw/source/core/layout/pagechg.cxx +++ b/sw/source/core/layout/pagechg.cxx @@ -1024,6 +1024,8 @@ bool IsPageFrameEmpty(SwPageFrame const& rPage) rPage.FindFootnoteCont() || (nullptr != (pBody = rPage.FindBodyCont()) && ( pBody->ContainsContent() || + // check for section frames that are being formatted on the stack + rPage.ContainsDeleteForbiddenLayFrame() || // #i47580# // Do not delete page if there's an empty tabframe // left. I think it might be correct to use ContainsAny() commit e555cffdac7b786d166aea5efc750060be1532fa Author: Jan-Marek Glogowski <glo...@fbihome.de> AuthorDate: Thu Apr 21 10:56:42 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:13:07 2022 +0200 tdf#148699 Qt track the active / shown popup I have no idea, if there can be multiple active popups in LO in some way. There can be multiple FloatingWindow and gtk does count them in m_nFloats... There is a whole lot going on in gtk3 related to isFloatGrabWindow(), with "funny" comments like: // FIXME: find out who the hell steals the focus from our frame So this goes with some "optimistic" approach: there is just one active popup, so we can track it in QtInstance. It WFM... Change-Id: I9778587696e1ad9e641dba4f102e2e921266eee6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133249 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> (cherry picked from commit 347622a98f512dae709f938a85498dcdcf9f225a) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133260 Reviewed-by: Jan-Marek Glogowski <glo...@fbihome.de> diff --git a/vcl/inc/qt5/QtInstance.hxx b/vcl/inc/qt5/QtInstance.hxx index 9a9853a7a2ce..fd111bb22abe 100644 --- a/vcl/inc/qt5/QtInstance.hxx +++ b/vcl/inc/qt5/QtInstance.hxx @@ -35,6 +35,7 @@ #include "QtFilePicker.hxx" +class QtFrame; class QtTimer; class QApplication; @@ -67,6 +68,8 @@ class VCLPLUG_QT_PUBLIC QtInstance : public QObject, Timer m_aUpdateStyleTimer; bool m_bUpdateFonts; + QtFrame* m_pActivePopup; + DECL_DLLPRIVATE_LINK(updateStyleHdl, Timer*, void); void AfterAppInit() override; @@ -172,6 +175,9 @@ public: void UpdateStyle(bool bFontsChanged); void* CreateGStreamerSink(const SystemChildWindow*) override; + + QtFrame* activePopup() const { return m_pActivePopup; } + void setActivePopup(QtFrame*); }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/qt5/QtWidget.hxx b/vcl/inc/qt5/QtWidget.hxx index 4a40589b16ba..8f7f6cc319e1 100644 --- a/vcl/inc/qt5/QtWidget.hxx +++ b/vcl/inc/qt5/QtWidget.hxx @@ -73,6 +73,7 @@ class QtWidget : public QWidget virtual void paintEvent(QPaintEvent*) override; virtual void resizeEvent(QResizeEvent*) override; virtual void showEvent(QShowEvent*) override; + virtual void hideEvent(QHideEvent*) override; virtual void wheelEvent(QWheelEvent*) override; virtual void closeEvent(QCloseEvent*) override; virtual void changeEvent(QEvent*) override; diff --git a/vcl/qt5/QtInstance.cxx b/vcl/qt5/QtInstance.cxx index d252109e122a..247001443020 100644 --- a/vcl/qt5/QtInstance.cxx +++ b/vcl/qt5/QtInstance.cxx @@ -223,6 +223,7 @@ QtInstance::QtInstance(std::unique_ptr<QApplication>& pQApp, bool bUseCairo) , m_pQApplication(std::move(pQApp)) , m_aUpdateStyleTimer("vcl::qt5 m_aUpdateStyleTimer") , m_bUpdateFonts(false) + , m_pActivePopup(nullptr) { ImplSVData* pSVData = ImplGetSVData(); const OUString sToolkit = "qt" + OUString::number(QT_VERSION_MAJOR); @@ -722,6 +723,12 @@ std::unique_ptr<QApplication> QtInstance::CreateQApplication(int& nArgc, char** return pQApp; } +void QtInstance::setActivePopup(QtFrame* pFrame) +{ + assert(!pFrame || pFrame->isPopup()); + m_pActivePopup = pFrame; +} + extern "C" { VCLPLUG_QT_PUBLIC SalInstance* create_SalInstance() { diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx index 5f07974600e8..8c545fd13377 100644 --- a/vcl/qt5/QtWidget.cxx +++ b/vcl/qt5/QtWidget.cxx @@ -317,9 +317,21 @@ void QtWidget::showEvent(QShowEvent*) // sequence from QtFrame::SetModal, if the frame was already set visible, // resulting in a hidden / unmapped window SalPaintEvent aPaintEvt(0, 0, aSize.width(), aSize.height()); + if (m_rFrame.isPopup()) + { + auto* pQtInst(static_cast<QtInstance*>(GetSalData()->m_pInstance)); + pQtInst->setActivePopup(&m_rFrame); + } m_rFrame.CallCallback(SalEvent::Paint, &aPaintEvt); } +void QtWidget::hideEvent(QHideEvent*) +{ + auto* pQtInst(static_cast<QtInstance*>(GetSalData()->m_pInstance)); + if (m_rFrame.isPopup() && pQtInst->activePopup() == &m_rFrame) + pQtInst->setActivePopup(nullptr); +} + void QtWidget::closeEvent(QCloseEvent* /*pEvent*/) { m_rFrame.CallCallback(SalEvent::Close, nullptr); @@ -627,11 +639,11 @@ bool QtWidget::handleEvent(QtFrame& rFrame, QWidget& rWidget, QEvent* pEvent) } else if (pEvent->type() == QEvent::ToolTip) { - // Qt's POV on focus is wrong for our fake popup windows, so check LO's state. + // Qt's POV on the active popup is wrong due to our fake popup, so check LO's state. // Otherwise Qt will continue handling ToolTip events from the "parent" window. - const vcl::Window* pFocusWin = Application::GetFocusWindow(); - if (!rFrame.m_aTooltipText.isEmpty() && pFocusWin - && pFocusWin->GetFrameWindow() == rFrame.GetWindow()) + const QtFrame* pPopupFrame + = static_cast<QtInstance*>(GetSalData()->m_pInstance)->activePopup(); + if (!rFrame.m_aTooltipText.isEmpty() && (!pPopupFrame || pPopupFrame == &rFrame)) QToolTip::showText(QCursor::pos(), toQString(rFrame.m_aTooltipText), &rWidget, rFrame.m_aTooltipArea); else commit b2537df437964b85832edc36d22f92b291388e8c Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Wed Apr 20 13:16:31 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:13:03 2022 +0200 tdf#146460 tdf#148429 ucb: webdav-curl: censor "curl" in UserAgent This is now the second bug filed because a server replies with 403 if the UserAgent contains the string "curl". Change-Id: I25ca2d255af76a7ff4e64dad900b1bf0b78de59f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133212 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 8d9c56e8f42428fd6695942c673bffb985d22ad5) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133146 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx b/ucb/source/ucp/webdav-curl/CurlSession.cxx index 813988c78489..66232a73a15f 100644 --- a/ucb/source/ucp/webdav-curl/CurlSession.cxx +++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx @@ -620,9 +620,10 @@ CurlSession::CurlSession(uno::Reference<uno::XComponentContext> const& xContext, // en.wikipedia.org:80 forces back 403 "Scripts should use an informative // User-Agent string with contact information, or they may be IP-blocked // without notice" otherwise: - OString const useragent(OString::Concat("LibreOffice " LIBO_VERSION_DOTTED " curl/") - + ::std::string_view(pVersion->version, strlen(pVersion->version)) + " " - + pVersion->ssl_version); + OString const useragent( + OString::Concat("LibreOffice " LIBO_VERSION_DOTTED " denylistedbackend/") + + ::std::string_view(pVersion->version, strlen(pVersion->version)) + " " + + pVersion->ssl_version); // looks like an explicit "User-Agent" header in CURLOPT_HTTPHEADER // will override CURLOPT_USERAGENT, see Curl_http_useragent(), so no need // to check anything here commit a8d3e2a19e464f0cd3b235cc3dba7af94e11bde6 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Wed Apr 20 15:04:47 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:12:58 2022 +0200 tdf#147723 sw_fieldmarkhide: fix crash when copying multiple fieldmarks The problem is the UpdateFramesForAddDeleteRedline() call in makeMark(), this is called in a loop for multiple fieldmarks and when it's called for the first one, of course the other ones aren't in the document yet, so HideIterator::Next() can't find them. But this is only needed when inserting a new fieldmark anyway, so just disable for copying. (regression from commit 92384a813176b964a67bcbeb2fa617c554dbc4a2) Change-Id: Ic1b34d469a553cf7bbf2d1a99edaea900bdd7417 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133215 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 2f726fa41cbd249f2fb30222b29d5f30bce52e6e) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133148 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx index 35d016c93ac0..e3c87f5ea065 100644 --- a/sw/source/core/doc/docbm.cxx +++ b/sw/source/core/doc/docbm.cxx @@ -687,8 +687,9 @@ namespace sw::mark // no special array for these break; } - if (eType == IDocumentMarkAccess::MarkType::TEXT_FIELDMARK - || eType == IDocumentMarkAccess::MarkType::DATE_FIELDMARK) + if (eMode == InsertMode::New + && (eType == IDocumentMarkAccess::MarkType::TEXT_FIELDMARK + || eType == IDocumentMarkAccess::MarkType::DATE_FIELDMARK)) { // due to SwInsText notifications everything is visible now - tell // layout to hide as appropriate commit 233f0b0d1888112d3acae356712cad1c5db0c5b1 Author: Jan-Marek Glogowski <glo...@fbihome.de> AuthorDate: Tue Apr 19 16:03:56 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:12:52 2022 +0200 tdf#140463 Qt handle mouse enter+leave events Currently just implemented for the QtWidget, but still as a static function, so it may be used for QtObject at some point too. But there is no (mouse) enter or leave event function in QWindow, so no way to handle these there. And since we can't modify the returned QWidget from QWidget::createWindowContainer, the only way would be to expand the static QtWidget::handleEvent used by QtObjectWindow::event ... if it's actually needed at some point. Includes squashed commit 5d56255c22c79b72c1cedb48cfe0a200f89bdc66 ("qt6: Fix build (QtWidget::enterEvent)"). Change-Id: If9009e5dfca508acd1e702df1a17eb8ad7c29690 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133190 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glo...@fbihome.de> (cherry picked from commit dc886bc6de2c0061a840bea2426663c3be2ecd26) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133149 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/inc/qt5/QtWidget.hxx b/vcl/inc/qt5/QtWidget.hxx index 878c8b1229ce..4a40589b16ba 100644 --- a/vcl/inc/qt5/QtWidget.hxx +++ b/vcl/inc/qt5/QtWidget.hxx @@ -51,6 +51,7 @@ class QtWidget : public QWidget static void commitText(QtFrame&, const QString& aText); static bool handleKeyEvent(QtFrame&, const QWidget&, QKeyEvent*, const ButtonKeyState); static void handleMouseButtonEvent(const QtFrame&, const QMouseEvent*, const ButtonKeyState); + static void handleMouseEnterLeaveEvents(const QtFrame&, QEvent*); static void fillSalAbstractMouseEvent(const QtFrame& rFrame, const QInputEvent* pQEvent, const QPoint& rPos, Qt::MouseButtons eButtons, int nWidth, SalAbstractMouseEvent& aSalEvent); @@ -75,6 +76,12 @@ class QtWidget : public QWidget virtual void wheelEvent(QWheelEvent*) override; virtual void closeEvent(QCloseEvent*) override; virtual void changeEvent(QEvent*) override; + virtual void leaveEvent(QEvent*) override; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + virtual void enterEvent(QEnterEvent*) override; +#else + virtual void enterEvent(QEvent*) override; +#endif void inputMethodEvent(QInputMethodEvent*) override; QVariant inputMethodQuery(Qt::InputMethodQuery) const override; diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx index 017249b05434..5f07974600e8 100644 --- a/vcl/qt5/QtWidget.cxx +++ b/vcl/qt5/QtWidget.cxx @@ -208,6 +208,41 @@ void QtWidget::mouseMoveEvent(QMouseEvent* pEvent) pEvent->accept(); } +void QtWidget::handleMouseEnterLeaveEvents(const QtFrame& rFrame, QEvent* pQEvent) +{ + const qreal fRatio = rFrame.devicePixelRatioF(); + const QWidget* pWidget = rFrame.GetQWidget(); + const Point aPos = toPoint(pWidget->mapFromGlobal(QCursor::pos()) * fRatio); + + SalMouseEvent aEvent; + aEvent.mnX + = QGuiApplication::isLeftToRight() ? aPos.X() : round(pWidget->width() * fRatio) - aPos.X(); + aEvent.mnY = aPos.Y(); + aEvent.mnTime = 0; + aEvent.mnButton = 0; + aEvent.mnCode = GetKeyModCode(QGuiApplication::keyboardModifiers()) + | GetMouseModCode(QGuiApplication::mouseButtons()); + + SalEvent nEventType; + if (pQEvent->type() == QEvent::Enter) + nEventType = SalEvent::MouseMove; + else + nEventType = SalEvent::MouseLeave; + rFrame.CallCallback(nEventType, &aEvent); + pQEvent->accept(); +} + +void QtWidget::leaveEvent(QEvent* pEvent) { handleMouseEnterLeaveEvents(m_rFrame, pEvent); } + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +void QtWidget::enterEvent(QEnterEvent* pEvent) +#else +void QtWidget::enterEvent(QEvent* pEvent) +#endif +{ + handleMouseEnterLeaveEvents(m_rFrame, pEvent); +} + void QtWidget::wheelEvent(QWheelEvent* pEvent) { SalWheelMouseEvent aEvent; commit 6ba5cca9b196d950f7bca596f2d6a154ddbd22d8 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Tue Apr 19 12:53:43 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:12:48 2022 +0200 tdf#148313 Basic IDE crashing while resizing dialog Change-Id: Ic68b78f26626f346f3ef8b54a584de64165d9eb2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133170 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> (cherry picked from commit d40c6601330b70c3cb9c1be0fa9e9775ad51113c) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133140 Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com> diff --git a/svx/source/svdraw/sdrhittesthelper.cxx b/svx/source/svdraw/sdrhittesthelper.cxx index 2a93dc372555..eb5116e584a7 100644 --- a/svx/source/svdraw/sdrhittesthelper.cxx +++ b/svx/source/svdraw/sdrhittesthelper.cxx @@ -136,9 +136,10 @@ bool ViewObjectContactPrimitiveHit( { // get primitive sequence sdr::contact::DisplayInfo aDisplayInfo; - const drawinglayer::primitive2d::Primitive2DContainer& rSequence(rVOC.getPrimitive2DSequence(aDisplayInfo)); + // have to make a copy of this container here, because it might be changed underneath us + const drawinglayer::primitive2d::Primitive2DContainer aSequence(rVOC.getPrimitive2DSequence(aDisplayInfo)); - if(!rSequence.empty()) + if(!aSequence.empty()) { // create a HitTest processor const drawinglayer::geometry::ViewInformation2D& rViewInformation2D = rVOC.GetObjectContact().getViewInformation2D(); @@ -152,7 +153,7 @@ bool ViewObjectContactPrimitiveHit( aHitTestProcessor2D.collectHitStack(true); // feed it with the primitives - aHitTestProcessor2D.process(rSequence); + aHitTestProcessor2D.process(aSequence); // deliver result if (aHitTestProcessor2D.getHit()) commit 44aa632d82fbff7bae9a832dee0a506bb4a570f4 Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Thu Apr 14 12:05:49 2022 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:12:41 2022 +0200 tdf#148101 don't autocomplete remote files dialog entry on delete/backspace Change-Id: Ieddb41eb37e7090416a418afeffb76ce0eddf90a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132873 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/fpicker/source/office/autocmpledit.cxx b/fpicker/source/office/autocmpledit.cxx index 5a31c7bdc501..89a2d0b0c245 100644 --- a/fpicker/source/office/autocmpledit.cxx +++ b/fpicker/source/office/autocmpledit.cxx @@ -7,21 +7,44 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <vcl/event.hxx> #include "autocmpledit.hxx" AutocompleteEdit::AutocompleteEdit(std::unique_ptr<weld::Entry> xEntry) : m_xEntry(std::move(xEntry)) , m_aChangedIdle("fpicker::AutocompleteEdit m_aChangedIdle") + , m_nLastCharCode(0) { m_xEntry->connect_changed(LINK(this, AutocompleteEdit, ChangedHdl)); + m_xEntry->connect_key_press(LINK(this, AutocompleteEdit, KeyInputHdl)); m_aChangedIdle.SetInvokeHandler(LINK(this, AutocompleteEdit, TryAutoComplete)); } +IMPL_LINK(AutocompleteEdit, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + m_nLastCharCode = rKEvt.GetKeyCode().GetCode(); + return false; +} + IMPL_LINK_NOARG(AutocompleteEdit, ChangedHdl, weld::Entry&, void) { m_aChangeHdl.Call(*m_xEntry); - m_aChangedIdle.Start(); //launch this to happen on idle after cursor position will have been set + + switch (m_nLastCharCode) + { + case css::awt::Key::DELETE_WORD_BACKWARD: + case css::awt::Key::DELETE_WORD_FORWARD: + case css::awt::Key::DELETE_TO_BEGIN_OF_LINE: + case css::awt::Key::DELETE_TO_END_OF_LINE: + case KEY_BACKSPACE: + case KEY_DELETE: + m_aChangedIdle.Stop(); + break; + default: + m_aChangedIdle.Start(); //launch this to happen on idle after cursor position will have been set + break; + } } void AutocompleteEdit::AddEntry( const OUString& rEntry ) diff --git a/fpicker/source/office/autocmpledit.hxx b/fpicker/source/office/autocmpledit.hxx index bfb2ee096a63..3eb79eb14aa6 100644 --- a/fpicker/source/office/autocmpledit.hxx +++ b/fpicker/source/office/autocmpledit.hxx @@ -22,7 +22,9 @@ private: std::vector<OUString> m_aMatching; Idle m_aChangedIdle; Link<weld::Entry&, void> m_aChangeHdl; + sal_uInt16 m_nLastCharCode; + DECL_LINK(KeyInputHdl, const KeyEvent&, bool); DECL_LINK(ChangedHdl, weld::Entry&, void); DECL_LINK(TryAutoComplete, Timer*, void); diff --git a/sfx2/source/appl/newhelp.cxx b/sfx2/source/appl/newhelp.cxx index 9312a83ccd04..b3b7483bb29a 100644 --- a/sfx2/source/appl/newhelp.cxx +++ b/sfx2/source/appl/newhelp.cxx @@ -475,6 +475,7 @@ IMPL_LINK_NOARG(IndexTabPage_Impl, EntryChangeHdl, weld::Entry&, void) case css::awt::Key::DELETE_TO_END_OF_LINE: case KEY_BACKSPACE: case KEY_DELETE: + aAutoCompleteIdle.Stop(); break; default: aAutoCompleteIdle.Start(); commit 8dd441eea4d190594deeb7c52bfb20be45b549fc Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Thu Apr 14 09:13:35 2022 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Apr 25 11:12:36 2022 +0200 tdf#148197 gtk_tree_row_reference_new_proxy warning on docking navigator Gtk-CRITICAL **: 09:05:11.124: gtk_tree_row_reference_new_proxy: assertion 'path->depth > 0' failed from TreeView::set_cursor(-1) gtk_tree_view_set_cursor is ok (and documented as such) with an "invalid" path to unset the cursor, but there isn't the same for gtk_tree_view_scroll_to_cell, though there null is docs as acceptable. Change-Id: I11b94ba997fbbd2f31031d9e73765ea1882ad9ae Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132872 Tested-by: Jenkins Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com> diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index 2732ea7dd0ad..9c6327d7c4f7 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -14552,7 +14552,7 @@ public: virtual void set_cursor(int pos) override { disable_notify_events(); - GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1); + GtkTreePath* path = pos != -1 ? gtk_tree_path_new_from_indices(pos, -1) : nullptr; gtk_tree_view_scroll_to_cell(m_pTreeView, path, nullptr, false, 0, 0); gtk_tree_view_set_cursor(m_pTreeView, path, nullptr, false); gtk_tree_path_free(path);