2007-12-03 Douglas S.Blank <dblank@cs.brynmawr.edu>

* src/plugins/CalculateEstimatedDates.py: Refinements, use results tab
	* src/PluginUtils/_PluginWindows.py: Tool support for a results tab



svn: r9441
This commit is contained in:
Doug Blank
2007-12-04 02:54:39 +00:00
parent 5cbf804684
commit a303f53386
3 changed files with 119 additions and 30 deletions

View File

@@ -1,3 +1,7 @@
2007-12-03 Douglas S.Blank <dblank@cs.brynmawr.edu>
* src/plugins/CalculateEstimatedDates.py: Refinements, use results tab
* src/PluginUtils/_PluginWindows.py: Tool support for a results tab
2007-12-02 Douglas S.Blank <dblank@cs.brynmawr.edu> 2007-12-02 Douglas S.Blank <dblank@cs.brynmawr.edu>
* src/gen/lib/date.py: added new method copy_ymd() * src/gen/lib/date.py: added new method copy_ymd()
* src/plugins/CalculateEstimatedDates.py: new tool based on * src/plugins/CalculateEstimatedDates.py: new tool based on

View File

@@ -211,9 +211,11 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
self.notebook.set_border_width(6) self.notebook.set_border_width(6)
self.window.vbox.add(self.notebook) self.window.vbox.add(self.notebook)
self.results_text = gtk.TextView()
self.setup_other_frames() self.setup_other_frames()
self.notebook.set_current_page(0)
self.window.show_all() self.window.show_all()
self.set_current_frame(self.initial_frame())
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@@ -232,6 +234,20 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
self.pre_run() self.pre_run()
self.run() # activate results tab self.run() # activate results tab
self.post_run() self.post_run()
def initial_frame(self):
return None
def results_write(self, text):
buffer = self.results_text.get_buffer()
mark = buffer.create_mark("end", buffer.get_end_iter())
self.results_text.scroll_to_mark(mark, 0)
buffer.insert_at_cursor(text)
buffer.delete_mark_by_name("end")
def results_clear(self):
buffer = self.results_text.get_buffer()
buffer.set_text("")
def pre_run(self): def pre_run(self):
from Utils import ProgressMeter from Utils import ProgressMeter
@@ -332,17 +348,49 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
if tooltip: if tooltip:
self.add_tooltip(widget,tooltip) self.add_tooltip(widget,tooltip)
def set_current_frame(self, name):
if name == None:
self.notebook.set_current_page(0)
else:
for frame_name in self.frame_names:
if name == frame_name:
if len(self.frames[frame_name]) > 0:
fname, child = self.frames[frame_name][0]
page = self.notebook.page_num(child)
self.notebook.set_current_page(page)
return
def add_results_frame(self,frame_name="Results"):
if frame_name not in self.frames:
widget = (frame_name, self.results_text)
self.frames[frame_name] = [widget]
self.frame_names.append(frame_name)
l = gtk.Label("<b>%s</b>" % _(frame_name))
l.set_use_markup(True)
self.notebook.append_page(widget[1], l)
self.window.show_all()
else:
self.results_clear()
self.set_current_frame(frame_name)
def setup_other_frames(self): def setup_other_frames(self):
"""Similar to add_option this method takes a frame_name, a
text string and a Gtk Widget. When the interface is built,
all widgets with the same frame_name are grouped into a
GtkFrame. This allows the subclass to create its own sections,
filling them with its own widgets. The subclass is reponsible for
all managing of the widgets, including extracting the final value
before the report executes. This task should only be called in
the add_user_options task."""
for key in self.frame_names: for key in self.frame_names:
flist = self.frames[key] flist = self.frames[key]
table = gtk.Table(3,len(flist)) table = gtk.Table(3,len(flist))
table.set_col_spacings(12) table.set_col_spacings(12)
table.set_row_spacings(6) table.set_row_spacings(6)
table.set_border_width(6) table.set_border_width(6)
l = gtk.Label("<b>%s</b>" % _(key)) l = gtk.Label("<b>%s</b>" % key)
l.set_use_markup(True) l.set_use_markup(True)
self.notebook.append_page(table,l) self.notebook.append_page(table,l)
row = 0 row = 0
for (text,widget) in flist: for (text,widget) in flist:
if text: if text:

View File

