include/svl/srchitem.hxx                |    3 +++
 sd/qa/uitest/findReplace/findReplace.py |    7 +++----
 sd/source/ui/view/Outliner.cxx          |   12 ++++++++++++
 svl/source/items/srchitem.cxx           |   21 ++++++++++++++++-----
 4 files changed, 34 insertions(+), 9 deletions(-)

New commits:
commit 0e1d4fec1b701c334c1e320f4d58c939aaa82910
Author:     Justin Luth <[email protected]>
AuthorDate: Wed Feb 2 10:44:23 2022 +0200
Commit:     Xisco Fauli <[email protected]>
CommitDate: Tue Feb 8 09:35:26 2022 +0100

    tdf#145868 sd replace: if search changes, restart find/replace
    
    REPLACE is really a replaceAndFind instead of a findAndReplace.
    Thus, when you changed your search parameter and did a replace,
    it replaced the previously searched for item, and then found the
    first instance of the new search parameter.
    That of course is just wrong.
    
    So make sure to verify that the previous search
    matches the current search competely.
    However, that doesn't mean that the entire searchItem matches,
    since we don't want to restart the search just
    because the replace parameter changed.
    
    In my testing, this wasn't an issue for REPLACE_ALL.
    So the only time we need to worry about the last search
    result is in a replace once situation.
    
    P.S. This commit exposed that mpSearchItem can point
    to a destructed SvxSearchItem, so this patches unit test
    will crash if the other 7.4 commit is missing.
    
    Change-Id: I7be14d64534018718145c6ac5f8629ff5f2e5611
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129385
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <[email protected]>
    Reviewed-by: Tomaž Vajngerl <[email protected]>
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129630

diff --git a/include/svl/srchitem.hxx b/include/svl/srchitem.hxx
index c7f7381f77c6..7aa403211ed6 100644
--- a/include/svl/srchitem.hxx
+++ b/include/svl/srchitem.hxx
@@ -108,6 +108,9 @@ public:
     // ConfigItem
     virtual void            Notify( const css::uno::Sequence< OUString > 
&rPropertyNames ) override;
 
+    bool equalsIgnoring(const SvxSearchItem& rSItem, bool bIgnoreReplace,
+                        bool bIgnoreCommand) const;
+
             SvxSearchCmd    GetCommand() const { return m_nCommand; }
             void            SetCommand(SvxSearchCmd nNewCommand) { m_nCommand 
= nNewCommand; }
 
diff --git a/sd/qa/uitest/findReplace/findReplace.py 
b/sd/qa/uitest/findReplace/findReplace.py
index 35afe95d43ee..82e1a4990872 100644
--- a/sd/qa/uitest/findReplace/findReplace.py
+++ b/sd/qa/uitest/findReplace/findReplace.py
@@ -83,8 +83,8 @@ class findReplace(UITestCase):
 
                 self.assertEqual("Replace first first", 
impress_doc.DrawPages[0].getByIndex(1).String)
                 self.assertEqual("second", 
impress_doc.DrawPages[1].getByIndex(1).String)
-                # FIXME: tdf#145868
-                self.assertEqual("Replace", 
impress_doc.DrawPages[2].getByIndex(1).String)
+                # tdf#145868 - Third was search for earlier, but never should 
have been replaced
+                self.assertEqual("Third", 
impress_doc.DrawPages[2].getByIndex(1).String)
                 self.assertEqual("Text size 16", 
impress_doc.DrawPages[3].getByIndex(1).String)
 
                 replaceterm = xDialog.getChild("replaceterm")
@@ -100,8 +100,7 @@ class findReplace(UITestCase):
             # AssertionError: 'Replace aaa aaa' != 'Replace first first'
             self.assertEqual("Replace aaa aaa", 
impress_doc.DrawPages[0].getByIndex(1).String)
             self.assertEqual("second", 
impress_doc.DrawPages[1].getByIndex(1).String)
-            # FIXME: tdf#145868
-            self.assertEqual("Replace", 
impress_doc.DrawPages[2].getByIndex(1).String)
+            self.assertEqual("Third", 
impress_doc.DrawPages[2].getByIndex(1).String)
             self.assertEqual("Text size 16", 
impress_doc.DrawPages[3].getByIndex(1).String)
 
 # vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx
