4435: Change WhatsNext gramplet to work with tags (based on a patch by Reinhard Mueller)

svn: r17299
This commit is contained in:
Nick Hall 2011-04-27 20:34:48 +00:00
parent 8ea51c62e3
commit 6a795ede88

View File

@ -27,7 +27,7 @@
# GRAMPS modules # GRAMPS modules
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
from gen.lib import EventType, FamilyRelType, MarkerType from gen.lib import EventType, FamilyRelType
from gen.plug import Gramplet from gen.plug import Gramplet
from gen.display.name import displayer as name_displayer from gen.display.name import displayer as name_displayer
from gen.plug.report import utils as ReportUtils from gen.plug.report import utils as ReportUtils
@ -40,37 +40,111 @@ from gen.ggettext import sgettext as _
#------------------------------------------------------------------------ #------------------------------------------------------------------------
class WhatNextGramplet(Gramplet): class WhatNextGramplet(Gramplet):
# Minimum number of lines we want to see. Further lines with the same
# distance to the main person will be added on top of this.
TODOS_WANTED = 10
# How many generations of descendants to process before we go up to the
# next level of ancestors.
DOWNS_PER_UP = 2
# After an ancestor was processed, how many extra rounds to delay until the
# descendants of this ancestor are processed.
ANCESTOR_DELAY = 1
# Use COMPLETE marker on a person to indicate that this person has no
# further marriages, if COMPLETE marker is not set, warn about this at the
# time the marriages for the person are processed.
PERSON_NEED_COMPLETE = False
# Use COMPLETE marker on a family to indicate that there are no further
# children in this family, if COMPLETE marker is not set, warn about this
# at the time the children of this family are processed.
FAMILY_NEED_COMPLETE = False
# Ignore all people and families with TODO_TYPE marker set. This way,
# hopeless cases can be marked separately and don't clutter up the list.
IGNORE_TODO = False
def init(self): def init(self):
self.set_tooltip(_("Double-click name for details")) self.set_tooltip(_("Double-click name for details"))
self.set_text(_("No Family Tree loaded.")) self.set_text(_("No Family Tree loaded."))
def build_options(self):
"""
Build the configuration options.
"""
from gen.plug.menu import NumberOption, EnumeratedListOption
self.opts = []
# Minimum number of lines we want to see. Further lines with the same
# distance to the main person will be added on top of this.
name = _("Minimum number of items to display")
opt = NumberOption(name, self.__todos_wanted, 1, 300)
self.opts.append(opt)
# How many generations of descendants to process before we go up to the
# next level of ancestors.
name = _("Descendant generations per ancestor generation")
opt = NumberOption(name, self.__downs_per_up, 1, 20)
self.opts.append(opt)
# After an ancestor was processed, how many extra rounds to delay until
# the descendants of this ancestor are processed.
name = _("Delay before descendants of an ancestor is processed")
opt = NumberOption(name, self.__ancestor_delay, 1, 10)
self.opts.append(opt)
# Tag to use to indicate that this person has no further marriages, if
# the person is not tagged, warn about this at the time the marriages
# for the person are processed.
name = _("Tag to indicate that a person is complete")
opt = EnumeratedListOption(name, self.__person_complete_tag)
self.opts.append(opt)
# Tag to use to indicate that there are no further children in this
# family, if this family is not tagged, warn about this at the time the
# children of this family are processed.
name = _("Tag to indicate that a family is complete")
opt = EnumeratedListOption(name, self.__family_complete_tag)
self.opts.append(opt)
# Tag to use to specify people and families to ignore. In his way,
# hopeless cases can be marked separately and don't clutter up the list.
name = _("Tag to indicate that a person or family should be ignored")
opt = EnumeratedListOption(name, self.__ignore_tag)
self.opts.append(opt)
self.opts[3].add_item('', '')
self.opts[4].add_item('', '')
self.opts[5].add_item('', '')
for tag_handle in self.dbstate.db.get_tag_handles():
tag = self.dbstate.db.get_tag_from_handle(tag_handle)
tag_name = tag.get_name()
self.opts[3].add_item(tag_name, tag_name)
self.opts[4].add_item(tag_name, tag_name)
self.opts[5].add_item(tag_name, tag_name)
map(self.add_option, self.opts)
def save_options(self):
"""
Save gramplet configuration data.
"""
self.__todos_wanted = int(self.opts[0].get_value())
self.__downs_per_up = int(self.opts[1].get_value())
self.__ancestor_delay = int(self.opts[2].get_value())
self.__person_complete_tag = self.opts[3].get_value()
self.__family_complete_tag = self.opts[4].get_value()
self.__ignore_tag = self.opts[5].get_value()
def save_update_options(self, obj):
"""
Save a gramplet's options to file.
"""
self.save_options()
self.gui.data = [self.__todos_wanted,
self.__downs_per_up,
self.__ancestor_delay,
self.__person_complete_tag,
self.__family_complete_tag,
self.__ignore_tag]
self.update()
def on_load(self):
"""
Load stored configuration data.
"""
if len(self.gui.data) == 6:
self.__todos_wanted = int(self.gui.data[0])
self.__downs_per_up = int(self.gui.data[1])
self.__ancestor_delay = int(self.gui.data[2])
self.__person_complete_tag = self.gui.data[3]
self.__family_complete_tag = self.gui.data[4]
self.__ignore_tag = self.gui.data[5]
else:
self.__todos_wanted = 10
self.__downs_per_up = 2
self.__ancestor_delay = 1
self.__person_complete_tag = ''
self.__family_complete_tag = ''
self.__ignore_tag = ''
def db_changed(self): def db_changed(self):
@ -90,6 +164,25 @@ class WhatNextGramplet(Gramplet):
self.set_text(_("No Home Person set.")) self.set_text(_("No Home Person set."))
return return
self.__person_complete_handle = None
self.__family_complete_handle = None
self.__ignore_handle = None
if self.__person_complete_tag:
tag = self.dbstate.db.get_tag_from_name(self.__person_complete_tag)
if tag is not None:
self.__person_complete_handle = tag.get_handle()
if self.__family_complete_tag:
tag = self.dbstate.db.get_tag_from_name(self.__family_complete_tag)
if tag is not None:
self.__family_complete_handle = tag.get_handle()
if self.__ignore_tag:
tag = self.dbstate.db.get_tag_from_name(self.__ignore_tag)
if tag is not None:
self.__ignore_handle = tag.get_handle()
self.__counter = 0 self.__counter = 0
self.set_text("") self.set_text("")
@ -108,7 +201,7 @@ class WhatNextGramplet(Gramplet):
# the ancestors of my sibling's spouses etc. # the ancestors of my sibling's spouses etc.
ancestors = [[default_person]] ancestors = [[default_person]]
ancestors_queue = ([[[default_person]]] + ancestors_queue = ([[[default_person]]] +
[[] for i in range(self.ANCESTOR_DELAY)]) [[] for i in range(self.__ancestor_delay)])
# List of lists of families of relatives in currently processed # List of lists of families of relatives in currently processed
# distance. We go up one level of distance in each round. # distance. We go up one level of distance in each round.
@ -128,7 +221,7 @@ class WhatNextGramplet(Gramplet):
# beginning of this class definition, but the principle remains the # beginning of this class definition, but the principle remains the
# same. # same.
families = [] families = []
families_queue = [[] for i in range(self.ANCESTOR_DELAY)] families_queue = [[] for i in range(self.__ancestor_delay)]
# List of spouses to add to ancestors list so we track ancestors of # List of spouses to add to ancestors list so we track ancestors of
# spouses, too, but delayed as defined by the parameter. # spouses, too, but delayed as defined by the parameter.
@ -153,11 +246,11 @@ class WhatNextGramplet(Gramplet):
families.append(new_family_group) families.append(new_family_group)
if new_spouses_group: if new_spouses_group:
spouses.append(new_spouses_group) spouses.append(new_spouses_group)
if self.__counter >= self.TODOS_WANTED: if self.__counter >= self.__todos_wanted:
break break
# Next generation of children # Next generation of children
for down in range(self.DOWNS_PER_UP): for down in range(self.__downs_per_up):
new_families = [] new_families = []
for family_group in families: for family_group in families:
children = [] children = []
@ -165,7 +258,7 @@ class WhatNextGramplet(Gramplet):
for child in self.__get_children(family): for child in self.__get_children(family):
self.__process_person(child, children) self.__process_person(child, children)
self.__process_family_2(family, person, spouse) self.__process_family_2(family, person, spouse)
if self.__counter >= self.TODOS_WANTED: if self.__counter >= self.__todos_wanted:
break break
# Families of children # Families of children
@ -184,14 +277,14 @@ class WhatNextGramplet(Gramplet):
new_families.append(new_family_group) new_families.append(new_family_group)
if new_spouses_group: if new_spouses_group:
spouses.append(new_spouses_group) spouses.append(new_spouses_group)
if self.__counter >= self.TODOS_WANTED: if self.__counter >= self.__todos_wanted:
break break
families = new_families families = new_families
spouses_queue.append(spouses) spouses_queue.append(spouses)
spouses = [] spouses = []
if self.__counter >= self.TODOS_WANTED: if self.__counter >= self.__todos_wanted:
break break
if self.__counter >= self.TODOS_WANTED: if self.__counter >= self.__todos_wanted:
break break
# Parents # Parents
@ -222,13 +315,13 @@ class WhatNextGramplet(Gramplet):
new_ancestors.append(new_ancestor_group_1 + new_ancestor_group_2) new_ancestors.append(new_ancestor_group_1 + new_ancestor_group_2)
if new_family_group: if new_family_group:
new_families.append(new_family_group) new_families.append(new_family_group)
if self.__counter >= self.TODOS_WANTED: if self.__counter >= self.__todos_wanted:
break break
ancestors = new_ancestors + spouses_queue.pop(0) ancestors = new_ancestors + spouses_queue.pop(0)
ancestors_queue.append(ancestors) ancestors_queue.append(ancestors)
families_queue.append(new_families) families_queue.append(new_families)
families += families_queue.pop(0) families += families_queue.pop(0)
if self.__counter >= self.TODOS_WANTED: if self.__counter >= self.__todos_wanted:
break break
# Separator between rounds # Separator between rounds
@ -290,7 +383,8 @@ class WhatNextGramplet(Gramplet):
if not name: if not name:
name = _("(person with unknown name)") name = _("(person with unknown name)")
if self.PERSON_NEED_COMPLETE and person.get_marker() != MarkerType.COMPLETE: if self.__person_complete_handle is not None and \
self.__person_complete_handle not in person.get_tag_list():
missingbits.append(_("person not complete")) missingbits.append(_("person not complete"))
if missingbits: if missingbits:
@ -374,7 +468,8 @@ class WhatNextGramplet(Gramplet):
'name1': name1, 'name1': name1,
'name2': name2} 'name2': name2}
if self.FAMILY_NEED_COMPLETE and family.get_marker() != MarkerType.COMPLETE: if self.__family_complete_handle is not None and \
self.__family_complete_handle not in family.get_tag_list():
missingbits.append(_("family not complete")) missingbits.append(_("family not complete"))
if missingbits: if missingbits:
@ -439,7 +534,8 @@ class WhatNextGramplet(Gramplet):
else: else:
return None return None
spouse = self.dbstate.db.get_person_from_handle(spouse_handle) spouse = self.dbstate.db.get_person_from_handle(spouse_handle)
if self.IGNORE_TODO and spouse.get_marker() == MarkerType.TODO_TYPE: if self.__ignore_handle is not None and \
self.__ignore_handle in spouse.get_tag_list():
return None return None
else: else:
return spouse return spouse
@ -449,7 +545,8 @@ class WhatNextGramplet(Gramplet):
for child_ref in family.get_child_ref_list(): for child_ref in family.get_child_ref_list():
child = self.dbstate.db.get_person_from_handle(child_ref.ref) child = self.dbstate.db.get_person_from_handle(child_ref.ref)
if self.IGNORE_TODO and child.get_marker() == MarkerType.TODO_TYPE: if self.__ignore_handle is not None and \
self.__ignore_handle in child.get_tag_list():
continue continue
yield child yield child
@ -460,7 +557,8 @@ class WhatNextGramplet(Gramplet):
if family_handle in self.__processed_families: if family_handle in self.__processed_families:
continue continue
family = self.dbstate.db.get_family_from_handle(family_handle) family = self.dbstate.db.get_family_from_handle(family_handle)
if self.IGNORE_TODO and family.get_marker() == MarkerType.TODO_TYPE: if self.__ignore_handle is not None and \
self.__ignore_handle in family.get_tag_list():
continue continue
yield family yield family
@ -474,7 +572,8 @@ class WhatNextGramplet(Gramplet):
return (None, None, None) return (None, None, None)
family = self.dbstate.db.get_family_from_handle(family_handle) family = self.dbstate.db.get_family_from_handle(family_handle)
if self.IGNORE_TODO and family.get_marker() == MarkerType.TODO_TYPE: if self.__ignore_handle is not None and \
self.__ignore_handle in family.get_tag_list():
return (None, None, None) return (None, None, None)
father_handle = family.get_father_handle() father_handle = family.get_father_handle()
@ -485,7 +584,8 @@ class WhatNextGramplet(Gramplet):
father = None father = None
else: else:
father = self.dbstate.db.get_person_from_handle(father_handle) father = self.dbstate.db.get_person_from_handle(father_handle)
if self.IGNORE_TODO and father.get_marker() == MarkerType.TODO_TYPE: if self.__ignore_handle is not None and \
self.__ignore_handle in father.get_tag_list():
father = None father = None
mother_handle = family.get_mother_handle() mother_handle = family.get_mother_handle()
@ -493,7 +593,8 @@ class WhatNextGramplet(Gramplet):
mother = UnknownPerson mother = UnknownPerson
else: else:
mother = self.dbstate.db.get_person_from_handle(mother_handle) mother = self.dbstate.db.get_person_from_handle(mother_handle)
if self.IGNORE_TODO and mother.get_marker() == MarkerType.TODO_TYPE: if self.__ignore_handle is not None and \
self.__ignore_handle in mother.get_tag_list():
mother = None mother = None
return (father, mother, family) return (father, mother, family)