6085: Convert filters to use the User class

The filter apply method can now be passed a User instance
instead of a progress callback.

The prepare progress will no longer be displayed without the main
filter progress.
This commit is contained in:
Nick Hall 2017-01-26 15:44:18 +00:00
parent 2cb8c2801a
commit 4912cc08e4
74 changed files with 178 additions and 161 deletions

View File

@ -29,7 +29,6 @@ Package providing filtering framework for GRAMPS.
# Gramps imports
#
#------------------------------------------------------------------------
from ..const import GRAMPS_LOCALE as glocale
from ..lib.person import Person
from ..lib.family import Family
from ..lib.src import Source
@ -40,6 +39,8 @@ from ..lib.repo import Repository
from ..lib.media import Media
from ..lib.note import Note
from ..lib.tag import Tag
from ..const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
#-------------------------------------------------------------------------
#
@ -129,16 +130,21 @@ class GenericFilter:
def find_from_handle(self, db, handle):
return db.get_person_from_handle(handle)
def check_func(self, db, id_list, task, cb_progress=None, tupleind=None):
final_list = []
def get_number(self, db):
return db.get_number_of_people()
def check_func(self, db, id_list, task, user=None, tupleind=None):
final_list = []
if user:
user.begin_progress(_('Filter'), _('Applying ...'),
self.get_number(db))
if id_list is None:
with self.get_cursor(db) as cursor:
for handle, data in cursor:
person = self.make_obj()
person.unserialize(data)
if cb_progress:
cb_progress()
if user:
user.step_progress()
if task(db, person) != self.invert:
final_list.append(handle)
else:
@ -148,23 +154,27 @@ class GenericFilter:
else:
handle = data[tupleind]
person = self.find_from_handle(db, handle)
if cb_progress:
cb_progress()
if user:
user.step_progress()
if task(db, person) != self.invert:
final_list.append(data)
if user:
user.end_progress()
return final_list
def check_and(self, db, id_list, cb_progress=None, tupleind=None):
def check_and(self, db, id_list, user=None, tupleind=None):
final_list = []
flist = self.flist
if user:
user.begin_progress(_('Filter'), _('Applying ...'),
self.get_number(db))
if id_list is None:
with self.get_cursor(db) as cursor:
for handle, data in cursor:
person = self.make_obj()
person.unserialize(data)
if cb_progress:
cb_progress()
if user:
user.step_progress()
val = all(rule.apply(db, person) for rule in flist)
if val != self.invert:
final_list.append(handle)
@ -175,24 +185,23 @@ class GenericFilter:
else:
handle = data[tupleind]
person = self.find_from_handle(db, handle)
if cb_progress:
cb_progress()
if user:
user.step_progress()
val = all(rule.apply(db, person) for rule in flist if person)
if val != self.invert:
final_list.append(data)
if user:
user.end_progress()
return final_list
def check_or(self, db, id_list, cb_progress=None, tupleind=None):
return self.check_func(db, id_list, self.or_test, cb_progress,
tupleind)
def check_or(self, db, id_list, user=None, tupleind=None):
return self.check_func(db, id_list, self.or_test, user, tupleind)
def check_one(self, db, id_list, cb_progress=None, tupleind=None):
return self.check_func(db, id_list, self.one_test, cb_progress,
tupleind)
def check_one(self, db, id_list, user=None, tupleind=None):
return self.check_func(db, id_list, self.one_test, user, tupleind)
def check_xor(self, db, id_list, cb_progress=None, tupleind=None):
return self.check_func(db, id_list, self.xor_test, cb_progress,
tupleind)
def check_xor(self, db, id_list, user=None, tupleind=None):
return self.check_func(db, id_list, self.xor_test, user, tupleind)
def xor_test(self, db, person):
test = False
@ -222,20 +231,18 @@ class GenericFilter:
def check(self, db, handle):
return self.get_check_func()(db, [handle])
def apply(self, db, id_list=None, cb_progress=None, tupleind=None):
def apply(self, db, id_list=None, tupleind=None, user=None):
"""
Apply the filter using db.
If id_list given, the handles in id_list are used. If not given
a database cursor will be used over all entries.
cb_progress is optional. If present it must be a function that takes no
parameters. If cb_progress given, it will be called occasionally to
indicate progress of the filtering.
If tupleind is given, id_list is supposed to consist of a list of
tuples, with the handle being index tupleind. So
handle_0 = id_list[0][tupleind]
user is optional. If present it must be an instance of a User class.
:Returns: if id_list given, it is returned with the items that
do not match the filter, filtered out.
if id_list not given, all items in the database that
@ -243,8 +250,8 @@ class GenericFilter:
"""
m = self.get_check_func()
for rule in self.flist:
rule.requestprepare(db)
res = m(db, id_list, cb_progress, tupleind)
rule.requestprepare(db, user)
res = m(db, id_list, user, tupleind)
for rule in self.flist:
rule.requestreset()
return res
@ -263,6 +270,9 @@ class GenericFamilyFilter(GenericFilter):
def find_from_handle(self, db, handle):
return db.get_family_from_handle(handle)
def get_number(self, db):
return db.get_number_of_families()
class GenericEventFilter(GenericFilter):
def __init__(self, source=None):
@ -277,6 +287,9 @@ class GenericEventFilter(GenericFilter):
def find_from_handle(self, db, handle):
return db.get_event_from_handle(handle)
def get_number(self, db):
return db.get_number_of_events()
class GenericSourceFilter(GenericFilter):
def __init__(self, source=None):
@ -291,6 +304,9 @@ class GenericSourceFilter(GenericFilter):
def find_from_handle(self, db, handle):
return db.get_source_from_handle(handle)
def get_number(self, db):
return db.get_number_of_sources()
class GenericCitationFilter(GenericFilter):
def __init__(self, source=None):
@ -305,6 +321,9 @@ class GenericCitationFilter(GenericFilter):
def find_from_handle(self, db, handle):
return db.get_citation_from_handle(handle)
def get_number(self, db):
return db.get_number_of_citations()
class GenericPlaceFilter(GenericFilter):
def __init__(self, source=None):
@ -319,6 +338,9 @@ class GenericPlaceFilter(GenericFilter):
def find_from_handle(self, db, handle):
return db.get_place_from_handle(handle)
def get_number(self, db):
return db.get_number_of_places()
class GenericMediaFilter(GenericFilter):
def __init__(self, source=None):
@ -333,6 +355,9 @@ class GenericMediaFilter(GenericFilter):
def find_from_handle(self, db, handle):
return db.get_media_from_handle(handle)
def get_number(self, db):
return db.get_number_of_media()
class GenericRepoFilter(GenericFilter):
def __init__(self, source=None):
@ -347,6 +372,9 @@ class GenericRepoFilter(GenericFilter):
def find_from_handle(self, db, handle):
return db.get_repository_from_handle(handle)
def get_number(self, db):
return db.get_number_of_repositories()
class GenericNoteFilter(GenericFilter):
def __init__(self, source=None):
@ -361,6 +389,9 @@ class GenericNoteFilter(GenericFilter):
def find_from_handle(self, db, handle):
return db.get_note_from_handle(handle)
def get_number(self, db):
return db.get_number_of_notes()
def GenericFilterFactory(namespace):
if namespace == 'Person':

