From daedc4961b8f333949fca63696cd9d9ad600843d Mon Sep 17 00:00:00 2001 From: Alex Roitman Date: Wed, 3 May 2006 01:02:54 +0000 Subject: [PATCH] * src/GenericFilters.py: Remove. * src/Filters: Move filtering to its own package. svn: r6521 --- gramps2/ChangeLog | 3 + gramps2/src/DataViews/_PersonView.py | 50 +- gramps2/src/Filters/Makefile.am | 28 + gramps2/src/Filters/Rules/Makefile.am | 74 + gramps2/src/Filters/Rules/_Disconnected.py | 52 + gramps2/src/Filters/Rules/_Everyone.py | 53 + .../Rules/_FamilyWithIncompleteEvent.py | 58 + gramps2/src/Filters/Rules/_HasAttribute.py | 60 + gramps2/src/Filters/Rules/_HasBirth.py | 80 + .../Filters/Rules/_HasCommonAncestorWith.py | 83 + .../_HasCommonAncestorWithFilterMatch.py | 66 + .../src/Filters/Rules/_HasCompleteRecord.py | 50 + gramps2/src/Filters/Rules/_HasDeath.py | 80 + gramps2/src/Filters/Rules/_HasEvent.py | 85 + .../src/Filters/Rules/_HasFamilyAttribute.py | 62 + gramps2/src/Filters/Rules/_HasFamilyEvent.py | 92 + gramps2/src/Filters/Rules/_HasIdOf.py | 51 + gramps2/src/Filters/Rules/_HasNameOf.py | 70 + gramps2/src/Filters/Rules/_HasNote.py | 48 + .../Rules/_HasNoteMatchingSubstringOf.py | 52 + gramps2/src/Filters/Rules/_HasRelationship.py | 86 + gramps2/src/Filters/Rules/_HasSourceOf.py | 59 + .../Filters/Rules/_HasTextMatchingRegexpOf.py | 56 + .../Rules/_HasTextMatchingSubstringOf.py | 197 ++ .../src/Filters/Rules/_HasUnknownGender.py | 51 + gramps2/src/Filters/Rules/_HaveAltFamilies.py | 53 + gramps2/src/Filters/Rules/_HaveChildren.py | 50 + gramps2/src/Filters/Rules/_HavePhotos.py | 48 + gramps2/src/Filters/Rules/_IncompleteNames.py | 55 + gramps2/src/Filters/Rules/_IsAncestorOf.py | 88 + .../Filters/Rules/_IsAncestorOfFilterMatch.py | 80 + gramps2/src/Filters/Rules/_IsBookmarked.py | 58 + .../Filters/Rules/_IsChildOfFilterMatch.py | 75 + gramps2/src/Filters/Rules/_IsDefaultPerson.py | 58 + .../Filters/Rules/_IsDescendantFamilyOf.py | 83 + gramps2/src/Filters/Rules/_IsDescendantOf.py | 83 + .../Rules/_IsDescendantOfFilterMatch.py | 80 + gramps2/src/Filters/Rules/_IsFemale.py | 51 + .../_IsLessThanNthGenerationAncestorOf.py | 87 + ...ssThanNthGenerationAncestorOfBookmarked.py | 93 + ...hanNthGenerationAncestorOfDefaultPerson.py | 91 + .../_IsLessThanNthGenerationDescendantOf.py | 79 + gramps2/src/Filters/Rules/_IsMale.py | 51 + .../_IsMoreThanNthGenerationAncestorOf.py | 85 + .../_IsMoreThanNthGenerationDescendantOf.py | 77 + .../Filters/Rules/_IsParentOfFilterMatch.py | 74 + .../Filters/Rules/_IsSiblingOfFilterMatch.py | 76 + .../Filters/Rules/_IsSpouseOfFilterMatch.py | 66 + gramps2/src/Filters/Rules/_IsWitness.py | 84 + gramps2/src/Filters/Rules/_MatchesFilter.py | 78 + .../src/Filters/Rules/_MultipleMarriages.py | 48 + gramps2/src/Filters/Rules/_NeverMarried.py | 48 + gramps2/src/Filters/Rules/_NoBirthdate.py | 54 + gramps2/src/Filters/Rules/_PeoplePrivate.py | 48 + .../Rules/_PersonWithIncompleteEvent.py | 56 + gramps2/src/Filters/Rules/_ProbablyAlive.py | 56 + .../Filters/Rules/_RelationshipPathBetween.py | 133 + gramps2/src/Filters/Rules/_Rule.py | 75 + gramps2/src/Filters/Rules/_RuleUtils.py | 39 + gramps2/src/Filters/Rules/_SearchName.py | 54 + gramps2/src/Filters/Rules/__init__.py | 146 + gramps2/src/Filters/_FilterComboBox.py | 96 + gramps2/src/Filters/_FilterList.py | 107 + gramps2/src/Filters/_FilterMenu.py | 72 + gramps2/src/Filters/_FilterParser.py | 179 ++ gramps2/src/Filters/_FilterStore.py | 75 + gramps2/src/Filters/_FilterWidget.py | 128 + gramps2/src/Filters/_GenericFilter.py | 185 ++ gramps2/src/Filters/_ParamFilter.py | 65 + gramps2/src/Filters/__init__.py | 57 + gramps2/src/GenericFilter.py | 2701 ----------------- gramps2/src/GrampsDb/_WriteGedcom.py | 22 +- gramps2/src/Makefile.am | 4 +- .../src/ObjectSelector/_FilterFrameBase.py | 2 +- .../src/ObjectSelector/_PersonFilterFrame.py | 64 +- gramps2/src/PageView.py | 12 +- gramps2/src/PluginUtils/_Report.py | 8 +- gramps2/src/PluginUtils/_Tool.py | 4 +- gramps2/src/plugins/Calendar.py | 28 +- gramps2/src/plugins/EventCmp.py | 8 +- gramps2/src/plugins/ExportVCalendar.py | 22 +- gramps2/src/plugins/ExportVCard.py | 22 +- gramps2/src/plugins/FilterEditor.py | 23 +- gramps2/src/plugins/GraphViz.py | 20 +- gramps2/src/plugins/IndivComplete.py | 24 +- gramps2/src/plugins/NarrativeWeb.py | 24 +- gramps2/src/plugins/StatisticsChart.py | 20 +- gramps2/src/plugins/TimeLine.py | 20 +- gramps2/src/plugins/WriteFtree.py | 22 +- gramps2/src/plugins/WriteGeneWeb.py | 23 +- 90 files changed, 5332 insertions(+), 2911 deletions(-) create mode 100644 gramps2/src/Filters/Makefile.am create mode 100644 gramps2/src/Filters/Rules/Makefile.am create mode 100644 gramps2/src/Filters/Rules/_Disconnected.py create mode 100644 gramps2/src/Filters/Rules/_Everyone.py create mode 100644 gramps2/src/Filters/Rules/_FamilyWithIncompleteEvent.py create mode 100644 gramps2/src/Filters/Rules/_HasAttribute.py create mode 100644 gramps2/src/Filters/Rules/_HasBirth.py create mode 100644 gramps2/src/Filters/Rules/_HasCommonAncestorWith.py create mode 100644 gramps2/src/Filters/Rules/_HasCommonAncestorWithFilterMatch.py create mode 100644 gramps2/src/Filters/Rules/_HasCompleteRecord.py create mode 100644 gramps2/src/Filters/Rules/_HasDeath.py create mode 100644 gramps2/src/Filters/Rules/_HasEvent.py create mode 100644 gramps2/src/Filters/Rules/_HasFamilyAttribute.py create mode 100644 gramps2/src/Filters/Rules/_HasFamilyEvent.py create mode 100644 gramps2/src/Filters/Rules/_HasIdOf.py create mode 100644 gramps2/src/Filters/Rules/_HasNameOf.py create mode 100644 gramps2/src/Filters/Rules/_HasNote.py create mode 100644 gramps2/src/Filters/Rules/_HasNoteMatchingSubstringOf.py create mode 100644 gramps2/src/Filters/Rules/_HasRelationship.py create mode 100644 gramps2/src/Filters/Rules/_HasSourceOf.py create mode 100644 gramps2/src/Filters/Rules/_HasTextMatchingRegexpOf.py create mode 100644 gramps2/src/Filters/Rules/_HasTextMatchingSubstringOf.py create mode 100644 gramps2/src/Filters/Rules/_HasUnknownGender.py create mode 100644 gramps2/src/Filters/Rules/_HaveAltFamilies.py create mode 100644 gramps2/src/Filters/Rules/_HaveChildren.py create mode 100644 gramps2/src/Filters/Rules/_HavePhotos.py create mode 100644 gramps2/src/Filters/Rules/_IncompleteNames.py create mode 100644 gramps2/src/Filters/Rules/_IsAncestorOf.py create mode 100644 gramps2/src/Filters/Rules/_IsAncestorOfFilterMatch.py create mode 100644 gramps2/src/Filters/Rules/_IsBookmarked.py create mode 100644 gramps2/src/Filters/Rules/_IsChildOfFilterMatch.py create mode 100644 gramps2/src/Filters/Rules/_IsDefaultPerson.py create mode 100644 gramps2/src/Filters/Rules/_IsDescendantFamilyOf.py create mode 100644 gramps2/src/Filters/Rules/_IsDescendantOf.py create mode 100644 gramps2/src/Filters/Rules/_IsDescendantOfFilterMatch.py create mode 100644 gramps2/src/Filters/Rules/_IsFemale.py create mode 100644 gramps2/src/Filters/Rules/_IsLessThanNthGenerationAncestorOf.py create mode 100644 gramps2/src/Filters/Rules/_IsLessThanNthGenerationAncestorOfBookmarked.py create mode 100644 gramps2/src/Filters/Rules/_IsLessThanNthGenerationAncestorOfDefaultPerson.py create mode 100644 gramps2/src/Filters/Rules/_IsLessThanNthGenerationDescendantOf.py create mode 100644 gramps2/src/Filters/Rules/_IsMale.py create mode 100644 gramps2/src/Filters/Rules/_IsMoreThanNthGenerationAncestorOf.py create mode 100644 gramps2/src/Filters/Rules/_IsMoreThanNthGenerationDescendantOf.py create mode 100644 gramps2/src/Filters/Rules/_IsParentOfFilterMatch.py create mode 100644 gramps2/src/Filters/Rules/_IsSiblingOfFilterMatch.py create mode 100644 gramps2/src/Filters/Rules/_IsSpouseOfFilterMatch.py create mode 100644 gramps2/src/Filters/Rules/_IsWitness.py create mode 100644 gramps2/src/Filters/Rules/_MatchesFilter.py create mode 100644 gramps2/src/Filters/Rules/_MultipleMarriages.py create mode 100644 gramps2/src/Filters/Rules/_NeverMarried.py create mode 100644 gramps2/src/Filters/Rules/_NoBirthdate.py create mode 100644 gramps2/src/Filters/Rules/_PeoplePrivate.py create mode 100644 gramps2/src/Filters/Rules/_PersonWithIncompleteEvent.py create mode 100644 gramps2/src/Filters/Rules/_ProbablyAlive.py create mode 100644 gramps2/src/Filters/Rules/_RelationshipPathBetween.py create mode 100644 gramps2/src/Filters/Rules/_Rule.py create mode 100644 gramps2/src/Filters/Rules/_RuleUtils.py create mode 100644 gramps2/src/Filters/Rules/_SearchName.py create mode 100644 gramps2/src/Filters/Rules/__init__.py create mode 100644 gramps2/src/Filters/_FilterComboBox.py create mode 100644 gramps2/src/Filters/_FilterList.py create mode 100644 gramps2/src/Filters/_FilterMenu.py create mode 100644 gramps2/src/Filters/_FilterParser.py create mode 100644 gramps2/src/Filters/_FilterStore.py create mode 100644 gramps2/src/Filters/_FilterWidget.py create mode 100644 gramps2/src/Filters/_GenericFilter.py create mode 100644 gramps2/src/Filters/_ParamFilter.py create mode 100644 gramps2/src/Filters/__init__.py delete mode 100644 gramps2/src/GenericFilter.py diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index 92ee19a5e..cf4077601 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -3,6 +3,9 @@ * data/gramps.schemas.in: add family-warn back in 2006-05-02 Alex Roitman + * src/GenericFilters.py: Remove. + * src/Filters: Move filtering to its own package. + * src/RelLib/_BaseObject.py (PrivacyBase): Remove class, as it already has its own module. * src/AutoComp.py (StandardCustomSelector.fill): Adapt to new types. diff --git a/gramps2/src/DataViews/_PersonView.py b/gramps2/src/DataViews/_PersonView.py index 3d0ffc351..176e316fb 100644 --- a/gramps2/src/DataViews/_PersonView.py +++ b/gramps2/src/DataViews/_PersonView.py @@ -52,7 +52,7 @@ from gtk.gdk import ACTION_COPY, BUTTON1_MASK import RelLib import PeopleModel import PageView -import GenericFilter +from Filters import FilterWidget, Rules import NameDisplay import Utils import QuestionDialog @@ -164,7 +164,7 @@ class PersonView(PageView.PersonNavView): self.vbox.set_border_width(4) self.vbox.set_spacing(4) - self.generic_filter_widget = GenericFilter.FilterWidget( self.uistate, self.build_tree, self.goto_active_person) + self.generic_filter_widget = FilterWidget( self.uistate, self.build_tree, self.goto_active_person) filter_box = self.generic_filter_widget.build() @@ -348,29 +348,29 @@ class PersonView(PageView.PersonNavView): Builds the default filters and add them to the filter menu. """ default_filters = [ - [GenericFilter.Everyone, []], - [GenericFilter.IsFemale, []], - [GenericFilter.IsMale, []], - [GenericFilter.HasUnknownGender, []], - [GenericFilter.Disconnected, []], - [GenericFilter.SearchName, ['']], - [GenericFilter.HaveAltFamilies, []], - [GenericFilter.HavePhotos, []], - [GenericFilter.IncompleteNames, []], - [GenericFilter.HaveChildren, []], - [GenericFilter.NeverMarried, []], - [GenericFilter.MultipleMarriages, []], - [GenericFilter.NoBirthdate, []], - [GenericFilter.PersonWithIncompleteEvent, []], - [GenericFilter.FamilyWithIncompleteEvent, []], - [GenericFilter.ProbablyAlive, ['']], - [GenericFilter.PeoplePrivate, []], - [GenericFilter.IsWitness, ['','']], - [GenericFilter.HasTextMatchingSubstringOf, ['',0,0]], - [GenericFilter.HasTextMatchingRegexpOf, ['',0,1]], - [GenericFilter.HasNote, []], - [GenericFilter.HasNoteMatchingSubstringOf, ['']], - [GenericFilter.IsFemale, []], + [Rules.Everyone, []], + [Rules.IsFemale, []], + [Rules.IsMale, []], + [Rules.HasUnknownGender, []], + [Rules.Disconnected, []], + [Rules.SearchName, ['']], + [Rules.HaveAltFamilies, []], + [Rules.HavePhotos, []], + [Rules.IncompleteNames, []], + [Rules.HaveChildren, []], + [Rules.NeverMarried, []], + [Rules.MultipleMarriages, []], + [Rules.NoBirthdate, []], + [Rules.PersonWithIncompleteEvent, []], + [Rules.FamilyWithIncompleteEvent, []], + [Rules.ProbablyAlive, ['']], + [Rules.PeoplePrivate, []], + [Rules.IsWitness, ['','']], + [Rules.HasTextMatchingSubstringOf, ['',0,0]], + [Rules.HasTextMatchingRegexpOf, ['',0,1]], + [Rules.HasNote, []], + [Rules.HasNoteMatchingSubstringOf, ['']], + [Rules.IsFemale, []], ] self.generic_filter_widget.setup_filter( default_filters, "person") diff --git a/gramps2/src/Filters/Makefile.am b/gramps2/src/Filters/Makefile.am new file mode 100644 index 000000000..36e2d617c --- /dev/null +++ b/gramps2/src/Filters/Makefile.am @@ -0,0 +1,28 @@ +# This is the src/Filters level Makefile for Gramps + +SUBDIRS = Filters + +pkgdatadir = $(datadir)/@PACKAGE@/Filters + +pkgdata_PYTHON = \ + _FilterComboBox.py \ + _FilterList.py \ + _FilterMenu.py \ + _FilterParser.py \ + _FilterStore.py \ + _FilterWidget.py \ + _GenericFilter.py \ + _ParamFilter.py \ + __init__.py + +pkgpyexecdir = @pkgpyexecdir@/Filters +pkgpythondir = @pkgpythondir@/Filters + +# Clean up all the byte-compiled files +MOSTLYCLEANFILES = *pyc *pyo + +GRAMPS_PY_MODPATH = "../" + +pycheck: + (export PYTHONPATH=$(GRAMPS_PY_MODPATH); \ + pychecker $(pkgdata_PYTHON)); diff --git a/gramps2/src/Filters/Rules/Makefile.am b/gramps2/src/Filters/Rules/Makefile.am new file mode 100644 index 000000000..a135ce0df --- /dev/null +++ b/gramps2/src/Filters/Rules/Makefile.am @@ -0,0 +1,74 @@ +# This is the src/Filters/Rules level Makefile for Gramps + +pkgdatadir = $(datadir)/@PACKAGE@/Filters/Rules + +pkgdata_PYTHON = \ + _Disconnected.py \ + _Everyone.py \ + _FamilyWithIncompleteEvent.py \ + _HasAttribute.py \ + _HasBirth.py \ + _HasCommonAncestorWith.py \ + _HasCommonAncestorWithFilterMatch.py \ + _HasCompleteRecord.py \ + _HasDeath.py \ + _HasEvent.py \ + _HasFamilyAttribute.py \ + _HasFamilyEvent.py \ + _HasIdOf.py \ + _HasNameOf.py \ + _HasNote.py \ + _HasNoteMatchingSubstringOf.py \ + _HasRelationship.py \ + _HasSourceOf.py \ + _HasTextMatchingRegexpOf.py \ + _HasTextMatchingSubstringOf.py \ + _HasUnknownGender.py \ + _HaveAltFamilies.py \ + _HaveChildren.py \ + _HavePhotos.py \ + _IncompleteNames.py \ + _IsAncestorOf.py \ + _IsAncestorOfFilterMatch.py \ + _IsBookmarked.py \ + _IsChildOfFilterMatch.py \ + _IsDefaultPerson.py \ + _IsDescendantFamilyOf.py \ + _IsDescendantOf.py \ + _IsDescendantOfFilterMatch.py \ + _IsFemale.py \ + _IsLessThanNthGenerationAncestorOf.py \ + _IsLessThanNthGenerationAncestorOfBookmarked.py \ + _IsLessThanNthGenerationAncestorOfDefaultPerson.py \ + _IsLessThanNthGenerationDescendantOf.py \ + _IsMale.py \ + _IsMoreThanNthGenerationAncestorOf.py \ + _IsMoreThanNthGenerationDescendantOf.py \ + _IsParentOfFilterMatch.py \ + _IsSiblingOfFilterMatch.py \ + _IsSpouseOfFilterMatch.py \ + _IsWitness.py \ + _MatchesFilter.py \ + _MultipleMarriages.py \ + _NeverMarried.py \ + _NoBirthdate.py \ + _PeoplePrivate.py \ + _PersonWithIncompleteEvent.py \ + _ProbablyAlive.py \ + _RelationshipPathBetween.py \ + _Rule.py \ + _RuleUtils.py \ + _SearchName.py \ + __init__.py + +pkgpyexecdir = @pkgpyexecdir@/Filters/Rules +pkgpythondir = @pkgpythondir@/Filters/Rules + +# Clean up all the byte-compiled files +MOSTLYCLEANFILES = *pyc *pyo + +GRAMPS_PY_MODPATH = "../" + +pycheck: + (export PYTHONPATH=$(GRAMPS_PY_MODPATH); \ + pychecker $(pkgdata_PYTHON)); diff --git a/gramps2/src/Filters/Rules/_Disconnected.py b/gramps2/src/Filters/Rules/_Disconnected.py new file mode 100644 index 000000000..478fa52a3 --- /dev/null +++ b/gramps2/src/Filters/Rules/_Disconnected.py @@ -0,0 +1,52 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# Disconnected +# +#------------------------------------------------------------------------- +class Disconnected(Rule): + """Matches disconnected people""" + + name = _('Disconnected people') + category = _('General filters') + description = _('Matches people that have no family relationships ' + 'to any other person in the database') + + def apply(self,db,person): + return (len(person.get_main_parents_family_handle()) + + len(person.get_family_handle_list()) == 0) diff --git a/gramps2/src/Filters/Rules/_Everyone.py b/gramps2/src/Filters/Rules/_Everyone.py new file mode 100644 index 000000000..ce0650d67 --- /dev/null +++ b/gramps2/src/Filters/Rules/_Everyone.py @@ -0,0 +1,53 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# Everyone +# +#------------------------------------------------------------------------- +class Everyone(Rule): + """Matches Everyone""" + + name = _('Everyone') + category = _('General filters') + description = _('Matches everyone in the database') + + def is_empty(self): + return True + + def apply(self,db,person): + return True diff --git a/gramps2/src/Filters/Rules/_FamilyWithIncompleteEvent.py b/gramps2/src/Filters/Rules/_FamilyWithIncompleteEvent.py new file mode 100644 index 000000000..d3dfeb219 --- /dev/null +++ b/gramps2/src/Filters/Rules/_FamilyWithIncompleteEvent.py @@ -0,0 +1,58 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# "Families with incomplete events" +#------------------------------------------------------------------------- +class FamilyWithIncompleteEvent(Rule): + """Families with incomplete events""" + + name = _('Families with incomplete events') + description = _("Matches people with missing date or " + "place in an event of the family") + category = _('Event filters') + + def apply(self,db,person): + for family_handle in person.get_family_handle_list(): + family = db.get_family_from_handle(family_handle) + for event_handle in family.get_event_list(): + event = db.get_event_from_handle(event_handle) + if event: + if not event.get_place_handle(): + return True + if not event.get_date_object(): + return True + return False diff --git a/gramps2/src/Filters/Rules/_HasAttribute.py b/gramps2/src/Filters/Rules/_HasAttribute.py new file mode 100644 index 000000000..0bcd18162 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasAttribute.py @@ -0,0 +1,60 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# HasAttribute +# +#------------------------------------------------------------------------- +class HasAttribute(Rule): + """Rule that checks for a person with a particular personal attribute""" + + labels = [ _('Personal attribute:'), _('Value:') ] + name = _('People with the personal ') + description = _("Matches people with the personal attribute " + "of a particular value") + category = _('General filters') + + def apply(self,db,person): + if not self.list[0]: + return False + for attr in person.get_attribute_list(): + name_match = self.list[0] == attr.get_type() + value_match = \ + attr.get_value().upper().find(self.list[1].upper()) != -1 + if name_match and value_match: + return True + return False diff --git a/gramps2/src/Filters/Rules/_HasBirth.py b/gramps2/src/Filters/Rules/_HasBirth.py new file mode 100644 index 000000000..0c61eacff --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasBirth.py @@ -0,0 +1,80 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +import DateHandler +from _Rule import Rule +from _RuleUtils import date_cmp + +#------------------------------------------------------------------------- +# +# HasBirth +# +#------------------------------------------------------------------------- +class HasBirth(Rule): + """Rule that checks for a person with a birth of a particular value""" + + labels = [ _('Date:'), _('Place:'), _('Description:') ] + name = _('People with the ') + description = _("Matches people with birth data of a particular value") + category = _('Event filters') + + def __init__(self,list): + Rule.__init__(self,list) + if self.list[0]: + self.date = DateHandler.parser.parse(self.list[0]) + else: + self.date = None + + def apply(self,db,person): + event_ref = person.get_birth_ref() + if not event_ref: + return False + event = db.get_event_from_handle(event_ref.ref) + ed = event.get_description().upper() + if self.list[2] \ + and ed.find(self.list[2].upper())==-1: + return False + if self.date: + if date_cmp(self.date,event.get_date_object()) == 0: + return False + if self.list[1]: + pl_id = event.get_place_handle() + if pl_id: + pl = db.get_place_from_handle(pl_id) + pn = pl.get_title().upper() + if pn.find(self.list[1].upper()) == -1: + return False + else: + return False + return True diff --git a/gramps2/src/Filters/Rules/_HasCommonAncestorWith.py b/gramps2/src/Filters/Rules/_HasCommonAncestorWith.py new file mode 100644 index 000000000..63c4935b6 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasCommonAncestorWith.py @@ -0,0 +1,83 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from Utils import for_each_ancestor +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# HasCommonAncestorWith +# +#------------------------------------------------------------------------- +class HasCommonAncestorWith(Rule): + """Rule that checks for a person that has a common ancestor with a specified person""" + + labels = [ _('ID:') ] + name = _('People with a common ancestor with ') + category = _("Ancestral filters") + description = _("Matches people that have a common ancestor " + "with a specified person") + + def prepare(self,db): + self.db = db + # Keys in `ancestor_cache' are ancestors of list[0]. + # We delay the computation of ancestor_cache until the + # first use, because it's not uncommon to instantiate + # this class and not use it. + self.ancestor_cache = {} + + def reset(self): + self.ancestor_cache = {} + + def init_ancestor_cache(self,db): + # list[0] is an Id, but we need to pass a Person to for_each_ancestor. + try: + handle = db.get_person_from_gramps_id(self.list[0]).get_handle() + if handle: + def init(self,handle): self.ancestor_cache[handle] = 1 + for_each_ancestor(db,[handle],init,self) + except: + pass + + def apply(self,db,person): + # On the first call, we build the ancestor cache for the + # reference person. Then, for each person to test, + # we browse his ancestors until we found one in the cache. + if len(self.ancestor_cache) == 0: + self.init_ancestor_cache(db) + handle = person.handle + return for_each_ancestor( + db,[handle], + lambda self,handle: self.ancestor_cache.has_key(handle), + self); diff --git a/gramps2/src/Filters/Rules/_HasCommonAncestorWithFilterMatch.py b/gramps2/src/Filters/Rules/_HasCommonAncestorWithFilterMatch.py new file mode 100644 index 000000000..a675644c8 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasCommonAncestorWithFilterMatch.py @@ -0,0 +1,66 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from Utils import for_each_ancestor +from _HasCommonAncestorWith import HasCommonAncestorWith +from _MatchesFilter import MatchesFilter + +#------------------------------------------------------------------------- +# +# HasCommonAncestorWithFilterMatch +# +#------------------------------------------------------------------------- +class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith): + """Rule that checks for a person that has a common ancestor with + someone matching a filter""" + + labels = [ _('Filter name:') ] + name = _('People with a common ancestor with match') + description = _("Matches people that have a common ancestor " + "with anybody matched by a filter") + category = _("Ancestral filters") + + def __init__(self,list): + HasCommonAncestorWith.__init__(self,list) + self.ancestor_cache = {} + + def init_ancestor_cache(self,db): + filt = MatchesFilter(self.list) + filt.prepare(db) + def init(self,h): self.ancestor_cache[h] = 1 + for handle in db.get_person_handles(sort_handles=False): + if (not self.ancestor_cache.has_key (handle) + and filt.apply (db, db.get_person_from_handle(handle))): + for_each_ancestor(db,[handle],init,self) + filt.reset() diff --git a/gramps2/src/Filters/Rules/_HasCompleteRecord.py b/gramps2/src/Filters/Rules/_HasCompleteRecord.py new file mode 100644 index 000000000..d6e5efd80 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasCompleteRecord.py @@ -0,0 +1,50 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# HasCompleteRecord +# +#------------------------------------------------------------------------- +class HasCompleteRecord(Rule): + """Rule that checks for a person whose record is complete""" + + name = _('People with complete records') + category = _('General filters') + description = _('Matches all people whose records are complete') + + def apply(self,db,person): + return person.get_complete_flag() == 1 diff --git a/gramps2/src/Filters/Rules/_HasDeath.py b/gramps2/src/Filters/Rules/_HasDeath.py new file mode 100644 index 000000000..ae92007fc --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasDeath.py @@ -0,0 +1,80 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +import DateHandler +from _Rule import Rule +from _RuleUtils import date_cmp + +#------------------------------------------------------------------------- +# +# HasDeath +# +#------------------------------------------------------------------------- +class HasDeath(Rule): + """Rule that checks for a person with a death of a particular value""" + + labels = [ _('Date:'), _('Place:'), _('Description:') ] + name = _('People with the ') + description = _("Matches people with death data of a particular value") + category = _('Event filters') + + def __init__(self,list): + Rule.__init__(self,list) + if self.list[0]: + self.date = DateHandler.parser.parse(self.list[0]) + else: + self.date = None + + def apply(self,db,person): + event_handle = person.get_death_handle() + if not event_handle: + return False + event = db.get_event_from_handle(event_handle) + ed = event.get_description().upper() + if self.list[2] \ + and ed.find(self.list[2].upper())==-1: + return False + if self.date: + if date_cmp(self.date,event.get_date_object()) == 0: + return False + if self.list[1]: + pl_id = event.get_place_handle() + if pl_id: + pl = db.get_place_from_handle(pl_id) + pn = pl.get_title().upper() + if self.list[1] and pn.find(self.list[1].upper()) == -1: + return False + else: + return False + return True diff --git a/gramps2/src/Filters/Rules/_HasEvent.py b/gramps2/src/Filters/Rules/_HasEvent.py new file mode 100644 index 000000000..1188d897f --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasEvent.py @@ -0,0 +1,85 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +import DateHandler +from _Rule import Rule +from _RuleUtils import date_cmp + +#------------------------------------------------------------------------- +# +# HasEvent +# +#------------------------------------------------------------------------- +class HasEvent(Rule): + """Rule that checks for a person with a particular value""" + + labels = [ _('Personal event:'), + _('Date:'), + _('Place:'), + _('Description:') ] + name = _('People with the personal ') + description = _("Matches people with a personal event of a particular value") + category = _('Event filters') + + def prepare(self,db): + self.date = None + try: + if self.list[1]: + self.date = DateHandler.parser.parse(self.list[1]) + except: pass + + def apply(self,db,person): + for event_handle in person.get_event_list(): + if not event_handle: + continue + event = db.get_event_from_handle(event_handle) + val = 1 + if self.list[0] and event.get_name() != self.list[0]: + val = 0 + if self.list[3] and event.get_description().upper().find( + self.list[3].upper())==-1: + val = 0 + if self.date: + if date_cmp(self.date,event.get_date_object()): + val = 0 + if self.list[2]: + pl_id = event.get_place_handle() + if pl_id: + pl = db.get_place_from_handle(pl_id) + pn = pl.get_title() + if pn.upper().find(self.list[2].upper()) == -1: + val = 0 + if val == 1: + return True + return False diff --git a/gramps2/src/Filters/Rules/_HasFamilyAttribute.py b/gramps2/src/Filters/Rules/_HasFamilyAttribute.py new file mode 100644 index 000000000..6e54dad20 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasFamilyAttribute.py @@ -0,0 +1,62 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# HasFamilyAttribute +# +#------------------------------------------------------------------------- +class HasFamilyAttribute(Rule): + """Rule that checks for a person with a particular family attribute""" + + labels = [ _('Family attribute:'), _('Value:') ] + name = _('People with the family ') + description = _("Matches people with the family attribute " + "of a particular value") + category = _('General filters') + + def apply(self,db,person): + if not self.list[0]: + return False + for f_id in person.get_family_handle_list(): + f = db.get_family_from_handle(f_id) + for attr in f.get_attribute_list(): + name_match = self.list[0] == attr.get_type() + value_match = \ + attr.get_value().upper().find(self.list[1].upper()) != -1 + if name_match and value_match: + return True + return False diff --git a/gramps2/src/Filters/Rules/_HasFamilyEvent.py b/gramps2/src/Filters/Rules/_HasFamilyEvent.py new file mode 100644 index 000000000..13040dab7 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasFamilyEvent.py @@ -0,0 +1,92 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +import DateHandler +from _Rule import Rule +from _RuleUtils import date_cmp + +#------------------------------------------------------------------------- +# +# HasFamilyEvent +# +#------------------------------------------------------------------------- +class HasFamilyEvent(Rule): + """Rule that checks for a person who has a relationship event + with a particular value""" + + labels = [ _('Family event:'), + _('Date:'), + _('Place:'), + _('Description:') ] + name = _('People with the family ') + description = _("Matches people with a family event of a particular value") + category = _('Event filters') + + def prepare(self,db): + self.date = None + try: + if self.list[1]: + self.date = DateHandler.parser.parse(self.list[1]) + except: + pass + + def apply(self,db,person): + for f_id in person.get_family_handle_list(): + f = db.get_family_from_handle(f_id) + for event_handle in f.get_event_list(): + if not event_handle: + continue + event = db.get_event_from_handle(event_handle) + val = 1 + if self.list[0] and event.get_name() != self.list[0]: + val = 0 + v = self.list[3] + if v and event.get_description().upper().find(v.upper())==-1: + val = 0 + if self.date: + if date_cmp(self.date,event.get_date_object()): + val = 0 + if self.list[2]: + pl_id = event.get_place_handle() + if pl_id: + pl = db.get_place_from_handle(pl_id) + pn = pl.get_title().upper() + if pn.find(self.list[2].upper()) == -1: + val = 0 + else: + val = 0 + + if val == 1: + return True + return False diff --git a/gramps2/src/Filters/Rules/_HasIdOf.py b/gramps2/src/Filters/Rules/_HasIdOf.py new file mode 100644 index 000000000..86291d58c --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasIdOf.py @@ -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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# HasIdOf +# +#------------------------------------------------------------------------- +class HasIdOf(Rule): + """Rule that checks for a person with a specific GRAMPS ID""" + + labels = [ _('ID:') ] + name = _('People with ') + description = _("Matches people with a specified GRAMPS ID") + category = _('General filters') + + def apply(self,db,person): + return person.gramps_id == self.list[0] diff --git a/gramps2/src/Filters/Rules/_HasNameOf.py b/gramps2/src/Filters/Rules/_HasNameOf.py new file mode 100644 index 000000000..7a2345da3 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasNameOf.py @@ -0,0 +1,70 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# HasNameOf +# +#------------------------------------------------------------------------- +class HasNameOf(Rule): + """Rule that checks for full or partial name matches""" + + labels = [ _('Given name:'), + _('Family name:'), + _('Suffix:'), + _('person|Title:')] + name = _('People with the ') + description = _("Matches people with a specified (partial) name") + category = _('General filters') + + def apply(self,db,person): + self.f = self.list[0] + self.l = self.list[1] + self.s = self.list[2] + self.t = self.list[3] + for name in [person.get_primary_name()] + person.get_alternate_names(): + val = 1 + if self.f and name.get_first_name().upper().find(self.f.upper()) == -1: + val = 0 + if self.l and name.get_surname().upper().find(self.l.upper()) == -1: + val = 0 + if self.s and name.get_suffix().upper().find(self.s.upper()) == -1: + val = 0 + if self.t and name.get_title().upper().find(self.t.upper()) == -1: + val = 0 + if val == 1: + return True + return False diff --git a/gramps2/src/Filters/Rules/_HasNote.py b/gramps2/src/Filters/Rules/_HasNote.py new file mode 100644 index 000000000..e0f59e2b2 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasNote.py @@ -0,0 +1,48 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# "People having notes" +#------------------------------------------------------------------------- +class HasNote(Rule): + """People having notes""" + + name = _('People having notes') + description = _("Matches people that have a note") + category = _('General filters') + + def apply(self,db,person): + return bool(person.get_note()) diff --git a/gramps2/src/Filters/Rules/_HasNoteMatchingSubstringOf.py b/gramps2/src/Filters/Rules/_HasNoteMatchingSubstringOf.py new file mode 100644 index 000000000..ade764beb --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasNoteMatchingSubstringOf.py @@ -0,0 +1,52 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# "People having notes that contain a substring" +#------------------------------------------------------------------------- +class HasNoteMatchingSubstringOf(Rule): + """People having notes containing """ + + labels = [ _('Substring:')] + name = _('People having notes containing ') + description = _("Matches people whose notes contain text matching a substring") + category = _('General filters') + + def apply(self,db,person): + n = person.get_note() + if n: + return n.upper().find(self.list[0].upper()) != -1 + return False diff --git a/gramps2/src/Filters/Rules/_HasRelationship.py b/gramps2/src/Filters/Rules/_HasRelationship.py new file mode 100644 index 000000000..54fa52209 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasRelationship.py @@ -0,0 +1,86 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# HasRelationship +# +#------------------------------------------------------------------------- +class HasRelationship(Rule): + """Rule that checks for a person who has a particular relationship""" + + labels = [ _('Number of relationships:'), + _('Relationship type:'), + _('Number of children:') ] + name = _('People with the ') + description = _("Matches people with a particular relationship") + category = _('Family filters') + + def apply(self,db,person): + rel_type = 0 + cnt = 0 + num_rel = len(person.get_family_handle_list()) + + # count children and look for a relationship type match + for f_id in person.get_family_handle_list(): + f = db.get_family_from_handle(f_id) + cnt = cnt + len(f.get_child_handle_list()) + if self.list[1] and int(self.list[1]) == f.get_relationship(): + rel_type = 1 + + # if number of relations specified + if self.list[0]: + try: + v = int(self.list[0]) + except: + return False + if v != num_rel: + return False + + # number of childred + if self.list[2]: + try: + v = int(self.list[2]) + except: + return False + if v != cnt: + return False + + # relation + if self.list[1]: + return rel_type == 1 + else: + return True diff --git a/gramps2/src/Filters/Rules/_HasSourceOf.py b/gramps2/src/Filters/Rules/_HasSourceOf.py new file mode 100644 index 000000000..29dc857a0 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasSourceOf.py @@ -0,0 +1,59 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# HasSourceOf +# +#------------------------------------------------------------------------- +class HasSourceOf(Rule): + """Rule that checks people that have a particular source.""" + + labels = [ _('Source ID:') ] + name = _('People with the ') + category = _('General filters') + description = _('Matches people who have a particular source') + + def prepare(self,db): + try: + self.source_handle = db.get_source_from_gramps_id(self.list[0]).get_handle() + except: + self.source_handle = None + + def apply(self,db,person): + if not self.source_handle: + return False + return person.has_source_reference( self.source_handle) diff --git a/gramps2/src/Filters/Rules/_HasTextMatchingRegexpOf.py b/gramps2/src/Filters/Rules/_HasTextMatchingRegexpOf.py new file mode 100644 index 000000000..9d097b1cd --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasTextMatchingRegexpOf.py @@ -0,0 +1,56 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _HasTextMatchingSubstringOf import HasTextMatchingSubstringOf + +#------------------------------------------------------------------------- +# "HasTextMatchingRegexOf" +#------------------------------------------------------------------------- +class HasTextMatchingRegexpOf(HasTextMatchingSubstringOf): + """This is wrapping HasTextMatchingSubstringOf to enable the regex_match parameter""" + def __init__(self,list): + HasTextMatchingSubstringOf.__init__(self,list) + + def prepare(self,db): + self.db = db + self.person_map = {} + self.event_map = {} + self.source_map = {} + self.repo_map = {} + self.family_map = {} + self.place_map = {} + self.media_map = {} + self.case_sensitive = False + self.regexp_match = True + self.cache_sources() diff --git a/gramps2/src/Filters/Rules/_HasTextMatchingSubstringOf.py b/gramps2/src/Filters/Rules/_HasTextMatchingSubstringOf.py new file mode 100644 index 000000000..a31695c28 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasTextMatchingSubstringOf.py @@ -0,0 +1,197 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from Utils import get_source_referents +from _Rule import Rule + +#------------------------------------------------------------------------- +# "HasTextMatchingSubstringOf" +#------------------------------------------------------------------------- +class HasTextMatchingSubstringOf(Rule): + """Rule that checks for string matches in any textual information""" + + labels = [ _('Substring:'), + _('Case sensitive:'), + _('Regular-Expression matching:')] + name = _('People with records containing ') + description = _("Matches people whose records contain text " + "matching a substring") + category = _('General filters') + + def prepare(self,db): + self.db = db + self.person_map = {} + self.event_map = {} + self.source_map = {} + self.repo_map = {} + self.family_map = {} + self.place_map = {} + self.media_map = {} + try: + if int(self.list[1]): + self.case_sensitive = True + else: + self.case_sensitive = False + except IndexError: + self.case_sensitive = False + try: + if int(self.list[2]): + self.regexp_match = True + else: + self.regexp_match = False + except IndexError: + self.regexp_match = False + self.cache_repos() + self.cache_sources() + + def reset(self): + self.person_map = {} + self.event_map = {} + self.source_map = {} + self.repo_map = {} + self.family_map = {} + self.place_map = {} + self.media_map = {} + + def apply(self,db,person): + if person.handle in self.person_map: # Cached by matching Source? + return self.person_map[person.handle] + if self.match_object(person): # first match the person itself + return True + for event_ref in person.get_event_ref_list()+[person.get_birth_ref(), person.get_death_ref()]: + if self.search_event(event_ref.ref): # match referenced events + return True + for family_handle in person.get_family_handle_list(): # match families + if self.search_family(family_handle): + return True + for media_ref in person.get_media_list(): # match Media object + if self.search_media(media_ref.get_reference_handle()): + return True + return False + + def search_family(self,family_handle): + if not family_handle: + return False + # search inside the family and cache the result to not search a family twice + if not family_handle in self.family_map: + match = 0 + family = self.db.get_family_from_handle(family_handle) + if self.match_object(family): + match = 1 + else: + for event_ref in family.get_event_ref_list(): + if self.search_event(event_ref.ref): + match = 1 + break + for media_ref in family.get_media_list(): # match Media object + if self.search_media(media_ref.get_reference_handle()): + return True + self.family_map[family_handle] = match + return self.family_map[family_handle] + + def search_event(self,event_handle): + if not event_handle: + return False + # search inside the event and cache the result (event sharing) + if not event_handle in self.event_map: + match = 0 + event = self.db.get_event_from_handle(event_handle) + if self.match_object(event): + match = 1 + elif event: + place_handle = event.get_place_handle() + if place_handle: + if self.search_place(place_handle): + match = 1 + for media_ref in event.get_media_list(): # match Media object + if self.search_media(media_ref.get_reference_handle()): + return True + self.event_map[event_handle] = match + return self.event_map[event_handle] + + def search_place(self,place_handle): + if not place_handle: + return False + # search inside the place and cache the result + if not place_handle in self.place_map: + place = self.db.get_place_from_handle(place_handle) + self.place_map[place_handle] = self.match_object(place) + return self.place_map[place_handle] + + def search_media(self,media_handle): + if not media_handle: + return False + # search inside the place and cache the result + if not media_handle in self.media_map: + media = self.db.get_object_from_handle(media_handle) + self.media_map[media_handle] = self.match_object(media) + return self.media_map[media_handle] + + def cache_repos(self): + # search all matching repositories + for repo_handle in self.db.get_repository_handles(): + repo = self.db.get_repository_from_handle(repo_handle) + if( self.match_object(repo)): + self.repo_map[repo_handle] = 1 + + def cache_sources(self): + # search all sources and match all referents of a matching source + for source_handle in self.db.get_source_handles(): + source = self.db.get_source_from_handle(source_handle) + match = self.match_object(source) + if not match: + for reporef in source.get_reporef_list(): + if reporef.get_reference_handle() in self.repo_map: + match = 1 + if match: + (person_list,family_list,event_list, + place_list,source_list,media_list + ) = get_source_referents(source_handle,self.db) + for handle in person_list: + self.person_map[handle] = 1 + for handle in family_list: + self.family_map[handle] = 1 + for handle in event_list: + self.event_map[handle] = 1 + for handle in place_list: + self.place_map[handle] = 1 + for handle in media_list: + self.media_map[handle] = 1 + + def match_object(self,obj): + if not obj: + return False + if self.regexp_match: + return obj.matches_regexp(self.list[0],self.case_sensitive) + return obj.matches_string(self.list[0],self.case_sensitive) diff --git a/gramps2/src/Filters/Rules/_HasUnknownGender.py b/gramps2/src/Filters/Rules/_HasUnknownGender.py new file mode 100644 index 000000000..a276d0075 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HasUnknownGender.py @@ -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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule +from RelLib import Person + +#------------------------------------------------------------------------- +# +# HasUnknownGender +# +#------------------------------------------------------------------------- +class HasUnknownGender(Rule): + """Rule that checks for a person that has unknown gender""" + + name = _('People with unknown gender') + category = _('General filters') + description = _('Matches all people with unknown gender') + + def apply(self,db,person): + return person.gender == Person.UNKNOWN diff --git a/gramps2/src/Filters/Rules/_HaveAltFamilies.py b/gramps2/src/Filters/Rules/_HaveAltFamilies.py new file mode 100644 index 000000000..250b1be50 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HaveAltFamilies.py @@ -0,0 +1,53 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule +from RelLib import ChildRefType + +#------------------------------------------------------------------------- +# "People who were adopted" +#------------------------------------------------------------------------- +class HaveAltFamilies(Rule): + """People who were adopted""" + + name = _('Adopted people') + description = _("Matches people who were adopted") + category = _('Family filters') + + def apply(self,db,person): + for (fam,rel1,rel2) in person.get_parent_family_handle_list(): + if rel1 == ChildRefType.CHILD_ADOPTED \ + or rel2 == ChildRefType.CHILD_ADOPTED: + return True + return False diff --git a/gramps2/src/Filters/Rules/_HaveChildren.py b/gramps2/src/Filters/Rules/_HaveChildren.py new file mode 100644 index 000000000..ead4f3645 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HaveChildren.py @@ -0,0 +1,50 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# "People with children" +#------------------------------------------------------------------------- +class HaveChildren(Rule): + """People with children""" + + name = _('People with children') + description = _("Matches people who have children") + category = _('Family filters') + + def apply(self,db,person): + for family_handle in person.get_family_handle_list(): + family = db.get_family_from_handle(family_handle) + return len(family.get_child_handle_list()) > 0 diff --git a/gramps2/src/Filters/Rules/_HavePhotos.py b/gramps2/src/Filters/Rules/_HavePhotos.py new file mode 100644 index 000000000..599b59690 --- /dev/null +++ b/gramps2/src/Filters/Rules/_HavePhotos.py @@ -0,0 +1,48 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# "People who have images" +#------------------------------------------------------------------------- +class HavePhotos(Rule): + """People who have images""" + + name = _('People with images') + description = _("Matches people with images in the gallery") + category = _('General filters') + + def apply(self,db,person): + return len( person.get_media_list()) > 0 diff --git a/gramps2/src/Filters/Rules/_IncompleteNames.py b/gramps2/src/Filters/Rules/_IncompleteNames.py new file mode 100644 index 000000000..83739ddba --- /dev/null +++ b/gramps2/src/Filters/Rules/_IncompleteNames.py @@ -0,0 +1,55 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# IncompleteNames +# +#------------------------------------------------------------------------- +class IncompleteNames(Rule): + """People with incomplete names""" + + name = _('People with incomplete names') + description = _("Matches people with firstname or lastname missing") + category = _('General filters') + + def apply(self,db,person): + for name in [person.get_primary_name()] + person.get_alternate_names(): + if name.get_first_name() == "": + return True + if name.get_surname() == "": + return True + return False diff --git a/gramps2/src/Filters/Rules/_IsAncestorOf.py b/gramps2/src/Filters/Rules/_IsAncestorOf.py new file mode 100644 index 000000000..b769aa009 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsAncestorOf.py @@ -0,0 +1,88 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# IsAncestorOf +# +#------------------------------------------------------------------------- +class IsAncestorOf(Rule): + """Rule that checks for a person that is an ancestor of a specified person""" + + labels = [ _('ID:'), _('Inclusive:') ] + name = _('Ancestors of ') + category = _("Ancestral filters") + description = _("Matches people that are ancestors of a specified person") + + def prepare(self,db): + """Assume that if 'Inclusive' not defined, assume inclusive""" + self.db = db + self.map = {} + try: + if int(self.list[1]): + first = 0 + else: + first = 1 + except IndexError: + first = 1 + try: + root_person = db.get_person_from_gramps_id(self.list[0]) + self.init_ancestor_list(db,root_person,first) + except: + pass + + def reset(self): + self.map = {} + + def apply(self,db,person): + return self.map.has_key(person.handle) + + def init_ancestor_list(self,db,person,first): + if not person: + return + if not first: + self.map[person.handle] = 1 + + fam_id = person.get_main_parents_family_handle() + fam = db.get_family_from_handle(fam_id) + if fam: + f_id = fam.get_father_handle() + m_id = fam.get_mother_handle() + + if f_id: + self.init_ancestor_list(db,db.get_person_from_handle(f_id),0) + if m_id: + self.init_ancestor_list(db,db.get_person_from_handle(m_id),0) diff --git a/gramps2/src/Filters/Rules/_IsAncestorOfFilterMatch.py b/gramps2/src/Filters/Rules/_IsAncestorOfFilterMatch.py new file mode 100644 index 000000000..8760e6f23 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsAncestorOfFilterMatch.py @@ -0,0 +1,80 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _IsAncestorOf import IsAncestorOf +from _MatchesFilter import MatchesFilter + +#------------------------------------------------------------------------- +# +# IsAncestorOfFilterMatch +# +#------------------------------------------------------------------------- +class IsAncestorOfFilterMatch(IsAncestorOf): + """Rule that checks for a person that is an ancestor of + someone matched by a filter""" + + labels = [ _('Filter name:') ] + name = _('Ancestors of match') + category = _("Ancestral filters") + description = _("Matches people that are ancestors " + "of anybody matched by a filter") + + + def __init__(self,list): + IsAncestorOf.__init__(self,list) + + def prepare(self,db): + self.db = db + self.map = {} + try: + if int(self.list[1]): + first = 0 + else: + first = 1 + except IndexError: + first = 1 + + filt = MatchesFilter(self.list[0:1]) + filt.prepare(db) + for person_handle in db.get_person_handles(sort_handles=False): + person = db.get_person_from_handle( person_handle) + if filt.apply (db, person): + self.init_ancestor_list (db,person,first) + filt.reset() + + def reset(self): + self.map = {} + + def apply(self,db,person): + return self.map.has_key(person.handle) diff --git a/gramps2/src/Filters/Rules/_IsBookmarked.py b/gramps2/src/Filters/Rules/_IsBookmarked.py new file mode 100644 index 000000000..737e7ce47 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsBookmarked.py @@ -0,0 +1,58 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# IsBookmarked +# +#------------------------------------------------------------------------- +class IsBookmarked(Rule): + """Rule that checks for the bookmark list in the database""" + + name = _('Bookmarked people') + category = _('General filters') + description = _("Matches the people on the bookmark list") + + def prepare(self,db): + bookmarks = db.get_bookmarks() + if len(bookmarks) == 0: + self.apply = lambda db,p : False + else: + self.bookmarks = sets.Set(bookmarks) + self.apply = self.apply_real + + def apply_real(self,db,person): + return person.handle in self.bookmarks diff --git a/gramps2/src/Filters/Rules/_IsChildOfFilterMatch.py b/gramps2/src/Filters/Rules/_IsChildOfFilterMatch.py new file mode 100644 index 000000000..17f8bf420 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsChildOfFilterMatch.py @@ -0,0 +1,75 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule +from _MatchesFilter import MatchesFilter + +#------------------------------------------------------------------------- +# +# IsChildOfFilterMatch +# +#------------------------------------------------------------------------- +class IsChildOfFilterMatch(Rule): + """Rule that checks for a person that is a child + of someone matched by a filter""" + + labels = [ _('Filter name:') ] + name = _('Children of match') + category = _('Family filters') + description = _("Matches children of anybody matched by a filter") + + def prepare(self,db): + self.db = db + self.map = {} + filt = MatchesFilter(self.list) + filt.prepare(db) + for person_handle in db.get_person_handles(sort_handles=False): + person = db.get_person_from_handle( person_handle) + if filt.apply (db, person): + self.init_list (person) + filt.reset() + + def reset(self): + self.map = {} + + def apply(self,db,person): + return self.map.has_key(person.handle) + + def init_list(self,person): + if not person: + return + for fam_id in person.get_family_handle_list(): + fam = self.db.get_family_from_handle(fam_id) + for child_handle in fam.get_child_handle_list(): + self.map[child_handle] = 1 diff --git a/gramps2/src/Filters/Rules/_IsDefaultPerson.py b/gramps2/src/Filters/Rules/_IsDefaultPerson.py new file mode 100644 index 000000000..58a4eb975 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsDefaultPerson.py @@ -0,0 +1,58 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# IsDefaultPerson +# +#------------------------------------------------------------------------- +class IsDefaultPerson(Rule): + """Rule that checks for a default person in the database""" + + name = _('Default person') + category = _('General filters') + description = _("Matches the default person") + + def prepare(self,db): + p = db.get_default_person() + if p: + self.def_handle = p.get_handle() + self.apply = self.apply_real + else: + self.apply = lambda db,p: False + + def apply_real(self,db,person): + return person.handle == self.def_handle diff --git a/gramps2/src/Filters/Rules/_IsDescendantFamilyOf.py b/gramps2/src/Filters/Rules/_IsDescendantFamilyOf.py new file mode 100644 index 000000000..dbad21a29 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsDescendantFamilyOf.py @@ -0,0 +1,83 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# IsDescendantFamilyOf +# +#------------------------------------------------------------------------- +class IsDescendantFamilyOf(Rule): + """Rule that checks for a person that is a descendant or the spouse + of a descendant of a specified person""" + + labels = [ _('ID:') ] + name = _('Descendant family members of ') + category = _('Descendant filters') + description = _("Matches people that are descendants or the spouse " + "of a descendant of a specified person") + + def apply(self,db,person): + self.map = {} + self.orig_handle = person.handle + self.db = db + return self.search(person.handle,1) + + def search(self,handle,val): + try: + if handle == self.db.get_person_from_gramps_id(self.list[0]).get_handle(): + self.map[handle] = 1 + return True + except: + return False + + p = self.db.get_person_from_handle(handle) + for (f,r1,r2) in p.get_parent_family_handle_list(): + family = self.db.get_family_from_handle(f) + for person_handle in [family.get_mother_handle(),family.get_father_handle()]: + if person_handle: + if self.search(person_handle,0): + return True + if val: + for family_handle in p.get_family_handle_list(): + family = self.db.get_family_from_handle(family_handle) + if handle == family.get_father_handle(): + spouse_id = family.get_mother_handle() + else: + spouse_id = family.get_father_handle() + if spouse_id: + if self.search(spouse_id,0): + return True + return False diff --git a/gramps2/src/Filters/Rules/_IsDescendantOf.py b/gramps2/src/Filters/Rules/_IsDescendantOf.py new file mode 100644 index 000000000..4ae5a2910 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsDescendantOf.py @@ -0,0 +1,83 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# IsDescendantOf +# +#------------------------------------------------------------------------- +class IsDescendantOf(Rule): + """Rule that checks for a person that is a descendant + of a specified person""" + + labels = [ _('ID:'), _('Inclusive:') ] + name = _('Descendants of ') + category = _('Descendant filters') + description = _('Matches all descendants for the specified person') + + def prepare(self,db): + self.db = db + self.map = {} + try: + if int(self.list[1]): + first = False + else: + first = True + except IndexError: + first = True + try: + root_person = db.get_person_from_gramps_id(self.list[0]) + self.init_list(root_person,first) + except: + pass + + def reset(self): + self.map = {} + + def apply(self,db,person): + return self.map.has_key(person.handle) + + def init_list(self,person,first): + if not person: + return + if not first: + self.map[person.handle] = 1 + + for fam_id in person.get_family_handle_list(): + fam = self.db.get_family_from_handle(fam_id) + if fam: + for child_handle in fam.get_child_handle_list(): + self.init_list(self.db.get_person_from_handle(child_handle),0) diff --git a/gramps2/src/Filters/Rules/_IsDescendantOfFilterMatch.py b/gramps2/src/Filters/Rules/_IsDescendantOfFilterMatch.py new file mode 100644 index 000000000..3a201c4fe --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsDescendantOfFilterMatch.py @@ -0,0 +1,80 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _IsDescendantOf import IsDescendantOf +from _MatchesFilter import MatchesFilter + +#------------------------------------------------------------------------- +# +# IsDescendantOfFilterMatch +# +#------------------------------------------------------------------------- +class IsDescendantOfFilterMatch(IsDescendantOf): + """Rule that checks for a person that is a descendant + of someone matched by a filter""" + + labels = [ _('Filter name:') ] + name = _('Descendants of match') + category = _('Descendant filters') + description = _("Matches people that are descendants " + "of anybody matched by a filter") + + +# def __init__(self,list): +# IsDescendantOf.__init__(self,list) + + def prepare(self,db): + self.db = db + self.map = {} + try: + if int(self.list[1]): + first = 0 + else: + first = 1 + except IndexError: + first = 1 + + filt = MatchesFilter(self.list[0:1]) + filt.prepare(db) + for person_handle in db.get_person_handles(sort_handles=False): + person = db.get_person_from_handle( person_handle) + if filt.apply (db, person): + self.init_list (person,first) + filt.reset() + + def reset(self): + self.map = {} + + def apply(self,db,person): + return self.map.has_key(person.handle) diff --git a/gramps2/src/Filters/Rules/_IsFemale.py b/gramps2/src/Filters/Rules/_IsFemale.py new file mode 100644 index 000000000..1b6ab5143 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsFemale.py @@ -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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule +from RelLib import Person + +#------------------------------------------------------------------------- +# +# IsFemale +# +#------------------------------------------------------------------------- +class IsFemale(Rule): + """Rule that checks for a person that is a female""" + + name = _('Females') + category = _('General filters') + description = _('Matches all females') + + def apply(self,db,person): + return person.gender == Person.FEMALE diff --git a/gramps2/src/Filters/Rules/_IsLessThanNthGenerationAncestorOf.py b/gramps2/src/Filters/Rules/_IsLessThanNthGenerationAncestorOf.py new file mode 100644 index 000000000..a3ef13972 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsLessThanNthGenerationAncestorOf.py @@ -0,0 +1,87 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# IsLessThanNthGenerationAncestorOf +# +#------------------------------------------------------------------------- +class IsLessThanNthGenerationAncestorOf(Rule): + """Rule that checks for a person that is an ancestor of a specified person + not more than N generations away""" + + labels = [ _('ID:'), _('Number of generations:') ] + name = _('Ancestors of not more than generations away') + category = _("Ancestral filters") + description = _("Matches people that are ancestors " + "of a specified person not more than N generations away") + + def prepare(self,db): + self.db = db + self.map = {} + try: + root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() + self.init_ancestor_list(root_handle,0) + except: + pass + + def reset(self): + self.map = {} + + def apply(self,db,person): + return self.map.has_key(person.handle) + + def init_ancestor_list(self,handle,gen): +# if self.map.has_key(p.get_handle()) == 1: +# loop_error(self.orig,p) + if not handle: + return + if gen: + self.map[handle] = 1 + if gen >= int(self.list[1]): + return + + p = self.db.get_person_from_handle(handle) + fam_id = p.get_main_parents_family_handle() + fam = self.db.get_family_from_handle(fam_id) + if fam: + f_id = fam.get_father_handle() + m_id = fam.get_mother_handle() + + if f_id: + self.init_ancestor_list(f_id,gen+1) + if m_id: + self.init_ancestor_list(m_id,gen+1) diff --git a/gramps2/src/Filters/Rules/_IsLessThanNthGenerationAncestorOfBookmarked.py b/gramps2/src/Filters/Rules/_IsLessThanNthGenerationAncestorOfBookmarked.py new file mode 100644 index 000000000..c7e578ce5 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsLessThanNthGenerationAncestorOfBookmarked.py @@ -0,0 +1,93 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# IsLessThanNthGenerationAncestorOfBookmarked +# +#------------------------------------------------------------------------- +class IsLessThanNthGenerationAncestorOfBookmarked(Rule): + # Submitted by Wayne Bergeron + """Rule that checks for a person that is an ancestor of bookmarked persons + not more than N generations away""" + + labels = [ _('Number of generations:') ] + name = _('Ancestors of bookmarked people not more ' + 'than generations away') + category = _('Ancestral filters') + description = _("Matches ancestors of the people on the bookmark list " + "not more than N generations away") + + def prepare(self,db): + self.db = db + bookmarks = self.db.get_bookmarks() + if len(bookmarks) == 0: + self.apply = lambda db,p : False + else: + self.map = {} + self.bookmarks = sets.Set(bookmarks) + self.apply = self.apply_real + for self.bookmarkhandle in self.bookmarks: + self.init_ancestor_list(self.bookmarkhandle, 1) + + + def init_ancestor_list(self,handle,gen): +# if self.map.has_key(p.get_handle()) == 1: +# loop_error(self.orig,p) + if not handle: + return + if gen: + self.map[handle] = 1 + if gen >= int(self.list[0]): + return + + p = self.db.get_person_from_handle(handle) + fam_id = p.get_main_parents_family_handle() + fam = self.db.get_family_from_handle(fam_id) + if fam: + f_id = fam.get_father_handle() + m_id = fam.get_mother_handle() + + if f_id: + self.init_ancestor_list(f_id,gen+1) + if m_id: + self.init_ancestor_list(m_id,gen+1) + + def apply_real(self,db,person): + return person.handle in self.map + + def reset(self): + self.map = {} diff --git a/gramps2/src/Filters/Rules/_IsLessThanNthGenerationAncestorOfDefaultPerson.py b/gramps2/src/Filters/Rules/_IsLessThanNthGenerationAncestorOfDefaultPerson.py new file mode 100644 index 000000000..7fc8774c1 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsLessThanNthGenerationAncestorOfDefaultPerson.py @@ -0,0 +1,91 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# IsLessThanNthGenerationAncestorOfDefaultPerson +# +#------------------------------------------------------------------------- +class IsLessThanNthGenerationAncestorOfDefaultPerson(Rule): + # Submitted by Wayne Bergeron + """Rule that checks for a person that is an ancestor of the default person + not more than N generations away""" + + labels = [ _('Number of generations:') ] + name = _('Ancestors of the default person ' + 'not more than generations away') + category = _('Ancestral filters') + description = _("Matches ancestors of the default person " + "not more than N generations away") + + def prepare(self,db): + self.db = db + p = db.get_default_person() + if p: + self.def_handle = p.get_handle() + self.apply = self.apply_real + self.map = {} + self.init_ancestor_list(self.def_handle, 1) + else: + self.apply = lambda db,p: False + + def init_ancestor_list(self,handle,gen): +# if self.map.has_key(p.get_handle()) == 1: +# loop_error(self.orig,p) + if not handle: + return + if gen: + self.map[handle] = 1 + if gen >= int(self.list[0]): + return + + p = self.db.get_person_from_handle(handle) + fam_id = p.get_main_parents_family_handle() + fam = self.db.get_family_from_handle(fam_id) + if fam: + f_id = fam.get_father_handle() + m_id = fam.get_mother_handle() + + if f_id: + self.init_ancestor_list(f_id,gen+1) + if m_id: + self.init_ancestor_list(m_id,gen+1) + + def apply_real(self,db,person): + return person.handle in self.map + + def reset(self): + self.map = {} diff --git a/gramps2/src/Filters/Rules/_IsLessThanNthGenerationDescendantOf.py b/gramps2/src/Filters/Rules/_IsLessThanNthGenerationDescendantOf.py new file mode 100644 index 000000000..83b06880b --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsLessThanNthGenerationDescendantOf.py @@ -0,0 +1,79 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# IsLessThanNthGenerationDescendantOf +# +#------------------------------------------------------------------------- +class IsLessThanNthGenerationDescendantOf(Rule): + """Rule that checks for a person that is a descendant of a specified person + not more than N generations away""" + + labels = [ _('ID:'), _('Number of generations:') ] + name = _('Descendants of not more than ' + ' generations away') + category = _('Descendant filters') + description = _("Matches people that are descendants of a " + "specified person not more than N generations away") + + def prepare(self,db): + self.db = db + self.map = {} + try: + root_person = db.get_person_from_gramps_id(self.list[0]) + self.init_list(root_person,0) + except: + pass + + def reset(self): + self.map = {} + + def apply(self,db,person): + return self.map.has_key(person.handle) + + def init_list(self,person,gen): + if not person: + return + if gen: + self.map[person.handle] = 1 + if gen >= int(self.list[1]): + return + + for fam_id in person.get_family_handle_list(): + fam = self.db.get_family_from_handle(fam_id) + for child_handle in fam.get_child_handle_list(): + self.init_list(self.db.get_person_from_handle(child_handle),gen+1) diff --git a/gramps2/src/Filters/Rules/_IsMale.py b/gramps2/src/Filters/Rules/_IsMale.py new file mode 100644 index 000000000..108b83ba4 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsMale.py @@ -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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule +from RelLib import Person + +#------------------------------------------------------------------------- +# +# IsMale +# +#------------------------------------------------------------------------- +class IsMale(Rule): + """Rule that checks for a person that is a male""" + + name = _('Males') + category = _('General filters') + description = _('Matches all males') + + def apply(self,db,person): + return person.gender == Person.MALE diff --git a/gramps2/src/Filters/Rules/_IsMoreThanNthGenerationAncestorOf.py b/gramps2/src/Filters/Rules/_IsMoreThanNthGenerationAncestorOf.py new file mode 100644 index 000000000..606a7a566 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsMoreThanNthGenerationAncestorOf.py @@ -0,0 +1,85 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# IsMoreThanNthGenerationAncestorOf +# +#------------------------------------------------------------------------- +class IsMoreThanNthGenerationAncestorOf(Rule): + """Rule that checks for a person that is an ancestor of a specified person + at least N generations away""" + + labels = [ _('ID:'), _('Number of generations:') ] + name = _('Ancestors of at least generations away') + category = _("Ancestral filters") + description = _("Matches people that are ancestors " + "of a specified person at least N generations away") + + def prepare(self,db): + self.db = db + self.map = {} + try: + root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() + self.init_ancestor_list(root_handle,0) + except: + pass + + def reset(self): + self.map = [] + + def apply(self,db,person): + return self.map.has_key(person.handle) + + def init_ancestor_list(self,handle,gen): +# if self.map.has_key(p.get_handle()) == 1: +# loop_error(self.orig,p) + if not handle: + return + if gen >= int(self.list[1]): + self.map[handle] = 1 + + p = self.db.get_person_from_handle(handle) + fam_id = p.get_main_parents_family_handle() + fam = self.db.get_family_from_handle(fam_id) + if fam: + f_id = fam.get_father_handle() + m_id = fam.get_mother_handle() + + if f_id: + self.init_ancestor_list(f_id,gen+1) + if m_id: + self.init_ancestor_list(m_id,gen+1) diff --git a/gramps2/src/Filters/Rules/_IsMoreThanNthGenerationDescendantOf.py b/gramps2/src/Filters/Rules/_IsMoreThanNthGenerationDescendantOf.py new file mode 100644 index 000000000..15a7196b2 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsMoreThanNthGenerationDescendantOf.py @@ -0,0 +1,77 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# IsMoreThanNthGenerationDescendantOf +# +#------------------------------------------------------------------------- +class IsMoreThanNthGenerationDescendantOf(Rule): + """Rule that checks for a person that is a descendant of a specified person + at least N generations away""" + + labels = [ _('ID:'), _('Number of generations:') ] + name = _('Descendants of at least generations away') + category = _("Descendant filters") + description = _("Matches people that are descendants of a specified " + "person at least N generations away") + + + def prepare(self,db): + self.db = db + self.map = {} + try: + root_person = db.get_person_from_gramps_id(self.list[0]) + self.init_list(root_person,0) + except: + pass + + def reset(self): + self.map = {} + + def apply(self,db,person): + return self.map.has_key(person.handle) + + def init_list(self,person,gen): + if not person: + return + if gen >= int(self.list[1]): + self.map[person.handle] = 1 + + for fam_id in person.get_family_handle_list(): + fam = self.db.get_family_from_handle(fam_id) + for child_handle in fam.get_child_handle_list(): + self.init_list(self.db.get_person_from_handle(child_handle),gen+1) diff --git a/gramps2/src/Filters/Rules/_IsParentOfFilterMatch.py b/gramps2/src/Filters/Rules/_IsParentOfFilterMatch.py new file mode 100644 index 000000000..effacc578 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsParentOfFilterMatch.py @@ -0,0 +1,74 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule +from _MatchesFilter import MatchesFilter + +#------------------------------------------------------------------------- +# +# IsParentOfFilterMatch +# +#------------------------------------------------------------------------- +class IsParentOfFilterMatch(Rule): + """Rule that checks for a person that is a parent + of someone matched by a filter""" + + labels = [ _('Filter name:') ] + name = _('Parents of match') + category = _('Family filters') + description = _("Matches parents of anybody matched by a filter") + + def prepare(self,db): + self.db = db + self.map = {} + filt = MatchesFilter(self.list) + filt.prepare(db) + for person_handle in db.get_person_handles(sort_handles=False): + person = db.get_person_from_handle(person_handle) + if filt.apply (db, person): + self.init_list (person) + filt.reset() + + def reset(self): + self.map = {} + + def apply(self,db,person): + return self.map.has_key(person.handle) + + def init_list(self,person): + for fam_id,frel,mrel in person.get_parent_family_handle_list(): + fam = self.db.get_family_from_handle(fam_id) + for parent_id in [fam.get_father_handle (), fam.get_mother_handle ()]: + if parent_id: + self.map[parent_id] = 1 diff --git a/gramps2/src/Filters/Rules/_IsSiblingOfFilterMatch.py b/gramps2/src/Filters/Rules/_IsSiblingOfFilterMatch.py new file mode 100644 index 000000000..309350146 --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsSiblingOfFilterMatch.py @@ -0,0 +1,76 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule +from _MatchesFilter import MatchesFilter + +#------------------------------------------------------------------------- +# +# IsSiblingOfFilterMatch +# +#------------------------------------------------------------------------- +class IsSiblingOfFilterMatch(Rule): + """Rule that checks for siblings of someone matched by a filter""" + + labels = [ _('Filter name:') ] + name = _('Siblings of match') + category = _('Family filters') + description = _("Matches siblings of anybody matched by a filter") + + def prepare(self,db): + self.db = db + self.map = {} + filt = MatchesFilter(self.list) + filt.prepare(db) + for person_handle in db.get_person_handles(sort_handles=False): + person = db.get_person_from_handle( person_handle) + if filt.apply (db, person): + self.init_list (person) + filt.reset() + + def reset(self): + self.map = {} + + def apply(self,db,person): + return self.map.has_key(person.handle) + + def init_list(self,person): + if not person: + return + fam_id = person.get_main_parents_family_handle() + fam = self.db.get_family_from_handle(fam_id) + if fam: + for child_handle in fam.get_child_handle_list(): + if child_handle != person.handle: + self.map[child_handle] = 1 diff --git a/gramps2/src/Filters/Rules/_IsSpouseOfFilterMatch.py b/gramps2/src/Filters/Rules/_IsSpouseOfFilterMatch.py new file mode 100644 index 000000000..52166fcab --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsSpouseOfFilterMatch.py @@ -0,0 +1,66 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule +from _MatchesFilter import MatchesFilter + +#------------------------------------------------------------------------- +# +# IsSpouseOfFilterMatch +# +#------------------------------------------------------------------------- +class IsSpouseOfFilterMatch(Rule): + """Rule that checks for a person married to someone matching + a filter""" + + labels = [_('Filter name:')] + name = _('Spouses of match') + description = _("Matches people married to anybody matching a filter") + category = _('Family filters') + + def prepare(self,db): + self.filt = MatchesFilter (self.list) + self.filt.prepare(db) + + def apply(self,db,person): + for family_handle in person.get_family_handle_list (): + family = db.get_family_from_handle(family_handle) + for spouse_id in [family.get_father_handle (), family.get_mother_handle ()]: + if not spouse_id: + continue + if spouse_id == person.handle: + continue + if self.filt.apply (db, db.get_person_from_handle( spouse_id)): + return True + return False diff --git a/gramps2/src/Filters/Rules/_IsWitness.py b/gramps2/src/Filters/Rules/_IsWitness.py new file mode 100644 index 000000000..f1031d55b --- /dev/null +++ b/gramps2/src/Filters/Rules/_IsWitness.py @@ -0,0 +1,84 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# "Witnesses" +#------------------------------------------------------------------------- +class IsWitness(Rule): + """Witnesses""" + + labels = [_('Personal event:'), _('Family event:')] + name = _('Witnesses') + description = _("Matches people who are witnesses in any event") + category = _('Event filters') + + def prepare(self,db): + self.db = db + self.map = [] + self.build_witness_list() + + def reset(self): + self.map = [] + + def apply(self,db,person): + return person.handle in self.map + + def build_witness_list(self): + for person_handle in self.db.get_person_handles(): + p = self.db.get_person_from_handle(person_handle) + self.get_witness_of_events(self.list[0], + p.get_event_ref_list()+ + [p.get_birth_ref(), + p.get_death_ref()] + ) + + for family_handle in self.db.get_family_handles(): + f = self.db.get_family_from_handle(family_handle) + self.get_witness_of_events(self.list[1],f.get_event_ref_list()) + + def get_witness_of_events(self, event_type, event_list): + if not event_list: + return + for event_ref in event_list: + if event_ref: + event = self.db.get_event_from_handle(event_ref.ref) + if event_type and not event.get_name() == event_type: + continue + wlist = event.get_witness_list() + if wlist: + for w in wlist: + if w.get_type() == 1: + self.map.append(w.get_value()) diff --git a/gramps2/src/Filters/Rules/_MatchesFilter.py b/gramps2/src/Filters/Rules/_MatchesFilter.py new file mode 100644 index 000000000..87980ccca --- /dev/null +++ b/gramps2/src/Filters/Rules/_MatchesFilter.py @@ -0,0 +1,78 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from Filters import SystemFilters, CustomFilters +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# MatchesFilter +# +#------------------------------------------------------------------------- +class MatchesFilter(Rule): + """Rule that checks against another filter""" + + labels = [_('Filter name:')] + name = _('People matching the ') + description = _("Matches people macthed by the specified filter name") + category = _('General filters') + + def prepare(self,db): + for filt in SystemFilters.get_filters(): + if filt.get_name() == self.list[0]: + for rule in filt.flist: + rule.prepare(db) + for filt in CustomFilters.get_filters(): + if filt.get_name() == self.list[0]: + for rule in filt.flist: + rule.prepare(db) + + def reset(self): + for filt in SystemFilters.get_filters(): + if filt.get_name() == self.list[0]: + for rule in filt.flist: + rule.reset() + for filt in CustomFilters.get_filters(): + if filt.get_name() == self.list[0]: + for rule in filt.flist: + rule.reset() + + def apply(self,db,person): + for filt in SystemFilters.get_filters(): + if filt.get_name() == self.list[0]: + return filt.check(db,person.handle) + for filt in CustomFilters.get_filters(): + if filt.get_name() == self.list[0]: + return filt.check(db,person.handle) + return False diff --git a/gramps2/src/Filters/Rules/_MultipleMarriages.py b/gramps2/src/Filters/Rules/_MultipleMarriages.py new file mode 100644 index 000000000..14821bd04 --- /dev/null +++ b/gramps2/src/Filters/Rules/_MultipleMarriages.py @@ -0,0 +1,48 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# "People with multiple marriage records" +#------------------------------------------------------------------------- +class MultipleMarriages(Rule): + """People with multiple marriage records""" + + name = _('People with multiple marriage records') + description = _("Matches people who have more than one spouse") + category = _('Family filters') + + def apply(self,db,person): + return len(person.get_family_handle_list()) > 1 diff --git a/gramps2/src/Filters/Rules/_NeverMarried.py b/gramps2/src/Filters/Rules/_NeverMarried.py new file mode 100644 index 000000000..e168bf239 --- /dev/null +++ b/gramps2/src/Filters/Rules/_NeverMarried.py @@ -0,0 +1,48 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# "People with no marriage records" +#------------------------------------------------------------------------- +class NeverMarried(Rule): + """People with no marriage records""" + + name = _('People with no marriage records') + description = _("Matches people who have no spouse") + category = _('Family filters') + + def apply(self,db,person): + return len(person.get_family_handle_list()) == 0 diff --git a/gramps2/src/Filters/Rules/_NoBirthdate.py b/gramps2/src/Filters/Rules/_NoBirthdate.py new file mode 100644 index 000000000..7a2f931b3 --- /dev/null +++ b/gramps2/src/Filters/Rules/_NoBirthdate.py @@ -0,0 +1,54 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# "People without a birth date" +#------------------------------------------------------------------------- +class NoBirthdate(Rule): + """People without a birth date""" + + name = _('People without a known birth date') + description = _("Matches people without a known birthdate") + category = _('General filters') + + def apply(self,db,person): + birth_ref = person.get_birth_ref() + if not birth_ref: + return True + birth = db.get_event_from_handle(birth_ref.ref) + if not birth.get_date_object(): + return True + return False diff --git a/gramps2/src/Filters/Rules/_PeoplePrivate.py b/gramps2/src/Filters/Rules/_PeoplePrivate.py new file mode 100644 index 000000000..029151917 --- /dev/null +++ b/gramps2/src/Filters/Rules/_PeoplePrivate.py @@ -0,0 +1,48 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# "People marked private" +#------------------------------------------------------------------------- +class PeoplePrivate(Rule): + """People marked private""" + + name = _('People marked private') + description = _("Matches people that are indicated as private") + category = _('General filters') + + def apply(self,db,person): + return person.get_privacy() diff --git a/gramps2/src/Filters/Rules/_PersonWithIncompleteEvent.py b/gramps2/src/Filters/Rules/_PersonWithIncompleteEvent.py new file mode 100644 index 000000000..221af6410 --- /dev/null +++ b/gramps2/src/Filters/Rules/_PersonWithIncompleteEvent.py @@ -0,0 +1,56 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# "People with incomplete events" +#------------------------------------------------------------------------- +class PersonWithIncompleteEvent(Rule): + """People with incomplete events""" + + name = _('People with incomplete events') + description = _("Matches people with missing date or place in an event") + category = _('Event filters') + + def apply(self,db,person): + for event_ref in person.get_event_ref_list() + \ + [person.get_birth_ref(), person.get_death_ref()]: + if event_ref: + event = db.get_event_from_handle(event_ref.ref) + if not event.get_place_handle(): + return True + if not event.get_date_object(): + return True + return False diff --git a/gramps2/src/Filters/Rules/_ProbablyAlive.py b/gramps2/src/Filters/Rules/_ProbablyAlive.py new file mode 100644 index 000000000..bb02632a9 --- /dev/null +++ b/gramps2/src/Filters/Rules/_ProbablyAlive.py @@ -0,0 +1,56 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from Utils import probably_alive +from _Rule import Rule + +#------------------------------------------------------------------------- +# "People probably alive" +#------------------------------------------------------------------------- +class ProbablyAlive(Rule): + """People probably alive""" + + labels = [_("On year:")] + name = _('People probably alive') + description = _("Matches people without indications of death that are not too old") + category = _('General filters') + + def prepare(self,db): + try: + self.current_year = int(self.list[0]) + except: + self.current_year = None + + def apply(self,db,person): + return probably_alive(person,db,self.current_year) diff --git a/gramps2/src/Filters/Rules/_RelationshipPathBetween.py b/gramps2/src/Filters/Rules/_RelationshipPathBetween.py new file mode 100644 index 000000000..21d462ba8 --- /dev/null +++ b/gramps2/src/Filters/Rules/_RelationshipPathBetween.py @@ -0,0 +1,133 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule + +#------------------------------------------------------------------------- +# +# RelationshipPathBetween +# +#------------------------------------------------------------------------- +class RelationshipPathBetween(Rule): + """Rule that checks for a person that is a descendant of a specified person + not more than N generations away""" + + labels = [ _('ID:'), _('ID:') ] + name = _("Relationship path between ") + category = _('Relationship filters') + description = _("Matches the ancestors of two persons back " + "to a common ancestor, producing the relationship " + "path between two persons.") + + def prepare(self,db): + self.db = db + self.map = {} + try: + root1_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() + root2_handle = db.get_person_from_gramps_id(self.list[1]).get_handle() + self.init_list(root1_handle,root2_handle) + except: + pass + + def reset(self): + self.map = {} + + def desc_list(self, handle, map, first): + if not first: + map[handle] = 1 + + p = self.db.get_person_from_handle(handle) + for fam_id in p.get_family_handle_list(): + fam = self.db.get_family_from_handle(fam_id) + if fam: + for child_handle in fam.get_child_handle_list(): + if child_handle: + self.desc_list(child_handle,map,0) + + def apply_filter(self,rank,handle,plist,pmap): + person = self.db.get_person_from_handle(handle) + if person == None: + return + plist.append(person) + pmap[person.get_handle()] = rank + + fam_id = person.get_main_parents_family_handle() + family = self.db.get_family_from_handle(fam_id) + if family != None: + self.apply_filter(rank+1,family.get_father_handle(),plist,pmap) + self.apply_filter(rank+1,family.get_mother_handle(),plist,pmap) + + def apply(self,db,person): + return self.map.has_key(person.handle) + + def init_list(self,p1_handle,p2_handle): + firstMap = {} + firstList = [] + secondMap = {} + secondList = [] + common = [] + rank = 9999999 + + self.apply_filter(0,p1_handle,firstList,firstMap) + self.apply_filter(0,p2_handle,secondList,secondMap) + + for person_handle in firstList: + if person_handle in secondList: + new_rank = firstMap[person_handle] + if new_rank < rank: + rank = new_rank + common = [ person_handle ] + elif new_rank == rank: + common.append(person_handle) + + path1 = { p1_handle : 1} + path2 = { p2_handle : 1} + + for person_handle in common: + new_map = {} + self.desc_list(person_handle,new_map,1) + self.get_intersection(path1,firstMap,new_map) + self.get_intersection(path2,secondMap,new_map) + + for e in path1: + self.map[e] = 1 + for e in path2: + self.map[e] = 1 + for e in common: + self.map[e] = 1 + + def get_intersection(self,target, map1, map2): + for e in map1.keys(): + if map2.has_key(e): + target[e] = map2[e] diff --git a/gramps2/src/Filters/Rules/_Rule.py b/gramps2/src/Filters/Rules/_Rule.py new file mode 100644 index 000000000..7ea4872a8 --- /dev/null +++ b/gramps2/src/Filters/Rules/_Rule.py @@ -0,0 +1,75 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# Rule +# +#------------------------------------------------------------------------- +class Rule: + """Base rule class""" + + labels = [] + name = '' + category = _('Miscellaneous filters') + description = _('No description') + + def __init__(self,list): + self.set_list(list) + + def is_empty(self): + return False + + def prepare(self,db): + pass + + def reset(self): + pass + + def set_list(self,list): + assert type(list) == type([]) or list == None, "Argument is not a list" + assert len(list) == len(self.labels), \ + "Number of arguments does not match number of labels.\n"\ + "list: %s\nlabels: %s" % (list,self.labels) + self.list = list + + def values(self): + return self.list + + def check(self): + return len(self.list) == len(self.labels) + + def apply(self,db,person): + return True + + def display_values(self): + v = [ '%s="%s"' % (_(self.labels[ix]),_(self.list[ix])) + for ix in range(0,len(self.list)) if self.list[ix] ] + + return ';'.join(v) diff --git a/gramps2/src/Filters/Rules/_RuleUtils.py b/gramps2/src/Filters/Rules/_RuleUtils.py new file mode 100644 index 000000000..0253f038b --- /dev/null +++ b/gramps2/src/Filters/Rules/_RuleUtils.py @@ -0,0 +1,39 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Useful functions used by some rules +# +#------------------------------------------------------------------------- +def date_cmp(rule,value): + sd = rule.get_start_date() + s = rule.get_modifier() + od = value.get_start_date() + cmp_rule = (sd[2],sd[1],sd[0]) + cmp_value = (od[2],od[1],od[0]) + if s == RelLib.Date.MOD_BEFORE: + return cmp_rule > cmp_value + elif s == RelLib.Date.MOD_AFTER: + return cmp_rule < cmp_value + else: + return cmp_rule == cmp_value diff --git a/gramps2/src/Filters/Rules/_SearchName.py b/gramps2/src/Filters/Rules/_SearchName.py new file mode 100644 index 000000000..8874b6c63 --- /dev/null +++ b/gramps2/src/Filters/Rules/_SearchName.py @@ -0,0 +1,54 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _Rule import Rule +import NameDisplay + +#------------------------------------------------------------------------- +# +# HasNameOf +# +#------------------------------------------------------------------------- +class SearchName(Rule): + """Rule that checks for full or partial name matches""" + + labels = [_('Substring:')] + name = _('People matching the ') + description = _("Matches people with a specified (partial) name") + category = _('General filters') + + def apply(self,db,person): + self.f = self.list[0] + n = NameDisplay.displayer.display(person) + return self.f and n.upper().find(self.f.upper()) != -1 diff --git a/gramps2/src/Filters/Rules/__init__.py b/gramps2/src/Filters/Rules/__init__.py new file mode 100644 index 000000000..b548d1168 --- /dev/null +++ b/gramps2/src/Filters/Rules/__init__.py @@ -0,0 +1,146 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +""" +Package providing filter rules for GRAMPS. +""" + +__author__ = "Don Allingham" + +from _Disconnected import Disconnected +from _Everyone import Everyone +from _FamilyWithIncompleteEvent import FamilyWithIncompleteEvent +from _HasAttribute import HasAttribute +from _HasBirth import HasBirth +from _HasCommonAncestorWith import HasCommonAncestorWith +from _HasCommonAncestorWithFilterMatch import HasCommonAncestorWithFilterMatch +from _HasCompleteRecord import HasCompleteRecord +from _HasDeath import HasDeath +from _HasEvent import HasEvent +from _HasFamilyAttribute import HasFamilyAttribute +from _HasFamilyEvent import HasFamilyEvent +from _HasIdOf import HasIdOf +from _HasNameOf import HasNameOf +from _HasNote import HasNote +from _HasNoteMatchingSubstringOf import HasNoteMatchingSubstringOf +from _HasRelationship import HasRelationship +from _HasSourceOf import HasSourceOf +from _HasTextMatchingRegexpOf import HasTextMatchingRegexpOf +from _HasTextMatchingSubstringOf import HasTextMatchingSubstringOf +from _HasUnknownGender import HasUnknownGender +from _HaveAltFamilies import HaveAltFamilies +from _HaveChildren import HaveChildren +from _HavePhotos import HavePhotos +from _IncompleteNames import IncompleteNames +from _IsAncestorOf import IsAncestorOf +from _IsAncestorOfFilterMatch import IsAncestorOfFilterMatch +from _IsBookmarked import IsBookmarked +from _IsChildOfFilterMatch import IsChildOfFilterMatch +from _IsDefaultPerson import IsDefaultPerson +from _IsDescendantFamilyOf import IsDescendantFamilyOf +from _IsDescendantOf import IsDescendantOf +from _IsDescendantOfFilterMatch import IsDescendantOfFilterMatch +from _IsFemale import IsFemale +from _IsLessThanNthGenerationAncestorOf import IsLessThanNthGenerationAncestorOf +from _IsLessThanNthGenerationAncestorOfBookmarked import \ + IsLessThanNthGenerationAncestorOfBookmarked +from _IsLessThanNthGenerationAncestorOfDefaultPerson import \ + IsLessThanNthGenerationAncestorOfDefaultPerson +from _IsLessThanNthGenerationDescendantOf import \ + IsLessThanNthGenerationDescendantOf +from _IsMale import IsMale +from _IsMoreThanNthGenerationAncestorOf import IsMoreThanNthGenerationAncestorOf +from _IsMoreThanNthGenerationDescendantOf import \ + IsMoreThanNthGenerationDescendantOf +from _IsParentOfFilterMatch import IsParentOfFilterMatch +from _IsSiblingOfFilterMatch import IsSiblingOfFilterMatch +from _IsSpouseOfFilterMatch import IsSpouseOfFilterMatch +from _IsWitness import IsWitness +from _MatchesFilter import MatchesFilter +from _MultipleMarriages import MultipleMarriages +from _NeverMarried import NeverMarried +from _NoBirthdate import NoBirthdate +from _PeoplePrivate import PeoplePrivate +from _PersonWithIncompleteEvent import PersonWithIncompleteEvent +from _ProbablyAlive import ProbablyAlive +from _RelationshipPathBetween import RelationshipPathBetween +from _Rule import Rule +from _SearchName import SearchName + +#------------------------------------------------------------------------- +# +# This is used by Custom Filter Editor tool +# +#------------------------------------------------------------------------- +editor_rule_list = [ + Everyone, + IsFemale, + HasUnknownGender, + IsMale, + IsDefaultPerson, + IsBookmarked, + HasIdOf, + HasNameOf, + HasRelationship, + HasDeath, + HasBirth, + HasCompleteRecord, + HasEvent, + HasFamilyEvent, + HasAttribute, + HasFamilyAttribute, + HasSourceOf, + HaveAltFamilies, + HavePhotos, + HaveChildren, + IncompleteNames, + NeverMarried, + MultipleMarriages, + NoBirthdate, + PersonWithIncompleteEvent, + FamilyWithIncompleteEvent, + ProbablyAlive, + PeoplePrivate, + IsWitness, + IsDescendantOf, + IsDescendantFamilyOf, + IsLessThanNthGenerationAncestorOfDefaultPerson, + IsDescendantOfFilterMatch, + IsLessThanNthGenerationDescendantOf, + IsMoreThanNthGenerationDescendantOf, + IsAncestorOf, + IsAncestorOfFilterMatch, + IsLessThanNthGenerationAncestorOf, + IsLessThanNthGenerationAncestorOfBookmarked, + IsMoreThanNthGenerationAncestorOf, + HasCommonAncestorWith, + HasCommonAncestorWithFilterMatch, + MatchesFilter, + IsChildOfFilterMatch, + IsParentOfFilterMatch, + IsSpouseOfFilterMatch, + IsSiblingOfFilterMatch, + RelationshipPathBetween, + HasTextMatchingSubstringOf, + HasNote, + HasNoteMatchingSubstringOf +] diff --git a/gramps2/src/Filters/_FilterComboBox.py b/gramps2/src/Filters/_FilterComboBox.py new file mode 100644 index 000000000..d27f2ea13 --- /dev/null +++ b/gramps2/src/Filters/_FilterComboBox.py @@ -0,0 +1,96 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +""" +Package providing filtering framework for GRAMPS. +""" + +#------------------------------------------------------------------------- +# +# GTK +# +#------------------------------------------------------------------------- +import gtk + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from Filters import SystemFilters, CustomFilters + +#------------------------------------------------------------------------- +# +# FilterComboBox +# +#------------------------------------------------------------------------- +class FilterComboBox(gtk.ComboBox): + + def set(self,local_filters,default=""): + self.store = gtk.ListStore(str) + self.set_model(self.store) + cell = gtk.CellRendererText() + self.pack_start(cell,True) + self.add_attribute(cell,'text',0) + + self.map = {} + + active = 0 + cnt = 0 + for filt in local_filters: + self.store.append(row=[filt.get_name()]) + self.map[filt.get_name()] = filt + if default != "" and default == filt.get_name(): + active = cnt + cnt += 1 + + for filt in SystemFilters.get_filters(): + self.store.append(row=[filt.get_name()]) + self.map[filt.get_name()] = filt + if default != "" and default == filt.get_name(): + active = cnt + cnt += 1 + + for filt in CustomFilters.get_filters(): + self.store.append(row=[filt.get_name()]) + self.map[filt.get_name()] = filt + if default != "" and default == filt.get_name(): + active = cnt + cnt += 1 + + if active: + self.set_active(active) + elif len(local_filters): + self.set_active(2) + elif len(SystemFilters.get_filters()): + self.set_active(4 + len(local_filters)) + elif len(CustomFilters.get_filters()): + self.set_active(6 + len(local_filters) + len(SystemFilters.get_filters())) + else: + self.set_active(0) + + def get_value(self): + active = self.get_active() + if active < 0: + return None + key = unicode(self.store[active][0]) + return self.map[key] diff --git a/gramps2/src/Filters/_FilterList.py b/gramps2/src/Filters/_FilterList.py new file mode 100644 index 000000000..dfcce1126 --- /dev/null +++ b/gramps2/src/Filters/_FilterList.py @@ -0,0 +1,107 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from xml.sax import make_parser,SAXParseException +import os + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _FilterParser import FilterParser + +#------------------------------------------------------------------------- +# +# FilterList +# +#------------------------------------------------------------------------- +class FilterList: + """ + Container class for managing the generic filters. + It stores, saves, and loads the filters. + """ + + def __init__(self,file): + self.filter_namespaces = {} + self.file = os.path.expanduser(file) + + def get_filters(self,namespace='generic'): + try: + return self.filter_namespaces[namespace] + except KeyError: + return [] + + def add(self,namespace,filt): + if namespace not in self.filter_namespaces.keys(): + self.filter_namespaces[namespace] = [] + self.filter_namespaces[namespace].append(filt) + + def load(self): + try: + if os.path.isfile(self.file): + parser = make_parser() + parser.setContentHandler(FilterParser(self)) + parser.parse(self.file) + except (IOError,OSError): + pass + except SAXParseException: + print "Parser error" + + def fix(self,line): + l = line.strip() + l = l.replace('&','&') + l = l.replace('>','>') + l = l.replace('<','<') + return l.replace('"','"') + + def save(self): + f = open(self.file.encode('utf-8'),'w') + + f.write("\n") + f.write('\n') + for namespace in self.filter_namespaces.keys(): + f.write('\n' % namespace) + filter_list = self.filter_namespaces[namespace] + for the_filter in filter_list: + f.write(' \n') + for rule in the_filter.get_rules(): + rule_class_name = rule.__class__.__name__ + rule_save_name = "Filters.Rules.%s" % rule_class_name + f.write(' \n' % rule_save_name) + for v in rule.values(): + f.write(' \n' % self.fix(v)) + f.write(' \n') + f.write(' \n') + f.write('\n') + f.write('\n') + f.close() diff --git a/gramps2/src/Filters/_FilterMenu.py b/gramps2/src/Filters/_FilterMenu.py new file mode 100644 index 000000000..6cdf4efc6 --- /dev/null +++ b/gramps2/src/Filters/_FilterMenu.py @@ -0,0 +1,72 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# GTK +# +#------------------------------------------------------------------------- +import gtk + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from Filters import SystemFilters, CustomFilters + +#------------------------------------------------------------------------- +# +# This is used by plugins to create a menu of available filters +# +#------------------------------------------------------------------------- +def build_filter_menu(local_filters = [], default=""): + menu = gtk.Menu() + + active = 0 + cnt = 0 + for filt in local_filters: + menuitem = gtk.MenuItem(filt.get_name()) + menuitem.show() + menu.append(menuitem) + menuitem.set_data("filter", filt) + if default != "" and default == filt.get_name(): + active = cnt + cnt += 1 + + for filt in SystemFilters.get_filters(): + menuitem = gtk.MenuItem(_(filt.get_name())) + menuitem.show() + menu.append(menuitem) + menuitem.set_data("filter", filt) + if default != "" and default == filt.get_name(): + active = cnt + cnt += 1 + + for filt in CustomFilters.get_filters(): + menuitem = gtk.MenuItem(_(filt.get_name())) + menuitem.show() + menu.append(menuitem) + menuitem.set_data("filter", filt) + if default != "" and default == filt.get_name(): + active = cnt + cnt += 1 diff --git a/gramps2/src/Filters/_FilterParser.py b/gramps2/src/Filters/_FilterParser.py new file mode 100644 index 000000000..747690b7b --- /dev/null +++ b/gramps2/src/Filters/_FilterParser.py @@ -0,0 +1,179 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from xml.sax import handler + +#------------------------------------------------------------------------- +# +# Gramps modules +# +#------------------------------------------------------------------------- +from _GenericFilter import GenericFilter +import Rules + +#------------------------------------------------------------------------- +# +# FilterParser +# +#------------------------------------------------------------------------- +class FilterParser(handler.ContentHandler): + """Parses the XML file and builds the list of filters""" + + def __init__(self,gfilter_list): + handler.ContentHandler.__init__(self) + self.gfilter_list = gfilter_list + self.f = None + self.r = None + self.a = [] + self.cname = None + self.namespace = "person" + + def setDocumentLocator(self,locator): + self.locator = locator + + def startElement(self,tag,attrs): + if tag == "object": + if attrs.has_key('type'): + self.namespace = attrs['type'] + else: + self.namespace = "generic" + elif tag == "filter": + self.f = GenericFilter() + self.f.set_name(attrs['name']) + if attrs.has_key('function'): + try: + if int(attrs['function']): + op = 'or' + else: + op = 'and' + except ValueError: + op = attrs['function'] + self.f.set_logical_op(op) + if attrs.has_key('comment'): + self.f.set_comment(attrs['comment']) + self.gfilter_list.add(self.namespace,self.f) + elif tag == "rule": + save_name = attrs['class'] + if save_name in old_names_2_class.keys(): + self.r = old_names_2_class[save_name] + else: + try: + # First try to use fully qualified name + exec 'self.r = %s' % save_name + except (ImportError,NameError,AttributeError): + # Now try to use name from Rules + mc_match = save_name.split('.') + try: + exec 'self.r = Rules.%s' % mc_match[-1] + except (ImportError,NameError): + print "ERROR: Filter rule '%s' in filter '%s' not found!"\ + % (save_name,self.f.get_name()) + self.r = None + return + self.a = [] + elif tag == "arg": + self.a.append(attrs['value']) + + def endElement(self,tag): + if tag == "rule" and self.r != None: + if len(self.r.labels) < len(self.a): + print "WARNING: Invalid number of arguments in filter '%s'!" %\ + self.f.get_name() + nargs = len(self.r.labels) + rule = self.r(self.a[0:nargs]) + self.f.add_rule(rule) + elif len(self.r.labels) > len(self.a): + print "ERROR: Invalid number of arguments in filter '%s'!" %\ + self.f.get_name() + else: + rule = self.r(self.a) + self.f.add_rule(rule) + + def characters(self, data): + pass + +#------------------------------------------------------------------------- +# +# Name to class mappings +# +#------------------------------------------------------------------------- +# This dict is mapping from old names to new names, so that the existing +# custom_filters.xml will continue working +old_names_2_class = { + "Everyone" : Rules.Everyone, + "Is default person" : Rules.IsDefaultPerson, + "Is bookmarked person" : Rules.IsBookmarked, + "Has the Id" : Rules.HasIdOf, + "Has a name" : Rules.HasNameOf, + "Has the relationships" : Rules.HasRelationship, + "Has the death" : Rules.HasDeath, + "Has the birth" : Rules.HasBirth, + "Is a descendant of" : Rules.IsDescendantOf, + "Is a descendant family member of" : Rules.IsDescendantFamilyOf, + "Is a descendant of filter match": Rules.IsDescendantOfFilterMatch, + "Is a descendant of person not more than N generations away": + Rules.IsLessThanNthGenerationDescendantOf, + "Is a descendant of person at least N generations away": + Rules.IsMoreThanNthGenerationDescendantOf, + "Is an descendant of person at least N generations away" : + Rules.IsMoreThanNthGenerationDescendantOf, + "Is a child of filter match" : Rules.IsChildOfFilterMatch, + "Is an ancestor of" : Rules.IsAncestorOf, + "Is an ancestor of filter match": Rules.IsAncestorOfFilterMatch, + "Is an ancestor of person not more than N generations away" : + Rules.IsLessThanNthGenerationAncestorOf, + "Is an ancestor of person at least N generations away": + Rules.IsMoreThanNthGenerationAncestorOf, + "Is a parent of filter match" : Rules.IsParentOfFilterMatch, + "Has a common ancestor with" : Rules.HasCommonAncestorWith, + "Has a common ancestor with filter match" :Rules.HasCommonAncestorWithFilterMatch, + "Is a female" : Rules.IsFemale, + "Is a male" : Rules.IsMale, + "Has complete record" : Rules.HasCompleteRecord, + "Has the personal event" : Rules.HasEvent, + "Has the family event" : Rules.HasFamilyEvent, + "Has the personal attribute" : Rules.HasAttribute, + "Has the family attribute" : Rules.HasFamilyAttribute, + "Has source of" : Rules.HasSourceOf, + "Matches the filter named" : Rules.HasSourceOf, + "Is spouse of filter match" : Rules.IsSpouseOfFilterMatch, + "Is a sibling of filter match" : Rules.IsSiblingOfFilterMatch, + "Relationship path between two people" : Rules.RelationshipPathBetween, + "People who were adopted" : Rules.HaveAltFamilies, + "People who have images" : Rules.HavePhotos, + "People with children" : Rules.HaveChildren, + "People with incomplete names" : Rules.IncompleteNames, + "People with no marriage records" : Rules.NeverMarried, + "People with multiple marriage records": Rules.MultipleMarriages, + "People without a birth date" : Rules.NoBirthdate, + "People with incomplete events" : Rules.PersonWithIncompleteEvent, + "Families with incomplete events" :Rules.FamilyWithIncompleteEvent, + "People probably alive" : Rules.ProbablyAlive, + "People marked private" : Rules.PeoplePrivate, + "Witnesses" : Rules.IsWitness, + "Has text matching substring of": Rules.HasTextMatchingSubstringOf, +} diff --git a/gramps2/src/Filters/_FilterStore.py b/gramps2/src/Filters/_FilterStore.py new file mode 100644 index 000000000..5002b8390 --- /dev/null +++ b/gramps2/src/Filters/_FilterStore.py @@ -0,0 +1,75 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +""" +Package providing filtering framework for GRAMPS. +""" + +#------------------------------------------------------------------------- +# +# GTK +# +#------------------------------------------------------------------------- +import gtk + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _GenericFilter import GenericFilter +from Filters import SystemFilters, CustomFilters + +#------------------------------------------------------------------------- +# +# FilterStore +# +#------------------------------------------------------------------------- +class FilterStore(gtk.ListStore): + + def __init__(self,local_filters=[], namespace="generic",default=""): + gtk.ListStore.__init__(self,str) + self.list_map = [] + self.def_index = 0 + + cnt = 0 + for filt in local_filters: + name = filt.get_name() + self.append(row=[name]) + self.list_map.append(filt) + if default != "" and default == name: + self.def_index = cnt + cnt += 1 + + for filt in SystemFilters.get_filters(namespace) + CustomFilters.get_filters(namespace): + name = _(filt.get_name()) + self.append(row=[name]) + self.list_map.append(filt) + if default != "" and default == name: + self.def_index = cnt + cnt += 1 + + def default_index(self): + return self.def_index + + def get_filter(self,index): + return self.list_map[index] diff --git a/gramps2/src/Filters/_FilterWidget.py b/gramps2/src/Filters/_FilterWidget.py new file mode 100644 index 000000000..0c38403bb --- /dev/null +++ b/gramps2/src/Filters/_FilterWidget.py @@ -0,0 +1,128 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +""" +Package providing filtering framework for GRAMPS. +""" + +#------------------------------------------------------------------------- +# +# GTK +# +#------------------------------------------------------------------------- +import gtk + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _GenericFilter import GenericFilter +from _FilterStore import FilterStore + +#------------------------------------------------------------------------- +# +# FilterWidget +# +#------------------------------------------------------------------------- +class FilterWidget: + def __init__( self, uistate, on_apply, apply_done = None): + self.on_apply_callback = on_apply + self.apply_done_callback = apply_done + self.uistate = uistate + + def build( self): + self.filterbar = gtk.HBox() + self.filterbar.set_spacing(4) + self.filter_text = gtk.Entry() + self.filter_list = gtk.ComboBox() + self.filter_button = gtk.Button(stock=gtk.STOCK_FIND) + self.filter_button.connect( 'clicked',self.apply_filter_clicked) + self.filterbar.pack_start(self.filter_list,False) + self.filterbar.pack_start(self.filter_text,True) + self.filterbar.pack_end(self.filter_button,False) + +# self.filter_text.set_sensitive(False) + + return self.filterbar + + def setup_filter( self, default_filters, namespace="generic"): + cell = gtk.CellRendererText() + self.filter_list.clear() + self.filter_list.pack_start(cell,True) + self.filter_list.add_attribute(cell,'text',0) + + filter_list = [] + + for f in default_filters: + all = GenericFilter() + rule = f[0](f[1]) + #print rule + all.set_name( rule.name) + all.add_rule( rule) + filter_list.append(all) + + self.filter_model = FilterStore(filter_list, namespace) + self.filter_list.set_model(self.filter_model) + self.filter_list.set_active(self.filter_model.default_index()) + self.filter_list.connect('changed',self.on_filter_name_changed) +# self.filter_text.set_sensitive(False) + self.DataFilter = filter_list[self.filter_model.default_index()] + + def apply_filter_clicked(self,ev=None): + print "apply_filter_clicked" + index = self.filter_list.get_active() + self.DataFilter = self.filter_model.get_filter(index) + if self.DataFilter.need_param: + qual = unicode(self.filter_text.get_text()) + self.DataFilter.set_parameter(qual) + self.apply_filter() + if self.apply_done_callback: + self.apply_done_callback() + + def on_filter_name_changed(self,obj): + print "on_filter_name_changed" + index = self.filter_list.get_active() +# mime_filter = self.filter_model.get_filter(index) +# qual = mime_filter.need_param +# if qual: +# self.filter_text.show() +# self.filter_text.set_sensitive(True) +# else: +# self.filter_text.hide() +# self.filter_text.set_sensitive(False) + + def apply_filter(self,current_model=None): + self.uistate.status_text(_('Updating display...')) + self.on_apply_callback() + self.uistate.modify_statusbar() + + def get_filter( self): + print "get_filter" + #print self.DataFilter.flist[0] + return self.DataFilter + + def show( self): + self.filterbar.show() + + def hide( self): + self.filterbar.hide() diff --git a/gramps2/src/Filters/_GenericFilter.py b/gramps2/src/Filters/_GenericFilter.py new file mode 100644 index 000000000..e47ca38aa --- /dev/null +++ b/gramps2/src/Filters/_GenericFilter.py @@ -0,0 +1,185 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +""" +Package providing filtering framework for GRAMPS. +""" + +#------------------------------------------------------------------------- +# +# GenericFilter +# +#------------------------------------------------------------------------- +class GenericFilter: + """Filter class that consists of several rules""" + + logical_functions = ['or', 'and', 'xor', 'one'] + + def __init__(self,source=None): + if source: + self.need_param = source.need_param + self.flist = source.flist[:] + self.name = source.name + self.comment = source.comment + self.logical_op = source.logical_op + else: + self.need_param = 0 + self.flist = [] + self.name = '' + self.comment = '' + self.logical_op = 'and' + + def match(self,handle): + return True + + def is_empty(self): + return len(self.flist) == 1 and self.flist[0].is_empty() + + def set_logical_op(self,val): + if val in GenericFilter.logical_functions: + self.logical_op = val + else: + self.logical_op = 'and' + + def get_logical_op(self): + return self.logical_op + + def get_name(self): + return self.name + + def set_name(self,name): + self.name = name + + def set_comment(self,comment): + self.comment = comment + + def get_comment(self): + return self.comment + + def add_rule(self,rule): + self.flist.append(rule) + + def delete_rule(self,rule): + self.flist.remove(rule) + + def set_rules(self,rules): + self.flist = rules + + def get_rules(self): + return self.flist + + def check_func(self,db,id_list,task): + final_list = [] + + if id_list == None: + cursor = db.get_person_cursor() + data = cursor.next() + while data: + person = RelLib.Person() + person.unserialize(data[1]) + if not task(db,person): + final_list.append(data[0]) + data = cursor.next() + else: + for handle in id_list: + person = db.get_person_from_handle(handle) + if not task(db,person): + final_list.append(handle) + return final_list + + def check_or(self,db,id_list): + return self.check_func(db,id_list,self.or_test) + + def check_and(self,db,id_list): + final_list = [] + flist = self.flist + if id_list == None: + cursor = db.get_person_cursor() + data = cursor.next() + p = RelLib.Person + while data: + person = p(data[1]) + val = True + for rule in flist: + if not rule.apply(db,person): + val = False + break + if not val: + final_list.append(data[0]) + data = cursor.next() + else: + for handle in id_list: + person = db.get_person_from_handle(handle) + val = True + for rule in flist: + if not rule.apply(db,person): + val = False + break + if val: + final_list.append(handle) + return final_list + + def check_one(self,db,id_list): + return self.check_func(db,id_list,self.one_test) + + def check_xor(self,db,id_list): + return self.check_func(db,id_list,self.xor_test) + + def xor_test(self,db,person): + test = False + for rule in self.flist: + test = test ^ rule.apply(db,person) + return test + + def one_test(self,db,person): + count = 0 + for rule in self.flist: + if rule.apply(db,person): + if count: + return False + count += 1 + return count == 1 + + def or_test(self,db,person): + for rule in self.flist: + if rule.apply(db,person): + return True + return False + + def get_check_func(self): + try: + m = getattr(self, 'check_' + self.logical_op) + except AttributeError: + m = self.check_and + return m + + def check(self,db,handle): + return self.get_check_func()(db,[handle]) + + def apply(self,db,id_list=None): + m = self.get_check_func() + for rule in self.flist: + rule.prepare(db) + res = m(db,id_list) + for rule in self.flist: + rule.reset() + return res diff --git a/gramps2/src/Filters/_ParamFilter.py b/gramps2/src/Filters/_ParamFilter.py new file mode 100644 index 000000000..14901eaa0 --- /dev/null +++ b/gramps2/src/Filters/_ParamFilter.py @@ -0,0 +1,65 @@ +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +""" +Package providing filtering framework for GRAMPS. +""" + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from _GenericFilter import GenericFilter + +#------------------------------------------------------------------------- +# +# ParamFilter +# +#------------------------------------------------------------------------- +class ParamFilter(GenericFilter): + + def __init__(self,source=None): + GenericFilter.__init__(self,source) + self.need_param = 1 + self.param_list = [] + + def set_parameter(self,param): + self.param_list = [param] + + def apply(self,db,id_list=None): + for rule in self.flist: + #rule.set_list(self.param_list) + # + # The above breaks filters with more than one param + # Need to change existing params one by one to keep + # the correct number of arguments + new_list = rule.list[:] + for ix in range(len(self.param_list)): + new_list[ix] = self.param_list[ix] + rule.set_list(new_list) + for rule in self.flist: + rule.prepare(db) + result = GenericFilter.apply(self,db,id_list) + for rule in self.flist: + rule.reset() + return result diff --git a/gramps2/src/Filters/__init__.py b/gramps2/src/Filters/__init__.py new file mode 100644 index 000000000..c53b7394b --- /dev/null +++ b/gramps2/src/Filters/__init__.py @@ -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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +""" +Package providing filtering framework for GRAMPS. +""" + +__author__ = "Don Allingham" + +SystemFilters = None +CustomFilters = None + +from const import system_filters, custom_filters +from _FilterList import FilterList +from _GenericFilter import GenericFilter +from _ParamFilter import ParamFilter +import Rules + +def reload_system_filters(): + global SystemFilters + SystemFilters = FilterList(system_filters) + SystemFilters.load() + +def reload_custom_filters(): + global CustomFilters + CustomFilters = FilterList(custom_filters) + CustomFilters.load() + +if not SystemFilters: + reload_system_filters() + +if not CustomFilters: + reload_custom_filters() + +from _FilterWidget import FilterWidget +from _FilterComboBox import FilterComboBox +from _FilterMenu import build_filter_menu +from _FilterStore import FilterStore diff --git a/gramps2/src/GenericFilter.py b/gramps2/src/GenericFilter.py deleted file mode 100644 index 156fe94d3..000000000 --- a/gramps2/src/GenericFilter.py +++ /dev/null @@ -1,2701 +0,0 @@ -# -# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -# $Id$ - -"""Generic Filtering Routines""" - -__author__ = "Don Allingham" - -#------------------------------------------------------------------------- -# -# Try to abstract SAX1 from SAX2 -# -#------------------------------------------------------------------------- -from xml.sax import make_parser,handler,SAXParseException - -#------------------------------------------------------------------------- -# -# Standard Python modules -# -#------------------------------------------------------------------------- -import os -import sets -from TransUtils import sgettext as _ - -#------------------------------------------------------------------------- -# -# set up logging -# -#------------------------------------------------------------------------- -import logging -log = logging.getLogger(".GenericFilter") - -#------------------------------------------------------------------------- -# -# gtk -# -#------------------------------------------------------------------------- -import gtk - -#------------------------------------------------------------------------- -# -# GRAMPS modules -# -#------------------------------------------------------------------------- -import const -import RelLib -import DateHandler -import NameDisplay -from Utils import for_each_ancestor,probably_alive,get_source_referents - -#------------------------------------------------------------------------- -# -# date_cmp -# -#------------------------------------------------------------------------- -def date_cmp(rule,value): - sd = rule.get_start_date() - s = rule.get_modifier() - od = value.get_start_date() - cmp_rule = (sd[2],sd[1],sd[0]) - cmp_value = (od[2],od[1],od[0]) - if s == RelLib.Date.MOD_BEFORE: - return cmp_rule > cmp_value - elif s == RelLib.Date.MOD_AFTER: - return cmp_rule < cmp_value - else: - return cmp_rule == cmp_value - -#------------------------------------------------------------------------- -# -# Rule -# -#------------------------------------------------------------------------- -class Rule: - """Base rule class""" - - labels = [] - name = '' - category = _('Miscellaneous filters') - description = _('No description') - - def __init__(self,list): - self.set_list(list) - - def is_empty(self): - return False - - def prepare(self,db): - pass - - def reset(self): - pass - - def set_list(self,list): - assert type(list) == type([]) or list == None, "Argument is not a list" - assert len(list) == len(self.labels), \ - "Number of arguments does not match number of labels.\n"\ - "list: %s\nlabels: %s" % (list,self.labels) - self.list = list - - def values(self): - return self.list - - def check(self): - return len(self.list) == len(self.labels) - - def apply(self,db,person): - return True - - def display_values(self): - v = [] - for i in range(0,len(self.list)): - if self.list[i]: - v.append('%s="%s"' % (_(self.labels[i]),_(self.list[i]))) - return ';'.join(v) - -#------------------------------------------------------------------------- -# -# Everyone -# -#------------------------------------------------------------------------- -class Everyone(Rule): - """Matches Everyone""" - - name = _('Everyone') - category = _('General filters') - description = _('Matches everyone in the database') - - def is_empty(self): - return True - - def apply(self,db,person): - return True - -#------------------------------------------------------------------------- -# -# Disconnected -# -#------------------------------------------------------------------------- -class Disconnected(Rule): - """Matches disconnected people""" - - name = _('Disconnected people') - category = _('General filters') - description = _('Matches people that have no family relationships ' - 'to any other person in the database') - - def apply(self,db,person): - return (not person.get_main_parents_family_handle() and - not len(person.get_family_handle_list())) - -#------------------------------------------------------------------------- -# -# RelationshipPathBetween -# -#------------------------------------------------------------------------- -class RelationshipPathBetween(Rule): - """Rule that checks for a person that is a descendant of a specified person - not more than N generations away""" - - labels = [ _('ID:'), _('ID:') ] - name = _("Relationship path between ") - category = _('Relationship filters') - description = _("Matches the ancestors of two persons back to a common ancestor, " - "producing the relationship path between two persons.") - - def prepare(self,db): - self.db = db - self.map = {} - try: - root1_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() - root2_handle = db.get_person_from_gramps_id(self.list[1]).get_handle() - self.init_list(root1_handle,root2_handle) - except: - pass - - def reset(self): - self.map = {} - - def desc_list(self, handle, map, first): - if not first: - map[handle] = 1 - - p = self.db.get_person_from_handle(handle) - for fam_id in p.get_family_handle_list(): - fam = self.db.get_family_from_handle(fam_id) - if fam: - for child_handle in fam.get_child_handle_list(): - if child_handle: - self.desc_list(child_handle,map,0) - - def apply_filter(self,rank,handle,plist,pmap): - person = self.db.get_person_from_handle(handle) - if person == None: - return - plist.append(person) - pmap[person.get_handle()] = rank - - fam_id = person.get_main_parents_family_handle() - family = self.db.get_family_from_handle(fam_id) - if family != None: - self.apply_filter(rank+1,family.get_father_handle(),plist,pmap) - self.apply_filter(rank+1,family.get_mother_handle(),plist,pmap) - - def apply(self,db,person): - return self.map.has_key(person.handle) - - def init_list(self,p1_handle,p2_handle): - firstMap = {} - firstList = [] - secondMap = {} - secondList = [] - common = [] - rank = 9999999 - - self.apply_filter(0,p1_handle,firstList,firstMap) - self.apply_filter(0,p2_handle,secondList,secondMap) - - for person_handle in firstList: - if person_handle in secondList: - new_rank = firstMap[person_handle] - if new_rank < rank: - rank = new_rank - common = [ person_handle ] - elif new_rank == rank: - common.append(person_handle) - - path1 = { p1_handle : 1} - path2 = { p2_handle : 1} - - for person_handle in common: - new_map = {} - self.desc_list(person_handle,new_map,1) - self.get_intersection(path1,firstMap,new_map) - self.get_intersection(path2,secondMap,new_map) - - for e in path1: - self.map[e] = 1 - for e in path2: - self.map[e] = 1 - for e in common: - self.map[e] = 1 - - def get_intersection(self,target, map1, map2): - for e in map1.keys(): - if map2.has_key(e): - target[e] = map2[e] - -#------------------------------------------------------------------------- -# -# HasIdOf -# -#------------------------------------------------------------------------- -class HasIdOf(Rule): - """Rule that checks for a person with a specific GRAMPS ID""" - - labels = [ _('ID:') ] - name = _('People with ') - description = _("Matches people with a specified GRAMPS ID") - category = _('General filters') - - def apply(self,db,person): - return person.gramps_id == self.list[0] - -#------------------------------------------------------------------------- -# -# IsDefaultPerson -# -#------------------------------------------------------------------------- -class IsDefaultPerson(Rule): - """Rule that checks for a default person in the database""" - - name = _('Default person') - category = _('General filters') - description = _("Matches the default person") - - def prepare(self,db): - p = db.get_default_person() - if p: - self.def_handle = p.get_handle() - self.apply = self.apply_real - else: - self.apply = lambda db,p: False - - def apply_real(self,db,person): - return person.handle == self.def_handle - -#------------------------------------------------------------------------- -# -# IsBookmarked -# -#------------------------------------------------------------------------- -class IsBookmarked(Rule): - """Rule that checks for the bookmark list in the database""" - - name = _('Bookmarked people') - category = _('General filters') - description = _("Matches the people on the bookmark list") - - def prepare(self,db): - bookmarks = db.get_bookmarks() - if len(bookmarks) == 0: - self.apply = lambda db,p : False - else: - self.bookmarks = sets.Set(bookmarks) - self.apply = self.apply_real - - def apply_real(self,db,person): - return person.handle in self.bookmarks - -#------------------------------------------------------------------------- -# -# HasCompleteRecord -# -#------------------------------------------------------------------------- -class HasCompleteRecord(Rule): - """Rule that checks for a person whose record is complete""" - - name = _('People with complete records') - category = _('General filters') - description = _('Matches all people whose records are complete') - - def apply(self,db,person): - return person.get_complete_flag() == 1 - -#------------------------------------------------------------------------- -# -# IsFemale -# -#------------------------------------------------------------------------- -class IsFemale(Rule): - """Rule that checks for a person that is a female""" - - name = _('Females') - category = _('General filters') - description = _('Matches all females') - - def apply(self,db,person): - return person.gender == RelLib.Person.FEMALE - -#------------------------------------------------------------------------- -# -# HasUnknownGender -# -#------------------------------------------------------------------------- -class HasUnknownGender(Rule): - """Rule that checks for a person that has unknown gender""" - - name = _('People with unknown gender') - category = _('General filters') - description = _('Matches all people with unknown gender') - - def apply(self,db,person): - return person.gender == RelLib.Person.UNKNOWN - -#------------------------------------------------------------------------- -# -# IsDescendantOf -# -#------------------------------------------------------------------------- -class IsDescendantOf(Rule): - """Rule that checks for a person that is a descendant - of a specified person""" - - labels = [ _('ID:'), _('Inclusive:') ] - name = _('Descendants of ') - category = _('Descendant filters') - description = _('Matches all descendants for the specified person') - - def prepare(self,db): - self.db = db - self.map = {} - try: - if int(self.list[1]): - first = False - else: - first = True - except IndexError: - first = True - try: - root_person = db.get_person_from_gramps_id(self.list[0]) - self.init_list(root_person,first) - except: - pass - - def reset(self): - self.map = {} - - def apply(self,db,person): - return self.map.has_key(person.handle) - - def init_list(self,person,first): - if not person: - return - if not first: - self.map[person.handle] = 1 - - for fam_id in person.get_family_handle_list(): - fam = self.db.get_family_from_handle(fam_id) - if fam: - for child_handle in fam.get_child_handle_list(): - self.init_list(self.db.get_person_from_handle(child_handle),0) - -#------------------------------------------------------------------------- -# -# IsDescendantOfFilterMatch -# -#------------------------------------------------------------------------- -class IsDescendantOfFilterMatch(IsDescendantOf): - """Rule that checks for a person that is a descendant - of someone matched by a filter""" - - labels = [ _('Filter name:') ] - name = _('Descendants of match') - category = _('Descendant filters') - description = _("Matches people that are descendants of anybody matched by a filter") - - -# def __init__(self,list): -# IsDescendantOf.__init__(self,list) - - def prepare(self,db): - self.db = db - self.map = {} - try: - if int(self.list[1]): - first = 0 - else: - first = 1 - except IndexError: - first = 1 - - filt = MatchesFilter(self.list[0:1]) - filt.prepare(db) - for person_handle in db.get_person_handles(sort_handles=False): - person = db.get_person_from_handle( person_handle) - if filt.apply (db, person): - self.init_list (person,first) - filt.reset() - - def reset(self): - self.map = {} - - def apply(self,db,person): - return self.map.has_key(person.handle) - -#------------------------------------------------------------------------- -# -# IsLessThanNthGenerationDescendantOf -# -#------------------------------------------------------------------------- -class IsLessThanNthGenerationDescendantOf(Rule): - """Rule that checks for a person that is a descendant of a specified person - not more than N generations away""" - - labels = [ _('ID:'), _('Number of generations:') ] - name = _('Descendants of not more than generations away') - category = _('Descendant filters') - description = _("Matches people that are descendants of a specified person " - "not more than N generations away") - - def prepare(self,db): - self.db = db - self.map = {} - try: - root_person = db.get_person_from_gramps_id(self.list[0]) - self.init_list(root_person,0) - except: - pass - - def reset(self): - self.map = {} - - def apply(self,db,person): - return self.map.has_key(person.handle) - - def init_list(self,person,gen): - if not person: - return - if gen: - self.map[person.handle] = 1 - if gen >= int(self.list[1]): - return - - for fam_id in person.get_family_handle_list(): - fam = self.db.get_family_from_handle(fam_id) - for child_handle in fam.get_child_handle_list(): - self.init_list(self.db.get_person_from_handle(child_handle),gen+1) - -#------------------------------------------------------------------------- -# -# IsMoreThanNthGenerationDescendantOf -# -#------------------------------------------------------------------------- -class IsMoreThanNthGenerationDescendantOf(Rule): - """Rule that checks for a person that is a descendant of a specified person - at least N generations away""" - - labels = [ _('ID:'), _('Number of generations:') ] - name = _('Descendants of at least generations away') - category = _("Descendant filters") - description = _("Matches people that are descendants of a specified " - "person at least N generations away") - - - def prepare(self,db): - self.db = db - self.map = {} - try: - root_person = db.get_person_from_gramps_id(self.list[0]) - self.init_list(root_person,0) - except: - pass - - def reset(self): - self.map = {} - - def apply(self,db,person): - return self.map.has_key(person.handle) - - def init_list(self,person,gen): - if not person: - return - if gen >= int(self.list[1]): - self.map[person.handle] = 1 - - for fam_id in person.get_family_handle_list(): - fam = self.db.get_family_from_handle(fam_id) - for child_handle in fam.get_child_handle_list(): - self.init_list(self.db.get_person_from_handle(child_handle),gen+1) - -#------------------------------------------------------------------------- -# -# IsChildOfFilterMatch -# -#------------------------------------------------------------------------- -class IsChildOfFilterMatch(Rule): - """Rule that checks for a person that is a child - of someone matched by a filter""" - - labels = [ _('Filter name:') ] - name = _('Children of match') - category = _('Family filters') - description = _("Matches children of anybody matched by a filter") - - def prepare(self,db): - self.db = db - self.map = {} - filt = MatchesFilter(self.list) - filt.prepare(db) - for person_handle in db.get_person_handles(sort_handles=False): - person = db.get_person_from_handle( person_handle) - if filt.apply (db, person): - self.init_list (person) - filt.reset() - - def reset(self): - self.map = {} - - def apply(self,db,person): - return self.map.has_key(person.handle) - - def init_list(self,person): - if not person: - return - for fam_id in person.get_family_handle_list(): - fam = self.db.get_family_from_handle(fam_id) - for child_handle in fam.get_child_handle_list(): - self.map[child_handle] = 1 - -#------------------------------------------------------------------------- -# -# IsSiblingOfFilterMatch -# -#------------------------------------------------------------------------- -class IsSiblingOfFilterMatch(Rule): - """Rule that checks for siblings of someone matched by a filter""" - - labels = [ _('Filter name:') ] - name = _('Siblings of match') - category = _('Family filters') - description = _("Matches siblings of anybody matched by a filter") - - def prepare(self,db): - self.db = db - self.map = {} - filt = MatchesFilter(self.list) - filt.prepare(db) - for person_handle in db.get_person_handles(sort_handles=False): - person = db.get_person_from_handle( person_handle) - if filt.apply (db, person): - self.init_list (person) - filt.reset() - - def reset(self): - self.map = {} - - def apply(self,db,person): - return self.map.has_key(person.handle) - - def init_list(self,person): - if not person: - return - fam_id = person.get_main_parents_family_handle() - fam = self.db.get_family_from_handle(fam_id) - if fam: - for child_handle in fam.get_child_handle_list(): - if child_handle != person.handle: - self.map[child_handle] = 1 - -#------------------------------------------------------------------------- -# -# IsDescendantFamilyOf -# -#------------------------------------------------------------------------- -class IsDescendantFamilyOf(Rule): - """Rule that checks for a person that is a descendant or the spouse - of a descendant of a specified person""" - - labels = [ _('ID:') ] - name = _('Descendant family members of ') - category = _('Descendant filters') - description = _("Matches people that are descendants or the spouse " - "of a descendant of a specified person") - - def apply(self,db,person): - self.map = {} - self.orig_handle = person.handle - self.db = db - return self.search(person.handle,1) - - def search(self,handle,val): - try: - if handle == self.db.get_person_from_gramps_id(self.list[0]).get_handle(): - self.map[handle] = 1 - return True - except: - return False - - p = self.db.get_person_from_handle(handle) - for (f,r1,r2) in p.get_parent_family_handle_list(): - family = self.db.get_family_from_handle(f) - for person_handle in [family.get_mother_handle(),family.get_father_handle()]: - if person_handle: - if self.search(person_handle,0): - return True - if val: - for family_handle in p.get_family_handle_list(): - family = self.db.get_family_from_handle(family_handle) - if handle == family.get_father_handle(): - spouse_id = family.get_mother_handle() - else: - spouse_id = family.get_father_handle() - if spouse_id: - if self.search(spouse_id,0): - return True - return False - -#------------------------------------------------------------------------- -# -# IsAncestorOf -# -#------------------------------------------------------------------------- -class IsAncestorOf(Rule): - """Rule that checks for a person that is an ancestor of a specified person""" - - labels = [ _('ID:'), _('Inclusive:') ] - name = _('Ancestors of ') - category = _("Ancestral filters") - description = _("Matches people that are ancestors of a specified person") - - def prepare(self,db): - """Assume that if 'Inclusive' not defined, assume inclusive""" - self.db = db - self.map = {} - try: - if int(self.list[1]): - first = 0 - else: - first = 1 - except IndexError: - first = 1 - try: - root_person = db.get_person_from_gramps_id(self.list[0]) - self.init_ancestor_list(db,root_person,first) - except: - pass - - def reset(self): - self.map = {} - - def apply(self,db,person): - return self.map.has_key(person.handle) - - def init_ancestor_list(self,db,person,first): - if not person: - return - if not first: - self.map[person.handle] = 1 - - fam_id = person.get_main_parents_family_handle() - fam = db.get_family_from_handle(fam_id) - if fam: - f_id = fam.get_father_handle() - m_id = fam.get_mother_handle() - - if f_id: - self.init_ancestor_list(db,db.get_person_from_handle(f_id),0) - if m_id: - self.init_ancestor_list(db,db.get_person_from_handle(m_id),0) - -#------------------------------------------------------------------------- -# -# IsAncestorOfFilterMatch -# -#------------------------------------------------------------------------- -class IsAncestorOfFilterMatch(IsAncestorOf): - """Rule that checks for a person that is an ancestor of - someone matched by a filter""" - - labels = [ _('Filter name:') ] - name = _('Ancestors of match') - category = _("Ancestral filters") - description = _("Matches people that are ancestors " - "of anybody matched by a filter") - - - def __init__(self,list): - IsAncestorOf.__init__(self,list) - - def prepare(self,db): - self.db = db - self.map = {} - try: - if int(self.list[1]): - first = 0 - else: - first = 1 - except IndexError: - first = 1 - - filt = MatchesFilter(self.list[0:1]) - filt.prepare(db) - for person_handle in db.get_person_handles(sort_handles=False): - person = db.get_person_from_handle( person_handle) - if filt.apply (db, person): - self.init_ancestor_list (db,person,first) - filt.reset() - - def reset(self): - self.map = {} - - def apply(self,db,person): - return self.map.has_key(person.handle) - -#------------------------------------------------------------------------- -# -# IsLessThanNthGenerationAncestorOf -# -#------------------------------------------------------------------------- -class IsLessThanNthGenerationAncestorOf(Rule): - """Rule that checks for a person that is an ancestor of a specified person - not more than N generations away""" - - labels = [ _('ID:'), _('Number of generations:') ] - name = _('Ancestors of not more than generations away') - category = _("Ancestral filters") - description = _("Matches people that are ancestors " - "of a specified person not more than N generations away") - - def prepare(self,db): - self.db = db - self.map = {} - try: - root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() - self.init_ancestor_list(root_handle,0) - except: - pass - - def reset(self): - self.map = {} - - def apply(self,db,person): - return self.map.has_key(person.handle) - - def init_ancestor_list(self,handle,gen): -# if self.map.has_key(p.get_handle()) == 1: -# loop_error(self.orig,p) - if not handle: - return - if gen: - self.map[handle] = 1 - if gen >= int(self.list[1]): - return - - p = self.db.get_person_from_handle(handle) - fam_id = p.get_main_parents_family_handle() - fam = self.db.get_family_from_handle(fam_id) - if fam: - f_id = fam.get_father_handle() - m_id = fam.get_mother_handle() - - if f_id: - self.init_ancestor_list(f_id,gen+1) - if m_id: - self.init_ancestor_list(m_id,gen+1) - -#------------------------------------------------------------------------- -# -# IsMoreThanNthGenerationAncestorOf -# -#------------------------------------------------------------------------- -class IsMoreThanNthGenerationAncestorOf(Rule): - """Rule that checks for a person that is an ancestor of a specified person - at least N generations away""" - - labels = [ _('ID:'), _('Number of generations:') ] - name = _('Ancestors of at least generations away') - category = _("Ancestral filters") - description = _("Matches people that are ancestors " - "of a specified person at least N generations away") - - def prepare(self,db): - self.db = db - self.map = {} - try: - root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() - self.init_ancestor_list(root_handle,0) - except: - pass - - def reset(self): - self.map = [] - - def apply(self,db,person): - return self.map.has_key(person.handle) - - def init_ancestor_list(self,handle,gen): -# if self.map.has_key(p.get_handle()) == 1: -# loop_error(self.orig,p) - if not handle: - return - if gen >= int(self.list[1]): - self.map[handle] = 1 - - p = self.db.get_person_from_handle(handle) - fam_id = p.get_main_parents_family_handle() - fam = self.db.get_family_from_handle(fam_id) - if fam: - f_id = fam.get_father_handle() - m_id = fam.get_mother_handle() - - if f_id: - self.init_ancestor_list(f_id,gen+1) - if m_id: - self.init_ancestor_list(m_id,gen+1) - -#------------------------------------------------------------------------- -# -# IsParentOfFilterMatch -# -#------------------------------------------------------------------------- -class IsParentOfFilterMatch(Rule): - """Rule that checks for a person that is a parent - of someone matched by a filter""" - - labels = [ _('Filter name:') ] - name = _('Parents of match') - category = _('Family filters') - description = _("Matches parents of anybody matched by a filter") - - def prepare(self,db): - self.db = db - self.map = {} - filt = MatchesFilter(self.list) - filt.prepare(db) - for person_handle in db.get_person_handles(sort_handles=False): - person = db.get_person_from_handle(person_handle) - if filt.apply (db, person): - self.init_list (person) - filt.reset() - - def reset(self): - self.map = {} - - def apply(self,db,person): - return self.map.has_key(person.handle) - - def init_list(self,person): - for fam_id,frel,mrel in person.get_parent_family_handle_list(): - fam = self.db.get_family_from_handle(fam_id) - for parent_id in [fam.get_father_handle (), fam.get_mother_handle ()]: - if parent_id: - self.map[parent_id] = 1 - -#------------------------------------------------------------------------- -# -# HasCommonAncestorWith -# -#------------------------------------------------------------------------- -class HasCommonAncestorWith(Rule): - """Rule that checks for a person that has a common ancestor with a specified person""" - - labels = [ _('ID:') ] - name = _('People with a common ancestor with ') - category = _("Ancestral filters") - description = _("Matches people that have a common ancestor " - "with a specified person") - - def prepare(self,db): - self.db = db - # Keys in `ancestor_cache' are ancestors of list[0]. - # We delay the computation of ancestor_cache until the - # first use, because it's not uncommon to instantiate - # this class and not use it. - self.ancestor_cache = {} - - def reset(self): - self.ancestor_cache = {} - - def init_ancestor_cache(self,db): - # list[0] is an Id, but we need to pass a Person to for_each_ancestor. - try: - handle = db.get_person_from_gramps_id(self.list[0]).get_handle() - if handle: - def init(self,handle): self.ancestor_cache[handle] = 1 - for_each_ancestor(db,[handle],init,self) - except: - pass - - def apply(self,db,person): - # On the first call, we build the ancestor cache for the - # reference person. Then, for each person to test, - # we browse his ancestors until we found one in the cache. - if len(self.ancestor_cache) == 0: - self.init_ancestor_cache(db) - handle = person.handle - return for_each_ancestor(db,[handle], - lambda self,handle: self.ancestor_cache.has_key(handle), - self); - -#------------------------------------------------------------------------- -# -# HasCommonAncestorWithFilterMatch -# -#------------------------------------------------------------------------- -class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith): - """Rule that checks for a person that has a common ancestor with - someone matching a filter""" - - labels = [ _('Filter name:') ] - name = _('People with a common ancestor with match') - description = _("Matches people that have a common ancestor " - "with anybody matched by a filter") - category = _("Ancestral filters") - - def __init__(self,list): - HasCommonAncestorWith.__init__(self,list) - self.ancestor_cache = {} - - def init_ancestor_cache(self,db): - filt = MatchesFilter(self.list) - filt.prepare(db) - def init(self,h): self.ancestor_cache[h] = 1 - for handle in db.get_person_handles(sort_handles=False): - if (not self.ancestor_cache.has_key (handle) - and filt.apply (db, db.get_person_from_handle(handle))): - for_each_ancestor(db,[handle],init,self) - filt.reset() - -#------------------------------------------------------------------------- -# -# IsMale -# -#------------------------------------------------------------------------- -class IsMale(Rule): - """Rule that checks for a person that is a male""" - - name = _('Males') - category = _('General filters') - description = _('Matches all males') - - def apply(self,db,person): - return person.gender == RelLib.Person.MALE - -#------------------------------------------------------------------------- -# -# HasEvent -# -#------------------------------------------------------------------------- -class HasEvent(Rule): - """Rule that checks for a person with a particular value""" - - labels = [ _('Personal event:'), - _('Date:'), - _('Place:'), - _('Description:') ] - name = _('People with the personal ') - description = _("Matches people with a personal event of a particular value") - category = _('Event filters') - - def prepare(self,db): - self.date = None - try: - if self.list[1]: - self.date = DateHandler.parser.parse(self.list[1]) - except: pass - - def apply(self,db,person): - for event_handle in person.get_event_list(): - if not event_handle: - continue - event = db.get_event_from_handle(event_handle) - val = 1 - if self.list[0] and event.get_name() != self.list[0]: - val = 0 - if self.list[3] and event.get_description().upper().find( - self.list[3].upper())==-1: - val = 0 - if self.date: - if date_cmp(self.date,event.get_date_object()): - val = 0 - if self.list[2]: - pl_id = event.get_place_handle() - if pl_id: - pl = db.get_place_from_handle(pl_id) - pn = pl.get_title() - if pn.upper().find(self.list[2].upper()) == -1: - val = 0 - if val == 1: - return True - return False - -#------------------------------------------------------------------------- -# -# HasFamilyEvent -# -#------------------------------------------------------------------------- -class HasFamilyEvent(Rule): - """Rule that checks for a person who has a relationship event - with a particular value""" - - labels = [ _('Family event:'), - _('Date:'), - _('Place:'), - _('Description:') ] - name = _('People with the family ') - description = _("Matches people with a family event of a particular value") - category = _('Event filters') - - def prepare(self,db): - self.date = None - try: - if self.list[1]: - self.date = DateHandler.parser.parse(self.list[1]) - except: - pass - - def apply(self,db,person): - for f_id in person.get_family_handle_list(): - f = db.get_family_from_handle(f_id) - for event_handle in f.get_event_list(): - if not event_handle: - continue - event = db.get_event_from_handle(event_handle) - val = 1 - if self.list[0] and event.get_name() != self.list[0]: - val = 0 - v = self.list[3] - if v and event.get_description().upper().find(v.upper())==-1: - val = 0 - if self.date: - if date_cmp(self.date,event.get_date_object()): - val = 0 - if self.list[2]: - pl_id = event.get_place_handle() - if pl_id: - pl = db.get_place_from_handle(pl_id) - pn = pl.get_title().upper() - if pn.find(self.list[2].upper()) == -1: - val = 0 - else: - val = 0 - - if val == 1: - return True - return False - -#------------------------------------------------------------------------- -# -# HasRelationship -# -#------------------------------------------------------------------------- -class HasRelationship(Rule): - """Rule that checks for a person who has a particular relationship""" - - labels = [ _('Number of relationships:'), - _('Relationship type:'), - _('Number of children:') ] - name = _('People with the ') - description = _("Matches people with a particular relationship") - category = _('Family filters') - - def apply(self,db,person): - rel_type = 0 - cnt = 0 - num_rel = len(person.get_family_handle_list()) - - # count children and look for a relationship type match - for f_id in person.get_family_handle_list(): - f = db.get_family_from_handle(f_id) - cnt = cnt + len(f.get_child_handle_list()) - if self.list[1] and int(self.list[1]) == f.get_relationship(): - rel_type = 1 - - # if number of relations specified - if self.list[0]: - try: - v = int(self.list[0]) - except: - return False - if v != num_rel: - return False - - # number of childred - if self.list[2]: - try: - v = int(self.list[2]) - except: - return False - if v != cnt: - return False - - # relation - if self.list[1]: - return rel_type == 1 - else: - return True - -#------------------------------------------------------------------------- -# -# HasBirth -# -#------------------------------------------------------------------------- -class HasBirth(Rule): - """Rule that checks for a person with a birth of a particular value""" - - labels = [ _('Date:'), _('Place:'), _('Description:') ] - name = _('People with the ') - description = _("Matches people with birth data of a particular value") - category = _('Event filters') - - def __init__(self,list): - Rule.__init__(self,list) - if self.list[0]: - self.date = DateHandler.parser.parse(self.list[0]) - else: - self.date = None - - def apply(self,db,person): - event_ref = person.get_birth_ref() - if not event_ref: - return False - event = db.get_event_from_handle(event_ref.ref) - ed = event.get_description().upper() - if self.list[2] \ - and ed.find(self.list[2].upper())==-1: - return False - if self.date: - if date_cmp(self.date,event.get_date_object()) == 0: - return False - if self.list[1]: - pl_id = event.get_place_handle() - if pl_id: - pl = db.get_place_from_handle(pl_id) - pn = pl.get_title().upper() - if pn.find(self.list[1].upper()) == -1: - return False - else: - return False - return True - -#------------------------------------------------------------------------- -# -# HasDeath -# -#------------------------------------------------------------------------- -class HasDeath(Rule): - """Rule that checks for a person with a death of a particular value""" - - labels = [ _('Date:'), _('Place:'), _('Description:') ] - name = _('People with the ') - description = _("Matches people with death data of a particular value") - category = _('Event filters') - - def __init__(self,list): - Rule.__init__(self,list) - if self.list[0]: - self.date = DateHandler.parser.parse(self.list[0]) - else: - self.date = None - - def apply(self,db,person): - event_handle = person.get_death_handle() - if not event_handle: - return False - event = db.get_event_from_handle(event_handle) - ed = event.get_description().upper() - if self.list[2] \ - and ed.find(self.list[2].upper())==-1: - return False - if self.date: - if date_cmp(self.date,event.get_date_object()) == 0: - return False - if self.list[1]: - pl_id = event.get_place_handle() - if pl_id: - pl = db.get_place_from_handle(pl_id) - pn = pl.get_title().upper() - if self.list[1] and pn.find(self.list[1].upper()) == -1: - return False - else: - return False - return True - -#------------------------------------------------------------------------- -# -# HasAttribute -# -#------------------------------------------------------------------------- -class HasAttribute(Rule): - """Rule that checks for a person with a particular personal attribute""" - - labels = [ _('Personal attribute:'), _('Value:') ] - name = _('People with the personal ') - description = _("Matches people with the personal attribute of a particular value") - category = _('General filters') - - def apply(self,db,person): - if not self.list[0]: - return False - for attr in person.get_attribute_list(): - name_match = self.list[0] == attr.get_type() - value_match = \ - attr.get_value().upper().find(self.list[1].upper()) != -1 - if name_match and value_match: - return True - return False - -#------------------------------------------------------------------------- -# -# HasFamilyAttribute -# -#------------------------------------------------------------------------- -class HasFamilyAttribute(Rule): - """Rule that checks for a person with a particular family attribute""" - - labels = [ _('Family attribute:'), _('Value:') ] - name = _('People with the family ') - description = _("Matches people with the family attribute of a particular value") - category = _('General filters') - - def apply(self,db,person): - if not self.list[0]: - return False - for f_id in person.get_family_handle_list(): - f = db.get_family_from_handle(f_id) - for attr in f.get_attribute_list(): - name_match = self.list[0] == attr.get_type() - value_match = \ - attr.get_value().upper().find(self.list[1].upper()) != -1 - if name_match and value_match: - return True - return False - -#------------------------------------------------------------------------- -# -# HasNameOf -# -#------------------------------------------------------------------------- -class HasNameOf(Rule): - """Rule that checks for full or partial name matches""" - - labels = [ _('Given name:'), - _('Family name:'), - _('Suffix:'), - _('person|Title:')] - name = _('People with the ') - description = _("Matches people with a specified (partial) name") - category = _('General filters') - - def apply(self,db,person): - self.f = self.list[0] - self.l = self.list[1] - self.s = self.list[2] - self.t = self.list[3] - for name in [person.get_primary_name()] + person.get_alternate_names(): - val = 1 - if self.f and name.get_first_name().upper().find(self.f.upper()) == -1: - val = 0 - if self.l and name.get_surname().upper().find(self.l.upper()) == -1: - val = 0 - if self.s and name.get_suffix().upper().find(self.s.upper()) == -1: - val = 0 - if self.t and name.get_title().upper().find(self.t.upper()) == -1: - val = 0 - if val == 1: - return True - return False - -#------------------------------------------------------------------------- -# -# HasNameOf -# -#------------------------------------------------------------------------- -class SearchName(Rule): - """Rule that checks for full or partial name matches""" - - labels = [_('Substring:')] - name = _('People matching the ') - description = _("Matches people with a specified (partial) name") - category = _('General filters') - - def apply(self,db,person): - self.f = self.list[0] - n = NameDisplay.displayer.display(person) - return self.f and n.upper().find(self.f.upper()) != -1 - -#------------------------------------------------------------------------- -# -# IncompleteNames -# -#------------------------------------------------------------------------- -class IncompleteNames(Rule): - """People with incomplete names""" - - name = _('People with incomplete names') - description = _("Matches people with firstname or lastname missing") - category = _('General filters') - - def apply(self,db,person): - for name in [person.get_primary_name()] + person.get_alternate_names(): - if name.get_first_name() == "": - return True - if name.get_surname() == "": - return True - return False - -#------------------------------------------------------------------------- -# -# MatchesFilter -# -#------------------------------------------------------------------------- -class MatchesFilter(Rule): - """Rule that checks against another filter""" - - labels = [_('Filter name:')] - name = _('People matching the ') - description = _("Matches people macthed by the specified filter name") - category = _('General filters') - - def prepare(self,db): - for filt in SystemFilters.get_filters(): - if filt.get_name() == self.list[0]: - for rule in filt.flist: - rule.prepare(db) - for filt in CustomFilters.get_filters(): - if filt.get_name() == self.list[0]: - for rule in filt.flist: - rule.prepare(db) - - def reset(self): - for filt in SystemFilters.get_filters(): - if filt.get_name() == self.list[0]: - for rule in filt.flist: - rule.reset() - for filt in CustomFilters.get_filters(): - if filt.get_name() == self.list[0]: - for rule in filt.flist: - rule.reset() - - def apply(self,db,person): - for filt in SystemFilters.get_filters(): - if filt.get_name() == self.list[0]: - return filt.check(db,person.handle) - for filt in CustomFilters.get_filters(): - if filt.get_name() == self.list[0]: - return filt.check(db,person.handle) - return False - -#------------------------------------------------------------------------- -# -# IsSpouseOfFilterMatch -# -#------------------------------------------------------------------------- -class IsSpouseOfFilterMatch(Rule): - """Rule that checks for a person married to someone matching - a filter""" - - labels = [_('Filter name:')] - name = _('Spouses of match') - description = _("Matches people married to anybody matching a filter") - category = _('Family filters') - - def prepare(self,db): - self.filt = MatchesFilter (self.list) - self.filt.prepare(db) - - def apply(self,db,person): - for family_handle in person.get_family_handle_list (): - family = db.get_family_from_handle(family_handle) - for spouse_id in [family.get_father_handle (), family.get_mother_handle ()]: - if not spouse_id: - continue - if spouse_id == person.handle: - continue - if self.filt.apply (db, db.get_person_from_handle( spouse_id)): - return True - return False - -#------------------------------------------------------------------------- -# "People who were adopted" -#------------------------------------------------------------------------- -class HaveAltFamilies(Rule): - """People who were adopted""" - - name = _('Adopted people') - description = _("Matches people who were adopted") - category = _('Family filters') - - def apply(self,db,person): - for (fam,rel1,rel2) in person.get_parent_family_handle_list(): - if rel1 == RelLib.ChildRefType.CHILD_ADOPTED \ - or rel2 == RelLib.ChildRefType.CHILD_ADOPTED: - return True - return False - - -#------------------------------------------------------------------------- -# "People who have images" -#------------------------------------------------------------------------- -class HavePhotos(Rule): - """People who have images""" - - name = _('People with images') - description = _("Matches people with images in the gallery") - category = _('General filters') - - def apply(self,db,person): - return len( person.get_media_list()) > 0 - -#------------------------------------------------------------------------- -# "People with children" -#------------------------------------------------------------------------- -class HaveChildren(Rule): - """People with children""" - - name = _('People with children') - description = _("Matches people who have children") - category = _('Family filters') - - def apply(self,db,person): - for family_handle in person.get_family_handle_list(): - family = db.get_family_from_handle(family_handle) - return len(family.get_child_handle_list()) > 0 - -#------------------------------------------------------------------------- -# "People with no marriage records" -#------------------------------------------------------------------------- -class NeverMarried(Rule): - """People with no marriage records""" - - name = _('People with no marriage records') - description = _("Matches people who have no spouse") - category = _('Family filters') - - def apply(self,db,person): - return len(person.get_family_handle_list()) == 0 - -#------------------------------------------------------------------------- -# "People with multiple marriage records" -#------------------------------------------------------------------------- -class MultipleMarriages(Rule): - """People with multiple marriage records""" - - name = _('People with multiple marriage records') - description = _("Matches people who have more than one spouse") - category = _('Family filters') - - def apply(self,db,person): - return len(person.get_family_handle_list()) > 1 - -#------------------------------------------------------------------------- -# "People without a birth date" -#------------------------------------------------------------------------- -class NoBirthdate(Rule): - """People without a birth date""" - - name = _('People without a known birth date') - description = _("Matches people without a known birthdate") - category = _('General filters') - - def apply(self,db,person): - birth_ref = person.get_birth_ref() - if not birth_ref: - return True - birth = db.get_event_from_handle(birth_ref.ref) - if not birth.get_date_object(): - return True - return False - -#------------------------------------------------------------------------- -# "People with incomplete events" -#------------------------------------------------------------------------- -class PersonWithIncompleteEvent(Rule): - """People with incomplete events""" - - name = _('People with incomplete events') - description = _("Matches people with missing date or place in an event") - category = _('Event filters') - - def apply(self,db,person): - for event_ref in person.get_event_ref_list() + \ - [person.get_birth_ref(), person.get_death_ref()]: - if event_ref: - event = db.get_event_from_handle(event_ref.ref) - if not event.get_place_handle(): - return True - if not event.get_date_object(): - return True - return False - -#------------------------------------------------------------------------- -# "Families with incomplete events" -#------------------------------------------------------------------------- -class FamilyWithIncompleteEvent(Rule): - """Families with incomplete events""" - - name = _('Families with incomplete events') - description = _("Matches people with missing date or place in an event of the family") - category = _('Event filters') - - def apply(self,db,person): - for family_handle in person.get_family_handle_list(): - family = db.get_family_from_handle(family_handle) - for event_handle in family.get_event_list(): - event = db.get_event_from_handle(event_handle) - if event: - if not event.get_place_handle(): - return True - if not event.get_date_object(): - return True - return False - -#------------------------------------------------------------------------- -# "People probably alive" -#------------------------------------------------------------------------- -class ProbablyAlive(Rule): - """People probably alive""" - - labels = [_("On year:")] - name = _('People probably alive') - description = _("Matches people without indications of death that are not too old") - category = _('General filters') - - def prepare(self,db): - try: - self.current_year = int(self.list[0]) - except: - self.current_year = None - - def apply(self,db,person): - return probably_alive(person,db,self.current_year) - -#------------------------------------------------------------------------- -# "People marked private" -#------------------------------------------------------------------------- -class PeoplePrivate(Rule): - """People marked private""" - - name = _('People marked private') - description = _("Matches people that are indicated as private") - category = _('General filters') - - def apply(self,db,person): - return person.get_privacy() - -#------------------------------------------------------------------------- -# "Witnesses" -#------------------------------------------------------------------------- -class IsWitness(Rule): - """Witnesses""" - - labels = [_('Personal event:'), _('Family event:')] - name = _('Witnesses') - description = _("Matches people who are witnesses in any event") - category = _('Event filters') - - def prepare(self,db): - self.db = db - self.map = [] - self.build_witness_list() - - def reset(self): - self.map = [] - - def apply(self,db,person): - return person.handle in self.map - - def build_witness_list(self): - for person_handle in self.db.get_person_handles(): - p = self.db.get_person_from_handle(person_handle) - self.get_witness_of_events(self.list[0], - p.get_event_ref_list()+ - [p.get_birth_ref(), - p.get_death_ref()] - ) - - for family_handle in self.db.get_family_handles(): - f = self.db.get_family_from_handle(family_handle) - self.get_witness_of_events(self.list[1],f.get_event_ref_list()) - - def get_witness_of_events(self, event_type, event_list): - if not event_list: - return - for event_ref in event_list: - if event_ref: - event = self.db.get_event_from_handle(event_ref.ref) - if event_type and not event.get_name() == event_type: - continue - wlist = event.get_witness_list() - if wlist: - for w in wlist: - if w.get_type() == RelLib.Event.ID: - self.map.append(w.get_value()) - - -#------------------------------------------------------------------------- -# "HasTextMatchingSubstringOf" -#------------------------------------------------------------------------- -class HasTextMatchingSubstringOf(Rule): - """Rule that checks for string matches in any textual information""" - - labels = [ _('Substring:'), - _('Case sensitive:'), - _('Regular-Expression matching:')] - name = _('People with records containing ') - description = _("Matches people whose records contain text matching a substring") - category = _('General filters') - - def prepare(self,db): - self.db = db - self.person_map = {} - self.event_map = {} - self.source_map = {} - self.repo_map = {} - self.family_map = {} - self.place_map = {} - self.media_map = {} - try: - if int(self.list[1]): - self.case_sensitive = True - else: - self.case_sensitive = False - except IndexError: - self.case_sensitive = False - try: - if int(self.list[2]): - self.regexp_match = True - else: - self.regexp_match = False - except IndexError: - self.regexp_match = False - self.cache_repos() - self.cache_sources() - - def reset(self): - self.person_map = {} - self.event_map = {} - self.source_map = {} - self.repo_map = {} - self.family_map = {} - self.place_map = {} - self.media_map = {} - - def apply(self,db,person): - if person.handle in self.person_map: # Cached by matching Source? - return self.person_map[person.handle] - if self.match_object(person): # first match the person itself - return True - for event_ref in person.get_event_ref_list()+[person.get_birth_ref(), person.get_death_ref()]: - if self.search_event(event_ref.ref): # match referenced events - return True - for family_handle in person.get_family_handle_list(): # match families - if self.search_family(family_handle): - return True - for media_ref in person.get_media_list(): # match Media object - if self.search_media(media_ref.get_reference_handle()): - return True - return False - - def search_family(self,family_handle): - if not family_handle: - return False - # search inside the family and cache the result to not search a family twice - if not family_handle in self.family_map: - match = 0 - family = self.db.get_family_from_handle(family_handle) - if self.match_object(family): - match = 1 - else: - for event_ref in family.get_event_ref_list(): - if self.search_event(event_ref.ref): - match = 1 - break - for media_ref in family.get_media_list(): # match Media object - if self.search_media(media_ref.get_reference_handle()): - return True - self.family_map[family_handle] = match - return self.family_map[family_handle] - - def search_event(self,event_handle): - if not event_handle: - return False - # search inside the event and cache the result (event sharing) - if not event_handle in self.event_map: - match = 0 - event = self.db.get_event_from_handle(event_handle) - if self.match_object(event): - match = 1 - elif event: - place_handle = event.get_place_handle() - if place_handle: - if self.search_place(place_handle): - match = 1 - for media_ref in event.get_media_list(): # match Media object - if self.search_media(media_ref.get_reference_handle()): - return True - self.event_map[event_handle] = match - return self.event_map[event_handle] - - def search_place(self,place_handle): - if not place_handle: - return False - # search inside the place and cache the result - if not place_handle in self.place_map: - place = self.db.get_place_from_handle(place_handle) - self.place_map[place_handle] = self.match_object(place) - return self.place_map[place_handle] - - def search_media(self,media_handle): - if not media_handle: - return False - # search inside the place and cache the result - if not media_handle in self.media_map: - media = self.db.get_object_from_handle(media_handle) - self.media_map[media_handle] = self.match_object(media) - return self.media_map[media_handle] - - def cache_repos(self): - # search all matching repositories - for repo_handle in self.db.get_repository_handles(): - repo = self.db.get_repository_from_handle(repo_handle) - if( self.match_object(repo)): - self.repo_map[repo_handle] = 1 - - def cache_sources(self): - # search all sources and match all referents of a matching source - for source_handle in self.db.get_source_handles(): - source = self.db.get_source_from_handle(source_handle) - match = self.match_object(source) - if not match: - for reporef in source.get_reporef_list(): - if reporef.get_reference_handle() in self.repo_map: - match = 1 - if match: - (person_list,family_list,event_list, - place_list,source_list,media_list - ) = get_source_referents(source_handle,self.db) - for handle in person_list: - self.person_map[handle] = 1 - for handle in family_list: - self.family_map[handle] = 1 - for handle in event_list: - self.event_map[handle] = 1 - for handle in place_list: - self.place_map[handle] = 1 - for handle in media_list: - self.media_map[handle] = 1 - - def match_object(self,obj): - if not obj: - return False - if self.regexp_match: - return obj.matches_regexp(self.list[0],self.case_sensitive) - return obj.matches_string(self.list[0],self.case_sensitive) - -#------------------------------------------------------------------------- -# "HasTextMatchingRegexOf" -#------------------------------------------------------------------------- -class HasTextMatchingRegexpOf(HasTextMatchingSubstringOf): - """This is wrapping HasTextMatchingSubstringOf to enable the regex_match parameter""" - def __init__(self,list): - HasTextMatchingSubstringOf.__init__(self,list) - - def prepare(self,db): - self.db = db - self.person_map = {} - self.event_map = {} - self.source_map = {} - self.repo_map = {} - self.family_map = {} - self.place_map = {} - self.media_map = {} - self.case_sensitive = False - self.regexp_match = True - self.cache_sources() - -#------------------------------------------------------------------------- -# -# HasSourceOf -# -#------------------------------------------------------------------------- -class HasSourceOf(Rule): - """Rule that checks people that have a particular source.""" - - labels = [ _('Source ID:') ] - name = _('People with the ') - category = _('General filters') - description = _('Matches people who have a particular source') - - def prepare(self,db): - try: - self.source_handle = db.get_source_from_gramps_id(self.list[0]).get_handle() - except: - self.source_handle = None - - def apply(self,db,person): - if not self.source_handle: - return False - return person.has_source_reference( self.source_handle) - -#------------------------------------------------------------------------- -# "People having notes" -#------------------------------------------------------------------------- -class HasNote(Rule): - """People having notes""" - - name = _('People having notes') - description = _("Matches people that have a note") - category = _('General filters') - - def apply(self,db,person): - return bool(person.get_note()) - -#------------------------------------------------------------------------- -# "People having notes that contain a substring" -#------------------------------------------------------------------------- -class HasNoteMatchingSubstringOf(Rule): - """People having notes containing """ - - labels = [ _('Substring:')] - name = _('People having notes containing ') - description = _("Matches people whose notes contain text matching a substring") - category = _('General filters') - - def apply(self,db,person): - n = person.get_note() - if n: - return n.upper().find(self.list[0].upper()) != -1 - return False - -#------------------------------------------------------------------------- -# -# GenericFilter -# -#------------------------------------------------------------------------- -class GenericFilter: - """Filter class that consists of several rules""" - - logical_functions = ['or', 'and', 'xor', 'one'] - - def __init__(self,source=None): - if source: - self.need_param = source.need_param - self.flist = source.flist[:] - self.name = source.name - self.comment = source.comment - self.logical_op = source.logical_op - else: - self.need_param = 0 - self.flist = [] - self.name = '' - self.comment = '' - self.logical_op = 'and' - - def match(self,handle): - return True - - def is_empty(self): - return len(self.flist) == 1 and self.flist[0].is_empty() - - def set_logical_op(self,val): - if val in GenericFilter.logical_functions: - self.logical_op = val - else: - self.logical_op = 'and' - - def get_logical_op(self): - return self.logical_op - - def get_name(self): - return self.name - - def set_name(self,name): - self.name = name - - def set_comment(self,comment): - self.comment = comment - - def get_comment(self): - return self.comment - - def add_rule(self,rule): - self.flist.append(rule) - - def delete_rule(self,rule): - self.flist.remove(rule) - - def set_rules(self,rules): - self.flist = rules - - def get_rules(self): - return self.flist - - def check_func(self,db,id_list,task): - final_list = [] - - if id_list == None: - cursor = db.get_person_cursor() - data = cursor.next() - while data: - person = RelLib.Person() - person.unserialize(data[1]) - if not task(db,person): - final_list.append(data[0]) - data = cursor.next() - else: - for handle in id_list: - person = db.get_person_from_handle(handle) - if not task(db,person): - final_list.append(handle) - return final_list - - def check_or(self,db,id_list): - return self.check_func(db,id_list,self.or_test) - - def check_and(self,db,id_list): - final_list = [] - flist = self.flist - if id_list == None: - cursor = db.get_person_cursor() - data = cursor.next() - p = RelLib.Person - while data: - person = p(data[1]) - val = True - for rule in flist: - if not rule.apply(db,person): - val = False - break - if not val: - final_list.append(data[0]) - data = cursor.next() - else: - for handle in id_list: - person = db.get_person_from_handle(handle) - val = True - for rule in flist: - if not rule.apply(db,person): - val = False - break - if val: - final_list.append(handle) - return final_list - - def check_one(self,db,id_list): - return self.check_func(db,id_list,self.one_test) - - def check_xor(self,db,id_list): - return self.check_func(db,id_list,self.xor_test) - - def xor_test(self,db,person): - test = False - for rule in self.flist: - test = test ^ rule.apply(db,person) - return test - - def one_test(self,db,person): - count = 0 - for rule in self.flist: - if rule.apply(db,person): - if count: - return False - count += 1 - return count == 1 - - def or_test(self,db,person): - for rule in self.flist: - if rule.apply(db,person): - return True - return False - - def get_check_func(self): - try: - m = getattr(self, 'check_' + self.logical_op) - except AttributeError: - m = self.check_and - return m - - def check(self,db,handle): - return self.get_check_func()(db,[handle]) - - def apply(self,db,id_list=None): - m = self.get_check_func() - for rule in self.flist: - rule.prepare(db) - res = m(db,id_list) - for rule in self.flist: - rule.reset() - return res - -#------------------------------------------------------------------------- -# -# IsLessThanNthGenerationAncestorOfBookmarked -# -#------------------------------------------------------------------------- -class IsLessThanNthGenerationAncestorOfBookmarked(Rule): - # Submitted by Wayne Bergeron - """Rule that checks for a person that is an ancestor of bookmarked persons - not more than N generations away""" - - labels = [ _('Number of generations:') ] - name = _('Ancestors of bookmarked people not more ' - 'than generations away') - category = _('Ancestral filters') - description = _("Matches ancestors of the people on the bookmark list " - "not more than N generations away") - - def prepare(self,db): - self.db = db - bookmarks = self.db.get_bookmarks() - if len(bookmarks) == 0: - self.apply = lambda db,p : False - else: - self.map = {} - self.bookmarks = sets.Set(bookmarks) - self.apply = self.apply_real - for self.bookmarkhandle in self.bookmarks: - self.init_ancestor_list(self.bookmarkhandle, 1) - - - def init_ancestor_list(self,handle,gen): -# if self.map.has_key(p.get_handle()) == 1: -# loop_error(self.orig,p) - if not handle: - return - if gen: - self.map[handle] = 1 - if gen >= int(self.list[0]): - return - - p = self.db.get_person_from_handle(handle) - fam_id = p.get_main_parents_family_handle() - fam = self.db.get_family_from_handle(fam_id) - if fam: - f_id = fam.get_father_handle() - m_id = fam.get_mother_handle() - - if f_id: - self.init_ancestor_list(f_id,gen+1) - if m_id: - self.init_ancestor_list(m_id,gen+1) - - def apply_real(self,db,person): - return person.handle in self.map - - def reset(self): - self.map = {} - -#------------------------------------------------------------------------- -# -# IsLessThanNthGenerationAncestorOfDefaultPerson -# -#------------------------------------------------------------------------- -class IsLessThanNthGenerationAncestorOfDefaultPerson(Rule): - # Submitted by Wayne Bergeron - """Rule that checks for a person that is an ancestor of the default person - not more than N generations away""" - - labels = [ _('Number of generations:') ] - name = _('Ancestors of the default person ' - 'not more than generations away') - category = _('Ancestral filters') - description = _("Matches ancestors of the default person " - "not more than N generations away") - - def prepare(self,db): - self.db = db - p = db.get_default_person() - if p: - self.def_handle = p.get_handle() - self.apply = self.apply_real - self.map = {} - self.init_ancestor_list(self.def_handle, 1) - else: - self.apply = lambda db,p: False - - def init_ancestor_list(self,handle,gen): -# if self.map.has_key(p.get_handle()) == 1: -# loop_error(self.orig,p) - if not handle: - return - if gen: - self.map[handle] = 1 - if gen >= int(self.list[0]): - return - - p = self.db.get_person_from_handle(handle) - fam_id = p.get_main_parents_family_handle() - fam = self.db.get_family_from_handle(fam_id) - if fam: - f_id = fam.get_father_handle() - m_id = fam.get_mother_handle() - - if f_id: - self.init_ancestor_list(f_id,gen+1) - if m_id: - self.init_ancestor_list(m_id,gen+1) - - def apply_real(self,db,person): - return person.handle in self.map - - def reset(self): - self.map = {} - -#------------------------------------------------------------------------- -# -# Name to class mappings -# -#------------------------------------------------------------------------- -# This dict is mapping from old names to new names, so that the existing -# custom_filters.xml will continue working -old_names_2_class = { - "Everyone" : Everyone, - "Is default person" : IsDefaultPerson, - "Is bookmarked person" : IsBookmarked, - "Has the Id" : HasIdOf, - "Has a name" : HasNameOf, - "Has the relationships" : HasRelationship, - "Has the death" : HasDeath, - "Has the birth" : HasBirth, - "Is a descendant of" : IsDescendantOf, - "Is a descendant family member of" : IsDescendantFamilyOf, - "Is a descendant of filter match": IsDescendantOfFilterMatch, - "Is a descendant of person not more than N generations away": - IsLessThanNthGenerationDescendantOf, - "Is a descendant of person at least N generations away": - IsMoreThanNthGenerationDescendantOf, - "Is an descendant of person at least N generations away" : - IsMoreThanNthGenerationDescendantOf, - "Is a child of filter match" : IsChildOfFilterMatch, - "Is an ancestor of" : IsAncestorOf, - "Is an ancestor of filter match": IsAncestorOfFilterMatch, - "Is an ancestor of person not more than N generations away" : - IsLessThanNthGenerationAncestorOf, - "Is an ancestor of person at least N generations away": - IsMoreThanNthGenerationAncestorOf, - "Is a parent of filter match" : IsParentOfFilterMatch, - "Has a common ancestor with" : HasCommonAncestorWith, - "Has a common ancestor with filter match" :HasCommonAncestorWithFilterMatch, - "Is a female" : IsFemale, - "Is a male" : IsMale, - "Has complete record" : HasCompleteRecord, - "Has the personal event" : HasEvent, - "Has the family event" : HasFamilyEvent, - "Has the personal attribute" : HasAttribute, - "Has the family attribute" : HasFamilyAttribute, - "Has source of" : HasSourceOf, - "Matches the filter named" : HasSourceOf, - "Is spouse of filter match" : IsSpouseOfFilterMatch, - "Is a sibling of filter match" : IsSiblingOfFilterMatch, - "Relationship path between two people" : RelationshipPathBetween, - "People who were adopted" : HaveAltFamilies, - "People who have images" : HavePhotos, - "People with children" : HaveChildren, - "People with incomplete names" : IncompleteNames, - "People with no marriage records" : NeverMarried, - "People with multiple marriage records": MultipleMarriages, - "People without a birth date" : NoBirthdate, - "People with incomplete events" : PersonWithIncompleteEvent, - "Families with incomplete events" :FamilyWithIncompleteEvent, - "People probably alive" : ProbablyAlive, - "People marked private" : PeoplePrivate, - "Witnesses" : IsWitness, - "Has text matching substring of":HasTextMatchingSubstringOf, -} - -editor_rule_list = [ - Everyone, - IsFemale, - HasUnknownGender, - IsMale, - IsDefaultPerson, - IsBookmarked, - HasIdOf, - HasNameOf, - HasRelationship, - HasDeath, - HasBirth, - HasCompleteRecord, - HasEvent, - HasFamilyEvent, - HasAttribute, - HasFamilyAttribute, - HasSourceOf, - HaveAltFamilies, - HavePhotos, - HaveChildren, - IncompleteNames, - NeverMarried, - MultipleMarriages, - NoBirthdate, - PersonWithIncompleteEvent, - FamilyWithIncompleteEvent, - ProbablyAlive, - PeoplePrivate, - IsWitness, - IsDescendantOf, - IsDescendantFamilyOf, - IsLessThanNthGenerationAncestorOfDefaultPerson, - IsDescendantOfFilterMatch, - IsLessThanNthGenerationDescendantOf, - IsMoreThanNthGenerationDescendantOf, - IsAncestorOf, - IsAncestorOfFilterMatch, - IsLessThanNthGenerationAncestorOf, - IsLessThanNthGenerationAncestorOfBookmarked, - IsMoreThanNthGenerationAncestorOf, - HasCommonAncestorWith, - HasCommonAncestorWithFilterMatch, - MatchesFilter, - IsChildOfFilterMatch, - IsParentOfFilterMatch, - IsSpouseOfFilterMatch, - IsSiblingOfFilterMatch, - RelationshipPathBetween, - HasTextMatchingSubstringOf, - HasNote, - HasNoteMatchingSubstringOf -] - -#------------------------------------------------------------------------- -# -# GenericFilterList -# -#------------------------------------------------------------------------- -class GenericFilterList: - """Container class for the generic filters. Stores, saves, and - loads the filters.""" - - def __init__(self,file): - self.filter_list = {} - self.file = os.path.expanduser(file) - - def get_filters(self,namespace='generic'): - try: - return self.filter_list[namespace] - except KeyError: - return [] - - def add(self,namespace,filt): - if namespace not in self.filter_list: - self.filter_list[namespace] = [] - self.filter_list[namespace].append(filt) - - def load(self): - try: - if os.path.isfile(self.file): - parser = make_parser() - parser.setContentHandler(FilterParser(self)) - parser.parse(self.file) - except (IOError,OSError): - pass - except SAXParseException: - print "Parser error" - - def fix(self,line): - l = line.strip() - l = l.replace('&','&') - l = l.replace('>','>') - l = l.replace('<','<') - return l.replace('"','"') - - def save(self): - f = open(self.file.encode('utf-8'),'w') - - f.write("\n") - f.write('\n') - for namespace in self.filter_list: - f.write('\n' % "person") - print namespace - for i in namespace: - f.write(' \n') - for rule in i.get_rules(): - rule_module_name = rule.__module__ - rule_class_name = rule.__class__.__name__ - rule_save_name = "%s.%s" % (rule_module_name,rule_class_name) - f.write(' \n' % rule_save_name) - for v in rule.values(): - f.write(' \n' % self.fix(v)) - f.write(' \n') - f.write(' \n') - f.write('\n') - f.write('\n') - f.close() - -#------------------------------------------------------------------------- -# -# FilterParser -# -#------------------------------------------------------------------------- -class FilterParser(handler.ContentHandler): - """Parses the XML file and builds the list of filters""" - - def __init__(self,gfilter_list): - handler.ContentHandler.__init__(self) - self.gfilter_list = gfilter_list - self.f = None - self.r = None - self.a = [] - self.cname = None - self.namespace = "person" - - def setDocumentLocator(self,locator): - self.locator = locator - - def startElement(self,tag,attrs): - if tag == "object": - if attrs.has_key('type'): - self.namespace = attrs['type'] - else: - self.namespace = "generic" - elif tag == "filter": - self.f = GenericFilter() - self.f.set_name(attrs['name']) - if attrs.has_key('function'): - try: - if int(attrs['function']): - op = 'or' - else: - op = 'and' - except ValueError: - op = attrs['function'] - self.f.set_logical_op(op) - if attrs.has_key('comment'): - self.f.set_comment(attrs['comment']) - self.gfilter_list.add(self.namespace,self.f) - elif tag == "rule": - save_name = attrs['class'] - if save_name in old_names_2_class.keys(): - self.r = old_names_2_class[save_name] - else: - mc_match = save_name.split('.') - if len(mc_match) != 2: - # rule has an old style name, that is not in old_names_2_class - # or is not in the format "module.class" - print "ERROR: Filter rule '%s' in filter '%s' not found!" % ( - save_name,self.f.get_name()) - self.r = None - return - module_name,class_name = mc_match - try: - if module_name == self.__module__: - exec 'self.r = %s' % class_name - else: - exec 'import %s' % module_name - exec 'self.r = %s.%s' % (module_name,class_name) - except (ImportError,NameError): - print "ERROR: Filter rule '%s' in filter '%s' not found!" % ( - save_name,self.f.get_name()) - self.r = None - return - self.a = [] - elif tag == "arg": - self.a.append(attrs['value']) - - def endElement(self,tag): - if tag == "rule" and self.r != None: - if len(self.r.labels) < len(self.a): - print "WARNING: Invalid number of arguments in filter '%s'!" %\ - self.f.get_name() - nargs = len(self.r.labels) - rule = self.r(self.a[0:nargs]) - self.f.add_rule(rule) - elif len(self.r.labels) > len(self.a): - print "ERROR: Invalid number of arguments in filter '%s'!" %\ - self.f.get_name() - else: - rule = self.r(self.a) - self.f.add_rule(rule) - - def characters(self, data): - pass - -class ParamFilter(GenericFilter): - - def __init__(self,source=None): - GenericFilter.__init__(self,source) - self.need_param = 1 - self.param_list = [] - - def set_parameter(self,param): - self.param_list = [param] - - def apply(self,db,id_list=None): - for rule in self.flist: - #rule.set_list(self.param_list) - # - # The above breaks filters with more than one param - # Need to change existing params one by one to keep - # the correct number of arguments - new_list = rule.list[:] - for ix in range(len(self.param_list)): - new_list[ix] = self.param_list[ix] - rule.set_list(new_list) - for rule in self.flist: - rule.prepare(db) - result = GenericFilter.apply(self,db,id_list) - for rule in self.flist: - rule.reset() - return result - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -SystemFilters = None -CustomFilters = None - -def reload_system_filters(): - global SystemFilters - SystemFilters = GenericFilterList(const.system_filters) - SystemFilters.load() - -def reload_custom_filters(): - global CustomFilters - CustomFilters = GenericFilterList(const.custom_filters) - CustomFilters.load() - -if not SystemFilters: - reload_system_filters() - -if not CustomFilters: - reload_custom_filters() - - -class GrampsFilterComboBox(gtk.ComboBox): - - def set(self,local_filters,default=""): - self.store = gtk.ListStore(str) - self.set_model(self.store) - cell = gtk.CellRendererText() - self.pack_start(cell,True) - self.add_attribute(cell,'text',0) - - self.map = {} - - active = 0 - cnt = 0 - for filt in local_filters: - self.store.append(row=[filt.get_name()]) - self.map[filt.get_name()] = filt - if default != "" and default == filt.get_name(): - active = cnt - cnt += 1 - - for filt in SystemFilters.get_filters(): - self.store.append(row=[filt.get_name()]) - self.map[filt.get_name()] = filt - if default != "" and default == filt.get_name(): - active = cnt - cnt += 1 - - for filt in CustomFilters.get_filters(): - self.store.append(row=[filt.get_name()]) - self.map[filt.get_name()] = filt - if default != "" and default == filt.get_name(): - active = cnt - cnt += 1 - - if active: - self.set_active(active) - elif len(local_filters): - self.set_active(2) - elif len(SystemFilters.get_filters()): - self.set_active(4 + len(local_filters)) - elif len(CustomFilters.get_filters()): - self.set_active(6 + len(local_filters) + len(SystemFilters.get_filters())) - else: - self.set_active(0) - - def get_value(self): - active = self.get_active() - if active < 0: - return None - key = unicode(self.store[active][0]) - return self.map[key] - - -class FilterStore(gtk.ListStore): - - def __init__(self,local_filters=[], namespace="generic",default=""): - gtk.ListStore.__init__(self,str) - self.list_map = [] - self.def_index = 0 - - cnt = 0 - for filt in local_filters: - name = filt.get_name() - self.append(row=[name]) - self.list_map.append(filt) - if default != "" and default == name: - self.def_index = cnt - cnt += 1 - - for filt in SystemFilters.get_filters(namespace) + CustomFilters.get_filters(namespace): - name = _(filt.get_name()) - self.append(row=[name]) - self.list_map.append(filt) - if default != "" and default == name: - self.def_index = cnt - cnt += 1 - - def default_index(self): - return self.def_index - - def get_filter(self,index): - return self.list_map[index] - -class FilterWidget: - def __init__( self, uistate, on_apply, apply_done = None): - self.on_apply_callback = on_apply - self.apply_done_callback = apply_done - self.uistate = uistate - - def build( self): - self.filterbar = gtk.HBox() - self.filterbar.set_spacing(4) - self.filter_text = gtk.Entry() - self.filter_list = gtk.ComboBox() - self.filter_button = gtk.Button(stock=gtk.STOCK_FIND) - self.filter_button.connect( 'clicked',self.apply_filter_clicked) - self.filterbar.pack_start(self.filter_list,False) - self.filterbar.pack_start(self.filter_text,True) - self.filterbar.pack_end(self.filter_button,False) - -# self.filter_text.set_sensitive(False) - - return self.filterbar - - def setup_filter( self, default_filters, namespace="generic"): - cell = gtk.CellRendererText() - self.filter_list.clear() - self.filter_list.pack_start(cell,True) - self.filter_list.add_attribute(cell,'text',0) - - filter_list = [] - - for f in default_filters: - all = GenericFilter() - rule = f[0](f[1]) - #print rule - all.set_name( rule.name) - all.add_rule( rule) - filter_list.append(all) - - self.filter_model = FilterStore(filter_list, namespace) - self.filter_list.set_model(self.filter_model) - self.filter_list.set_active(self.filter_model.default_index()) - self.filter_list.connect('changed',self.on_filter_name_changed) -# self.filter_text.set_sensitive(False) - self.DataFilter = filter_list[self.filter_model.default_index()] - - def apply_filter_clicked(self,ev=None): - print "apply_filter_clicked" - index = self.filter_list.get_active() - self.DataFilter = self.filter_model.get_filter(index) - if self.DataFilter.need_param: - qual = unicode(self.filter_text.get_text()) - self.DataFilter.set_parameter(qual) - self.apply_filter() - if self.apply_done_callback: - self.apply_done_callback() - - def on_filter_name_changed(self,obj): - print "on_filter_name_changed" - index = self.filter_list.get_active() -# mime_filter = self.filter_model.get_filter(index) -# qual = mime_filter.need_param -# if qual: -# self.filter_text.show() -# self.filter_text.set_sensitive(True) -# else: -# self.filter_text.hide() -# self.filter_text.set_sensitive(False) - - def apply_filter(self,current_model=None): - self.uistate.status_text(_('Updating display...')) - self.on_apply_callback() - self.uistate.modify_statusbar() - - def get_filter( self): - print "get_filter" - #print self.DataFilter.flist[0] - return self.DataFilter - - def show( self): - self.filterbar.show() - - def hide( self): - self.filterbar.hide() - -def build_filter_menu(local_filters = [], default=""): - menu = gtk.Menu() - - active = 0 - cnt = 0 - for filt in local_filters: - menuitem = gtk.MenuItem(filt.get_name()) - menuitem.show() - menu.append(menuitem) - menuitem.set_data("filter", filt) - if default != "" and default == filt.get_name(): - active = cnt - cnt += 1 - - for filt in SystemFilters.get_filters(): - menuitem = gtk.MenuItem(_(filt.get_name())) - menuitem.show() - menu.append(menuitem) - menuitem.set_data("filter", filt) - if default != "" and default == filt.get_name(): - active = cnt - cnt += 1 - - for filt in CustomFilters.get_filters(): - menuitem = gtk.MenuItem(_(filt.get_name())) - menuitem.show() - menu.append(menuitem) - menuitem.set_data("filter", filt) - if default != "" and default == filt.get_name(): - active = cnt - cnt += 1 - - if active: - menu.set_active(active) - elif len(local_filters): - menu.set_active(2) - elif len(SystemFilters.get_filters()): - menu.set_active(4 + len(local_filters)) - elif len(CustomFilters.get_filters()): - menu.set_active(6 + len(local_filters) + len(SystemFilters.get_filters())) - else: - menu.set_active(0) - - return menu diff --git a/gramps2/src/GrampsDb/_WriteGedcom.py b/gramps2/src/GrampsDb/_WriteGedcom.py index 0f5952788..f6daa8e42 100644 --- a/gramps2/src/GrampsDb/_WriteGedcom.py +++ b/gramps2/src/GrampsDb/_WriteGedcom.py @@ -60,7 +60,7 @@ import gtk.glade # #------------------------------------------------------------------------- import RelLib -import GenericFilter +from Filters import GenericFilter, Rules, build_filter_menu import const import lds import _GedcomInfo as GedcomInfo @@ -370,32 +370,32 @@ class GedcomWriterOptionBox: filter_obj = self.topDialog.get_widget("filter") self.copy = 0 - all = GenericFilter.GenericFilter() + all = GenericFilter() all.set_name(_("Entire Database")) - all.add_rule(GenericFilter.Everyone([])) + all.add_rule(Rules.Everyone([])) if self.person: - des = GenericFilter.GenericFilter() + des = GenericFilter() des.set_name(_("Descendants of %s") % NameDisplay.displayer.display(self.person)) - des.add_rule(GenericFilter.IsDescendantOf( + des.add_rule(Rules.IsDescendantOf( [self.person.get_gramps_id(),1])) - ans = GenericFilter.GenericFilter() + ans = GenericFilter() ans.set_name(_("Ancestors of %s") % NameDisplay.displayer.display(self.person)) - ans.add_rule(GenericFilter.IsAncestorOf( + ans.add_rule(Rules.IsAncestorOf( [self.person.get_gramps_id(),1])) - com = GenericFilter.GenericFilter() + com = GenericFilter() com.set_name(_("People with common ancestor with %s") % NameDisplay.displayer.display(self.person)) - com.add_rule(GenericFilter.HasCommonAncestorWith( + com.add_rule(Rules.HasCommonAncestorWith( [self.person.get_gramps_id()])) - self.filter_menu = GenericFilter.build_filter_menu([all,des,ans,com]) + self.filter_menu = build_filter_menu([all,des,ans,com]) else: - self.filter_menu = GenericFilter.build_filter_menu([all]) + self.filter_menu = build_filter_menu([all]) filter_obj.set_menu(self.filter_menu) gedmap = GedcomInfo.GedcomInfoDB() diff --git a/gramps2/src/Makefile.am b/gramps2/src/Makefile.am index 56038f297..1896983ac 100644 --- a/gramps2/src/Makefile.am +++ b/gramps2/src/Makefile.am @@ -5,6 +5,7 @@ SUBDIRS = \ Config \ DataViews \ Editors \ + Filters \ GrampsDb \ GrampsLogger \ Mime \ @@ -41,7 +42,6 @@ gdir_PYTHON = \ Errors.py\ Exporter.py\ FontScale.py\ - GenericFilter.py\ GrampsCfg.py\ GrampsDisplay.py\ GrampsLocale.py\ @@ -83,7 +83,7 @@ gdir_PYTHON = \ MOSTLYCLEANFILES = *pyc *pyo # Which modules to document -docmodules = RelLib DateHandler GrampsDb BaseDoc +docmodules = RelLib DateHandler GrampsDb Filters BaseDoc pycheck: for d in $(SUBDIRS) ; do \ diff --git a/gramps2/src/ObjectSelector/_FilterFrameBase.py b/gramps2/src/ObjectSelector/_FilterFrameBase.py index 156c12444..28533df6c 100644 --- a/gramps2/src/ObjectSelector/_FilterFrameBase.py +++ b/gramps2/src/ObjectSelector/_FilterFrameBase.py @@ -24,7 +24,7 @@ import gtk import gobject from GrampsWidgets import IntEdit -import GenericFilter +from Filters import GenericFilter class FilterFrameBase(gtk.Frame): diff --git a/gramps2/src/ObjectSelector/_PersonFilterFrame.py b/gramps2/src/ObjectSelector/_PersonFilterFrame.py index e5baf60c0..88d40e3ec 100644 --- a/gramps2/src/ObjectSelector/_PersonFilterFrame.py +++ b/gramps2/src/ObjectSelector/_PersonFilterFrame.py @@ -29,7 +29,7 @@ log = getLogger(".ObjectSelector") from GrampsWidgets import IntEdit from _FilterFrameBase import FilterFrameBase -import GenericFilter +from Filters import GenericFilter, Rules import RelLib class PersonFilterFrame(FilterFrameBase): @@ -157,29 +157,29 @@ class PersonFilterFrame(FilterFrameBase): filter_label.set_alignment(xalign=0,yalign=0.5) default_filters = [ - GenericFilter.Everyone, - GenericFilter.IsFemale, - GenericFilter.IsMale, - GenericFilter.HasUnknownGender, - GenericFilter.Disconnected, - GenericFilter.SearchName, - GenericFilter.HaveAltFamilies, - GenericFilter.HavePhotos, - GenericFilter.IncompleteNames, - GenericFilter.HaveChildren, - GenericFilter.NeverMarried, - GenericFilter.MultipleMarriages, - GenericFilter.NoBirthdate, - GenericFilter.PersonWithIncompleteEvent, - GenericFilter.FamilyWithIncompleteEvent, - GenericFilter.ProbablyAlive, - GenericFilter.PeoplePrivate, - GenericFilter.IsWitness, - GenericFilter.HasTextMatchingSubstringOf, - GenericFilter.HasTextMatchingRegexpOf, - GenericFilter.HasNote, - GenericFilter.HasNoteMatchingSubstringOf, - GenericFilter.IsFemale, + Rules.Everyone, + Rules.IsFemale, + Rules.IsMale, + Rules.HasUnknownGender, + Rules.Disconnected, + Rules.SearchName, + Rules.HaveAltFamilies, + Rules.HavePhotos, + Rules.IncompleteNames, + Rules.HaveChildren, + Rules.NeverMarried, + Rules.MultipleMarriages, + Rules.NoBirthdate, + Rules.PersonWithIncompleteEvent, + Rules.FamilyWithIncompleteEvent, + Rules.ProbablyAlive, + Rules.PeoplePrivate, + Rules.IsWitness, + Rules.HasTextMatchingSubstringOf, + Rules.HasTextMatchingRegexpOf, + Rules.HasNote, + Rules.HasNoteMatchingSubstringOf, + Rules.IsFemale, ] self._filter_list = gtk.ListStore(object,str) @@ -362,22 +362,22 @@ class PersonFilterFrame(FilterFrameBase): self.emit('clear-filter') def on_apply(self,button=None): - filter = GenericFilter.GenericFilter() + filter = GenericFilter() if self._id_check.get_active(): - filter.add_rule(GenericFilter.HasIdOf([self._id_edit.get_text()])) + filter.add_rule(Rules.HasIdOf([self._id_edit.get_text()])) if self._name_check.get_active(): - filter.add_rule(GenericFilter.SearchName([self._name_edit.get_text()])) + filter.add_rule(Rules.SearchName([self._name_edit.get_text()])) if self._gender_check.get_active(): gender = self._gender_list.get_value(self._gender_combo.get_active_iter(),1) if gender == RelLib.Person.MALE: - filter.add_rule(GenericFilter.IsMale([])) + filter.add_rule(Rules.IsMale([])) elif gender == RelLib.Person.FEMALE: - filter.add_rule(GenericFilter.IsFemale([])) + filter.add_rule(Rules.IsFemale([])) elif gender == RelLib.Person.UNKNOWN: - filter.add_rule(GenericFilter.HasUnknownGender([])) + filter.add_rule(Rules.HasUnknownGender([])) else: log.warn("Received unknown gender from filter widget") @@ -389,7 +389,7 @@ class PersonFilterFrame(FilterFrameBase): date = "after " + self._b_edit.get_text() else: log.warn("neither before or after is selected, this should not happen") - filter.add_rule(GenericFilter.HasBirth([date,'',''])) + filter.add_rule(Rules.HasBirth([date,'',''])) if self._death_check.get_active(): date = "" @@ -399,7 +399,7 @@ class PersonFilterFrame(FilterFrameBase): date = "after " + self._d_edit.get_text() else: log.warn("neither before or after is selected, this should not happen") - filter.add_rule(GenericFilter.HasDeath([date,'',''])) + filter.add_rule(Rules.HasDeath([date,'',''])) if self._filter_check.get_active(): diff --git a/gramps2/src/PageView.py b/gramps2/src/PageView.py index 4a79ee43e..6d2332940 100644 --- a/gramps2/src/PageView.py +++ b/gramps2/src/PageView.py @@ -44,7 +44,7 @@ from gtk.gdk import ACTION_COPY, BUTTON1_MASK #---------------------------------------------------------------- import TreeTips import Bookmarks -import GenericFilter +from Filters import FilterWidget, Rules import const NAVIGATION_NONE = -1 @@ -466,7 +466,7 @@ class ListView(BookMarkView): self.vbox.set_border_width(0) self.vbox.set_spacing(4) - self.generic_filter_widget = GenericFilter.FilterWidget( self.uistate, self.build_tree) + self.generic_filter_widget = FilterWidget( self.uistate, self.build_tree) filter_box = self.generic_filter_widget.build() self.list = gtk.TreeView() @@ -527,10 +527,10 @@ class ListView(BookMarkView): Builds the default filters and add them to the filter menu. """ default_filters = [ - [GenericFilter.Everyone, []], - [GenericFilter.HasTextMatchingSubstringOf, ['',0,0]], - [GenericFilter.HasTextMatchingRegexpOf, ['',0,1]], - [GenericFilter.PeoplePrivate, []], + [Rules.Everyone, []], + [Rules.HasTextMatchingSubstringOf, ['',0,0]], + [Rules.HasTextMatchingRegexpOf, ['',0,1]], + [Rules.PeoplePrivate, []], ] self.generic_filter_widget.setup_filter( default_filters) diff --git a/gramps2/src/PluginUtils/_Report.py b/gramps2/src/PluginUtils/_Report.py index 794bfc048..8219e5e42 100644 --- a/gramps2/src/PluginUtils/_Report.py +++ b/gramps2/src/PluginUtils/_Report.py @@ -58,7 +58,7 @@ from _StyleEditor import StyleListDisplay import Config import _PaperMenu import Errors -import GenericFilter +from Filters import FilterComboBox, Rules, CustomFilters import NameDisplay from QuestionDialog import ErrorDialog, OptionDialog @@ -741,7 +741,7 @@ class BareReportDialog: row += 1 if len(self.local_filters): - self.filter_combo = GenericFilter.GrampsFilterComboBox() + self.filter_combo = FilterComboBox() label = gtk.Label("%s:" % _("Filter")) label.set_alignment(0.0,0.5) table.attach(label, 1, 2, row, row+1, gtk.SHRINK|gtk.FILL, @@ -912,7 +912,7 @@ class BareReportDialog: self.options.handler.set_filter_number(active) except: print "Error setting filter. Proceeding with 'Everyone'" - self.filter = GenericFilter.Everyone([]) + self.filter = Rules.Everyone([]) else: self.filter = None @@ -1750,7 +1750,7 @@ class CommandLineReport: filt_list = [ filt.get_name() for filt in self.filters ] cust_filt_list = [ filt2.get_name() for filt2 in - GenericFilter.CustomFilters.get_filters() ] + CustomFilters.get_filters() ] filt_list.extend(cust_filt_list) self.options_help['filter'].append(filt_list) self.options_help['filter'].append(True) diff --git a/gramps2/src/PluginUtils/_Tool.py b/gramps2/src/PluginUtils/_Tool.py index 5254704a8..6d6bdd52f 100644 --- a/gramps2/src/PluginUtils/_Tool.py +++ b/gramps2/src/PluginUtils/_Tool.py @@ -42,7 +42,7 @@ log = logging.getLogger(".") #------------------------------------------------------------------------- import const import Utils -import GenericFilter +from Filters import CustomFilters import NameDisplay import Errors from _Options import * @@ -191,7 +191,7 @@ class CommandLineTool: filt_list = [ filt.get_name() for filt in self.filters ] cust_filt_list = [ filt2.get_name() for filt2 in - GenericFilter.CustomFilters.get_filters() ] + CustomFilters.get_filters() ] filt_list.extend(cust_filt_list) self.options_help['filter'].append(filt_list) self.options_help['filter'].append(True) diff --git a/gramps2/src/plugins/Calendar.py b/gramps2/src/plugins/Calendar.py index 0a2ee9ca0..7c9edbfee 100644 --- a/gramps2/src/plugins/Calendar.py +++ b/gramps2/src/plugins/Calendar.py @@ -40,7 +40,7 @@ import locale import BaseDoc from PluginUtils import Report, ReportOptions, ReportUtils, register_report pt2cm = ReportUtils.pt2cm -import GenericFilter +from Filters import CustomFilters, GenericFilter, ParamFilter, Rules from DateHandler import DateDisplay import RelLib @@ -259,7 +259,7 @@ class Calendar(Report.Report): """ filter_num = self.options_class.get_filter_number() filters = self.options_class.get_report_filters(self.start_person) - filters.extend(GenericFilter.CustomFilters.get_filters()) + filters.extend(CustomFilters.get_filters()) self.filter = filters[filter_num] people = self.filter.apply(self.database, self.database.get_person_handles(sort_handles=False)) @@ -526,34 +526,34 @@ class FilterWidget(Widget): retval = [] for filter in self["filters"]: if filter in ["everyone", "all filters"]: - f = GenericFilter.GenericFilter() + f = GenericFilter() f.set_name(_("Entire Database")) - f.add_rule(GenericFilter.Everyone([])) + f.add_rule(Rules.Everyone([])) retval.append(f) if filter in ["descendants", "all filters"]: - f = GenericFilter.GenericFilter() + f = GenericFilter() f.set_name(_("Descendants of %s") % name) - f.add_rule(GenericFilter.IsDescendantOf([gramps_id,1])) + f.add_rule(Rules.IsDescendantOf([gramps_id,1])) retval.append(f) if filter in ["descendant families", "all filters"]: - f = GenericFilter.GenericFilter() + f = GenericFilter() f.set_name(_("Descendant Families of %s") % name) - f.add_rule(GenericFilter.IsDescendantFamilyOf([gramps_id])) + f.add_rule(Rules.IsDescendantFamilyOf([gramps_id])) retval.append(f) if filter in ["ancestors", "all filters"]: - f = GenericFilter.GenericFilter() + f = GenericFilter() f.set_name(_("Ancestors of %s") % name) - f.add_rule(GenericFilter.IsAncestorOf([gramps_id,1])) + f.add_rule(Rules.IsAncestorOf([gramps_id,1])) retval.append(f) if filter in ["common ancestors", "all filters"]: - f = GenericFilter.GenericFilter() + f = GenericFilter() f.set_name(_("People with common ancestor with %s") % name) - f.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id])) + f.add_rule(Rules.HasCommonAncestorWith([gramps_id])) retval.append(f) if filter in ["calendar attribute", "all filters"]: - f = GenericFilter.ParamFilter() + f = ParamFilter() f.set_name(_("People with a Calendar attribute")) - f.add_rule(GenericFilter.HasTextMatchingSubstringOf(['Calendar',0,0])) + f.add_rule(Rules.HasTextMatchingSubstringOf(['Calendar',0,0])) retval.append(f) return retval diff --git a/gramps2/src/plugins/EventCmp.py b/gramps2/src/plugins/EventCmp.py index 2a8078787..a1abd609d 100644 --- a/gramps2/src/plugins/EventCmp.py +++ b/gramps2/src/plugins/EventCmp.py @@ -43,7 +43,7 @@ import gtk.glade # GRAMPS modules # #------------------------------------------------------------------------ -import GenericFilter +from Filters import GenericFilter, build_filter_menu, Rules import ListModel import Sort import Utils @@ -152,11 +152,11 @@ class EventComparison(Tool.Tool,ManagedWindow.ManagedWindow): self.set_window(window,self.filterDialog.get_widget('title'), self.label) - self.all = GenericFilter.GenericFilter() + self.all = GenericFilter() self.all.set_name(_("Entire Database")) - self.all.add_rule(GenericFilter.Everyone([])) + self.all.add_rule(Rules.Everyone([])) - self.filter_menu = GenericFilter.build_filter_menu([self.all]) + self.filter_menu = build_filter_menu([self.all]) filter_num = self.options.handler.get_filter_number() self.filter_menu.set_active(filter_num) self.filter_menu.show() diff --git a/gramps2/src/plugins/ExportVCalendar.py b/gramps2/src/plugins/ExportVCalendar.py index 032ee3406..2b1f23877 100644 --- a/gramps2/src/plugins/ExportVCalendar.py +++ b/gramps2/src/plugins/ExportVCalendar.py @@ -51,7 +51,7 @@ log = logging.getLogger(".ExportVCal") # GRAMPS modules # #------------------------------------------------------------------------- -import GenericFilter +from Filters import GenericFilter, Rules, build_filter_menu import const import Utils from RelLib import Date @@ -84,33 +84,33 @@ class CalendarWriterOptionBox: filter_obj = self.topDialog.get_widget("filter") self.copy = 0 - all = GenericFilter.GenericFilter() + all = GenericFilter() all.set_name(_("Entire Database")) - all.add_rule(GenericFilter.Everyone([])) + all.add_rule(Rules.Everyone([])) if self.person: - des = GenericFilter.GenericFilter() + des = GenericFilter() des.set_name(_("Descendants of %s") % self.person.get_primary_name().get_name()) - des.add_rule(GenericFilter.IsDescendantOf( + des.add_rule(Rules.IsDescendantOf( [self.person.get_gramps_id(),1])) - ans = GenericFilter.GenericFilter() + ans = GenericFilter() ans.set_name(_("Ancestors of %s") % self.person.get_primary_name().get_name()) - ans.add_rule(GenericFilter.IsAncestorOf( + ans.add_rule(Rules.IsAncestorOf( [self.person.get_gramps_id(),1])) - com = GenericFilter.GenericFilter() + com = GenericFilter() com.set_name(_("People with common ancestor with %s") % self.person.get_primary_name().get_name()) - com.add_rule(GenericFilter.HasCommonAncestorWith( + com.add_rule(Rules.HasCommonAncestorWith( [self.person.get_gramps_id()])) - self.filter_menu = GenericFilter.build_filter_menu( + self.filter_menu = build_filter_menu( [all,des,ans,com]) else: - self.filter_menu = GenericFilter.build_filter_menu([all]) + self.filter_menu = build_filter_menu([all]) filter_obj.set_menu(self.filter_menu) the_box = self.topDialog.get_widget('vbox1') diff --git a/gramps2/src/plugins/ExportVCard.py b/gramps2/src/plugins/ExportVCard.py index 828e451c7..3dae47b75 100644 --- a/gramps2/src/plugins/ExportVCard.py +++ b/gramps2/src/plugins/ExportVCard.py @@ -50,7 +50,7 @@ import gtk.glade # GRAMPS modules # #------------------------------------------------------------------------- -import GenericFilter +from Filters import GenericFilter, Rules, build_filter_menu import const from RelLib import Date import Errors @@ -82,33 +82,33 @@ class CardWriterOptionBox: filter_obj = self.topDialog.get_widget("filter") self.copy = 0 - all = GenericFilter.GenericFilter() + all = GenericFilter() all.set_name(_("Entire Database")) - all.add_rule(GenericFilter.Everyone([])) + all.add_rule(Rules.Everyone([])) if self.person: - des = GenericFilter.GenericFilter() + des = GenericFilter() des.set_name(_("Descendants of %s") % self.person.get_primary_name().get_name()) - des.add_rule(GenericFilter.IsDescendantOf( + des.add_rule(Rules.IsDescendantOf( [self.person.get_gramps_id(),1])) - ans = GenericFilter.GenericFilter() + ans = GenericFilter() ans.set_name(_("Ancestors of %s") % self.person.get_primary_name().get_name()) - ans.add_rule(GenericFilter.IsAncestorOf( + ans.add_rule(Rules.IsAncestorOf( [self.person.get_gramps_id(),1])) - com = GenericFilter.GenericFilter() + com = GenericFilter() com.set_name(_("People with common ancestor with %s") % self.person.get_primary_name().get_name()) - com.add_rule(GenericFilter.HasCommonAncestorWith( + com.add_rule(Rules.HasCommonAncestorWith( [self.person.get_gramps_id()])) - self.filter_menu = GenericFilter.build_filter_menu( + self.filter_menu = build_filter_menu( [all,des,ans,com]) else: - self.filter_menu = GenericFilter.build_filter_menu([all]) + self.filter_menu = build_filter_menu([all]) filter_obj.set_menu(self.filter_menu) the_box = self.topDialog.get_widget('vbox1') diff --git a/gramps2/src/plugins/FilterEditor.py b/gramps2/src/plugins/FilterEditor.py index 1c102d87c..af684b892 100644 --- a/gramps2/src/plugins/FilterEditor.py +++ b/gramps2/src/plugins/FilterEditor.py @@ -20,7 +20,9 @@ # $Id$ -"""Generic Filtering Routines""" +""" +Custom Filter Editor tool. +""" __author__ = "Don Allingham" @@ -56,7 +58,8 @@ import GrampsDisplay # #------------------------------------------------------------------------- import const -import GenericFilter +from Filters import GenericFilter, FilterList, Rules, \ + reload_custom_filters, reload_system_filters import AutoComp import ListModel import Utils @@ -325,7 +328,7 @@ class FilterEditor(ManagedWindow.ManagedWindow): FilterEditor) self.db = db - self.filterdb = GenericFilter.GenericFilterList(filterdb) + self.filterdb = FilterList(filterdb) self.filterdb.load() self.editor = gtk.glade.XML(const.rule_glade,'filter_list',"gramps") @@ -365,8 +368,8 @@ class FilterEditor(ManagedWindow.ManagedWindow): def on_delete_event(self,obj,b): self.filterdb.save() self.remove_itself_from_menu() - GenericFilter.reload_custom_filters() - GenericFilter.reload_system_filters() + reload_custom_filters() + reload_system_filters() # self.parent.init_filters() def add_itself_to_menu(self): @@ -404,8 +407,8 @@ class FilterEditor(ManagedWindow.ManagedWindow): def close_filter_editor(self,obj): self.filterdb.save() self.window.destroy() - GenericFilter.reload_custom_filters() - GenericFilter.reload_system_filters() + reload_custom_filters() + reload_system_filters() # self.parent.init_filters() def draw_filters(self): @@ -414,8 +417,8 @@ class FilterEditor(ManagedWindow.ManagedWindow): self.clist.add([f.get_name(),f.get_comment()],f) def add_new_filter(self,obj): - filter = GenericFilter.GenericFilter() - EditFilter(self,filter) + the_filter = GenericFilter() + EditFilter(self,the_filter) def edit_filter(self,obj): store,iter = self.clist.get_selected() @@ -617,7 +620,7 @@ class EditRule: self.page = [] self.class2page = {} the_map = {} - for class_obj in GenericFilter.editor_rule_list: + for class_obj in Rules.editor_rule_list: arglist = class_obj.labels vallist = [] tlist = [] diff --git a/gramps2/src/plugins/GraphViz.py b/gramps2/src/plugins/GraphViz.py index bfd480b02..da4191af2 100644 --- a/gramps2/src/plugins/GraphViz.py +++ b/gramps2/src/plugins/GraphViz.py @@ -53,7 +53,7 @@ import gtk # #------------------------------------------------------------------------ from PluginUtils import Report, ReportOptions, register_report -import GenericFilter +from Filters import GenericFilter, CustomFilters, Rules import RelLib import DateHandler import const @@ -232,7 +232,7 @@ class GraphViz: filter_num = options_class.get_filter_number() filters = options_class.get_report_filters(person) - filters.extend(GenericFilter.CustomFilters.get_filters()) + filters.extend(CustomFilters.get_filters()) self.filter = filters[filter_num] the_buffer = self.get_report() @@ -654,21 +654,21 @@ class GraphVizOptions(ReportOptions.ReportOptions): name = 'PERSON' gramps_id = '' - all = GenericFilter.GenericFilter() + all = GenericFilter() all.set_name(_("Entire Database")) - all.add_rule(GenericFilter.Everyone([])) + all.add_rule(Rules.Everyone([])) - des = GenericFilter.GenericFilter() + des = GenericFilter() des.set_name(_("Descendants of %s") % name) - des.add_rule(GenericFilter.IsDescendantOf([gramps_id,1])) + des.add_rule(Rule.IsDescendantOf([gramps_id,1])) - ans = GenericFilter.GenericFilter() + ans = GenericFilter() ans.set_name(_("Ancestors of %s") % name) - ans.add_rule(GenericFilter.IsAncestorOf([gramps_id,1])) + ans.add_rule(Rule.IsAncestorOf([gramps_id,1])) - com = GenericFilter.GenericFilter() + com = GenericFilter() com.set_name(_("People with common ancestor with %s") % name) - com.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id])) + com.add_rule(Rules.HasCommonAncestorWith([gramps_id])) return [all,des,ans,com] diff --git a/gramps2/src/plugins/IndivComplete.py b/gramps2/src/plugins/IndivComplete.py index f3f4927cd..2e74df425 100644 --- a/gramps2/src/plugins/IndivComplete.py +++ b/gramps2/src/plugins/IndivComplete.py @@ -44,7 +44,7 @@ import RelLib import const import Utils import BaseDoc -import GenericFilter +from Filters import GenericFilter, Rules, CustomFilters import DateHandler from PluginUtils import Report, ReportOptions, ReportUtils, register_report @@ -80,7 +80,7 @@ class IndivCompleteReport(Report.Report): filter_num = options_class.get_filter_number() filters = options_class.get_report_filters(person) - filters.extend(GenericFilter.CustomFilters.get_filters()) + filters.extend(CustomFilters.get_filters()) self.filter = filters[filter_num] def define_table_styles(self): @@ -520,25 +520,25 @@ class IndivCompleteOptions(ReportOptions.ReportOptions): name = 'PERSON' gramps_id = '' - filt_id = GenericFilter.GenericFilter() + filt_id = GenericFilter() filt_id.set_name(name) - filt_id.add_rule(GenericFilter.HasIdOf([gramps_id])) + filt_id.add_rule(Rules.HasIdOf([gramps_id])) - all = GenericFilter.GenericFilter() + all = GenericFilter() all.set_name(_("Entire Database")) - all.add_rule(GenericFilter.Everyone([])) + all.add_rule(Rules.Everyone([])) - des = GenericFilter.GenericFilter() + des = GenericFilter() des.set_name(_("Descendants of %s") % name) - des.add_rule(GenericFilter.IsDescendantOf([gramps_id,1])) + des.add_rule(Rules.IsDescendantOf([gramps_id,1])) - ans = GenericFilter.GenericFilter() + ans = GenericFilter() ans.set_name(_("Ancestors of %s") % name) - ans.add_rule(GenericFilter.IsAncestorOf([gramps_id,1])) + ans.add_rule(Rules.IsAncestorOf([gramps_id,1])) - com = GenericFilter.GenericFilter() + com = GenericFilter() com.set_name(_("People with common ancestor with %s") % name) - com.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id])) + com.add_rule(Rules.HasCommonAncestorWith([gramps_id])) return [filt_id,all,des,ans,com] diff --git a/gramps2/src/plugins/NarrativeWeb.py b/gramps2/src/plugins/NarrativeWeb.py index 4f8e663d6..dad8f3f17 100644 --- a/gramps2/src/plugins/NarrativeWeb.py +++ b/gramps2/src/plugins/NarrativeWeb.py @@ -67,7 +67,7 @@ import gtk import RelLib import const from GrampsCfg import get_researcher -import GenericFilter +from Filters import GenericFilter, Rules, CustomFilters import Sort from PluginUtils import Report, ReportOptions, ReportUtils, register_report import Errors @@ -2045,7 +2045,7 @@ class WebReport(Report.Report): filter_num = options.get_filter_number() filters = options.get_report_filters(person) - filters.extend(GenericFilter.CustomFilters.get_filters()) + filters.extend(CustomFilters.get_filters()) self.filter = filters[filter_num] self.target_path = options.handler.options_dict['NWEBod'] @@ -2403,25 +2403,25 @@ class WebReportOptions(ReportOptions.ReportOptions): name = 'PERSON' gramps_id = '' - all = GenericFilter.GenericFilter() + all = GenericFilter() all.set_name(_("Entire Database")) - all.add_rule(GenericFilter.Everyone([])) + all.add_rule(Rules.Everyone([])) - des = GenericFilter.GenericFilter() + des = GenericFilter() des.set_name(_("Descendants of %s") % name) - des.add_rule(GenericFilter.IsDescendantOf([gramps_id,1])) + des.add_rule(Rules.IsDescendantOf([gramps_id,1])) - df = GenericFilter.GenericFilter() + df = GenericFilter() df.set_name(_("Descendant Families of %s") % name) - df.add_rule(GenericFilter.IsDescendantFamilyOf([gramps_id])) + df.add_rule(Rules.IsDescendantFamilyOf([gramps_id])) - ans = GenericFilter.GenericFilter() + ans = GenericFilter() ans.set_name(_("Ancestors of %s") % name) - ans.add_rule(GenericFilter.IsAncestorOf([gramps_id,1])) + ans.add_rule(Rules.IsAncestorOf([gramps_id,1])) - com = GenericFilter.GenericFilter() + com = GenericFilter() com.set_name(_("People with common ancestor with %s") % name) - com.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id])) + com.add_rule(Rules.HasCommonAncestorWith([gramps_id])) return [all,des,df,ans,com] diff --git a/gramps2/src/plugins/StatisticsChart.py b/gramps2/src/plugins/StatisticsChart.py index e9bd6bed2..538e71700 100644 --- a/gramps2/src/plugins/StatisticsChart.py +++ b/gramps2/src/plugins/StatisticsChart.py @@ -54,7 +54,7 @@ from RelLib import Person, FamilyRelType, EventType # gender and report type names import BaseDoc from PluginUtils import Report, ReportOptions, ReportUtils, register_report -import GenericFilter +from Filters import GenericFilter, Rules, CustomFilters import DateHandler from Utils import ProgressMeter @@ -487,7 +487,7 @@ class StatisticsChart(Report.Report): filter_num = options_class.get_filter_number() filters = options_class.get_report_filters(person) - filters.extend(GenericFilter.CustomFilters.get_filters()) + filters.extend(CustomFilters.get_filters()) filterfun = filters[filter_num] options = options_class.handler.options_dict @@ -841,21 +841,21 @@ class StatisticsChartOptions(ReportOptions.ReportOptions): name = 'PERSON' gramps_id = '' - all = GenericFilter.GenericFilter() + all = GenericFilter() all.set_name(_("Entire Database")) - all.add_rule(GenericFilter.Everyone([])) + all.add_rule(Rules.Everyone([])) - des = GenericFilter.GenericFilter() + des = GenericFilter() des.set_name(_("Descendants of %s") % name) - des.add_rule(GenericFilter.IsDescendantOf([gramps_id, 1])) + des.add_rule(Rules.IsDescendantOf([gramps_id, 1])) - ans = GenericFilter.GenericFilter() + ans = GenericFilter() ans.set_name(_("Ancestors of %s") % name) - ans.add_rule(GenericFilter.IsAncestorOf([gramps_id, 1])) + ans.add_rule(Rules.IsAncestorOf([gramps_id, 1])) - com = GenericFilter.GenericFilter() + com = GenericFilter() com.set_name(_("People with common ancestor with %s") % name) - com.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id])) + com.add_rule(Rules.HasCommonAncestorWith([gramps_id])) return [all, des, ans, com] diff --git a/gramps2/src/plugins/TimeLine.py b/gramps2/src/plugins/TimeLine.py index 11185e8dd..544a6bf52 100644 --- a/gramps2/src/plugins/TimeLine.py +++ b/gramps2/src/plugins/TimeLine.py @@ -46,7 +46,7 @@ import gtk from PluginUtils import Report, ReportOptions, ReportUtils, register_report pt2cm = ReportUtils.pt2cm import BaseDoc -import GenericFilter +from Filters import GenericFilter, Rules, CustomFilters import Sort from QuestionDialog import ErrorDialog @@ -84,7 +84,7 @@ class TimeLine(Report.Report): filter_num = options_class.get_filter_number() filters = options_class.get_report_filters(person) - filters.extend(GenericFilter.CustomFilters.get_filters()) + filters.extend(CustomFilters.get_filters()) self.filter = filters[filter_num] self.title = options_class.handler.options_dict['title'] @@ -409,21 +409,21 @@ class TimeLineOptions(ReportOptions.ReportOptions): name = 'PERSON' gramps_id = '' - all = GenericFilter.GenericFilter() + all = GenericFilter() all.set_name(_("Entire Database")) - all.add_rule(GenericFilter.Everyone([])) + all.add_rule(Rules.Everyone([])) - des = GenericFilter.GenericFilter() + des = GenericFilter() des.set_name(_("Descendants of %s") % name) - des.add_rule(GenericFilter.IsDescendantOf([gramps_id,1])) + des.add_rule(Rules.IsDescendantOf([gramps_id,1])) - ans = GenericFilter.GenericFilter() + ans = GenericFilter() ans.set_name(_("Ancestors of %s") % name) - ans.add_rule(GenericFilter.IsAncestorOf([gramps_id,1])) + ans.add_rule(Rules.IsAncestorOf([gramps_id,1])) - com = GenericFilter.GenericFilter() + com = GenericFilter() com.set_name(_("People with common ancestor with %s") % name) - com.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id])) + com.add_rule(Rules.HasCommonAncestorWith([gramps_id])) return [all,des,ans,com] diff --git a/gramps2/src/plugins/WriteFtree.py b/gramps2/src/plugins/WriteFtree.py index 996ed9214..742340735 100644 --- a/gramps2/src/plugins/WriteFtree.py +++ b/gramps2/src/plugins/WriteFtree.py @@ -53,7 +53,7 @@ import gtk.glade # #------------------------------------------------------------------------- import Utils -import GenericFilter +from Filters import GenericFilter, Rules, build_filter_menu import Errors from QuestionDialog import ErrorDialog from PluginUtils import register_export @@ -86,32 +86,32 @@ class FtreeWriterOptionBox: filter_obj = self.top.get_widget("filter") - all = GenericFilter.GenericFilter() + all = GenericFilter() all.set_name(_("Entire Database")) - all.add_rule(GenericFilter.Everyone([])) + all.add_rule(Rules.Everyone([])) if self.person: - des = GenericFilter.GenericFilter() + des = GenericFilter() des.set_name(_("Descendants of %s") % self.person.get_primary_name().get_name()) - des.add_rule(GenericFilter.IsDescendantOf( + des.add_rule(Rules.IsDescendantOf( [self.person.get_gramps_id(),1])) - ans = GenericFilter.GenericFilter() + ans = GenericFilter() ans.set_name(_("Ancestors of %s") % self.person.get_primary_name().get_name()) - ans.add_rule(GenericFilter.IsAncestorOf( + ans.add_rule(Rules.IsAncestorOf( [self.person.get_gramps_id(),1])) - com = GenericFilter.GenericFilter() + com = GenericFilter() com.set_name(_("People with common ancestor with %s") % self.person.get_primary_name().get_name()) - com.add_rule(GenericFilter.HasCommonAncestorWith( + com.add_rule(Rules.HasCommonAncestorWith( [self.person.get_gramps_id()])) - self.filter_menu = GenericFilter.build_filter_menu([all,des,ans,com]) + self.filter_menu = build_filter_menu([all,des,ans,com]) else: - self.filter_menu = GenericFilter.build_filter_menu([all]) + self.filter_menu = build_filter_menu([all]) filter_obj.set_menu(self.filter_menu) the_box = self.top.get_widget("vbox1") diff --git a/gramps2/src/plugins/WriteGeneWeb.py b/gramps2/src/plugins/WriteGeneWeb.py index 3bd560ccc..3b41de941 100644 --- a/gramps2/src/plugins/WriteGeneWeb.py +++ b/gramps2/src/plugins/WriteGeneWeb.py @@ -52,7 +52,7 @@ log = logging.getLogger(".WriteGeneWeb") # #------------------------------------------------------------------------- import RelLib -import GenericFilter +from Filters import GenericFilter, build_filter_menu import const import Utils import Errors @@ -88,33 +88,32 @@ class GeneWebWriterOptionBox: filter_obj = self.topDialog.get_widget("filter") self.copy = 0 - all = GenericFilter.GenericFilter() + all = GenericFilter() all.set_name(_("Entire Database")) - all.add_rule(GenericFilter.Everyone([])) + all.add_rule(Rules.Everyone([])) if self.person: - des = GenericFilter.GenericFilter() + des = GenericFilter() des.set_name(_("Descendants of %s") % self.person.get_primary_name().get_name()) - des.add_rule(GenericFilter.IsDescendantOf( + des.add_rule(Rules.IsDescendantOf( [self.person.get_gramps_id(),1])) - ans = GenericFilter.GenericFilter() + ans = GenericFilter() ans.set_name(_("Ancestors of %s") % self.person.get_primary_name().get_name()) - ans.add_rule(GenericFilter.IsAncestorOf( + ans.add_rule(Rules.IsAncestorOf( [self.person.get_gramps_id(),1])) - com = GenericFilter.GenericFilter() + com = GenericFilter() com.set_name(_("People with common ancestor with %s") % self.person.get_primary_name().get_name()) - com.add_rule(GenericFilter.HasCommonAncestorWith( + com.add_rule(Rules.HasCommonAncestorWith( [self.person.get_gramps_id()])) - self.filter_menu = GenericFilter.build_filter_menu( - [all,des,ans,com]) + self.filter_menu = build_filter_menu([all,des,ans,com]) else: - self.filter_menu = GenericFilter.build_filter_menu([all]) + self.filter_menu = build_filter_menu([all]) filter_obj.set_menu(self.filter_menu) the_box = self.topDialog.get_widget('vbox1')