From e0f28fc4e1e78205976a479109d6b7f663bb4fc6 Mon Sep 17 00:00:00 2001
From: Marek Roszko <mark.roszko@gmail.com>
Date: Thu, 4 Aug 2022 22:40:38 -0400
Subject: [PATCH] Replace wxFindReplaceData with our own container

By dropping the flags, we can be strict with options.
Also it makes future usage of search functionality a little more "UI" framework independent
---
 common/eda_draw_frame.cpp                     | 20 ++---
 common/eda_item.cpp                           | 24 +++---
 common/eda_text.cpp                           |  2 +-
 common/settings/app_settings.cpp              |  9 ++-
 eeschema/dialogs/dialog_schematic_find.cpp    | 66 ++++++++--------
 eeschema/dialogs/dialog_schematic_find.h      |  4 +-
 .../dialogs/dialog_schematic_find_base.fbp    |  9 ++-
 eeschema/eeschema_config.cpp                  | 13 ++++
 eeschema/eeschema_settings.cpp                | 14 ++++
 eeschema/eeschema_settings.h                  | 11 +++
 eeschema/lib_textbox.h                        |  4 +-
 eeschema/sch_edit_frame.cpp                   |  7 +-
 eeschema/sch_field.cpp                        | 36 +++++++--
 eeschema/sch_field.h                          |  4 +-
 eeschema/sch_marker.cpp                       |  2 +-
 eeschema/sch_marker.h                         |  2 +-
 eeschema/sch_pin.cpp                          |  9 ++-
 eeschema/sch_pin.h                            |  4 +-
 eeschema/sch_sheet.cpp                        |  2 +-
 eeschema/sch_sheet.h                          |  2 +-
 eeschema/sch_sheet_pin.h                      |  4 +-
 eeschema/sch_symbol.cpp                       |  2 +-
 eeschema/sch_symbol.h                         |  2 +-
 eeschema/sch_text.h                           |  4 +-
 eeschema/sch_textbox.h                        |  4 +-
 eeschema/tools/sch_editor_control.cpp         | 54 ++++++++-----
 eeschema/tools/sch_editor_control.h           |  2 +-
 include/eda_draw_frame.h                      |  4 +-
 include/eda_item.h                            | 10 +--
 include/eda_search_data.h                     | 76 +++++++++++++++++++
 include/eda_text.h                            |  6 +-
 include/settings/app_settings.h               |  8 +-
 pcbnew/dialogs/dialog_find.cpp                | 18 ++---
 pcbnew/fp_text.h                              |  2 +-
 pcbnew/fp_textbox.h                           |  2 +-
 pcbnew/netinfo.h                              |  2 +-
 pcbnew/netinfo_item.cpp                       |  2 +-
 pcbnew/pcb_marker.h                           |  2 +-
 pcbnew/pcb_text.h                             |  2 +-
 pcbnew/pcb_textbox.h                          |  2 +-
 pcbnew/zone.h                                 |  2 +-
 41 files changed, 313 insertions(+), 141 deletions(-)
 create mode 100644 include/eda_search_data.h

diff --git a/common/eda_draw_frame.cpp b/common/eda_draw_frame.cpp
index 4e2f894210..c63202c7dc 100644
--- a/common/eda_draw_frame.cpp
+++ b/common/eda_draw_frame.cpp
@@ -106,7 +106,7 @@ EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
     m_msgFrameHeight      = EDA_MSG_PANEL::GetRequiredHeight( this );
     m_userUnits           = EDA_UNITS::MILLIMETRES;
     m_polarCoords         = false;
-    m_findReplaceData     = new wxFindReplaceData( wxFR_DOWN );
+    m_findReplaceData     = std::make_unique<EDA_SEARCH_DATA>();
 
     m_auimgr.SetFlags( wxAUI_MGR_DEFAULT );
 
@@ -191,8 +191,6 @@ EDA_DRAW_FRAME::~EDA_DRAW_FRAME()
     delete m_currentScreen;
     m_currentScreen = nullptr;
 
-    delete m_findReplaceData;
-
     m_auimgr.UnInit();
 
     ReleaseFile();
@@ -648,9 +646,12 @@ void EDA_DRAW_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg )
 
     m_galDisplayOptions.ReadConfig( *cmnCfg, *window, this );
 
-    m_findReplaceData->SetFlags( aCfg->m_FindReplace.flags );
-    m_findReplaceData->SetFindString( aCfg->m_FindReplace.find_string );
-    m_findReplaceData->SetReplaceString( aCfg->m_FindReplace.replace_string );
+    m_findReplaceData->findString = aCfg->m_FindReplace.find_string;
+    m_findReplaceData->replaceString = aCfg->m_FindReplace.replace_string;
+    m_findReplaceData->matchMode =
+            static_cast<EDA_SEARCH_MATCH_MODE>( aCfg->m_FindReplace.match_mode );
+    m_findReplaceData->matchCase = aCfg->m_FindReplace.match_case;
+    m_findReplaceData->searchAndReplace = aCfg->m_FindReplace.search_and_replace;
 
     for( auto& s : aCfg->m_FindReplace.find_history )
         m_findStringHistoryList.Add( s );
@@ -672,9 +673,10 @@ void EDA_DRAW_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
 
     m_galDisplayOptions.WriteConfig( *window );
 
-    aCfg->m_FindReplace.flags = m_findReplaceData->GetFlags();
-    aCfg->m_FindReplace.find_string = m_findReplaceData->GetFindString();
-    aCfg->m_FindReplace.replace_string = m_findReplaceData->GetReplaceString();
+    aCfg->m_FindReplace.search_and_replace = m_findReplaceData->searchAndReplace;
+
+    aCfg->m_FindReplace.find_string = m_findReplaceData->findString;
+    aCfg->m_FindReplace.replace_string = m_findReplaceData->replaceString;
 
     aCfg->m_FindReplace.find_history.clear();
     aCfg->m_FindReplace.replace_history.clear();
diff --git a/common/eda_item.cpp b/common/eda_item.cpp
index 57a54a04e3..a089f65ca2 100644
--- a/common/eda_item.cpp
+++ b/common/eda_item.cpp
@@ -115,23 +115,22 @@ wxString EDA_ITEM::GetSelectMenuText( EDA_UNITS aUnits ) const
 }
 
 
