Skip to content

Commit

Permalink
Merge pull request #1721 from kkujansuu/master
Browse files Browse the repository at this point in the history
  • Loading branch information
Nick-Hall committed Jan 7, 2025
2 parents b5e41a0 + 4a6bf10 commit cc898ef
Show file tree
Hide file tree
Showing 9 changed files with 238 additions and 9 deletions.
4 changes: 4 additions & 0 deletions data/gramps.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ paned>separator {
margin: 0px;
padding: 1px;
}

label.error {
color: @error_color;
}
3 changes: 1 addition & 2 deletions gramps/gen/filters/rules/event/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@
Package providing filter rules for Gramps.
"""

from .._haseventbase import HasEventBase as HasEvent

from ._hastype import HasType
from ._allevents import AllEvents
from ._hasgallery import HasGallery
from ._hasidof import HasIdOf
from ._regexpidof import RegExpIdOf
from ._hascitation import HasCitation
from ._hasevent import HasEvent
from ._hasnote import HasNote
from ._hasnoteregexp import HasNoteRegexp
from ._hasnotematchingsubstringof import HasNoteMatchingSubstringOf
Expand Down
57 changes: 57 additions & 0 deletions gramps/gen/filters/rules/event/_hasevent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2002-2006 Donald N. Allingham
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

"""
Filter rule to match events with a particular value.
"""
# -------------------------------------------------------------------------
#
# Standard Python modules
#
# -------------------------------------------------------------------------
from ....const import GRAMPS_LOCALE as glocale

_ = glocale.translation.gettext

# -------------------------------------------------------------------------
#
# Gramps modules
#
# -------------------------------------------------------------------------
from .._haseventbase import HasEventBase


# -------------------------------------------------------------------------
#
# HasEvent
#
# -------------------------------------------------------------------------
class HasEvent(HasEventBase):
"""Rule that checks for an event with a particular value"""

labels = [
_("Event type:"),
_("Date:"),
_("Place:"),
_("Description:"),
_("Main Participants:"),
]
name = _("Events matching parameters")
description = _("Matches events with particular parameters")
3 changes: 1 addition & 2 deletions gramps/gen/filters/rules/source/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
Package providing filter rules for Gramps.
"""

from .._hassourcebase import HasSourceBase as HasSource

from ._allsources import AllSources
from ._hasattribute import HasAttribute
from ._hasgallery import HasGallery
Expand All @@ -36,6 +34,7 @@
from ._hasnotematchingsubstringof import HasNoteMatchingSubstringOf
from ._hasnotetype import HasNoteType
from ._hasreferencecountof import HasReferenceCountOf
from ._hassource import HasSource
from ._sourceprivate import SourcePrivate
from ._matchesfilter import MatchesFilter
from ._changedsince import ChangedSince
Expand Down
51 changes: 51 additions & 0 deletions gramps/gen/filters/rules/source/_hassource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2002-2006 Donald N. Allingham
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

"""
Filter rule to match sources with a particular value.
"""
# -------------------------------------------------------------------------
#
# Standard Python modules
#
# -------------------------------------------------------------------------
from ....const import GRAMPS_LOCALE as glocale

_ = glocale.translation.gettext

# -------------------------------------------------------------------------
#
# Gramps modules
#
# -------------------------------------------------------------------------
from .._hassourcebase import HasSourceBase


# -------------------------------------------------------------------------
#
# HasSource
#
# -------------------------------------------------------------------------
class HasSource(HasSourceBase):
"""Rule that checks for a source with a particular value"""

labels = [_("Title:"), _("Author:"), _("Abbreviation:"), _("Publication:")]
name = _("Sources matching parameters")
description = _("Matches sources with particular parameters")
2 changes: 1 addition & 1 deletion gramps/gui/filters/sidebar/_citationsidebarfilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __init__(self, dbstate, uistate, clicked):
for conf_value in sorted(conf_strings.keys()):
model.append((_(conf_strings[conf_value]),))
self.filter_conf.set_model(model)
self.filter_conf.set_active(Citation.CONF_NORMAL)
self.filter_conf.set_active(Citation.CONF_VERY_LOW)