View File

@ -45,7 +45,7 @@ class ParamFilter(GenericFilter):
def set_parameter(self, param):
self.param_list = [param]
def apply(self, db, id_list=None):
def apply(self, db, id_list=None, user=None):
for rule in self.flist:
#rule.set_list(self.param_list)
#
@ -60,7 +60,7 @@ class ParamFilter(GenericFilter):
if rule.nrprepare > 0:
raise FilterError('Custom filters can not twice be used' \
' in a parameter filter')
rule.requestprepare(db)
rule.requestprepare(db, user)
result = GenericFilter.apply(self, db, id_list)
for rule in self.flist:
rule.requestreset()

View File

@ -85,7 +85,7 @@ class ChangedSinceBase(Rule):
"accepted. %s does not satisfy.") % iso_date_time)
return time_sec
def prepare(self, db):
def prepare(self, db, user):
self.since = None
self.before = None
if self.list[0]:

View File

@ -54,7 +54,7 @@ class HasCitationBase(Rule):
category = _('Citation/source filters')
allow_regex = True
def prepare(self, db):
def prepare(self, db, user):
self.date = None
try:
if self.list[1]:

View File

@ -56,7 +56,7 @@ class HasEventBase(Rule):
category = _('Event filters')
allow_regex = True
def prepare(self, db):
def prepare(self, db, user):
self.date = None
if self.list[0]:
self.etype = EventType()

View File