-bool EDA_ITEM::Matches( const wxString& aText, const wxFindReplaceData& aSearchData ) const
+bool EDA_ITEM::Matches( const wxString& aText, const EDA_SEARCH_DATA& aSearchData ) const
 {
     wxString text = aText;
-    int      flags = aSearchData.GetFlags();
-    wxString searchText = aSearchData.GetFindString();
+    wxString searchText = aSearchData.findString;
 
     // Don't match if searching for replaceable item and the item doesn't support text replace.
-    if( ( flags & FR_SEARCH_REPLACE ) && !IsReplaceable() )
+    if( aSearchData.searchAndReplace && !IsReplaceable() )
         return false;
 
-    if( !( flags & wxFR_MATCHCASE ) )
+    if( !aSearchData.matchCase )
     {
         text.MakeUpper();
         searchText.MakeUpper();
     }
 
-    if( flags & wxFR_WHOLEWORD )
+    if( aSearchData.matchMode == EDA_SEARCH_MATCH_MODE::WHOLEWORD )
     {
         int ii = 0;
 
@@ -156,7 +155,7 @@ bool EDA_ITEM::Matches( const wxString& aText, const wxFindReplaceData& aSearchD
 
         return false;
     }
-    else if( flags & FR_MATCH_WILDCARD )
+    else if( aSearchData.matchMode == EDA_SEARCH_MATCH_MODE::WILDCARD )
     {
         return text.Matches( searchText );
     }
@@ -167,15 +166,14 @@ bool EDA_ITEM::Matches( const wxString& aText, const wxFindReplaceData& aSearchD
 }
 
 
-bool EDA_ITEM::Replace( const wxFindReplaceData& aSearchData, wxString& aText )
+bool EDA_ITEM::Replace( const EDA_SEARCH_DATA& aSearchData, wxString& aText )
 {
     wxString text = aText;
-    int      flags = aSearchData.GetFlags();
-    wxString searchText = aSearchData.GetFindString();
+    wxString searchText = aSearchData.findString;
     wxString result;
     bool     replaced = false;
 
-    if( flags & wxFR_MATCHCASE )
+    if( !aSearchData.matchCase )
     {
         text = text.Upper();
         searchText = searchText.Upper();
@@ -202,7 +200,7 @@ bool EDA_ITEM::Replace( const wxFindReplaceData& aSearchData, wxString& aText )
         bool startOK;
         bool endOK;
 
-        if( flags & wxFR_WHOLEWORD )
+        if( aSearchData.matchMode == EDA_SEARCH_MATCH_MODE::WHOLEWORD )
         {
             startOK = ( ii == 0 || !wxIsalnum( text.GetChar( ii - 1 ) ) );
             endOK = ( next == (int) text.length() || !wxIsalnum( text.GetChar( next ) ) );
@@ -215,7 +213,7 @@ bool EDA_ITEM::Replace( const wxFindReplaceData& aSearchData, wxString& aText )
 
         if( startOK && endOK )
         {
-            result += aSearchData.GetReplaceString();
+            result += aSearchData.replaceString;
             replaced = true;
             ii = next;
         }
diff --git a/common/eda_text.cpp b/common/eda_text.cpp
index 8a03f75317..d6381fdb97 100644
--- a/common/eda_text.cpp
+++ b/common/eda_text.cpp
@@ -315,7 +315,7 @@ int EDA_TEXT::GetEffectiveTextPenWidth( int aDefaultPenWidth ) const
 }
 
 
-bool EDA_TEXT::Replace( const wxFindReplaceData& aSearchData )
+bool EDA_TEXT::Replace( const EDA_SEARCH_DATA& aSearchData )
 {
     bool retval = EDA_ITEM::Replace( aSearchData, m_text );
 
diff --git a/common/settings/app_settings.cpp b/common/settings/app_settings.cpp
index e2713d8698..5dadb5738f 100644
--- a/common/settings/app_settings.cpp
+++ b/common/settings/app_settings.cpp
@@ -46,7 +46,14 @@ APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaV
     m_Graphics.canvas_type = EDA_DRAW_PANEL_GAL::GAL_FALLBACK;
 
     // Build parameters list:
-    m_params.emplace_back( new PARAM<int>( "find_replace.flags", &m_FindReplace.flags, 1 ) );
+    m_params.emplace_back(
+            new PARAM<int>( "find_replace.match_mode", &m_FindReplace.match_mode, 0 ) );
+
+    m_params.emplace_back(
+            new PARAM<bool>( "find_replace.match_case", &m_FindReplace.match_case, false ) );
+
+    m_params.emplace_back( new PARAM<bool>( "find_replace.search_and_replace",
+                                            &m_FindReplace.search_and_replace, false ) );
 
     m_params.emplace_back( new PARAM<wxString>( "find_replace.find_string",
             &m_FindReplace.find_string, "" ) );
diff --git a/eeschema/dialogs/dialog_schematic_find.cpp b/eeschema/dialogs/dialog_schematic_find.cpp
index d1dd725c37..b909d39ad1 100644
--- a/eeschema/dialogs/dialog_schematic_find.cpp
+++ b/eeschema/dialogs/dialog_schematic_find.cpp
@@ -28,7 +28,7 @@
 #include <tools/sch_editor_control.h>
 
 
-DIALOG_SCH_FIND::DIALOG_SCH_FIND( SCH_EDIT_FRAME* aParent, wxFindReplaceData* aData,
+DIALOG_SCH_FIND::DIALOG_SCH_FIND( SCH_EDIT_FRAME* aParent, SCH_SEARCH_DATA* aData,
                                   const wxPoint& aPosition, const wxSize& aSize, int aStyle ) :
     DIALOG_SCH_FIND_BASE( aParent, wxID_ANY, _( "Find" ), aPosition, aSize,
                           wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | aStyle ),
@@ -50,20 +50,15 @@ DIALOG_SCH_FIND::DIALOG_SCH_FIND( SCH_EDIT_FRAME* aParent, wxFindReplaceData* aD
         m_checkWildcardMatch->Show( false );  // Wildcard replace is not implemented.
     }
 
-    int flags = m_findReplaceData->GetFlags();
-    m_radioForward->SetValue( flags & wxFR_DOWN );
-    m_radioBackward->SetValue( ( flags & wxFR_DOWN ) == 0 );
-    m_checkMatchCase->SetValue( flags & wxFR_MATCHCASE );
-    m_checkWholeWord->SetValue( flags & wxFR_WHOLEWORD );
+    m_checkMatchCase->SetValue( m_findReplaceData->matchCase );
+    m_checkWholeWord->SetValue( m_findReplaceData->matchMode == EDA_SEARCH_MATCH_MODE::WHOLEWORD );
+    m_checkWildcardMatch->SetValue( m_findReplaceData->matchMode
+                                    == EDA_SEARCH_MATCH_MODE::WILDCARD );
 
-    /* Whole word and wild card searches are mutually exclusive. */
-    if( !( flags & wxFR_WHOLEWORD ) )
-        m_checkWildcardMatch->SetValue( flags & FR_MATCH_WILDCARD );
-
-    m_checkAllFields->SetValue( flags & FR_SEARCH_ALL_FIELDS );
-    m_checkReplaceReferences->SetValue( flags & FR_REPLACE_REFERENCES );
-    m_checkAllPins->SetValue( flags & FR_SEARCH_ALL_PINS );
-    m_checkCurrentSheetOnly->SetValue( flags & FR_CURRENT_SHEET_ONLY );
+    m_checkAllFields->SetValue( m_findReplaceData->searchAllFields );
+    m_checkReplaceReferences->SetValue( m_findReplaceData->replaceReferences );
+    m_checkAllPins->SetValue( m_findReplaceData->searchAllPins );
+    m_checkCurrentSheetOnly->SetValue( m_findReplaceData->searchCurrentSheetOnly );
 
     m_buttonFind->SetDefault();
     SetInitialFocus( m_comboFind );
@@ -139,14 +134,14 @@ void DIALOG_SCH_FIND::OnChar( wxKeyEvent& aEvent )
 
 void DIALOG_SCH_FIND::OnSearchForText( wxCommandEvent& aEvent )
 {
-    m_findReplaceData->SetFindString( m_comboFind->GetValue() );
+    m_findReplaceData->findString = m_comboFind->GetValue();
     m_findDirty = true;
 }
 
 
 void DIALOG_SCH_FIND::OnSearchForSelect( wxCommandEvent& aEvent )
 {
-    m_findReplaceData->SetFindString( m_comboFind->GetValue() );
+    m_findReplaceData->findString = m_comboFind->GetValue();
 
     // Move the search string to the top of the list if it isn't already there.
     if( aEvent.GetSelection() != 0 )
@@ -163,13 +158,13 @@ void DIALOG_SCH_FIND::OnSearchForSelect( wxCommandEvent& aEvent )
 
 void DIALOG_SCH_FIND::OnReplaceWithText( wxCommandEvent& aEvent )
 {
-    m_findReplaceData->SetReplaceString( m_comboReplace->GetValue() );
+    m_findReplaceData->replaceString = m_comboReplace->GetValue();
 }
 
 
 void DIALOG_SCH_FIND::OnReplaceWithSelect( wxCommandEvent& aEvent )
 {
-    m_findReplaceData->SetReplaceString( m_comboReplace->GetValue() );
+    m_findReplaceData->replaceString = m_comboReplace->GetValue();
 
     // Move the replace string to the top of the list if it isn't already there.
     if( aEvent.GetSelection() != 0 )
@@ -203,33 +198,38 @@ void DIALOG_SCH_FIND::OnOptions( wxCommandEvent& aEvent )
 void DIALOG_SCH_FIND::updateFlags()
 {
     // Rebuild the search flags in m_findReplaceData from dialog settings
-    int flags = 0;
-
-    if( m_radioForward->GetValue() )
-        flags |= wxFR_DOWN;
 
     if( m_checkMatchCase->GetValue() )
-        flags |= wxFR_MATCHCASE;
+        m_findReplaceData->matchCase = true;
+    else
+        m_findReplaceData->matchCase = false;
 
     if( m_checkWholeWord->GetValue() )
-        flags |= wxFR_WHOLEWORD;
-
-    if( m_checkWildcardMatch->IsShown() && m_checkWildcardMatch->GetValue() )
-        flags |= FR_MATCH_WILDCARD;
+        m_findReplaceData->matchMode = EDA_SEARCH_MATCH_MODE::WHOLEWORD;
+    else if( m_checkWildcardMatch->IsShown() && m_checkWildcardMatch->GetValue() )
+        m_findReplaceData->matchMode = EDA_SEARCH_MATCH_MODE::WILDCARD;
+    else
+        m_findReplaceData->matchMode = EDA_SEARCH_MATCH_MODE::PLAIN;
 
     if( m_checkAllFields->GetValue() )
-        flags |= FR_SEARCH_ALL_FIELDS;
+        m_findReplaceData->searchAllFields = true;
+    else
+        m_findReplaceData->searchAllFields = false;
 
     if( m_checkAllPins->GetValue() )
-        flags |= FR_SEARCH_ALL_PINS;
+        m_findReplaceData->searchAllPins = true;
+    else
+        m_findReplaceData->searchAllPins = false;
 
     if( m_checkCurrentSheetOnly->GetValue() )
-        flags |= FR_CURRENT_SHEET_ONLY;
+        m_findReplaceData->searchCurrentSheetOnly = true;
+    else
+        m_findReplaceData->searchCurrentSheetOnly = false;
 
     if( m_checkReplaceReferences->GetValue() )
-        flags |= FR_REPLACE_REFERENCES;
-
-    m_findReplaceData->SetFlags( flags );
+        m_findReplaceData->replaceReferences = true;
+    else
+        m_findReplaceData->replaceReferences = false;
 }
 
 
diff --git a/eeschema/dialogs/dialog_schematic_find.h b/eeschema/dialogs/dialog_schematic_find.h
index 63cbc7127d..95fbde1386 100644
--- a/eeschema/dialogs/dialog_schematic_find.h
+++ b/eeschema/dialogs/dialog_schematic_find.h
@@ -47,7 +47,7 @@ class SCH_EDITOR_CONTROL;
 class DIALOG_SCH_FIND : public DIALOG_SCH_FIND_BASE
 {
 public:
-    DIALOG_SCH_FIND( SCH_EDIT_FRAME* aParent, wxFindReplaceData* aData,
+    DIALOG_SCH_FIND( SCH_EDIT_FRAME* aParent, SCH_SEARCH_DATA* aData,
                      const wxPoint& aPosition = wxDefaultPosition,
                      const wxSize& aSize = wxDefaultSize, int aStyle = 0 );
 
@@ -80,7 +80,7 @@ protected:
 
     SCH_EDIT_FRAME*     m_frame;
     SCH_EDITOR_CONTROL* m_editorControl;
-    wxFindReplaceData*  m_findReplaceData;
+    SCH_SEARCH_DATA*    m_findReplaceData;
     bool                m_findDirty;
 
     DECLARE_NO_COPY_CLASS( DIALOG_SCH_FIND )
diff --git a/eeschema/dialogs/dialog_schematic_find_base.fbp b/eeschema/dialogs/dialog_schematic_find_base.fbp
index bb6a0e4675..5f3dec880c 100644
--- a/eeschema/dialogs/dialog_schematic_find_base.fbp
+++ b/eeschema/dialogs/dialog_schematic_find_base.fbp
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
 <wxFormBuilder_Project>
-    <FileVersion major="1" minor="15" />
+    <FileVersion major="1" minor="16" />
     <object class="Project" expanded="1">
         <property name="class_decoration"></property>
         <property name="code_generation">C++</property>
@@ -14,6 +14,7 @@
         <property name="file">dialog_schematic_find_base</property>
         <property name="first_id">1000</property>
         <property name="help_provider">none</property>
+        <property name="image_path_wrapper_function_name"></property>
         <property name="indent_with_spaces"></property>
         <property name="internationalize">1</property>
         <property name="name">dialog_sch_find</property>
@@ -25,6 +26,7 @@
         <property name="skip_php_events">1</property>
         <property name="skip_python_events">1</property>
         <property name="ui_table">UI</property>
+        <property name="use_array_enum">0</property>
         <property name="use_enum">0</property>
         <property name="use_microsoft_bom">0</property>
         <object class="Dialog" expanded="1">
@@ -50,6 +52,7 @@
             <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
             <property name="title">Find</property>
             <property name="tooltip"></property>
+            <property name="two_step_creation">0</property>
             <property name="window_extra_style"></property>
             <property name="window_name"></property>
             <property name="window_style"></property>
@@ -1072,6 +1075,7 @@
                                         <property name="aui_name"></property>
                                         <property name="aui_position"></property>
                                         <property name="aui_row"></property>
+                                        <property name="auth_needed">0</property>
                                         <property name="best_size"></property>
                                         <property name="bg"></property>
                                         <property name="bitmap"></property>
@@ -1145,6 +1149,7 @@
                                         <property name="aui_name"></property>
                                         <property name="aui_position"></property>
                                         <property name="aui_row"></property>
+                                        <property name="auth_needed">0</property>
                                         <property name="best_size"></property>
                                         <property name="bg"></property>
                                         <property name="bitmap"></property>
@@ -1219,6 +1224,7 @@
                                         <property name="aui_name"></property>
                                         <property name="aui_position"></property>
                                         <property name="aui_row"></property>
+                                        <property name="auth_needed">0</property>
                                         <property name="best_size"></property>
                                         <property name="bg"></property>
                                         <property name="bitmap"></property>
@@ -1293,6 +1299,7 @@
                                         <property name="aui_name"></property>
                                         <property name="aui_position"></property>
                                         <property name="aui_row"></property>
+                                        <property name="auth_needed">0</property>
                                         <property name="best_size"></property>
                                         <property name="bg"></property>
                                         <property name="bitmap"></property>
diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp
index 3945888bce..63e20ba6b2 100644
--- a/eeschema/eeschema_config.cpp
+++ b/eeschema/eeschema_config.cpp
@@ -138,6 +138,12 @@ void SCH_EDIT_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg )
 
     SCH_BASE_FRAME::LoadSettings( eeconfig() );
 
+    SCH_SEARCH_DATA* searchData = dynamic_cast<SCH_SEARCH_DATA*>( m_findReplaceData.get() );
+    searchData->replaceReferences = eeconfig()->m_FindReplaceExtra.replace_references;
+    searchData->searchAllFields = eeconfig()->m_FindReplaceExtra.search_all_fields;
+    searchData->searchAllPins = eeconfig()->m_FindReplaceExtra.search_all_pins;
+    searchData->searchCurrentSheetOnly = eeconfig()->m_FindReplaceExtra.search_current_sheet_only;
+
     GetRenderSettings()->m_ShowPinsElectricalType = false;
 }
 
@@ -156,6 +162,13 @@ void SCH_EDIT_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
         // Other parameters (hierarchy_panel_float_width, hierarchy_panel_float_height,
         // and hierarchy_panel_docked_width should have been updated when resizing the
         // hierarchy panel
+
+        SCH_SEARCH_DATA* searchData = dynamic_cast<SCH_SEARCH_DATA*>( m_findReplaceData.get() );
+        eeconfig()->m_FindReplaceExtra.replace_references = searchData->replaceReferences;
+        eeconfig()->m_FindReplaceExtra.search_all_fields = searchData->searchAllFields;
+        eeconfig()->m_FindReplaceExtra.search_all_pins = searchData->searchAllPins;
+        eeconfig()->m_FindReplaceExtra.search_current_sheet_only =
+                searchData->searchCurrentSheetOnly;
     }
 }
 
diff --git a/eeschema/eeschema_settings.cpp b/eeschema/eeschema_settings.cpp
index a32819b93c..6cb12484bc 100644
--- a/eeschema/eeschema_settings.cpp
+++ b/eeschema/eeschema_settings.cpp
@@ -61,6 +61,7 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
         m_Appearance(),
         m_AutoplaceFields(),
         m_Drawing(),
+        m_FindReplaceExtra(),
         m_Input(),
         m_PageSettings(),
         m_AnnotatePanel(),
@@ -198,6 +199,19 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
     m_params.emplace_back(new PARAM <int>( "drawing.junction_size_choice",
             &m_Drawing.junction_size_choice, 3 ) );
 
+    m_params.emplace_back( new PARAM<bool>( "find_replace.search_all_fields",
+                                            &m_FindReplaceExtra.search_all_fields, false ) );
+
+    m_params.emplace_back( new PARAM<bool>( "find_replace.search_all_pins",
+                                            &m_FindReplaceExtra.search_all_pins, false ) );
+
+    m_params.emplace_back( new PARAM<bool>( "find_replace.search_current_sheet_only",
+                                            &m_FindReplaceExtra.search_current_sheet_only,
+                                            false ) );
+
+    m_params.emplace_back( new PARAM<bool>( "find_replace.replace_references",
+                                            &m_FindReplaceExtra.replace_references, false ) );
+
     m_params.emplace_back( new PARAM<bool>( "input.drag_is_move",
             &m_Input.drag_is_move, false ) );
 
diff --git a/eeschema/eeschema_settings.h b/eeschema/eeschema_settings.h
index 81e0bdd938..44c37c4493 100644
--- a/eeschema/eeschema_settings.h
+++ b/eeschema/eeschema_settings.h
@@ -236,6 +236,15 @@ public:
         WINDOW_SETTINGS window;
     };
 
+    struct FIND_REPLACE_EXTRA
+    {
+        bool search_all_fields;
+        bool search_all_pins;
+        bool search_current_sheet_only;
+
+        bool replace_references;
+    };
+
     EESCHEMA_SETTINGS();
 
     virtual ~EESCHEMA_SETTINGS() {}
@@ -267,6 +276,8 @@ public:
 
     DRAWING m_Drawing;
 
+    FIND_REPLACE_EXTRA m_FindReplaceExtra;
+
     INPUT m_Input;
 
     PAGE_SETTINGS m_PageSettings;
diff --git a/eeschema/lib_textbox.h b/eeschema/lib_textbox.h
index d6ca1734e6..998d718eb9 100644
--- a/eeschema/lib_textbox.h
+++ b/eeschema/lib_textbox.h
@@ -67,12 +67,12 @@ public:
 
     bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override
     {
         return LIB_ITEM::Matches( GetText(), aSearchData );
     }
 
-    bool Replace( const wxFindReplaceData& aSearchData, void* aAuxData ) override
+    bool Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) override
     {
         return EDA_TEXT::Replace( aSearchData );
     }
diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp
index 57591c1ff6..549ef47f15 100644
--- a/eeschema/sch_edit_frame.cpp
+++ b/eeschema/sch_edit_frame.cpp
@@ -125,6 +125,8 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
 
     m_findReplaceDialog = nullptr;
 
+    m_findReplaceData = std::make_unique<SCH_SEARCH_DATA>();
+
     // Give an icon
     wxIcon icon;
     wxIconBundle icon_bundle;
@@ -1045,8 +1047,9 @@ void SCH_EDIT_FRAME::ShowFindReplaceDialog( bool aReplace )
     if( m_findReplaceDialog )
         m_findReplaceDialog->Destroy();
 
-    m_findReplaceDialog= new DIALOG_SCH_FIND( this, m_findReplaceData, wxDefaultPosition,
-                                              wxDefaultSize, aReplace ? wxFR_REPLACEDIALOG : 0 );
+    m_findReplaceDialog = new DIALOG_SCH_FIND(
+            this, static_cast<SCH_SEARCH_DATA*>( m_findReplaceData.get() ), wxDefaultPosition,
+            wxDefaultSize, aReplace ? wxFR_REPLACEDIALOG : 0 );
 
     m_findReplaceDialog->SetFindEntries( m_findStringHistoryList, findString );
     m_findReplaceDialog->SetReplaceEntries( m_replaceStringHistoryList );
diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp
index 6ebff7f45f..5d14f1048e 100644
--- a/eeschema/sch_field.cpp
+++ b/eeschema/sch_field.cpp
@@ -521,13 +521,24 @@ bool SCH_FIELD::IsVoid() const
 }
 
 
-bool SCH_FIELD::Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const
+bool SCH_FIELD::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
 {
+    bool searchHiddenFields = false;
+    bool searchAndReplace = false;
+    bool replaceReferences = false;
+
+    try
+    {
+        const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData ); // downcast
+        searchHiddenFields = schSearchData.searchAllFields;
+        searchAndReplace = schSearchData.searchAndReplace;
+        replaceReferences = schSearchData.replaceReferences;
+    }
+    catch( const std::bad_cast& e )
+    {
+    }
+
     wxString text = GetShownText();
-    int      flags = aSearchData.GetFlags();
-    bool     searchHiddenFields = flags & FR_SEARCH_ALL_FIELDS;
-    bool     searchAndReplace = flags & FR_SEARCH_REPLACE;
-    bool     replaceReferences = flags & FR_REPLACE_REFERENCES;
 
     wxLogTrace( traceFindItem, wxT( "    child item " )
                     + GetSelectMenuText( EDA_UNITS::MILLIMETRES ) );
@@ -589,8 +600,19 @@ bool SCH_FIELD::IsReplaceable() const
 }
 
 
-bool SCH_FIELD::Replace( const wxFindReplaceData& aSearchData, void* aAuxData )
+bool SCH_FIELD::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
 {
+    bool replaceReferences = false;
+
+    try
+    {
+        const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
+        replaceReferences = schSearchData.replaceReferences;
+    }
+    catch( const std::bad_cast& e )
+    {
+    }
+
     wxString text;
     bool     resolve = false;    // Replace in source text, not shown text
     bool     isReplaced = false;
@@ -604,7 +626,7 @@ bool SCH_FIELD::Replace( const wxFindReplaceData& aSearchData, void* aAuxData )
         case REFERENCE_FIELD:
             wxCHECK_MSG( aAuxData, false, wxT( "Need sheetpath to replace in refdes." ) );
 
-            if( !( aSearchData.GetFlags() & FR_REPLACE_REFERENCES ) )
+            if( !replaceReferences )
                 return false;
 
             text = parentSymbol->GetRef( (SCH_SHEET_PATH*) aAuxData );
diff --git a/eeschema/sch_field.h b/eeschema/sch_field.h
index b6e63bc723..5b59b336b7 100644
--- a/eeschema/sch_field.h
+++ b/eeschema/sch_field.h
@@ -194,9 +194,9 @@ public:
     {
     }
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override;
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override;
 
-    bool Replace( const wxFindReplaceData& aSearchData, void* aAuxData = nullptr ) override;
+    bool Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData = nullptr ) override;
 
     wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
     void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
diff --git a/eeschema/sch_marker.cpp b/eeschema/sch_marker.cpp
index bbbb7ef504..3531227507 100644
--- a/eeschema/sch_marker.cpp
+++ b/eeschema/sch_marker.cpp
@@ -173,7 +173,7 @@ void SCH_MARKER::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffse
 }
 
 
-bool SCH_MARKER::Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const
+bool SCH_MARKER::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
 {
     return SCH_ITEM::Matches( m_rcItem->GetErrorMessage(), aSearchData );
 }
diff --git a/eeschema/sch_marker.h b/eeschema/sch_marker.h
index 0ba706046c..558e522d13 100644
--- a/eeschema/sch_marker.h
+++ b/eeschema/sch_marker.h
@@ -90,7 +90,7 @@ public:
      * @param[in] aAuxData is the optional data required for the search or NULL if not used.
      * @return True if the DRC main or auxiliary text matches the search criteria.
      */
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxDat ) const override;
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxDat ) const override;
 
     void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
 
