Skip to content

Commit

Permalink
Add the possibility of case sensitive/insensitive search
Browse files Browse the repository at this point in the history
  • Loading branch information
SNoiraud authored and Nick-Hall committed Jul 24, 2023
1 parent e7e1b74 commit 8b64b9f
Show file tree
Hide file tree
Showing 15 changed files with 121 additions and 51 deletions.
4 changes: 2 additions & 2 deletions gramps/gen/filters/_filterlist.py
Expand Up @@ -142,9 +142,9 @@ def save(self):
file.write(' comment="%s"' % self.fix(comment))
file.write('>\n')
for rule in the_filter.get_rules():
file.write(' <rule class="%s" use_regex="%s">'
file.write(' <rule class="%s" use_regex="%s" use_case="%s">'
'\n' % (rule.__class__.__name__,
rule.use_regex))
rule.use_regex, rule.use_case))
for value in list(rule.values()):
file.write(' <arg value="%s"/>'
'\n' % self.fix(value))
Expand Down
9 changes: 7 additions & 2 deletions gramps/gen/filters/_filterparser.py
Expand Up @@ -52,6 +52,7 @@ def __init__(self, gfilter_list):
self.cname = None
self.namespace = 'Person'
self.use_regex = False
self.use_case = False

def setDocumentLocator(self, locator):
self.locator = locator
Expand Down Expand Up @@ -87,6 +88,10 @@ def startElement(self, tag, attrs):
self.use_regex = attrs['use_regex'] == 'True'
else:
self.use_regex = False
if 'use_case' in attrs:
self.use_case = attrs['use_case'] == 'True'
else:
self.use_case = False
save_name = attrs['class']
if save_name in old_names_2_class:
self.r = old_names_2_class[save_name]
Expand Down Expand Up @@ -120,7 +125,7 @@ def endElement(self, tag):
"Trying to load with subset of arguments.") %\
self.f.get_name())
nargs = len(self.r.labels)
rule = self.r(self.a[0:nargs], self.use_regex)
rule = self.r(self.a[0:nargs], self.use_regex, self.use_case)
self.f.add_rule(rule)
else:
if len(self.r.labels) > len(self.a):
Expand All @@ -129,7 +134,7 @@ def endElement(self, tag):
"will be upgraded.") %\
self.f.get_name())
try:
rule = self.r(self.a, self.use_regex)
rule = self.r(self.a, self.use_regex, self.use_case)
except AssertionError as msg:
print(msg)
print(_("ERROR: filter %s could not be correctly loaded. "
Expand Down
6 changes: 3 additions & 3 deletions gramps/gen/filters/rules/_hasnotebase.py
Expand Up @@ -48,13 +48,13 @@ class HasNoteBase(Rule):
description = "Matches objects that have a certain number of notes"
category = _('General filters')

def __init__(self, arg, use_regex=False):
def __init__(self, arg, use_regex=False, use_case=False):
# Upgrade from pre 3.1 HasNote filter, use defaults that correspond
# Previous filter had 0 arguments
if len(arg) == 0:
Rule.__init__(self, ["0", 'greater than'], use_regex)
Rule.__init__(self, ["0", 'greater than'], use_regex, use_case)
else:
Rule.__init__(self, arg, use_regex)
Rule.__init__(self, arg, use_regex, use_case)

def prepare(self, db, user):
# things we want to do just once, not for every handle
Expand Down
8 changes: 6 additions & 2 deletions gramps/gen/filters/rules/_rule.py
Expand Up @@ -56,12 +56,13 @@ class Rule:
description = _('No description')
allow_regex = False

def __init__(self, arg, use_regex=False):
def __init__(self, arg, use_regex=False, use_case=False):
self.list = []
self.regex = []
self.match_substring = self.__match_substring
self.set_list(arg)
self.use_regex = use_regex
self.use_case = use_case
self.nrprepare = 0

def is_empty(self):
Expand All @@ -84,7 +85,10 @@ def requestprepare(self, db, user):
for index, label in enumerate(self.labels):
if self.list[index]:
try:
self.regex[index] = re.compile(self.list[index], re.I)
if self.use_case:
self.regex[index] = re.compile(self.list[index])
else:
self.regex[index] = re.compile(self.list[index], re.I)
except re.error:
self.regex[index] = re.compile('')
self.match_substring = self.match_regex
Expand Down
25 changes: 21 additions & 4 deletions gramps/gui/editors/filtereditor.py
Expand Up @@ -609,6 +609,7 @@ def __init__(self, namespace, dbstate, uistate, track, filterdb, val,
pos += 1

use_regex = None
use_case = None
if class_obj.allow_regex:
use_regex = Gtk.CheckButton(label=_('Use regular expressions'))
tip = _('Interpret the contents of string fields as regular '
Expand All @@ -625,7 +626,13 @@ def __init__(self, namespace, dbstate, uistate, track, filterdb, val,
use_regex.set_tooltip_text(tip)
grid.attach(use_regex, 1, pos, 1, 1)

self.page.append((class_obj, vallist, tlist, use_regex))
pos += 1
use_case = Gtk.CheckButton(label=_('Case sensitive'))
grid.attach(use_case, 1, pos, 1, 1)
use_regex.connect('toggled', self.regex_selection, use_case)
use_case.set_sensitive(False)

self.page.append((class_obj, vallist, tlist, use_regex, use_case))

# put the grid into a scrollable area:
scrolled_win = Gtk.ScrolledWindow()
Expand Down Expand Up @@ -684,12 +691,14 @@ def __init__(self, namespace, dbstate, uistate, track, filterdb, val,
page = self.class2page[self.active_rule.__class__]
self.notebook.set_current_page(page)
self.display_values(self.active_rule.__class__)
(class_obj, vallist, tlist, use_regex) = self.page[page]
(class_obj, vallist, tlist, use_regex, use_case) = self.page[page]
r = list(self.active_rule.values())
for i in range(0, min(len(tlist), len(r))):
tlist[i].set_text(r[i])
if class_obj.allow_regex:
use_regex.set_active(self.active_rule.use_regex)
use_case.set_active(self.active_rule.use_case)
self.regex_selection()

self.selection.connect('changed', self.on_node_selected)
self.rname.connect('button-press-event', self._button_press)
Expand All @@ -706,6 +715,14 @@ def __init__(self, namespace, dbstate, uistate, track, filterdb, val,
self.rname.restore_column_size()
self.show()

def regex_selection(self, widget=None, use_case=None):
if use_case:
if widget and widget.get_active():
use_case.set_sensitive(True)
else:
use_case.set_active(False)
use_case.set_sensitive(False)

def select_iter(self, data):
"""
Workaround to get self.selection to move to iter row.
Expand Down Expand Up @@ -787,10 +804,10 @@ def rule_ok(self, obj):

try:
page = self.notebook.get_current_page()
(class_obj, vallist, tlist, use_regex) = self.page[page]
(class_obj, vallist, tlist, use_regex, use_case) = self.page[page]
value_list = [str(sclass.get_text()) for sclass in tlist]
if class_obj.allow_regex:
new_rule = class_obj(value_list, use_regex.get_active())
new_rule = class_obj(value_list, use_regex.get_active(), use_case.get_active())
else:
new_rule = class_obj(value_list)

Expand Down
17 changes: 11 additions & 6 deletions gramps/gui/filters/sidebar/_citationsidebarfilter.py
Expand Up @@ -74,6 +74,7 @@ def __init__(self, dbstate, uistate, clicked):
self.filter_note = Gtk.Entry()

self.filter_regex = Gtk.CheckButton(label=_('Use regular expressions'))
self.sensitive_regex = Gtk.CheckButton(label=_('Case sensitive'))

self.tag = Gtk.ComboBox()
self.generic = Gtk.ComboBox()
Expand Down Expand Up @@ -116,6 +117,9 @@ def create_widget(self):
self.add_entry(_('Tag'), self.tag)
self.add_filter_entry(_('Custom filter'), self.generic)
self.add_entry(None, self.filter_regex)
self.add_entry(None, self.sensitive_regex)
self.filter_regex.connect('toggled', self.regex_selection)
self.regex_selection()

def clear(self, obj):
self.filter_src_id.set_text('')
Expand Down Expand Up @@ -145,6 +149,7 @@ def get_filter(self):
conf = str(self.filter_conf.get_active())
note = str(self.filter_note.get_text()).strip()
regex = self.filter_regex.get_active()
usecase = self.sensitive_regex.get_active()
tag = self.tag.get_active() > 0
gen = self.generic.get_active() > 0

Expand All @@ -156,26 +161,26 @@ def get_filter(self):
else:
generic_filter = GenericCitationFilter()
if gid:
rule = RegExpIdOf([gid], use_regex=regex)
rule = RegExpIdOf([gid], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

rule = HasCitation([page, date, conf], use_regex=regex)
rule = HasCitation([page, date, conf], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

if src_id:
rule = RegExpSourceIdOf([src_id], use_regex=regex)
rule = RegExpSourceIdOf([src_id], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

rule = HasSource([src_title, src_author, src_abbr, src_pub],
use_regex=regex)
use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

if note:
rule = HasNoteRegexp([note], use_regex=regex)
rule = HasNoteRegexp([note], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

if src_note:
rule = HasSourceNoteRegexp([src_note], use_regex=regex)
rule = HasSourceNoteRegexp([src_note], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

# check the Tag
Expand Down
9 changes: 6 additions & 3 deletions gramps/gui/filters/sidebar/_eventsidebarfilter.py
Expand Up @@ -78,6 +78,7 @@ def __init__(self, dbstate, uistate, clicked):
self.filter_note = widgets.BasicEntry()

self.filter_regex = Gtk.CheckButton(label=_('Use regular expressions'))
self.sensitive_regex = Gtk.CheckButton(label=_('Case sensitive'))

self.tag = Gtk.ComboBox()
self.generic = Gtk.ComboBox()
Expand Down Expand Up @@ -110,6 +111,7 @@ def create_widget(self):
self.add_entry(_('Tag'), self.tag)
self.add_filter_entry(_('Custom filter'), self.generic)
self.add_regex_entry(self.filter_regex)
self.add_regex_case(self.sensitive_regex)

def clear(self, obj):
self.filter_id.set_text('')
Expand All @@ -130,6 +132,7 @@ def get_filter(self):
place = str(self.filter_place.get_text()).strip()
note = str(self.filter_note.get_text()).strip()
regex = self.filter_regex.get_active()
usecase = self.sensitive_regex.get_active()
tag = self.tag.get_active() > 0
generic = self.generic.get_active() > 0
etype = self.filter_event.get_type().xml_str()
Expand All @@ -141,15 +144,15 @@ def get_filter(self):
else:
generic_filter = GenericEventFilter()
if gid:
rule = RegExpIdOf([gid], use_regex=regex)
rule = RegExpIdOf([gid], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

rule = HasEvent([etype, date, place, desc, mainparts],
use_regex=regex)
use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

if note:
rule = HasNoteRegexp([note], use_regex=regex)
rule = HasNoteRegexp([note], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

# check the Tag
Expand Down
23 changes: 13 additions & 10 deletions gramps/gui/filters/sidebar/_familysidebarfilter.py
Expand Up @@ -95,6 +95,7 @@ def __init__(self, dbstate, uistate, clicked):
self.filter_note = widgets.BasicEntry()

self.filter_regex = Gtk.CheckButton(label=_('Use regular expressions'))
self.sensitive_regex = Gtk.CheckButton(label=_('Case sensitive'))

self.tag = Gtk.ComboBox()
self.generic = Gtk.ComboBox()
Expand Down Expand Up @@ -128,6 +129,7 @@ def create_widget(self):
self.add_entry(_('Tag'), self.tag)
self.add_filter_entry(_('Custom filter'), self.generic)
self.add_regex_entry(self.filter_regex)
self.add_regex_case(self.sensitive_regex)

def clear(self, obj):
self.filter_id.set_text('')
Expand All @@ -149,6 +151,7 @@ def get_filter(self):
etype = self.filter_event.get_type().xml_str()
rtype = self.filter_family.get_relationship().xml_str()
regex = self.filter_regex.get_active()
usecase = self.sensitive_regex.get_active()
tag = self.tag.get_active() > 0
generic = self.generic.get_active() > 0

Expand All @@ -159,7 +162,7 @@ def get_filter(self):
else:
generic_filter = GenericFamilyFilter()
if gid:
rule = RegExpIdOf([gid], use_regex=regex)
rule = RegExpIdOf([gid], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

if father:
Expand All @@ -169,10 +172,10 @@ def get_filter(self):
if not regex:
name_parts = father.split(sep=" ")
for name_part in name_parts:
rule = RegExpFatherName([name_part], use_regex=regex)
rule = RegExpFatherName([name_part], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)
else:
rule = RegExpFatherName([father], use_regex=regex)
rule = RegExpFatherName([father], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

if mother:
Expand All @@ -182,10 +185,10 @@ def get_filter(self):
if not regex:
name_parts = mother.split(sep=" ")
for name_part in name_parts:
rule = RegExpMotherName([name_part], use_regex=regex)
rule = RegExpMotherName([name_part], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)
else:
rule = RegExpMotherName([mother], use_regex=regex)
rule = RegExpMotherName([mother], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

if child:
Expand All @@ -195,22 +198,22 @@ def get_filter(self):
if not regex:
name_parts = child.split(sep=" ")
for name_part in name_parts:
rule = RegExpChildName([name_part], use_regex=regex)
rule = RegExpChildName([name_part], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)
else:
rule = RegExpChildName([child], use_regex=regex)
rule = RegExpChildName([child], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

if etype:
rule = HasEvent([etype, '', '', '', ''], use_regex=regex)
rule = HasEvent([etype, '', '', '', ''], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

if rtype:
rule = HasRelType([rtype], use_regex=regex)
rule = HasRelType([rtype], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

if note:
rule = HasNoteRegexp([note], use_regex=regex)
rule = HasNoteRegexp([note], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

# check the Tag
Expand Down
9 changes: 6 additions & 3 deletions gramps/gui/filters/sidebar/_mediasidebarfilter.py
Expand Up @@ -64,6 +64,7 @@ def __init__(self, dbstate, uistate, clicked):
self.filter_note = widgets.BasicEntry()

self.filter_regex = Gtk.CheckButton(label=_('Use regular expressions'))
self.sensitive_regex = Gtk.CheckButton(label=_('Case sensitive'))

self.tag = Gtk.ComboBox()
self.generic = Gtk.ComboBox()
Expand Down Expand Up @@ -93,6 +94,7 @@ def create_widget(self):
self.add_entry(_('Tag'), self.tag)
self.add_filter_entry(_('Custom filter'), self.generic)
self.add_regex_entry(self.filter_regex)
self.add_regex_case(self.sensitive_regex)

def clear(self, obj):
self.filter_id.set_text('')
Expand All @@ -112,6 +114,7 @@ def get_filter(self):
date = str(self.filter_date.get_text()).strip()
note = str(self.filter_note.get_text()).strip()
regex = self.filter_regex.get_active()
usecase = self.sensitive_regex.get_active()
tag = self.tag.get_active() > 0
gen = self.generic.get_active() > 0

Expand All @@ -122,14 +125,14 @@ def get_filter(self):
else:
generic_filter = GenericMediaFilter()
if gid:
rule = RegExpIdOf([gid], use_regex=regex)
rule = RegExpIdOf([gid], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

rule = HasMedia([title, mime, path, date], use_regex=regex)
rule = HasMedia([title, mime, path, date], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

if note:
rule = HasNoteRegexp([note], use_regex=regex)
rule = HasNoteRegexp([note], use_regex=regex, use_case=usecase)
generic_filter.add_rule(rule)

# check the Tag
Expand Down

0 comments on commit 8b64b9f

Please sign in to comment.