@ -47,7 +47,7 @@ class HasGalleryBase(Rule):
description = "Matches objects with certain number of items in the gallery"
category = _('General filters')
def prepare(self, db):
def prepare(self, db, user):
# things we want to do just once, not for every handle
if self.list[1] == 'less than':
self.count_type = 0

View File

@ -50,7 +50,7 @@ class HasLDSBase(Rule):
description = "Matches objects with LDS events"
category = _('General filters')
def prepare(self, db):
def prepare(self, db, user):
# things we want to do just once, not for every handle
if self.list[1] == 'less than':
self.count_type = 0

View File

@ -56,7 +56,7 @@ class HasNoteBase(Rule):
else:
Rule.__init__(self, arg, use_regex)
def prepare(self, db):
def prepare(self, db, user):
# things we want to do just once, not for every handle
if self.list[1] == 'less than':
self.count_type = 0

View File

@ -45,7 +45,7 @@ class HasReferenceCountBase(Rule):
category = _('General filters')
def prepare(self, db):
def prepare(self, db, user):
# things we want to do just once, not for every handle
if self.list[0] == 'less than':
self.count_type = 0

View File

@ -48,7 +48,7 @@ class HasSourceCountBase(Rule):
"connected to it (actually citations are counted)"
category = _('Citation/source filters')
def prepare(self, db):
def prepare(self, db, user):
# things we want to do just once, not for every handle
if self.list[1] == 'less than':
self.count_type = 0

View File

@ -47,7 +47,7 @@ class HasSourceOfBase(Rule):
category = _('Citation/source filters')
description = 'Matches objects who have a particular source'
def prepare(self,db):
def prepare(self, db, user):
if self.list[0] == '':
self.source_handle = None
self.nosource = True

View File

@ -51,7 +51,7 @@ class HasTagBase(Rule):
description = "Matches objects with the given tag"
category = _('General filters')
def prepare(self, db):
def prepare(self, db, user):
"""
Prepare the rule. Things we want to do just once.
"""

View File

@ -56,7 +56,7 @@ class MatchesEventFilterBase(MatchesFilterBase):
# we want to have this filter show event filters
namespace = 'Event'
def prepare(self, db):
def prepare(self, db, user):
MatchesFilterBase.prepare(self, db)
self.MEF_filt = self.find_filter()

View File

@ -56,13 +56,13 @@ class MatchesFilterBase(Rule):
description = "Matches objects matched by the specified filter name"
category = _('General filters')
def prepare(self, db):
def prepare(self, db, user):
if gramps.gen.filters.CustomFilters:
filters = gramps.gen.filters.CustomFilters.get_filters_dict(self.namespace)
if self.list[0] in filters:
filt = filters[self.list[0]]
for rule in filt.flist:
rule.requestprepare(db)
rule.requestprepare(db, user)
else:
LOG.warning(_("Can't find filter %s in the defined custom filters")
% self.list[0])

View File

@ -53,7 +53,7 @@ class MatchesSourceFilterBase(MatchesFilterBase):
# we want to have this filter show source filters
namespace = 'Source'
def prepare(self, db):
def prepare(self, db, user):
MatchesFilterBase.prepare(self, db)
self.MSF_filt = self.find_filter()

View File