diff --git a/eeschema/sch_pin.cpp b/eeschema/sch_pin.cpp
index 1e77b46616..21f5db0547 100644
--- a/eeschema/sch_pin.cpp
+++ b/eeschema/sch_pin.cpp
@@ -160,9 +160,12 @@ void SCH_PIN::ViewGetLayers( int aLayers[], int& aCount ) const
 }
 
 
-bool SCH_PIN::Matches( const wxFindReplaceData& aSearchData, void* aAuxDat ) const
+bool SCH_PIN::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxDat ) const
 {
-    if( !( aSearchData.GetFlags() & FR_SEARCH_ALL_PINS ) )
+    const SCH_SEARCH_DATA& schSearchData =
+            dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
+
+    if( !schSearchData.searchAllPins )
         return false;
 
     return EDA_ITEM::Matches( GetName(), aSearchData )
@@ -170,7 +173,7 @@ bool SCH_PIN::Matches( const wxFindReplaceData& aSearchData, void* aAuxDat ) con
 }
 
 
-bool SCH_PIN::Replace( const wxFindReplaceData& aSearchData, void* aAuxData )
+bool SCH_PIN::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
 {
     bool isReplaced = false;
 
diff --git a/eeschema/sch_pin.h b/eeschema/sch_pin.h
index f4b5d66379..636281421c 100644
--- a/eeschema/sch_pin.h
+++ b/eeschema/sch_pin.h
@@ -118,9 +118,9 @@ public:
     /// @return the pin's position in global coordinates.
     VECTOR2I GetTransformedPosition() const;
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override;
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override;
 
-    bool Replace( const wxFindReplaceData& aSearchData, void* aAuxData ) override;
+    bool Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) override;
 
     /*
      * While many of these are currently simply covers for the equivalent LIB_PIN methods,
diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp
index 0bbcc5ba16..c44d40ce57 100644
--- a/eeschema/sch_sheet.cpp
+++ b/eeschema/sch_sheet.cpp
@@ -887,7 +887,7 @@ void SCH_SHEET::Resize( const wxSize& aSize )
 }
 
 
-bool SCH_SHEET::Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const
+bool SCH_SHEET::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
 {
     wxLogTrace( traceFindItem, wxT( "  item " ) + GetSelectMenuText( EDA_UNITS::MILLIMETRES ) );
 
diff --git a/eeschema/sch_sheet.h b/eeschema/sch_sheet.h
index ef7191f339..37ac02948f 100644
--- a/eeschema/sch_sheet.h
+++ b/eeschema/sch_sheet.h
@@ -320,7 +320,7 @@ public:
     void MirrorVertically( int aCenter ) override;
     void Rotate( const VECTOR2I& aCenter ) override;
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override;
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override;
 
     bool IsReplaceable() const override { return true; }
 
diff --git a/eeschema/sch_sheet_pin.h b/eeschema/sch_sheet_pin.h
index dd31064886..637de4391c 100644
--- a/eeschema/sch_sheet_pin.h
+++ b/eeschema/sch_sheet_pin.h
@@ -166,12 +166,12 @@ public:
     void MirrorHorizontally( int aCenter ) override;
     void Rotate( const VECTOR2I& aCenter ) override;
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override
     {
         return SCH_ITEM::Matches( GetText(), aSearchData );
     }
 
-    bool Replace( const wxFindReplaceData& aSearchData, void* aAuxData = nullptr ) override
+    bool Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData = nullptr ) override
     {
         return EDA_TEXT::Replace( aSearchData );
     }
diff --git a/eeschema/sch_symbol.cpp b/eeschema/sch_symbol.cpp
index 3f3edbc03b..fa66ead617 100644
--- a/eeschema/sch_symbol.cpp
+++ b/eeschema/sch_symbol.cpp
@@ -1585,7 +1585,7 @@ void SCH_SYMBOL::Rotate( const VECTOR2I& aCenter )
 }
 
 
-bool SCH_SYMBOL::Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const
+bool SCH_SYMBOL::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
 {
     wxLogTrace( traceFindItem, wxT( "  item " ) + GetSelectMenuText( EDA_UNITS::MILLIMETRES ) );
 
diff --git a/eeschema/sch_symbol.h b/eeschema/sch_symbol.h
index 84a0b61400..9116ea9c70 100644
--- a/eeschema/sch_symbol.h
+++ b/eeschema/sch_symbol.h
@@ -605,7 +605,7 @@ public:
     void MirrorVertically( int aCenter ) override;
     void Rotate( const VECTOR2I& aCenter ) override;
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override;
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override;
 
     void GetEndPoints( std::vector<DANGLING_END_ITEM>& aItemList ) override;
 
diff --git a/eeschema/sch_text.h b/eeschema/sch_text.h
index 6171bd36ca..c7f930f3bf 100644
--- a/eeschema/sch_text.h
+++ b/eeschema/sch_text.h
@@ -180,12 +180,12 @@ public:
     virtual void Rotate90( bool aClockwise );
     virtual void MirrorSpinStyle( bool aLeftRight );
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override
     {
         return SCH_ITEM::Matches( GetText(), aSearchData );
     }
 
-    bool Replace( const wxFindReplaceData& aSearchData, void* aAuxData ) override
+    bool Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) override
     {
         return EDA_TEXT::Replace( aSearchData );
     }
diff --git a/eeschema/sch_textbox.h b/eeschema/sch_textbox.h
index e5e3b5ef33..c1df42be52 100644
--- a/eeschema/sch_textbox.h
+++ b/eeschema/sch_textbox.h
@@ -81,12 +81,12 @@ public:
 
     bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override
     {
         return SCH_ITEM::Matches( GetText(), aSearchData );
     }
 
-    bool Replace( const wxFindReplaceData& aSearchData, void* aAuxData ) override
+    bool Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) override
     {
         return EDA_TEXT::Replace( aSearchData );
     }
diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp
index 4d1f2a32ee..b74068b8e2 100644
--- a/eeschema/tools/sch_editor_control.cpp
+++ b/eeschema/tools/sch_editor_control.cpp
@@ -310,7 +310,7 @@ int SCH_EDITOR_CONTROL::Quit( const TOOL_EVENT& aEvent )
 
 
 // A dummy wxFindReplaceData signaling any marker should be found
-static wxFindReplaceData g_markersOnly;
+static EDA_SEARCH_DATA g_markersOnly;
 
 
 int SCH_EDITOR_CONTROL::FindAndReplace( const TOOL_EVENT& aEvent )
@@ -322,7 +322,7 @@ int SCH_EDITOR_CONTROL::FindAndReplace( const TOOL_EVENT& aEvent )
 
 int SCH_EDITOR_CONTROL::UpdateFind( const TOOL_EVENT& aEvent )
 {
-    wxFindReplaceData& data = m_frame->GetFindReplaceData();
+    EDA_SEARCH_DATA& data = m_frame->GetFindReplaceData();
 
     auto visit =
             [&]( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheet )
@@ -331,7 +331,7 @@ int SCH_EDITOR_CONTROL::UpdateFind( const TOOL_EVENT& aEvent )
                 // SelectedItemsModified we also get triggered when the find dialog is
                 // closed....so we need to double check the dialog is open.
                 if( m_frame->m_findReplaceDialog != nullptr
-                    && !data.GetFindString().IsEmpty()
+                    && !data.findString.IsEmpty()
                     && aItem->Matches( data, aSheet ) )
                 {
                     aItem->SetForceVisible( true );
@@ -375,7 +375,7 @@ int SCH_EDITOR_CONTROL::UpdateFind( const TOOL_EVENT& aEvent )
 
 
 SCH_ITEM* SCH_EDITOR_CONTROL::nextMatch( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aSheet,
-                                         SCH_ITEM* aAfter, wxFindReplaceData& aData )
+                                         SCH_ITEM* aAfter, EDA_SEARCH_DATA& aData )
 {
     bool past_item = true;
 
@@ -464,23 +464,31 @@ SCH_ITEM* SCH_EDITOR_CONTROL::nextMatch( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aS
 
 int SCH_EDITOR_CONTROL::FindNext( const TOOL_EVENT& aEvent )
 {
+    EDA_SEARCH_DATA& data = m_frame->GetFindReplaceData();
+    bool searchAllSheets = false;
+    try
+    {
+        const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( data );
+        searchAllSheets = !( schSearchData.searchCurrentSheetOnly );
+    }
+    catch( const std::bad_cast& e )
+    {
+    }
+
     // A timer during which a subsequent FindNext will result in a wrap-around
     static wxTimer wrapAroundTimer;
 
-    wxFindReplaceData& data = m_frame->GetFindReplaceData();
-
     if( aEvent.IsAction( &ACTIONS::findNextMarker ) )
     {
-        g_markersOnly.SetFlags( data.GetFlags() );
+       // g_markersOnly.SetFlags( data.GetFlags() );
 
-        data = g_markersOnly;
+       // data = g_markersOnly;
     }
-    else if( data.GetFindString().IsEmpty() )
+    else if( data.findString.IsEmpty() )
     {
         return FindAndReplace( ACTIONS::find.MakeEvent() );
     }
 
-    bool          searchAllSheets = !( data.GetFlags() & FR_CURRENT_SHEET_ONLY );
     EE_SELECTION& selection       = m_selectionTool->GetSelection();
     SCH_ITEM*     afterItem       = dynamic_cast<SCH_ITEM*>( selection.Front() );
     SCH_ITEM*     item            = nullptr;
@@ -572,7 +580,7 @@ int SCH_EDITOR_CONTROL::FindNext( const TOOL_EVENT& aEvent )
 
 bool SCH_EDITOR_CONTROL::HasMatch()
 {
-    wxFindReplaceData& data = m_frame->GetFindReplaceData();
+    EDA_SEARCH_DATA& data = m_frame->GetFindReplaceData();
     EDA_ITEM*          item = m_selectionTool->GetSelection().Front();
 
     return item && item->Matches( data, &m_frame->GetCurrentSheet() );
@@ -581,11 +589,11 @@ bool SCH_EDITOR_CONTROL::HasMatch()
 
 int SCH_EDITOR_CONTROL::ReplaceAndFindNext( const TOOL_EVENT& aEvent )
 {
-    wxFindReplaceData& data = m_frame->GetFindReplaceData();
+    EDA_SEARCH_DATA& data = m_frame->GetFindReplaceData();
     EDA_ITEM*          item = m_selectionTool->GetSelection().Front();
     SCH_SHEET_PATH*    sheet = &m_frame->GetCurrentSheet();
 
-    if( data.GetFindString().IsEmpty() )
+    if( data.findString.IsEmpty() )
         return FindAndReplace( ACTIONS::find.MakeEvent() );
 
     if( item && item->Matches( data, sheet ) )
@@ -610,15 +618,25 @@ int SCH_EDITOR_CONTROL::ReplaceAndFindNext( const TOOL_EVENT& aEvent )
 
 int SCH_EDITOR_CONTROL::ReplaceAll( const TOOL_EVENT& aEvent )
 {
-    wxFindReplaceData& data = m_frame->GetFindReplaceData();
-    bool               currentSheetOnly = ( data.GetFlags() & FR_CURRENT_SHEET_ONLY ) > 0;
-    bool               modified = false;
+    EDA_SEARCH_DATA& data = m_frame->GetFindReplaceData();
+    bool             currentSheetOnly = false;
 
-    if( data.GetFindString().IsEmpty() )
+    try
+    {
+        const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( data );
+        currentSheetOnly = schSearchData.searchCurrentSheetOnly;
+    }
+    catch( const std::bad_cast& e )
+    {
+    }
+
+    bool modified = false;
+
+    if( data.findString.IsEmpty() )
         return FindAndReplace( ACTIONS::find.MakeEvent() );
 
     auto doReplace =
-            [&]( SCH_ITEM* aItem, SCH_SHEET_PATH* aSheet, wxFindReplaceData& aData )
+            [&]( SCH_ITEM* aItem, SCH_SHEET_PATH* aSheet, EDA_SEARCH_DATA& aData )
             {
                 m_frame->SaveCopyInUndoList( aSheet->LastScreen(), aItem, UNDO_REDO::CHANGED,
                                              modified );
diff --git a/eeschema/tools/sch_editor_control.h b/eeschema/tools/sch_editor_control.h
index 3b318b4a38..49a240542e 100644
--- a/eeschema/tools/sch_editor_control.h
+++ b/eeschema/tools/sch_editor_control.h
@@ -219,7 +219,7 @@ private:
      * @return pointer to the next search item found or NULL if nothing found
      */
     SCH_ITEM* nextMatch( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aSheet, SCH_ITEM* aAfter,
-                         wxFindReplaceData& aData );
+                         EDA_SEARCH_DATA& aData );
 
 private:
     bool      m_probingPcbToSch; // Recursion guard when cross-probing to schematic editor