index 23353ba87c82..26c8347d5bf5 100644
--- a/sd/source/ui/view/Outliner.cxx
+++ b/sd/source/ui/view/Outliner.cxx
@@ -425,6 +425,18 @@ bool SdOutliner::StartSearchAndReplace (const 
SvxSearchItem* pSearchItem)
     SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::Empty);
 
     mpDrawDocument->GetDocSh()->SetWaitCursor( true );
+
+    // Since REPLACE is really a replaceAndSearchNext instead of a 
searchAndReplace,
+    // make sure that the search portion has not changed since the last FIND.
+    if (!mbPrepareSpellingPending && mpSearchItem
+        && pSearchItem->GetCommand() == SvxSearchCmd::REPLACE
+        && !mpSearchItem->equalsIgnoring(*pSearchItem, /*bIgnoreReplace=*/true,
+            /*bIgnoreCommand=*/true))
+    {
+        EndSpelling();
+        mbPrepareSpellingPending = true;
+    }
+
     if (mbPrepareSpellingPending)
         PrepareSpelling();
     sd::ViewShellBase* pBase = getViewShellBase();
diff --git a/svl/source/items/srchitem.cxx b/svl/source/items/srchitem.cxx
index 24a46e28bd0b..1554f55efd3e 100644
--- a/svl/source/items/srchitem.cxx
+++ b/svl/source/items/srchitem.cxx
@@ -235,12 +235,13 @@ SvxSearchItem* SvxSearchItem::Clone( SfxItemPool *) const
 }
 
 //! used below
-static bool equalsWithoutLocale( const i18nutil::SearchOptions2& rItem1, const 
i18nutil::SearchOptions2& rItem2 )
+static bool equalsWithoutLocaleOrReplace(const i18nutil::SearchOptions2& 
rItem1,
+                                         const i18nutil::SearchOptions2& 
rItem2)
 {
     return rItem1.algorithmType         == rItem2.algorithmType &&
            rItem1.searchFlag            == rItem2.searchFlag    &&
            rItem1.searchString          == rItem2.searchString  &&
-           rItem1.replaceString         == rItem2.replaceString &&
+           //rItem1.replaceString       == rItem2.replaceString &&
            //rItem1.Locale              == rItem2.Locale        &&
            rItem1.changedChars          == rItem2.changedChars  &&
            rItem1.deletedChars          == rItem2.deletedChars  &&
@@ -255,8 +256,18 @@ bool SvxSearchItem::operator==( const SfxPoolItem& rItem ) 
const
 {
     assert(SfxPoolItem::operator==(rItem));
     const SvxSearchItem &rSItem = static_cast<const SvxSearchItem &>(rItem);
-    return ( m_nCommand       == rSItem.m_nCommand )        &&
-           ( m_bBackward      == rSItem.m_bBackward )       &&
+    return equalsIgnoring(rSItem, /*bIgnoreReplace=*/false, 
/*bIgnoreCommand=*/false);
+}
+
+bool SvxSearchItem::equalsIgnoring(const SvxSearchItem& rSItem, bool 
bIgnoreReplace,
+                                   bool bIgnoreCommand) const
+{
+    if (!bIgnoreReplace && m_aSearchOpt.replaceString != 
rSItem.m_aSearchOpt.replaceString)
+        return false;
+    if (!bIgnoreCommand && m_nCommand != rSItem.m_nCommand)
+        return false;
+
+    return ( m_bBackward      == rSItem.m_bBackward )       &&
            ( m_bPattern       == rSItem.m_bPattern )        &&
            ( m_bContent       == rSItem.m_bContent )        &&
            ( m_eFamily        == rSItem.m_eFamily )         &&
@@ -267,7 +278,7 @@ bool SvxSearchItem::operator==( const SfxPoolItem& rItem ) 
const
            ( m_nCellType      == rSItem.m_nCellType )       &&
            ( m_nAppFlag       == rSItem.m_nAppFlag )        &&
            ( m_bAsianOptions  == rSItem.m_bAsianOptions )   &&
-           ( equalsWithoutLocale(m_aSearchOpt,rSItem.m_aSearchOpt )) &&
+           ( equalsWithoutLocaleOrReplace(m_aSearchOpt, rSItem.m_aSearchOpt )) 
&&
            ( m_bNotes         == rSItem.m_bNotes );
 }
 

Reply via email to