From f66b9f75a3258032db19b14a55d023b9a6ee4bfe Mon Sep 17 00:00:00 2001
From: Jeff Young <jeff@rokeby.ie>
Date: Sat, 10 Jun 2023 14:49:37 +0100
Subject: [PATCH] Allow EDA_COMBINED_MATCHER use in KiCad find architecture.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/12532
---
 common/eda_item.cpp                  | 11 +++++++++--
 common/eda_pattern_match.cpp         |  6 ++++++
 eeschema/widgets/search_handlers.cpp | 12 +++++++++---
 include/eda_pattern_match.h          |  3 ++-
 include/eda_search_data.h            |  5 +++--
 pcbnew/widgets/search_handlers.cpp   | 18 +++++++++++++-----
 6 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/common/eda_item.cpp b/common/eda_item.cpp
index 64c84621cb..6ef3c199f4 100644
--- a/common/eda_item.cpp
+++ b/common/eda_item.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2015 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
- * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.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
@@ -32,6 +32,7 @@
 #include <wx/log.h>
 
 #include <wx/fdrepdlg.h>
+#include <eda_pattern_match.h>
 
 EDA_ITEM::EDA_ITEM( EDA_ITEM* parent, KICAD_T idType ) :
         m_parent( parent ),
@@ -128,7 +129,13 @@ bool EDA_ITEM::Matches( const wxString& aText, const EDA_SEARCH_DATA& aSearchDat
         searchText.MakeUpper();
     }
 
-    if( aSearchData.matchMode == EDA_SEARCH_MATCH_MODE::WHOLEWORD )
+    if( aSearchData.matchMode == EDA_SEARCH_MATCH_MODE::PERMISSIVE )
+    {
+        EDA_COMBINED_MATCHER matcher( searchText, CTX_SEARCH );
+
+        return matcher.Find( text );
+    }
+    else if( aSearchData.matchMode == EDA_SEARCH_MATCH_MODE::WHOLEWORD )
     {
         int ii = 0;
 
diff --git a/common/eda_pattern_match.cpp b/common/eda_pattern_match.cpp
index 98ea454c77..a48ac48f1f 100644
--- a/common/eda_pattern_match.cpp
+++ b/common/eda_pattern_match.cpp
@@ -395,6 +395,12 @@ EDA_COMBINED_MATCHER::EDA_COMBINED_MATCHER( const wxString& aPattern,
         AddMatcher( aPattern, std::make_unique<EDA_PATTERN_MATCH_WILDCARD>() );
         AddMatcher( aPattern, std::make_unique<EDA_PATTERN_MATCH_SUBSTR>() );
         break;
+
+    case CTX_SEARCH:
+        AddMatcher( aPattern, std::make_unique<EDA_PATTERN_MATCH_REGEX>() );
+        AddMatcher( aPattern, std::make_unique<EDA_PATTERN_MATCH_WILDCARD>() );
+        AddMatcher( aPattern, std::make_unique<EDA_PATTERN_MATCH_SUBSTR>() );
+        break;
     }
 }
 
diff --git a/eeschema/widgets/search_handlers.cpp b/eeschema/widgets/search_handlers.cpp
index f957c34117..4e3a197adb 100644
--- a/eeschema/widgets/search_handlers.cpp
+++ b/eeschema/widgets/search_handlers.cpp
@@ -124,7 +124,9 @@ int SYMBOL_SEARCH_HANDLER::Search( const wxString& aQuery )
 
     SCH_SEARCH_DATA frp;
     frp.findString = aQuery;
-    frp.matchMode = EDA_SEARCH_MATCH_MODE::WILDCARD;
+
+    // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
+    frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
     frp.searchCurrentSheetOnly = false;
 
     auto search = [frp]( SCH_ITEM* item, SCH_SHEET_PATH* sheet )
@@ -202,7 +204,9 @@ int TEXT_SEARCH_HANDLER::Search( const wxString& aQuery )
 
     SCH_SEARCH_DATA frp;
     frp.findString = aQuery;