diff --git a/include/eda_draw_frame.h b/include/eda_draw_frame.h
index e504e30955..a6310073e1 100644
--- a/include/eda_draw_frame.h
+++ b/include/eda_draw_frame.h
@@ -101,7 +101,7 @@ public:
      */
     bool IsScriptingConsoleVisible();
 
-    wxFindReplaceData& GetFindReplaceData() { return *m_findReplaceData; }
+    EDA_SEARCH_DATA& GetFindReplaceData() { return *m_findReplaceData; }
     wxArrayString& GetFindHistoryList() { return m_findStringHistoryList; }
 
     virtual void SetPageSettings( const PAGE_INFO& aPageSettings ) = 0;
@@ -501,7 +501,7 @@ protected:
     ACTION_TOOLBAR*    m_drawToolBar;       // Drawing tools (typically on right edge of window)
     ACTION_TOOLBAR*    m_optionsToolBar;    // Options (typically on left edge of window)
 
-    wxFindReplaceData* m_findReplaceData;
+    std::unique_ptr<EDA_SEARCH_DATA> m_findReplaceData;
     wxArrayString      m_findStringHistoryList;
     wxArrayString      m_replaceStringHistoryList;
 
diff --git a/include/eda_item.h b/include/eda_item.h
index 8128d03318..ed227f26a5 100644
--- a/include/eda_item.h
+++ b/include/eda_item.h
@@ -31,6 +31,7 @@
 
 #include <core/typeinfo.h>
 #include <eda_item_flags.h>