@ -65,7 +65,7 @@ class Rule:
def is_empty(self):
return False
def requestprepare(self, dbase):
def requestprepare(self, db, user):
"""
Request that the prepare method of the rule is executed if needed
@ -86,10 +86,10 @@ class Rule:
except re.error:
self.regex[i] = re.compile('')
self.match_substring = self.match_regex
self.prepare(dbase)
self.prepare(db, user)
self.nrprepare += 1
def prepare(self, dummy_db):
def prepare(self, db, user):
"""prepare so the rule can be executed efficiently"""
pass

View File

@ -53,7 +53,7 @@ class HasCitation(Rule):
description = _("Matches citations with particular parameters")
allow_regex = True
def prepare(self, db):
def prepare(self, db, user):
self.date = None
try:
if self.list[1]:

View File

@ -53,7 +53,7 @@ class MatchesRepositoryFilter(MatchesFilterBase):
namespace = 'Repository'
def prepare(self, db):
def prepare(self, db, user):
MatchesFilterBase.prepare(self, db)
self.MRF_filt = self.find_filter()

View File

@ -54,7 +54,7 @@ class MatchesSourceFilter(MatchesFilterBase):
# we want to have this filter show source filters
namespace = 'Source'
def prepare(self, db):
def prepare(self, db, user):
MatchesFilterBase.prepare(self, db)
self.MRF_filt = self.find_filter()

View File

@ -51,7 +51,7 @@ class HasData(Rule):
category = _('General filters')
allow_regex = True
def prepare(self, dbase):
def prepare(self, db, user):
self.event_type = self.list[0]
self.date = self.list[1]

View File

@ -56,7 +56,7 @@ class MatchesPersonFilter(MatchesFilterBase):
# we want to have this filter show person filters
namespace = 'Person'
def prepare(self, db):
def prepare(self, db, user):
MatchesFilterBase.prepare(self, db)
try :

View File

@ -48,7 +48,7 @@ class HasRelType(Rule):
"of a particular value")
category = _('General filters')
def prepare(self, dbase):
def prepare(self, db, user):
if self.list[0]:
self.rtype = FamilyRelType()
self.rtype.set_from_xml_str(self.list[0])

View File

@ -46,7 +46,7 @@ class IsAncestorOf(Rule):
category = _('General filters')
description = _('Matches ancestor families of the specified family')
def prepare(self, db):
def prepare(self, db, user):
self.map = set()
first = False if int(self.list[1]) else True
root_family = db.get_family_from_gramps_id(self.list[0])

View File

@ -45,7 +45,7 @@ class IsBookmarked(Rule):
category = _('General filters')
description = _("Matches the families on the bookmark list")
def prepare(self, db):
def prepare(self, db, user):
self.bookmarks = db.get_family_bookmarks().get()
def apply(self, db, family):

View File

@ -46,7 +46,7 @@ class IsDescendantOf(Rule):
category = _('General filters')
description = _('Matches descendant families of the specified family')
def prepare(self, db):
def prepare(self, db, user):
self.map = set()
first = False if int(self.list[1]) else True
root_family = db.get_family_from_gramps_id(self.list[0])

View File

@ -53,7 +53,7 @@ class HasMedia(Rule):
category = _('General filters')
allow_regex = True
def prepare(self,db):
def prepare(self, db, user):
self.date = None
try:
if self.list[3]:

View File

@ -51,7 +51,7 @@ class HasNote(Rule):
category = _('General filters')
allow_regex = True
def prepare(self, dbase):
def prepare(self, db, user):
if self.list[1]:
self.ntype = NoteType()
self.ntype.set_from_xml_str(self.list[1])

View File

@ -41,26 +41,30 @@ from . import MatchesFilter
#
#-------------------------------------------------------------------------
def filter_database(db, progress, filter_name):
def filter_database(db, user, filter_name):
"""Returns a list of person handles"""
filt = MatchesFilter([filter_name])
progress.set_header(_('Preparing sub-filter'))
filt.requestprepare(db)
filt.requestprepare(db, user)
progress.set_header(_('Retrieving all sub-filter matches'))
if user:
user.begin_progress(_('Finding relationship paths'),
_('Retrieving all sub-filter matches'),
db.get_number_of_people())
matches = []
for handle in db.iter_person_handles():
person = db.get_person_from_handle(handle)
if filt.apply(db, person):
matches.append(handle)
progress.step()
if user:
user.step_progress()
if user:
user.end_progress()
filt.requestreset()
return matches
def get_family_handle_people(db, exclude_handle, family_handle):
people = set()
@ -91,7 +95,7 @@ def get_person_family_people(db, person, person_handle):
return people
def find_deep_relations(db, progress, person, path, seen, target_people):
def find_deep_relations(db, user, person, path, seen, target_people):
if len(target_people) < 1:
return []
@ -113,8 +117,9 @@ def find_deep_relations(db, progress, person, path, seen, target_people):
family_people = get_person_family_people(db, person, handle)
for family_person in family_people:
pers = db.get_person_from_handle(family_person)
return_paths += find_deep_relations(db, progress, pers, person_path, seen, target_people)
if progress: progress.step()
return_paths += find_deep_relations(db, user, pers, person_path, seen, target_people)
if user:
user.step_progress()
return return_paths
@ -131,23 +136,20 @@ class DeepRelationshipPathBetween(Rule):
" by marriage) between the specified person and the target people."
" Each path is not necessarily the shortest path.")
def prepare(self, db):
# FIXME: this should use the User class
from gramps.gui.utils import ProgressMeter
def prepare(self, db, user):
root_person_id = self.list[0]
root_person = db.get_person_from_gramps_id(root_person_id)
progress = ProgressMeter( # TODO no-parent
_('Finding relationship paths'))
progress.set_pass(header=_('Evaluating people'), mode=ProgressMeter.MODE_ACTIVITY)
filter_name = self.list[1]
target_people = filter_database(db, progress, filter_name)
target_people = filter_database(db, user, filter_name)
paths = find_deep_relations(db, progress, root_person, [], [], target_people)
progress.close()
progress = None
if user:
user.begin_progress(_('Finding relationship paths'),
_('Evaluating people'),
db.get_number_of_people())
paths = find_deep_relations(db, user, root_person, [], [], target_people)
if user:
user.end_progress()
self.__matches = set()
list(map(self.__matches.update, paths))

View File

@ -51,7 +51,7 @@ class HasAddress(Rule):
category = _('General filters')
def prepare(self, db):
def prepare(self, db, user):
# things we want to do just once, not for every handle
if self.list[1] == 'less than':
self.count_type = 0

View File

@ -50,7 +50,7 @@ class HasAssociation(Rule):
description = _("Matches people with a certain number of associations")
category = _('General filters')
def prepare(self, db):
def prepare(self, db, user):
# things we want to do just once, not for every handle
if self.list[1] == 'less than':
self.count_type = 0

View File

@ -51,7 +51,7 @@ class HasBirth(Rule):
category = _('Event filters')
allow_regex = True
def prepare(self, db):
def prepare(self, db, user):
if self.list[0]:
self.date = parser.parse(self.list[0])
else:

View File

@ -48,7 +48,7 @@ class HasCommonAncestorWith(Rule):
description = _("Matches people that have a common ancestor "
"with a specified person")
def prepare(self, db):
def prepare(self, db, user):
self.db = db
# For each(!) person we keep track of who their ancestors
# are, in a set(). So we only have to compute a person's

View File

@ -54,7 +54,7 @@ class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith):
HasCommonAncestorWith.__init__(self, list, use_regex)
self.ancestor_cache = {}
def prepare(self, db):
def prepare(self, db, user):
self.db = db
# For each(!) person we keep track of who their ancestors
# are, in a set(). So we only have to compute a person's
@ -63,7 +63,7 @@ class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith):
self.ancestor_cache = {}
self.with_people = []
filt = MatchesFilter(self.list)
filt.requestprepare(db)
filt.requestprepare(db, user)
for handle in db.iter_person_handles():
person = db.get_person_from_handle(handle)
if person and filt.apply(db, person):

View File

@ -51,7 +51,7 @@ class HasDeath(Rule):
category = _('Event filters')
allow_regex = True
def prepare(self, db):
def prepare(self, db, user):
if self.list[0]:
self.date = parser.parse(self.list[0])
else:

View File

@ -54,7 +54,7 @@ class HasFamilyEvent(Rule):
category = _('Event filters')
allow_regex = True
def prepare(self,db):
def prepare(self, db, user):
self.date = None
try:
if self.list[1]:

View File

@ -42,7 +42,7 @@ class HasTextMatchingRegexpOf(HasTextMatchingSubstringOf):
def __init__(self, list, use_regex=False):
HasTextMatchingSubstringOf.__init__(self, list, use_regex)
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.person_map = set()
self.event_map = set()

View File

@ -51,7 +51,7 @@ class HasTextMatchingSubstringOf(Rule):
category = _('General filters')
allow_regex = True
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.person_map = set()
self.event_map = set()

View File

@ -46,7 +46,7 @@ class IsAncestorOf(Rule):
category = _("Ancestral filters")
description = _("Matches people that are ancestors of a specified person")
def prepare(self, db):
def prepare(self, db, user):
"""Assume that if 'Inclusive' not defined, assume inclusive"""
self.db = db
self.map = set()

View File

@ -49,7 +49,7 @@ class IsAncestorOfFilterMatch(IsAncestorOf):
description = _("Matches people that are ancestors "
"of anybody matched by a filter")
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.map = set()
try:
@ -61,7 +61,7 @@ class IsAncestorOfFilterMatch(IsAncestorOf):
first = 1
filt = MatchesFilter(self.list[0:1])
filt.requestprepare(db)
filt.requestprepare(db, user)
for person in db.iter_people():
if filt.apply(db, person):
self.init_ancestor_list(db, person, first)

View File

@ -46,7 +46,7 @@ class IsBookmarked(Rule):
category = _('General filters')
description = _("Matches the people on the bookmark list")
def prepare(self,db):
def prepare(self, db, user):
self.bookmarks = db.get_bookmarks().get()
def apply(self,db,person):

View File

@ -48,11 +48,11 @@ class IsChildOfFilterMatch(Rule):
category = _('Family filters')
description = _("Matches children of anybody matched by a filter")
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.map = set()
filt = MatchesFilter(self.list)
filt.requestprepare(db)
filt.requestprepare(db, user)
for person in db.iter_people():
if filt.apply(db, person):
self.init_list(person)

View File

@ -45,7 +45,7 @@ class IsDefaultPerson(Rule):
category = _('General filters')
description = _("Matches the default person")
def prepare(self,db):
def prepare(self, db, user):
p = db.get_default_person()
if p:
self.def_handle = p.get_handle()

View File

@ -52,7 +52,7 @@ class IsDescendantFamilyOf(Rule):
description = _("Matches people that are descendants or the spouse "
"of a descendant of a specified person")
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.matches = set()
self.root_person = db.get_person_from_gramps_id(self.list[0])

View File

@ -49,12 +49,12 @@ class IsDescendantFamilyOfFilterMatch(IsDescendantFamilyOf):
description = _("Matches people that are descendants or the spouse "
"of anybody matched by a filter")
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.matches = set()
filt = MatchesFilter(self.list[0:1])
filt.requestprepare(db)
filt.requestprepare(db, user)
for person in db.iter_people():
if filt.apply(db, person):
self.add_matches(person)

View File

@ -47,7 +47,7 @@ class IsDescendantOf(Rule):
category = _('Descendant filters')
description = _('Matches all descendants for the specified person')
def prepare(self, db):
def prepare(self, db, user):
self.db = db
self.map = set()
try:

View File

@ -49,7 +49,7 @@ class IsDescendantOfFilterMatch(IsDescendantOf):
description = _("Matches people that are descendants "
"of anybody matched by a filter")
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.map = set()
try:
@ -61,7 +61,7 @@ class IsDescendantOfFilterMatch(IsDescendantOf):
first = 1
filt = MatchesFilter(self.list[0:1])
filt.requestprepare(db)
filt.requestprepare(db, user)
for person in db.iter_people():
if filt.apply(db, person):
self.init_list(person, first)

View File

@ -49,7 +49,7 @@ class IsDuplicatedAncestorOf(Rule):
description = _("Matches people that are ancestors twice or more "
"of a specified person")
def prepare(self, db):
def prepare(self, db, user):
self.db = db
self.map = set()
self.map2 = set()

View File

@ -48,7 +48,7 @@ class IsLessThanNthGenerationAncestorOf(Rule):
description = _("Matches people that are ancestors "
"of a specified person not more than N generations away")
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.map = set()
try:

View File

@ -55,7 +55,7 @@ class IsLessThanNthGenerationAncestorOfBookmarked(Rule):
description = _("Matches ancestors of the people on the bookmark list "
"not more than N generations away")
def prepare(self, db):
def prepare(self, db, user):
self.db = db
bookmarks = db.get_bookmarks().get()
self.map = set()

View File

@ -50,7 +50,7 @@ class IsLessThanNthGenerationAncestorOfDefaultPerson(Rule):
description = _("Matches ancestors of the default person "
"not more than N generations away")
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.map = set()
p = db.get_default_person()

View File

@ -49,7 +49,7 @@ class IsLessThanNthGenerationDescendantOf(Rule):
description = _("Matches people that are descendants of a "
"specified person not more than N generations away")
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.map = set()
try:

View File

@ -48,7 +48,7 @@ class IsMoreThanNthGenerationAncestorOf(Rule):
description = _("Matches people that are ancestors "
"of a specified person at least N generations away")
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.map = set()
try:

View File

@ -49,7 +49,7 @@ class IsMoreThanNthGenerationDescendantOf(Rule):
"person at least N generations away")
def prepare(self ,db):
def prepare(self, db, user):
self.db = db
self.map = set()
try:

View File

@ -48,11 +48,11 @@ class IsParentOfFilterMatch(Rule):
category = _('Family filters')
description = _("Matches parents of anybody matched by a filter")
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.map = set()
filt = MatchesFilter(self.list)
filt.requestprepare(db)
filt.requestprepare(db, user)
for person in db.iter_people():
if filt.apply(db, person):
self.init_list(person)

View File

@ -46,7 +46,7 @@ class IsRelatedWith(Rule):
category = _("Relationship filters")
description = _("Matches people related to a specified person")
def prepare(self, db):
def prepare(self, db, user):
"""prepare so the rule can be executed efficiently
we build the list of people related to <person> here,
so that apply is only a check into this list