-    frp.matchMode = EDA_SEARCH_MATCH_MODE::WILDCARD;
+
+    // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
+    frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
     frp.searchCurrentSheetOnly = false;
 
     auto search = [frp]( SCH_ITEM* item, SCH_SHEET_PATH* sheet )
@@ -302,7 +306,9 @@ int LABEL_SEARCH_HANDLER::Search( const wxString& aQuery )
 
     SCH_SEARCH_DATA frp;
     frp.findString = aQuery;
-    frp.matchMode = EDA_SEARCH_MATCH_MODE::WILDCARD;
+
+    // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
+    frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
     frp.searchCurrentSheetOnly = false;
 
     auto search = [frp]( SCH_ITEM* item, SCH_SHEET_PATH* sheet )
diff --git a/include/eda_pattern_match.h b/include/eda_pattern_match.h
index 53f53911e7..693642e739 100644
--- a/include/eda_pattern_match.h
+++ b/include/eda_pattern_match.h
@@ -198,7 +198,8 @@ enum COMBINED_MATCHER_CONTEXT
 {
     CTX_LIBITEM,
     CTX_NETCLASS,
-    CTX_SIGNAL
+    CTX_SIGNAL,
+    CTX_SEARCH
 };
 
 
diff --git a/include/eda_search_data.h b/include/eda_search_data.h
index 0b112b0573..eeb31463a3 100644
--- a/include/eda_search_data.h
+++ b/include/eda_search_data.h
@@ -1,7 +1,7 @@
 /*
  * 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.
+ * Copyright (C) 2004-2023 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
@@ -30,7 +30,8 @@ enum class EDA_SEARCH_MATCH_MODE
 {
     PLAIN,
     WHOLEWORD,
-    WILDCARD
+    WILDCARD,
+    PERMISSIVE
 };
 
 struct EDA_SEARCH_DATA
diff --git a/pcbnew/widgets/search_handlers.cpp b/pcbnew/widgets/search_handlers.cpp
index caf67f63e2..12f626305f 100644
--- a/pcbnew/widgets/search_handlers.cpp
+++ b/pcbnew/widgets/search_handlers.cpp
@@ -1,7 +1,7 @@
 /*
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
- * Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.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
@@ -63,7 +63,9 @@ int FOOTPRINT_SEARCH_HANDLER::Search( const wxString& aQuery )
 
     EDA_SEARCH_DATA frp;
     frp.findString = aQuery;
-    frp.matchMode = EDA_SEARCH_MATCH_MODE::WILDCARD;
+
+    // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
+    frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
 
     for( FOOTPRINT* fp : board->Footprints() )
     {
@@ -139,7 +141,9 @@ int ZONE_SEARCH_HANDLER::Search( const wxString& aQuery )
 
     EDA_SEARCH_DATA frp;
     frp.findString = aQuery;
-    frp.matchMode = EDA_SEARCH_MATCH_MODE::WILDCARD;
+
+    // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
+    frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
 
     for( BOARD_ITEM* item : board->Zones() )
     {
@@ -222,7 +226,9 @@ int TEXT_SEARCH_HANDLER::Search( const wxString& aQuery )
 
     EDA_SEARCH_DATA frp;
     frp.findString = aQuery;
-    frp.matchMode = EDA_SEARCH_MATCH_MODE::WILDCARD;
+
+    // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
+    frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
 
     for( BOARD_ITEM* item : board->Drawings() )
     {
@@ -304,7 +310,9 @@ int NETS_SEARCH_HANDLER::Search( const wxString& aQuery )
 
     EDA_SEARCH_DATA frp;
     frp.findString = aQuery;
-    frp.matchMode = EDA_SEARCH_MATCH_MODE::WILDCARD;
+
+    // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
+    frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
 
     BOARD* board = m_frame->GetBoard();