+#include <eda_search_data.h>
 #include <view/view_item.h>
 #include <kiid.h>
 
@@ -61,7 +62,6 @@ enum FIND_REPLACE_FLAGS
     FR_REPLACE_REFERENCES = 0x4 << 9    // Don't replace in references.
 };
 
-
 class wxFindReplaceData;
 class EDA_DRAW_FRAME;
 class EDA_RECT;
@@ -389,7 +389,7 @@ public:
      * @param aAuxData A pointer to optional data required for the search or NULL if not used.
      * @return True if the item's text matches the search criteria in \a aSearchData.
      */
-    virtual bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const
+    virtual bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
     {
         return false;
     }
@@ -403,7 +403,7 @@ public:
      * @param aText A reference to a wxString object containing the text to be replaced.
      * @return True if \a aText was modified, otherwise false.
      */
-    static bool Replace( const wxFindReplaceData& aSearchData, wxString& aText );
+    static bool Replace( const EDA_SEARCH_DATA& aSearchData, wxString& aText );
 
     /**
      * Perform a text replace using the find and replace criteria in \a aSearchData
@@ -416,7 +416,7 @@ public:
      * @param aAuxData A pointer to optional data required for the search or NULL if not used.
      * @return True if the item text was modified, otherwise false.
      */
-    virtual bool Replace( const wxFindReplaceData& aSearchData, void* aAuxData = nullptr )
+    virtual bool Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData = nullptr )
     {
         return false;
     }