@@ -36,15 +36,11 @@ import time
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
from PluginUtils import Tool, register_tool, PluginWindows, \ from PluginUtils import Tool, register_tool, PluginWindows, \
MenuToolOptions, BooleanOption, FilterListOption, StringOption MenuToolOptions, BooleanOption, FilterListOption, StringOption, \
NumberOption
import gen.lib import gen.lib
import Config import Config
_MAX_AGE_PROB_ALIVE = Config.get(Config.MAX_AGE_PROB_ALIVE)
_MAX_SIB_AGE_DIFF = Config.get(Config.MAX_SIB_AGE_DIFF)
_MIN_GENERATION_YEARS = Config.get(Config.MIN_GENERATION_YEARS)
_AVG_GENERATION_GAP = Config.get(Config.AVG_GENERATION_GAP)
class CalcEstDateOptions(MenuToolOptions): class CalcEstDateOptions(MenuToolOptions):
""" Calculate Estimated Date options """ """ Calculate Estimated Date options """
@@ -74,9 +70,41 @@ class CalcEstDateOptions(MenuToolOptions):
death.set_help(_("Add estimated death dates")) death.set_help(_("Add estimated death dates"))
menu.add_option(category_name, "add_death", death) menu.add_option(category_name, "add_death", death)
# -----------------------------------------------------
category_name = _("Config")
num = NumberOption(_("Maximum age"),
Config.get(Config.MAX_AGE_PROB_ALIVE),
0, 200)
num.set_help(_("Maximum age that one can live to"))
menu.add_option(category_name, "MAX_AGE_PROB_ALIVE", num)
num = NumberOption(_("Maximum sibling age difference"),
Config.get(Config.MAX_SIB_AGE_DIFF),
0, 200)
num.set_help(_("Maximum age difference between siblings"))
menu.add_option(category_name, "MAX_SIB_AGE_DIFF", num)
num = NumberOption(_("Minimum years between generations"),
Config.get(Config.MIN_GENERATION_YEARS),
0, 200)
num.set_help(_("Minimum years between two generations"))
menu.add_option(category_name, "MIN_GENERATION_YEARS", num)
num = NumberOption(_("Average years between generations"),
Config.get(Config.AVG_GENERATION_GAP),
0, 200)
num.set_help(_("Average years between two generations"))
menu.add_option(category_name, "AVG_GENERATION_GAP", num)
class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch): class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
def initial_frame(self):
return _("Options")
def run(self): def run(self):
self.add_results_frame()
self.results_write("Processing...\n")
self.trans = self.db.transaction_begin("",batch=True) self.trans = self.db.transaction_begin("",batch=True)
self.db.disable_signals() self.db.disable_signals()
self.filter = self.options.handler.options_dict['filter'] self.filter = self.options.handler.options_dict['filter']
@@ -85,7 +113,14 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
source_text = self.options.handler.options_dict['source_text'] source_text = self.options.handler.options_dict['source_text']
add_birth = self.options.handler.options_dict['add_birth'] add_birth = self.options.handler.options_dict['add_birth']
add_death = self.options.handler.options_dict['add_death'] add_death = self.options.handler.options_dict['add_death']
if self.options.handler.options_dict['remove']: remove_old = self.options.handler.options_dict['remove']
self.MIN_GENERATION_YEARS = self.options.handler.options_dict['MIN_GENERATION_YEARS']
self.MAX_SIB_AGE_DIFF = self.options.handler.options_dict['MAX_SIB_AGE_DIFF']
self.MAX_AGE_PROB_ALIVE = self.options.handler.options_dict['MAX_AGE_PROB_ALIVE']
self.AVG_GENERATION_GAP = self.options.handler.options_dict['AVG_GENERATION_GAP']
if remove_old:
self.results_write("Replacing...\n")
self.progress.set_pass(_("Removing '%s'..." % source_text), self.progress.set_pass(_("Removing '%s'..." % source_text),
len(people)) len(people))
for person_handle in people: for person_handle in people:
@@ -127,6 +162,7 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
if pupdate == 1: if pupdate == 1:
self.db.commit_person(person, self.trans) self.db.commit_person(person, self.trans)
if add_birth or add_death: if add_birth or add_death:
self.results_write("Calculating...\n")
self.progress.set_pass(_('Calculating estimated dates...'), self.progress.set_pass(_('Calculating estimated dates...'),
len(people)) len(people))
source = self.get_or_create_source(source_text) source = self.get_or_create_source(source_text)
@@ -165,6 +201,7 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
self.db.transaction_commit(self.trans, _("Calculate date estimates")) self.db.transaction_commit(self.trans, _("Calculate date estimates"))
self.db.enable_signals() self.db.enable_signals()
self.db.request_rebuild() self.db.request_rebuild()
self.results_write("Done!\n")
def get_or_create_source(self, source_text): def get_or_create_source(self, source_text):
source_list = self.db.get_source_handles() source_list = self.db.get_source_handles()
@@ -227,11 +264,11 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
if not birth_date and death_date: if not birth_date and death_date:
# person died more than MAX after current year # person died more than MAX after current year
birth_date = death_date.copy_offset_ymd(year=-_MAX_AGE_PROB_ALIVE) birth_date = death_date.copy_offset_ymd(year=-self.MAX_AGE_PROB_ALIVE)
if not death_date and birth_date: if not death_date and birth_date:
# person died more than MAX after current year # person died more than MAX after current year
death_date = birth_date.copy_offset_ymd(year=_MAX_AGE_PROB_ALIVE) death_date = birth_date.copy_offset_ymd(year=self.MAX_AGE_PROB_ALIVE)
if death_date and birth_date: if death_date and birth_date:
return (birth_date, death_date) return (birth_date, death_date)
@@ -259,8 +296,8 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
year = dobj.get_year() year = dobj.get_year()
if year != 0: if year != 0:
# sibling birth date # sibling birth date
return (gen.lib.Date().copy_ymd(year - _MAX_SIB_AGE_DIFF), return (gen.lib.Date().copy_ymd(year - self.MAX_SIB_AGE_DIFF),
gen.lib.Date().copy_ymd(year + _MAX_SIB_AGE_DIFF + _MAX_AGE_PROB_ALIVE)) gen.lib.Date().copy_ymd(year + self.MAX_SIB_AGE_DIFF + self.MAX_AGE_PROB_ALIVE))
child_death_ref = child.get_death_ref() child_death_ref = child.get_death_ref()
if child_death_ref: if child_death_ref:
child_death = self.db.get_event_from_handle(child_death_ref.ref) child_death = self.db.get_event_from_handle(child_death_ref.ref)
@@ -270,8 +307,8 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
year = dobj.get_year() year = dobj.get_year()
if year != 0: if year != 0:
# sibling death date # sibling death date
return (gen.lib.Date().copy_ymd(year - _MAX_SIB_AGE_DIFF - _MAX_AGE_PROB_ALIVE), return (gen.lib.Date().copy_ymd(year - self.MAX_SIB_AGE_DIFF - self.MAX_AGE_PROB_ALIVE),
gen.lib.Date().copy_ymd(year + _MAX_SIB_AGE_DIFF)) gen.lib.Date().copy_ymd(year + self.MAX_SIB_AGE_DIFF))
# Try looking for descendants that were born more than a lifespan # Try looking for descendants that were born more than a lifespan
# ago. # ago.
@@ -291,15 +328,15 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
val = d.get_start_date() val = d.get_start_date()
val = d.get_year() - years val = d.get_year() - years
d.set_year(val) d.set_year(val)
return (d, d.copy_offset_ymd(_MAX_AGE_PROB_ALIVE)) return (d, d.copy_offset_ymd(self.MAX_AGE_PROB_ALIVE))
child_death_ref = child.get_death_ref() child_death_ref = child.get_death_ref()
if child_death_ref: if child_death_ref:
child_death = self.db.get_event_from_handle(child_death_ref.ref) child_death = self.db.get_event_from_handle(child_death_ref.ref)
dobj = child_death.get_date_object() dobj = child_death.get_date_object()
if dobj.get_start_date() != gen.lib.Date.EMPTY: if dobj.get_start_date() != gen.lib.Date.EMPTY:
return (dobj.copy_offset_ymd(- _MIN_GENERATION_YEARS), return (dobj.copy_offset_ymd(- self.MIN_GENERATION_YEARS),
dobj.copy_offset_ymd(- _MIN_GENERATION_YEARS + _MAX_AGE_PROB_ALIVE)) dobj.copy_offset_ymd(- self.MIN_GENERATION_YEARS + self.MAX_AGE_PROB_ALIVE))
date1, date2 = descendants_too_old (child, years + _MIN_GENERATION_YEARS) date1, date2 = descendants_too_old (child, years + self.MIN_GENERATION_YEARS)
if date1 and date2: if date1 and date2:
return date1, date2 return date1, date2
return (None, None) return (None, None)
@@ -309,7 +346,7 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
date1, date2 = None, None date1, date2 = None, None
try: try:
date1, date2 = descendants_too_old(person, _MIN_GENERATION_YEARS) date1, date2 = descendants_too_old(person, self.MIN_GENERATION_YEARS)
except RuntimeError: except RuntimeError:
raise Errors.DatabaseError( raise Errors.DatabaseError(
_("Database error: %s is defined as his or her own ancestor") % _("Database error: %s is defined as his or her own ancestor") %
@@ -332,16 +369,16 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
dobj = father_birth.get_date_object() dobj = father_birth.get_date_object()
if dobj.get_start_date() != gen.lib.Date.EMPTY: if dobj.get_start_date() != gen.lib.Date.EMPTY:
return (dobj.copy_offset_ymd(- year), return (dobj.copy_offset_ymd(- year),
dobj.copy_offset_ymd(- year + _MAX_AGE_PROB_ALIVE)) dobj.copy_offset_ymd(- year + self.MAX_AGE_PROB_ALIVE))
father_death_ref = father.get_death_ref() father_death_ref = father.get_death_ref()
if father_death_ref and father_death_ref.get_role() == gen.lib.EventRoleType.PRIMARY: if father_death_ref and father_death_ref.get_role() == gen.lib.EventRoleType.PRIMARY:
father_death = self.db.get_event_from_handle( father_death = self.db.get_event_from_handle(
father_death_ref.ref) father_death_ref.ref)
dobj = father_death.get_date_object() dobj = father_death.get_date_object()
if dobj.get_start_date() != gen.lib.Date.EMPTY: if dobj.get_start_date() != gen.lib.Date.EMPTY:
return (dobj.copy_offset_ymd(- year - _MAX_AGE_PROB_ALIVE), return (dobj.copy_offset_ymd(- year - self.MAX_AGE_PROB_ALIVE),
dobj.copy_offset_ymd(- year - _MAX_AGE_PROB_ALIVE + _MAX_AGE_PROB_ALIVE)) dobj.copy_offset_ymd(- year - self.MAX_AGE_PROB_ALIVE + self.MAX_AGE_PROB_ALIVE))
date1, date2 = ancestors_too_old (father, year - _AVG_GENERATION_GAP) date1, date2 = ancestors_too_old (father, year - self.AVG_GENERATION_GAP)
if date1 and date2: if date1 and date2:
return date1, date2 return date1, date2
mother_handle = family.get_mother_handle() mother_handle = family.get_mother_handle()
@@ -353,23 +390,23 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
dobj = mother_birth.get_date_object() dobj = mother_birth.get_date_object()
if dobj.get_start_date() != gen.lib.Date.EMPTY: if dobj.get_start_date() != gen.lib.Date.EMPTY:
return (dobj.copy_offset_ymd(- year), return (dobj.copy_offset_ymd(- year),
dobj.copy_offset_ymd(- year + _MAX_AGE_PROB_ALIVE)) dobj.copy_offset_ymd(- year + self.MAX_AGE_PROB_ALIVE))
mother_death_ref = mother.get_death_ref() mother_death_ref = mother.get_death_ref()
if mother_death_ref and mother_death_ref.get_role() == gen.lib.EventRoleType.PRIMARY: if mother_death_ref and mother_death_ref.get_role() == gen.lib.EventRoleType.PRIMARY:
mother_death = self.db.get_event_from_handle( mother_death = self.db.get_event_from_handle(
mother_death_ref.ref) mother_death_ref.ref)
dobj = mother_death.get_date_object() dobj = mother_death.get_date_object()
if dobj.get_start_date() != gen.lib.Date.EMPTY: if dobj.get_start_date() != gen.lib.Date.EMPTY:
return (dobj.copy_offset_ymd(- year - _MAX_AGE_PROB_ALIVE), return (dobj.copy_offset_ymd(- year - self.MAX_AGE_PROB_ALIVE),
dobj.copy_offset_ymd(- year - _MAX_AGE_PROB_ALIVE + _MAX_AGE_PROB_ALIVE)) dobj.copy_offset_ymd(- year - self.MAX_AGE_PROB_ALIVE + self.MAX_AGE_PROB_ALIVE))
date1, date2 = ancestors_too_old (mother, year - _AVG_GENERATION_GAP) date1, date2 = ancestors_too_old (mother, year - self.AVG_GENERATION_GAP)
if date1 and date2: if date1 and date2:
return (date1, date2) return (date1, date2)
return (None, None) return (None, None)
# If there are ancestors that would be too old in the current year # If there are ancestors that would be too old in the current year
# then assume our person must be dead too. # then assume our person must be dead too.
date1, date2 = ancestors_too_old (person, - _MIN_GENERATION_YEARS) date1, date2 = ancestors_too_old (person, - self.MIN_GENERATION_YEARS)
if date1 and date2: if date1 and date2:
return (date1, date2) return (date1, date2)
#print " FAIL" #print " FAIL"