@@ -69,17 +69,20 @@ def dataValue(self, index: QModelIndex) -> str | None:
69
69
return self .table_data [row ][col ]
70
70
return None
71
71
72
- def setFilter (self , query : str , match_case : bool , match_whole_word : bool ):
72
+ def setFilter (
73
+ self , query : str , match_case : bool , match_whole_word : bool , exact_match : bool
74
+ ):
73
75
"""Filter rows based on a query in column 1"""
74
76
75
77
# build the regex pattern based on the options
76
78
flags = 0 if match_case else re .IGNORECASE
77
79
word_boundary = r"\b" if match_whole_word else ""
78
80
pattern = rf"{ word_boundary } { re .escape (query )} { word_boundary } "
81
+ search_type = re .fullmatch if exact_match else re .search
79
82
80
83
# filter rows
81
84
self .filtered_data = [
82
- row for row in self .table_data if re . search (pattern , row [0 ], flags )
85
+ row for row in self .table_data if search_type (pattern , row [0 ], flags )
83
86
]
84
87
85
88
self .layoutChanged .emit ()
@@ -211,6 +214,15 @@ def initialize_central_widget(self, screen_geo: QRect):
211
214
self .match_whole_word .stateChanged .connect (self .hide_dynamic_widget ) # type: ignore
212
215
self .match_whole_word .stateChanged .connect (self .perform_search ) # type: ignore
213
216
217
+ # create 'Exact match only' checkbox
218
+ self .exact_match = QCheckBox ()
219
+ self .exact_match .setText ("Exact match only" )
220
+ self .search_layout .addWidget (self .exact_match )
221
+
222
+ # connect the stateChanged signal of the `Exact match only` checkbox
223
+ self .exact_match .stateChanged .connect (self .hide_dynamic_widget ) # type: ignore
224
+ self .exact_match .stateChanged .connect (self .perform_search ) # type: ignore
225
+
214
226
# create spacer to maintain consistent layout
215
227
self .spacer = QSpacerItem (
216
228
240 , 0 , QSizePolicy .Policy .Fixed , QSizePolicy .Policy .Fixed
@@ -381,11 +393,16 @@ def perform_search(self):
381
393
search_text = self .search_bar .text ()
382
394
match_case = self .match_case .isChecked ()
383
395
match_whole_word = self .match_whole_word .isChecked ()
396
+ exact_match = self .exact_match .isChecked ()
384
397
385
398
if len (search_text ) >= 2 :
386
- self .table_model .setFilter (search_text , match_case , match_whole_word )
399
+ self .table_model .setFilter (
400
+ search_text , match_case , match_whole_word , exact_match
401
+ )
387
402
else :
388
- self .table_model .setFilter ("" , match_case , match_whole_word )
403
+ self .table_model .setFilter (
404
+ "" , match_case , match_whole_word , exact_match = False
405
+ )
389
406
390
407
# update visibility of rows
391
408
self .update_rows_visibility ()
0 commit comments