@@ -496,7 +496,7 @@ protected:
      * @param aSearchData The criteria to search against.
      * @return True if \a aText matches the search criteria in \a aSearchData.
      */
-    bool Matches( const wxString& aText, const wxFindReplaceData& aSearchData ) const;
+    bool Matches( const wxString& aText, const EDA_SEARCH_DATA& aSearchData ) const;
 
 public:
     const KIID  m_Uuid;
diff --git a/include/eda_search_data.h b/include/eda_search_data.h
new file mode 100644
index 0000000000..12f0f503da
--- /dev/null
+++ b/include/eda_search_data.h
@@ -0,0 +1,76 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2022 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#ifndef EDA_ITEM_SEARCH_H
+#define EDA_ITEM_SEARCH_H
+
+#include <wx/string.h>
+
+enum class EDA_SEARCH_MATCH_MODE
+{
+    PLAIN,
+    WHOLEWORD,
+    WILDCARD
+};
+
+struct EDA_SEARCH_DATA
+{
+    wxString findString;
+    wxString replaceString;
+
+    bool searchAndReplace;
+
+    bool matchCase;
+    EDA_SEARCH_MATCH_MODE matchMode;
+
+    EDA_SEARCH_DATA() :
+            findString(),
+            replaceString(),
+            searchAndReplace( false ),
+            matchCase( false ),
+            matchMode( EDA_SEARCH_MATCH_MODE::PLAIN )
+    {
+    }
+
+    virtual ~EDA_SEARCH_DATA() {}
+};
+
+struct SCH_SEARCH_DATA : public EDA_SEARCH_DATA
+{
+    bool searchAllFields;
+    bool searchAllPins;
+    bool searchCurrentSheetOnly;
+
+    bool replaceReferences;
+
+    SCH_SEARCH_DATA() :
+            EDA_SEARCH_DATA(),
+            searchAllFields( false ),
+            searchAllPins( false ),
+            searchCurrentSheetOnly( false ),
+            replaceReferences( false )
+    {
+    }
+};
+
+#endif
\ No newline at end of file
diff --git a/include/eda_text.h b/include/eda_text.h
index 4e91685092..cf2163f3bb 100644
--- a/include/eda_text.h
+++ b/include/eda_text.h
@@ -30,13 +30,13 @@
 
 #include <outline_mode.h>
 #include <eda_rect.h>
