From d54d9f927013074db2bb850818564414e5b22446 Mon Sep 17 00:00:00 2001 From: Alex Roitman Date: Tue, 5 Aug 2003 03:35:42 +0000 Subject: [PATCH] * src/GenericFilter.py: Fixes for existing filters (ancestors and descendants used to include the original person). Four new filters: ancestors and descendants more and less than so many generations away. * NEWS: Compile preliminary contents for the next release. svn: r1960 --- ChangeLog | 5 ++ NEWS | 18 ++++ src/GenericFilter.py | 202 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 212 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index fd7f8ecf0..05639607d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2003-08-04 Alex Roitman * src/plugins/GraphViz.py (make_doc_menu): Add paper option to the menu. + * src/GenericFilter.py: Fixes for existing filters (ancestors and + descendants used to include the original person). + Four new filters: ancestors and descendants more and less than so many + generations away. + * NEWS: Compile preliminary contents for the next release. 2003-08-02 Alex Roitman * src/dialog.glade: Consistent tooltips. diff --git a/NEWS b/NEWS index 26814c122..0c8503804 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,21 @@ +Version 0.9.4 -- the "This used to bug me..." release +* More compliance with GNOME HIG. +* Fixed style problems for book items. +* New Book item: Custom Text. +* New export plugin: Web Family Tree. +* GEDCOM import and export fixes. +* WebPage enchancement: mini-ancestor tree (Daryle C. Lewis). +* Intelligent guessing of whether the person is alive. +* Various Merge and Import fixes. +* More privacy options for GEDCOM export. +* New types of filters: + (1) iterating over other filters, + (2) specifying number of generations away for ancestors and descendants. +* Preliminary support for printing copies of reports. +* Performance improvements for list views. +* Context menus in Family View upon right-click. +* Fair share of bug fixes. + Version 0.9.3 * New reports: Ancestors (text), Fan Chart (graphics), and Book (collection of any number of any reports in a single document). diff --git a/src/GenericFilter.py b/src/GenericFilter.py index 0ff4dd17c..bb6d951d6 100644 --- a/src/GenericFilter.py +++ b/src/GenericFilter.py @@ -1,7 +1,7 @@ # # Gramps - a GTK+/GNOME based genealogy program # -# Copyright (C) 2002 Donald N. Allingham +# Copyright (C) 2002-2003 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 @@ -181,17 +181,18 @@ class IsDescendantOf(Rule): if not self.init: self.init = 1 root = db.getPerson(self.list[0]) - self.init_list(root) + self.init_list(root,1) return self.map.has_key(p.getId()) - def init_list(self,p): + def init_list(self,p,first): # if self.map.has_key(p.getId()) == 1: # loop_error(self.orig,p) - self.map[p.getId()] = 1 + if not first: + self.map[p.getId()] = 1 for fam in p.getFamilyList(): for child in fam.getChildList(): - self.init_list(child) + self.init_list(child,0) #------------------------------------------------------------------------- # @@ -218,9 +219,87 @@ class IsDescendantOfFilterMatch(IsDescendantOf): filter = MatchesFilter(self.list) for person in db.getPersonMap ().values (): if filter.apply (db, person): - self.init_list (person) + self.init_list (person, 1) return self.map.has_key(p.getId()) +#------------------------------------------------------------------------- +# +# 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:') ] + + def __init__(self,list): + Rule.__init__(self,list) + self.init = 0 + self.map = {} + + def name(self): + return 'Is a descendant of person not more than N generations away' + + def apply(self,db,p): + self.orig = p + + if not self.init: + self.init = 1 + root = db.getPerson(self.list[0]) + self.init_list(root,0) + return self.map.has_key(p.getId()) + + def init_list(self,p,gen): +# if self.map.has_key(p.getId()) == 1: +# loop_error(self.orig,p) + if gen: + self.map[p.getId()] = 1 + if gen >= int(self.list[1]): + return + + for fam in p.getFamilyList(): + for child in fam.getChildList(): + self.init_list(child,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:') ] + + def __init__(self,list): + Rule.__init__(self,list) + self.init = 0 + self.map = {} + + def name(self): + return 'Is a descendant of person at least N generations away' + + def apply(self,db,p): + self.orig = p + + if not self.init: + self.init = 1 + root = db.getPerson(self.list[0]) + self.init_list(root,0) + return self.map.has_key(p.getId()) + + def init_list(self,p,gen): +# if self.map.has_key(p.getId()) == 1: +# loop_error(self.orig,p) + if gen >= int(self.list[1]): + self.map[p.getId()] = 1 + + for fam in p.getFamilyList(): + for child in fam.getChildList(): + self.init_list(child,gen+1) + #------------------------------------------------------------------------- # # IsChildOfFilterMatch @@ -323,13 +402,14 @@ class IsAncestorOf(Rule): if not self.init: self.init = 1 root = db.getPerson(self.list[0]) - self.init_ancestor_list(root) + self.init_ancestor_list(root,1) return self.map.has_key(p.getId()) - def init_ancestor_list(self,p): + def init_ancestor_list(self,p,first): # if self.map.has_key(p.getId()) == 1: # loop_error(self.orig,p) - self.map[p.getId()] = 1 + if not first: + self.map[p.getId()] = 1 fam = p.getMainParents() if fam: @@ -337,16 +417,16 @@ class IsAncestorOf(Rule): m = fam.getMother() if f: - self.init_ancestor_list(f) + self.init_ancestor_list(f,0) if m: - self.init_ancestor_list(m) + self.init_ancestor_list(m,0) #------------------------------------------------------------------------- # # IsAncestorOfFilterMatch # #------------------------------------------------------------------------- -class IsAncestorOfFilterMatch(Rule): +class IsAncestorOfFilterMatch(IsAncestorOf): """Rule that checks for a person that is an ancestor of someone matched by a filter""" @@ -365,9 +445,97 @@ class IsAncestorOfFilterMatch(Rule): filter = MatchesFilter(self.list) for person in db.getPersonMap ().values (): if filter.apply (db, person): - self.init_ancestor_list (person) + self.init_ancestor_list (person,1) return self.map.has_key(p.getId()) +#------------------------------------------------------------------------- +# +# 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:') ] + + def __init__(self,list): + Rule.__init__(self,list) + self.init = 0 + self.map = {} + + def name(self): + return 'Is an ancestor of person not more than N generations away' + + def apply(self,db,p): + self.orig = p + if not self.init: + self.init = 1 + root = db.getPerson(self.list[0]) + self.init_ancestor_list(root,0) + return self.map.has_key(p.getId()) + + def init_ancestor_list(self,p,gen): +# if self.map.has_key(p.getId()) == 1: +# loop_error(self.orig,p) + if gen: + self.map[p.getId()] = 1 + if gen >= int(self.list[1]): + return + + fam = p.getMainParents() + if fam: + f = fam.getFather() + m = fam.getMother() + + if f: + self.init_ancestor_list(f,gen+1) + if m: + self.init_ancestor_list(m,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:') ] + + def __init__(self,list): + Rule.__init__(self,list) + self.init = 0 + self.map = {} + + def name(self): + return 'Is an ancestor of person at least N generations away' + + def apply(self,db,p): + self.orig = p + if not self.init: + self.init = 1 + root = db.getPerson(self.list[0]) + self.init_ancestor_list(root,0) + return self.map.has_key(p.getId()) + + def init_ancestor_list(self,p,gen): +# if self.map.has_key(p.getId()) == 1: +# loop_error(self.orig,p) + if gen >= int(self.list[1]): + self.map[p.getId()] = 1 + + fam = p.getMainParents() + if fam: + f = fam.getFather() + m = fam.getMother() + + if f: + self.init_ancestor_list(f,gen+1) + if m: + self.init_ancestor_list(m,gen+1) + #------------------------------------------------------------------------- # # IsParentOfFilterMatch @@ -973,9 +1141,17 @@ tasks = { _("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 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")