View File

@ -47,11 +47,11 @@ class IsSiblingOfFilterMatch(Rule):
category = _('Family filters')
description = _("Matches siblings of anybody matched by a filter")
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.map = set()
filt = MatchesFilter(self.list)
filt.requestprepare(db)
filt.requestprepare(db, user)
for person in db.iter_people():
if filt.apply (db, person):
self.init_list (person)

View File

@ -48,9 +48,9 @@ class IsSpouseOfFilterMatch(Rule):
description = _("Matches people married to anybody matching a filter")
category = _('Family filters')
def prepare(self,db):
def prepare(self, db, user):
self.filt = MatchesFilter (self.list)
self.filt.requestprepare(db)
self.filt.requestprepare(db, user)
def apply(self,db,person):
for family_handle in person.get_family_handle_list ():

View File

@ -46,7 +46,7 @@ class ProbablyAlive(Rule):
description = _("Matches people without indications of death that are not too old")
category = _('General filters')
def prepare(self,db):
def prepare(self, db, user):
try:
self.current_date = parser.parse(str(self.list[0]))
except:

View File

@ -49,7 +49,7 @@ class RelationshipPathBetween(Rule):
"to a common ancestor, producing the relationship "
"path between two persons.")
def prepare(self, db):
def prepare(self, db, user):
self.db = db
self.map = set()
try:

View File

@ -54,7 +54,7 @@ class RelationshipPathBetweenBookmarks(Rule):
"back to common ancestors, producing the relationship "
"path(s) between bookmarked persons.")
def prepare(self,db):
def prepare(self, db, user):
self.db = db
self.map = set()
bookmarks = db.get_bookmarks().get()

View File

@ -54,7 +54,7 @@ class HasData(Rule):
category = _('General filters')
allow_regex = True
def prepare(self, dbase):
def prepare(self, db, user):
self.place_type = self.list[1]
if self.place_type:

View File

@ -55,7 +55,7 @@ class InLatLonNeighborhood(Rule):
)
category = _('Position filters')
def prepare(self,db):
def prepare(self, db, user):
if self.list[0] :
try:
self.halfheight = float(self.list[2])/2.

View File

@ -50,7 +50,7 @@ class IsEnclosedBy(Rule):
description = _('Matches a place enclosed by a particular place')
category = _('General filters')
def prepare(self, db):
def prepare(self, db, user):
self.handle = None
place = db.get_place_from_gramps_id(self.list[0])
if place:

View File

@ -53,7 +53,7 @@ class HasRepo(Rule):
category = _('General filters')
allow_regex = True
def prepare(self, dummy_db):
def prepare(self, db, user):
if self.list[1]:
self.rtype = RepositoryType()
self.rtype.set_from_xml_str(self.list[1])