self.filter_note = Gtk.Entry()

Expand Down
22 changes: 18 additions & 4 deletions gramps/gui/filters/sidebar/_personsidebarfilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ def __init__(self, dbstate, uistate, clicked):
self.filter_name = widgets.BasicEntry()
self.filter_id = widgets.BasicEntry()
self.filter_birth = widgets.DateEntry(uistate, [])
self.filter_birth_place = widgets.BasicEntry()
self.filter_death = widgets.DateEntry(uistate, [])
self.filter_death_place = widgets.BasicEntry()
self.filter_event = Event()
self.filter_event.set_type((EventType.CUSTOM, ""))
self.etype = Gtk.ComboBox(has_entry=True)
Expand Down Expand Up @@ -163,11 +165,13 @@ def create_widget(self):
self.filter_birth,
_('example: "%(msg1)s" or "%(msg2)s"') % {"msg1": msg1, "msg2": msg2},
)
self.add_text_entry(_("Birth place"), self.filter_birth_place)
self.add_text_entry(
_("Death date"),
self.filter_death,
_('example: "%(msg1)s" or "%(msg2)s"') % {"msg1": msg1, "msg2": msg2},
)
self.add_text_entry(_("Death place"), self.filter_death_place)
self.add_entry(_("Event"), self.etype)
self.add_text_entry(_("Note"), self.filter_note)
self.add_entry(_("Tag"), self.tag)
Expand All @@ -179,7 +183,9 @@ def clear(self, obj):
self.filter_name.set_text("")
self.filter_id.set_text("")
self.filter_birth.set_text("")
self.filter_birth_place.set_text("")
self.filter_death.set_text("")
self.filter_death_place.set_text("")
self.filter_note.set_text("")
self.filter_gender.set_active(0)
self.etype.get_child().set_text("")
Expand All @@ -196,7 +202,9 @@ def get_filter(self):
name = extract_text(self.filter_name)
gid = extract_text(self.filter_id)
birth = extract_text(self.filter_birth)
birth_place = extract_text(self.filter_birth_place)
death = extract_text(self.filter_death)
death_place = extract_text(self.filter_death_place)
note = extract_text(self.filter_note)

# extract remaining data from the menus
Expand All @@ -214,7 +222,9 @@ def get_filter(self):
name
or gid
or birth
or birth_place
or death
or death_place
or etype
or note
or gender
Expand Down Expand Up @@ -271,13 +281,17 @@ def get_filter(self):
# Arguments for the HasBirth filter are Date, Place, and Description
# Since the value we extracted to the "birth" variable is the
# request date, we pass it as the first argument
if birth:
rule = HasBirth([birth, "", ""])
if birth or birth_place:
rule = HasBirth(
[birth, birth_place, ""], use_regex=regex, use_case=usecase
)
generic_filter.add_rule(rule)

# Build death event filter if needed
if death:
rule = HasDeath([death, "", ""])
if death or death_place:
rule = HasDeath(
[death, death_place, ""], use_regex=regex, use_case=usecase
)
generic_filter.add_rule(rule)

# Build note filter if needed
Expand Down
103 changes: 103 additions & 0 deletions gramps/gui/filters/sidebar/_sidebarfilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,21 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

# -------------------------------------------------------------------------
#
# Python modules
#
# -------------------------------------------------------------------------
import time

# -------------------------------------------------------------------------
#
# Gramps modules
#
# -------------------------------------------------------------------------

from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gen.filters import reload_custom_filters

_ = glocale.translation.gettext
from bisect import insort_left
Expand All @@ -32,6 +46,11 @@
from gramps.gen.config import config
from ...utils import no_match_primary_mask

from ...editors import EditFilter
import gramps.gen.filters

# import gramps.gen.filters.rules.place

_RETURN = Gdk.keyval_from_name("Return")
_KP_ENTER = Gdk.keyval_from_name("KP_Enter")