+#include <eda_search_data.h>
 #include <font/glyph.h>
 #include <font/text_attributes.h>
 
 class OUTPUTFORMATTER;
 class SHAPE_COMPOUND;
 class SHAPE_POLY_SET;
-class wxFindReplaceData;
 
 
 namespace KIGFX
@@ -167,11 +167,11 @@ public:
      *
      * Perform a text replace using the find and replace criteria in \a aSearchData.
      *
-     * @param aSearchData A reference to a wxFindReplaceData object containing the
+     * @param aSearchData A reference to a EDA_SEARCH_DATA object containing the
      *                    search and replace criteria.
      * @return True if the text item was modified, otherwise false.
      */
-    bool Replace( const wxFindReplaceData& aSearchData );
+    bool Replace( const EDA_SEARCH_DATA& aSearchData );
 
     bool IsDefaultFormatting() const;
 
diff --git a/include/settings/app_settings.h b/include/settings/app_settings.h
index 8e23dbc42a..5209d04125 100644
--- a/include/settings/app_settings.h
+++ b/include/settings/app_settings.h
@@ -100,15 +100,17 @@ struct WINDOW_SETTINGS
 class APP_SETTINGS_BASE : public JSON_SETTINGS
 {
 public:
-
-
     struct FIND_REPLACE
     {
-        int                   flags;
         wxString              find_string;
         std::vector<wxString> find_history;
         wxString              replace_string;
         std::vector<wxString> replace_history;
+
+        bool search_and_replace;
+
+        bool match_case;
+        int match_mode;
     };
 
     struct GRAPHICS
diff --git a/pcbnew/dialogs/dialog_find.cpp b/pcbnew/dialogs/dialog_find.cpp
index 50db7d765b..b719bb34ac 100644
--- a/pcbnew/dialogs/dialog_find.cpp
+++ b/pcbnew/dialogs/dialog_find.cpp
@@ -134,7 +134,6 @@ void DIALOG_FIND::onSearchAgainClick( wxCommandEvent& aEvent )
 void DIALOG_FIND::search( bool aDirection )
 {
     PCB_SCREEN* screen = m_frame->GetScreen();
-    int         flags;
     int         index;
     wxString    msg;
     wxString    searchString;
@@ -178,9 +177,6 @@ void DIALOG_FIND::search( bool aDirection )
         m_frame->GetFindHistoryList().Insert( searchString, 0 );
     }
 
-    // Update search flags
-    flags = 0;
-
     if( FindOptionCase != m_matchCase->GetValue() )
     {
         FindOptionCase = m_matchCase->GetValue();
@@ -232,17 +228,17 @@ void DIALOG_FIND::search( bool aDirection )
     }
 
     if( FindOptionCase )
-        flags |= wxFR_MATCHCASE;
+        m_frame->GetFindReplaceData().matchCase = true;
 
     if( FindOptionWords )
-        flags |= wxFR_WHOLEWORD;
-
-    if( FindOptionWildcards )
-        flags |= FR_MATCH_WILDCARD;
+        m_frame->GetFindReplaceData().matchMode = EDA_SEARCH_MATCH_MODE::WHOLEWORD;
+    else if( FindOptionWildcards )
+        m_frame->GetFindReplaceData().matchMode = EDA_SEARCH_MATCH_MODE::WILDCARD;
+    else
+        m_frame->GetFindReplaceData().matchMode = EDA_SEARCH_MATCH_MODE::PLAIN;
 
     // Search parameters
-    m_frame->GetFindReplaceData().SetFindString( searchString );
-    m_frame->GetFindReplaceData().SetFlags( flags );
+    m_frame->GetFindReplaceData().findString = searchString;
 
     m_frame->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
     m_frame->GetCanvas()->GetViewStart( &screen->m_StartVisu.x, &screen->m_StartVisu.y );
diff --git a/pcbnew/fp_text.h b/pcbnew/fp_text.h
index d27412d265..e024b25c3c 100644
--- a/pcbnew/fp_text.h
+++ b/pcbnew/fp_text.h
@@ -80,7 +80,7 @@ public:
 
     wxString GetParentAsString() const { return m_parent->m_Uuid.AsString(); }
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override
     {
         return BOARD_ITEM::Matches( GetShownText(), aSearchData );
     }
diff --git a/pcbnew/fp_textbox.h b/pcbnew/fp_textbox.h
index 02051706b0..6e9688a981 100644
--- a/pcbnew/fp_textbox.h
+++ b/pcbnew/fp_textbox.h
@@ -74,7 +74,7 @@ public:
 
     wxString GetParentAsString() const { return m_parent->m_Uuid.AsString(); }
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override
     {
         return BOARD_ITEM::Matches( GetShownText(), aSearchData );
     }
diff --git a/pcbnew/netinfo.h b/pcbnew/netinfo.h
index 6fcb1f11e1..639d1f5f12 100644
--- a/pcbnew/netinfo.h
+++ b/pcbnew/netinfo.h
@@ -158,7 +158,7 @@ public:
         return m_parent;
     }
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override;
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override;
 
 private:
     friend class NETINFO_LIST;
diff --git a/pcbnew/netinfo_item.cpp b/pcbnew/netinfo_item.cpp
index e5a06293cd..a3b0d96143 100644
--- a/pcbnew/netinfo_item.cpp
+++ b/pcbnew/netinfo_item.cpp
@@ -143,7 +143,7 @@ void NETINFO_ITEM::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANE
 }
 
 
-bool NETINFO_ITEM::Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const
+bool NETINFO_ITEM::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
 {
     return BOARD_ITEM::Matches( GetNetname(), aSearchData );
 }
diff --git a/pcbnew/pcb_marker.h b/pcbnew/pcb_marker.h
index 8c7ac583fb..681c7f4e9e 100644
--- a/pcbnew/pcb_marker.h
+++ b/pcbnew/pcb_marker.h
@@ -93,7 +93,7 @@ public:
 
     void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override
     {
         return BOARD_ITEM::Matches( m_rcItem->GetErrorMessage(), aSearchData );
     }
diff --git a/pcbnew/pcb_text.h b/pcbnew/pcb_text.h
index 646a046b94..7f6f3ff275 100644
--- a/pcbnew/pcb_text.h
+++ b/pcbnew/pcb_text.h
@@ -68,7 +68,7 @@ public:
     void SetVisible( bool aVisible ) override { /* do nothing */}
     bool IsVisible() const override { return true; }
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override
     {
         return BOARD_ITEM::Matches( GetShownText(), aSearchData );
     }
diff --git a/pcbnew/pcb_textbox.h b/pcbnew/pcb_textbox.h
index 9a01ee4a75..3752e53ff7 100644
--- a/pcbnew/pcb_textbox.h
+++ b/pcbnew/pcb_textbox.h
@@ -80,7 +80,7 @@ public:
     void SetVisible( bool aVisible ) override { /* do nothing */}
     bool IsVisible() const override { return true; }
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override
     {
         return BOARD_ITEM::Matches( GetShownText(), aSearchData );
     }
diff --git a/pcbnew/zone.h b/pcbnew/zone.h
index 7bda8fce60..79ee7122da 100644
--- a/pcbnew/zone.h
+++ b/pcbnew/zone.h
@@ -118,7 +118,7 @@ public:
     wxString GetZoneName() const { return m_zoneName; }
     void SetZoneName( const wxString& aName ) { m_zoneName = aName; }
 
-    bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override
+    bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override
     {
         return BOARD_ITEM::Matches( GetZoneName(), aSearchData );
     }