View File

@ -48,7 +48,7 @@ class HasRepository(Rule):
description = _("Matches sources with a certain number of repository references")
category = _('General filters')
def prepare(self, db):
def prepare(self, db, user):
# things we want to do just once, not for every handle
if self.list[1] == 'less than':
self.count_type = 0

View File

@ -50,7 +50,7 @@ class MatchesRepositoryFilter(MatchesFilterBase):
namespace = 'Repository'
def prepare(self, db):
def prepare(self, db, user):
MatchesFilterBase.prepare(self, db)
self.MRF_filt = self.find_filter()

View File

@ -53,6 +53,7 @@ from gi.repository import Gtk
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
import gramps.gui.widgets.progressdialog as progressdlg
from ...user import User
from bisect import bisect_right
from gramps.gen.filters import SearchFilter, ExactSearchFilter
from .basemodel import BaseModel
@ -586,8 +587,8 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
self.__total += items
assert not skip
if dfilter:
for handle in dfilter.apply(self.db,
cb_progress=status_ppl.heartbeat):
for handle in dfilter.apply(self.db, user=User()):
status_ppl.heartbeat()
data = data_map(handle)
add_func(handle, data)
self.__displayed += 1

View File

@ -311,10 +311,7 @@ class Calendar(Report):
"""
db = self.database
people = db.iter_person_handles()
with self._user.progress(_('Calendar Report'),
_('Applying Filter...'),
db.get_number_of_people()) as step:
people = self.filter.apply(self.database, people, step)
people = self.filter.apply(self.database, people, user=self._user)
ngettext = self._locale.translation.ngettext # to see "nearby" comments

View File

@ -637,13 +637,13 @@ class Extract:
chart[1][key] = 1
def collect_data(self, dbase, filter_func, menu, genders,
def collect_data(self, dbase, people, menu, genders,
year_from, year_to, no_years, cb_progress, rlocale):
"""goes through the database and collects the selected personal
data persons fitting the filter and birth year criteria. The
arguments are:
dbase - the GRAMPS database
filter_func - filtering function selected by the StatisticsDialog
people - a list of filtered people
options - report options_dict which sets which methods are used
genders - which gender(s) to include into statistics
year_from - use only persons who've born this year of after
@ -672,9 +672,7 @@ class Extract:
data.append((ext[name][1], {}, ext[name][2], ext[name][3]))
# go through the people and collect data
for person_handle in filter_func.apply(dbase,
dbase.iter_person_handles(),
cb_progress):
for person_handle in people:
cb_progress()
person = dbase.get_person_from_handle(person_handle)
# check whether person has suitable gender
@ -795,11 +793,15 @@ class StatisticsChart(Report):
"%(year_from)04d-%(year_to)04d"
) % mapping
people = self.filter.apply(self.database,
self.database.iter_person_handles(),
user=self._user)
# extract requested items from the database and count them
self._user.begin_progress(_('Statistics Charts'),
_('Collecting data...'),
self.database.get_number_of_people())
tables = _Extract.collect_data(self.database, self.filter, menu,
tables = _Extract.collect_data(self.database, people, menu,
gender, year_from, year_to,
get_value('no_years'),
self._user.step_progress,

View File

@ -129,12 +129,9 @@ class TimeLine(Report):
def write_report(self):
# Apply the filter
with self._user.progress(_('Timeline'),
_('Applying filter...'),
self.database.get_number_of_people()) as step:
self.plist = self.filter.apply(self.database,
self.database.iter_person_handles(),
step)
self.plist = self.filter.apply(self.database,
self.database.iter_person_handles(),
user=self._user)
# Find the range of dates to include
(low, high) = self.find_year_range()

View File

@ -255,11 +255,7 @@ class BirthdayReport(Report):
and text.
"""
people = self.database.iter_person_handles()
with self._user.progress(_('Birthday and Anniversary Report'),
_('Applying Filter...'),
self.database.get_number_of_people()) as step:
people = self.filter.apply(self.database, people,
step)
people = self.filter.apply(self.database, people, user=self._user)
ngettext = self._locale.translation.ngettext # to see "nearby" comments
rel_calc = get_relationship_calculator(reinit=True,

View File

@ -659,10 +659,7 @@ class FamilyGroup(Report):
if not self.filter:
fam_list = flist
else:
with self._user.progress(_('Family Group Report'),
_('Applying filter...'),
self.db.get_number_of_families()) as step:
fam_list = self.filter.apply(self.db, flist, step)
fam_list = self.filter.apply(self.db, flist, user=self._user)
if fam_list:
with self._user.progress(_('Family Group Report'),
_('Writing families'),

View File

@ -8573,10 +8573,7 @@ class NavWebReport(Report):
self.obj_dict[obj_class] = defaultdict(set)
ind_list = self._db.iter_person_handles()
with self.user.progress(_("Narrated Web Site Report"),
_('Applying Person Filter...'),
self._db.get_number_of_people()) as step:
ind_list = self.filter.apply(self._db, ind_list, step)
ind_list = self.filter.apply(self._db, ind_list, user=self.user)
with self.user.progress(_("Narrated Web Site Report"),
_('Constructing list of other objects...'),

View File

@ -1265,10 +1265,7 @@ class WebCalReport(Report):
db = self.database
people = db.iter_person_handles()
with self._user.progress(_("Web Calendar Report"),
_('Applying Filter...'),
db.get_number_of_people()) as step:
people = self.filter.apply(db, people, step)
people = self.filter.apply(db, people, user=self._user)
with self._user.progress(_("Web Calendar Report"),
_("Reading database..."), len(people)) as step: