sw/qa/extras/uiwriter/data/tdf147583_backwardSearch.odt |binary
 sw/qa/extras/uiwriter/uiwriter7.cxx                     |   31 +++++++
 sw/source/core/crsr/findtxt.cxx                         |   67 ++++++++--------
 3 files changed, 66 insertions(+), 32 deletions(-)

New commits:
commit 8b58007fc5a619012b58a1f8d8731a753bc1c40d
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Fri Mar 15 20:01:39 2024 -0400
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Mar 18 14:25:39 2024 +0100

    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>

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/uiwriter7.cxx 
b/sw/qa/extras/uiwriter/uiwriter7.cxx
index fe873d8cfb3b..898ed6dcd1b5 100644
--- a/sw/qa/extras/uiwriter/uiwriter7.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter7.cxx
@@ -358,6 +358,37 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTextSearch)
                          pCursor->GetPointNode().GetTextNode()->GetText());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf147583_backwardSearch)
+{
+    createSwDoc("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_FIXTURE(SwUiWriterTest7, testTdf69282)
 {
     createSwDoc();
diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx
index 1edde20d7ccc..930ac7926ce2 100644
--- a/sw/source/core/crsr/findtxt.cxx
+++ b/sw/source/core/crsr/findtxt.cxx
@@ -727,7 +727,6 @@ bool DoSearch(SwPaM & rSearchPam,
         SwRootFrame const*const pLayout, SwPaM& rPam)
 {
     bool bFound = false;
-    SwPosition& rPtPos = *rPam.GetPoint();
     OUString sCleanStr;
     std::vector<AmbiguousIndex> aFltArr;
     LanguageType eLastLang = LANGUAGE_SYSTEM;
@@ -869,39 +868,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() = *rPam.GetPoint();
+    if (pLayout)
     {
-        *rSearchPam.GetPoint() = *rPam.GetPoint();
-        if (pLayout)
-        {
-            *rSearchPam.GetPoint() = pFrame->MapViewToModelPos(
-                bChkParaEnd ? nTextLen.GetFrameIndex() : TextFrameIndex(0));
-        }
-        else
-        {
-            rSearchPam.GetPoint()->SetContent( bChkParaEnd ? 
nTextLen.GetModelIndex() : 0 );
-        }
-        rSearchPam.SetMark();
-        const SwNode *const pSttNd = bSrchForward
-            ? &rSearchPam.GetPoint()->GetNode() // end of the frame
-            : &rPtPos.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 != &rPtPos.GetNode()) &&
-            rSearchPam.Move(fnMoveForward, GoInContent) &&
-            (!bSrchForward || pSttNd != &rSearchPam.GetPoint()->GetNode()) &&
-            SwNodeOffset(1) == abs(rSearchPam.GetPoint()->GetNodeIndex() -
-                                   rSearchPam.GetMark()->GetNodeIndex()))
-        {
-            // 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()->SetContent(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 (!rPam.ContainsPosition(*rSearchPam.GetPoint()))
+        return false;
+
+    if (SwNodeOffset(1) == abs(rSearchPam.GetPoint()->GetNodeIndex() -
+                               rSearchPam.GetMark()->GetNodeIndex()))
+    {
+        if (bChkEmptyPara && !bSrchForward && 
rSearchPam.GetPoint()->GetContentIndex())
+            return false; // the length is not zero - there is content here
+
+        return true;
+    }
+
+    return false;
 }
 
 namespace {

Reply via email to