Expand Down Expand Up @@ -68,6 +87,17 @@ def __init__(self, dbstate, uistate, namespace):
"defaults."
)
)
self.define_filter_btn = Gtk.Button(_("Define filter"))
self.define_filter_btn.set_tooltip_text(
_(
"This opens a dialog to add a new custom filter "
"based on the values given."
)
)

self.msg_label = Gtk.Label()
self.msg_label.set_halign(Gtk.Align.START)
self.msg_label.set_margin_left(12)

self._init_interface()
uistate.connect("filters-changed", self.on_filters_changed)
Expand Down Expand Up @@ -96,6 +126,7 @@ def _init_interface(self):

self.clear_btn.add(hbox)
self.clear_btn.connect("clicked", self.clear)
self.clear_btn.set_halign(Gtk.Align.END)

hbox = Gtk.ButtonBox()
hbox.set_layout(Gtk.ButtonBoxStyle.START)
Expand All @@ -105,6 +136,17 @@ def _init_interface(self):
hbox.add(self.clear_btn)
hbox.show()
self.vbox.pack_start(hbox, False, False, 0)

self.define_filter_btn.connect("clicked", self.define_filter)
hbox = Gtk.ButtonBox()
hbox.set_layout(Gtk.ButtonBoxStyle.START)
hbox.set_spacing(6)
hbox.set_border_width(12)
hbox.add(self.define_filter_btn)

self.vbox.pack_start(hbox, False, False, 0)
self.vbox.pack_start(self.msg_label, False, False, 0)

self.vbox.show()

def get_widget(self):
Expand All @@ -117,8 +159,15 @@ def clear(self, obj):
pass

def clicked(self, obj):
if not self.filter_is_ok():
return
self.uistate.set_busy_cursor(True)
t1 = time.perf_counter()
self.clicked_func()
t2 = time.perf_counter()
msg = _("Elapsed time: %.2fs") % (t2 - t1)
self.msg_label.set_text(msg)
self.msg_label.get_style_context().remove_class("error")
self.uistate.set_busy_cursor(False)

def clicked_func(self):
Expand Down Expand Up @@ -316,3 +365,57 @@ def set_filters_to_name(self, filter_name):
self.generic.set_active_iter(iter)
break
iter = liststore.iter_next(iter)

def filter_is_ok(self):
the_filter = self.get_filter()
if the_filter is None:
return True
for rule in the_filter.get_rules():
if isinstance(rule, gramps.gen.filters.rules.place.WithinArea):
if rule.list[0] is None: # No active place
msg = _("You should select a place when using the 'Within' rule")
self.msg_label.set_text(msg)
self.msg_label.get_style_context().add_class("error")
return False
return True

def define_filter(self, _obj):
self.filterdb = gramps.gen.filters.CustomFilters
the_filter = self.get_filter()
if the_filter is None:
self.msg_label.set_text(_("Supply at least one value"))
self.msg_label.get_style_context().add_class("error")
return

if not self.filter_is_ok():
return
# fix some rules:
new_rules = []
for rule in the_filter.get_rules():
# The Place rule WithinArea might have numeric values while custom_filters.xml only accepts strings.
if isinstance(rule, gramps.gen.filters.rules.place.WithinArea):
rule.list[1] = str(rule.list[1])
rule.list[2] = str(rule.list[2])
new_rules.append(rule)
the_filter.flist = new_rules
comment = _("Created by Filter gramplet on {today}").format(
today=time.strftime("%Y-%m-%d", time.localtime())
)
the_filter.set_comment(comment)

self.msg_label.set_text("")
track = []
EditFilter(
self.namespace,
self.dbstate,
self.uistate,
track,
the_filter,
self.filterdb,
update=self.update,
)

def update(self):
self.filterdb.save()
reload_custom_filters()
self.uistate.emit("filters-changed", (self.namespace,))
Loading

0 comments on commit cc898ef

Please sign in to comment.