sw/qa/extras/uiwriter/data/tdf147583_backwardSearch.odt |binary sw/qa/extras/uiwriter/uiwriter4.cxx | 38 +++++++ sw/source/core/crsr/findtxt.cxx | 86 ++++++++++------ 3 files changed, 92 insertions(+), 32 deletions(-)
New commits: commit 7a7df4c0ea28e460ac6781d54f7da95a19355dde Author: Justin Luth <justin.l...@collabora.com> AuthorDate: Tue Mar 19 15:28:32 2024 -0400 Commit: Aron Budea <aron.bu...@collabora.com> CommitDate: Thu Mar 28 22:46:56 2024 +1030 related tdf#147583 sw find: fix backwards search for string at end of para Prior to this fix, it was finding every single character in the document when searching for ".$". Interestingly, the unit test worked even before the patch. Not sure how that could be possible... make CppunitTest_sw_uiwriter7 \ CPPUNIT_TEST_NAME=testTdf147583_backwardSearch Change-Id: I20779898c01736eb39ecd7db7d66c2c24e4358b0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165037 Tested-by: Jenkins Reviewed-by: Justin Luth <jl...@mail.com> Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> (cherry picked from commit e830394c068c229bb840018f2f0e8810da6a1487) (cherry picked from commit 5a78a44c486a2a49532d32a8ef53b2f2b4833ffe) diff --git a/sw/qa/extras/uiwriter/uiwriter4.cxx b/sw/qa/extras/uiwriter/uiwriter4.cxx index e9e6eb2bd148..7c2a2f930a09 100644 --- a/sw/qa/extras/uiwriter/uiwriter4.cxx +++ b/sw/qa/extras/uiwriter/uiwriter4.cxx @@ -4193,6 +4193,11 @@ void SwUiWriterTest4::testTdf147583_backwardSearch() xIndex.set(xSearch->findAll(xSearchDes), uno::UNO_SET_THROW); // should actually be 10 (including the empty para with the comment marker, and the last para) CPPUNIT_ASSERT_EQUAL(sal_Int32(8), xIndex->getCount()); + + xSearchDes->setSearchString(".$"); // any last character (not just full-stops) in a paragraph + xIndex.set(xSearch->findAll(xSearchDes), uno::UNO_SET_THROW); + // should be one for every non-empty paragraph + CPPUNIT_ASSERT_EQUAL(sal_Int32(14), xIndex->getCount()); } CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest4); diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx index 1f2d130f7147..06f72ea06306 100644 --- a/sw/source/core/crsr/findtxt.cxx +++ b/sw/source/core/crsr/findtxt.cxx @@ -734,6 +734,25 @@ bool DoSearch(SwPaM & rSearchPam, SwTextNode const*const pNode, SwTextFrame const*const pFrame, SwRootFrame const*const pLayout, SwPaM* pPam) { + if (bRegSearch && rSearchOpt.searchString.endsWith("$")) + { + bool bAlwaysSearchingForEndOfPara = true; + sal_Int32 nIndex = 0; + while ((nIndex = rSearchOpt.searchString.indexOf("|", nIndex)) != -1) + { + if (!nIndex || rSearchOpt.searchString[nIndex - 1] != '$') + { + bAlwaysSearchingForEndOfPara = false; + break; + } + ++nIndex; + } + // when searching for something at the end of the paragraph, the para end must be in range + const AmbiguousIndex& rParaEnd = bSrchForward ? nEnd : nStart; + if (bAlwaysSearchingForEndOfPara && nTextLen.GetAnyIndex() != rParaEnd.GetAnyIndex()) + return false; + } + bool bFound = false; OUString sCleanStr; std::vector<AmbiguousIndex> aFltArr; commit d8ff9e1e259f7b11940f76d1055bce3dd44f0844 Author: Justin Luth <justin.l...@collabora.com> AuthorDate: Fri Mar 15 20:01:39 2024 -0400 Commit: Aron Budea <aron.bu...@collabora.com> CommitDate: Thu Mar 28 22:33:03 2024 +1030 tdf#147583 sw find: fix backwards search for emptyPara/endOfPara A comment added 10 years ago thought that it had never worked. The very last paragraph end cannot be selected manually, and so of course it can't work in find either. It didn't work earlier either. Everything goes ballistic if searching inside comments, but that would be handled elsewhere anyway I guess. It didn't work earlier either. Keeping the search "inside the selection" didn't work earlier either. That should be fixed now. make CppunitTest_sw_uiwriter7 \ CPPUNIT_TEST_NAME=testTdf147583_backwardSearch Change-Id: I48a72084d277b8c270255de9296a2743162937cf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164892 Tested-by: Jenkins Reviewed-by: Justin Luth <jl...@mail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164982 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> (cherry picked from commit 2f5b9916baaf0017ece84bf867a9e9acfe86d61a) (cherry picked from commit 098a2536d08a18981032273b55e287bd231dc58e) diff --git a/sw/qa/extras/uiwriter/data/tdf147583_backwardSearch.odt b/sw/qa/extras/uiwriter/data/tdf147583_backwardSearch.odt new file mode 100644 index 000000000000..9bfde3bfaa6b Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf147583_backwardSearch.odt differ diff --git a/sw/qa/extras/uiwriter/uiwriter4.cxx b/sw/qa/extras/uiwriter/uiwriter4.cxx index 803c4821e4a5..e9e6eb2bd148 100644 --- a/sw/qa/extras/uiwriter/uiwriter4.cxx +++ b/sw/qa/extras/uiwriter/uiwriter4.cxx @@ -293,6 +293,7 @@ public: void testTdf143760WrapContourToOff(); void testHatchFill(); void testTdf62032ApplyStyle(); + void testTdf147583_backwardSearch(); CPPUNIT_TEST_SUITE(SwUiWriterTest4); CPPUNIT_TEST(testTdf96515); @@ -419,6 +420,7 @@ public: CPPUNIT_TEST(testTdf143760WrapContourToOff); CPPUNIT_TEST(testHatchFill); CPPUNIT_TEST(testTdf62032ApplyStyle); + CPPUNIT_TEST(testTdf147583_backwardSearch); CPPUNIT_TEST_SUITE_END(); }; @@ -4162,6 +4164,37 @@ void SwUiWriterTest4::testTdf62032ApplyStyle() getProperty<OUString>(getParagraph(2), "ListLabelString").trim()); } +void SwUiWriterTest4::testTdf147583_backwardSearch() +{ + createSwDoc(DATA_DIRECTORY, "tdf147583_backwardSearch.odt"); + uno::Reference<util::XSearchable> xSearch(mxComponent, uno::UNO_QUERY); + uno::Reference<util::XSearchDescriptor> xSearchDes = xSearch->createSearchDescriptor(); + uno::Reference<util::XPropertyReplace> xProp(xSearchDes, uno::UNO_QUERY); + + uno::Reference<container::XIndexAccess> xIndex; + const sal_Int32 nParas = getParagraphs(); + + //specifying the search attributes + uno::Reference<beans::XPropertySet> xPropSet(xSearchDes, uno::UNO_QUERY_THROW); + xSearchDes->setPropertyValue("SearchRegularExpression", uno::Any(true)); // regex + xSearchDes->setSearchString("$"); // the end of the paragraph pilcrow marker + + // xSearchDes->setPropertyValue("SearchBackwards", uno::Any(false)); + // xIndex.set(xSearch->findAll(xSearchDes), uno::UNO_SET_THROW); + // // all paragraphs (including the unselected last one) should be found + // CPPUNIT_ASSERT_EQUAL(nParas, xIndex->getCount()); + + xSearchDes->setPropertyValue("SearchBackwards", uno::Any(true)); + xIndex.set(xSearch->findAll(xSearchDes), uno::UNO_SET_THROW); + // all paragraphs (except the troublesome last one) are found + CPPUNIT_ASSERT_EQUAL(nParas - 1, xIndex->getCount()); + + xSearchDes->setSearchString("^$"); // empty paragraphs + xIndex.set(xSearch->findAll(xSearchDes), uno::UNO_SET_THROW); + // should actually be 10 (including the empty para with the comment marker, and the last para) + CPPUNIT_ASSERT_EQUAL(sal_Int32(8), xIndex->getCount()); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest4); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx index 6e29c3614e55..1f2d130f7147 100644 --- a/sw/source/core/crsr/findtxt.cxx +++ b/sw/source/core/crsr/findtxt.cxx @@ -735,7 +735,6 @@ bool DoSearch(SwPaM & rSearchPam, SwRootFrame const*const pLayout, SwPaM* pPam) { bool bFound = false; - SwNodeIndex& rNdIdx = pPam->GetPoint()->nNode; OUString sCleanStr; std::vector<AmbiguousIndex> aFltArr; LanguageType eLastLang = LANGUAGE_SYSTEM; @@ -876,39 +875,43 @@ bool DoSearch(SwPaM & rSearchPam, if ( bFound ) return true; - else if ((bChkEmptyPara && !nStart.GetAnyIndex() && !nTextLen.GetAnyIndex()) - || bChkParaEnd) + + if (!bChkEmptyPara && !bChkParaEnd) + return false; + + if (bChkEmptyPara && bSrchForward && nTextLen.GetAnyIndex()) + return false; // the length is not zero - there is content here + + // move to the end (or start) of the paragraph + *rSearchPam.GetPoint() = *pPam->GetPoint(); + if (pLayout) { - *rSearchPam.GetPoint() = *pPam->GetPoint(); - if (pLayout) - { - *rSearchPam.GetPoint() = pFrame->MapViewToModelPos( - bChkParaEnd ? nTextLen.GetFrameIndex() : TextFrameIndex(0)); - } - else - { - rSearchPam.GetPoint()->nContent = bChkParaEnd ? nTextLen.GetModelIndex() : 0; - } - rSearchPam.SetMark(); - const SwNode *const pSttNd = bSrchForward - ? &rSearchPam.GetPoint()->nNode.GetNode() // end of the frame - : &rNdIdx.GetNode(); // keep the bug as-is for now... - /* FIXME: this condition does not work for !bSrchForward backward - * search, it probably never did. (pSttNd != &rNdIdx.GetNode()) - * is never true in this case. */ - if( (bSrchForward || pSttNd != &rNdIdx.GetNode()) && - rSearchPam.Move(fnMoveForward, GoInContent) && - (!bSrchForward || pSttNd != &rSearchPam.GetPoint()->nNode.GetNode()) && - SwNodeOffset(1) == abs(rSearchPam.GetPoint()->nNode.GetIndex() - - rSearchPam.GetMark()->nNode.GetIndex())) - { - // if backward search, switch point and mark - if( !bSrchForward ) - rSearchPam.Exchange(); - return true; - } + *rSearchPam.GetPoint() = pFrame->MapViewToModelPos( + bSrchForward ? nTextLen.GetFrameIndex() : TextFrameIndex(0)); } - return bFound; + else + { + rSearchPam.GetPoint()->nContent = bSrchForward ? nTextLen.GetModelIndex() : 0; + } + rSearchPam.SetMark(); + + if (!rSearchPam.Move(fnMove, GoInContent)) + return false; // at start or end of the document + + // selection must not be outside of the search area + if (!pPam->ContainsPosition(*rSearchPam.GetPoint())) + return false; + + if (SwNodeOffset(1) == abs(rSearchPam.GetPoint()->nNode.GetIndex() - + rSearchPam.GetMark()->nNode.GetIndex())) + { + if (bChkEmptyPara && !bSrchForward && rSearchPam.GetPoint()->nContent.GetIndex()) + return false; // the length is not zero - there is content here + + return true; + } + + return false; } namespace {