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>
* src/gen/lib/date.py: added new method copy_ymd()
* 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.window.vbox.add(self.notebook)
self.results_text = gtk.TextView()
self.setup_other_frames()
self.notebook.set_current_page(0)
self.window.show_all()
self.set_current_frame(self.initial_frame())
#------------------------------------------------------------------------
#
@ -232,6 +234,20 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
self.pre_run()
self.run() # activate results tab
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):
from Utils import ProgressMeter
@ -332,17 +348,49 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
if 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):
"""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:
flist = self.frames[key]
table = gtk.Table(3,len(flist))
table.set_col_spacings(12)
table.set_row_spacings(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)
self.notebook.append_page(table,l)
row = 0
for (text,widget) in flist:
if text:

View File

@ -36,15 +36,11 @@ import time
#
#------------------------------------------------------------------------
from PluginUtils import Tool, register_tool, PluginWindows, \
MenuToolOptions, BooleanOption, FilterListOption, StringOption
MenuToolOptions, BooleanOption, FilterListOption, StringOption, \
NumberOption
import gen.lib
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):
""" Calculate Estimated Date options """
@ -74,9 +70,41 @@ class CalcEstDateOptions(MenuToolOptions):
death.set_help(_("Add estimated death dates"))
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):
def initial_frame(self):
return _("Options")
def run(self):
self.add_results_frame()
self.results_write("Processing...\n")
self.trans = self.db.transaction_begin("",batch=True)
self.db.disable_signals()
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']
add_birth = self.options.handler.options_dict['add_birth']
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),
len(people))
for person_handle in people:
@ -127,6 +162,7 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
if pupdate == 1:
self.db.commit_person(person, self.trans)
if add_birth or add_death:
self.results_write("Calculating...\n")
self.progress.set_pass(_('Calculating estimated dates...'),
len(people))
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.enable_signals()
self.db.request_rebuild()
self.results_write("Done!\n")
def get_or_create_source(self, source_text):
source_list = self.db.get_source_handles()
@ -227,11 +264,11 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
if not birth_date and death_date:
# 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:
# 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:
return (birth_date, death_date)
@ -259,8 +296,8 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
year = dobj.get_year()
if year != 0:
# sibling birth date
return (gen.lib.Date().copy_ymd(year - _MAX_SIB_AGE_DIFF),
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),
gen.lib.Date().copy_ymd(year + self.MAX_SIB_AGE_DIFF + self.MAX_AGE_PROB_ALIVE))
child_death_ref = child.get_death_ref()
if child_death_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()
if year != 0:
# sibling death date
return (gen.lib.Date().copy_ymd(year - _MAX_SIB_AGE_DIFF - _MAX_AGE_PROB_ALIVE),
gen.lib.Date().copy_ymd(year + _MAX_SIB_AGE_DIFF))
return (gen.lib.Date().copy_ymd(year - self.MAX_SIB_AGE_DIFF - self.MAX_AGE_PROB_ALIVE),
gen.lib.Date().copy_ymd(year + self.MAX_SIB_AGE_DIFF))
# Try looking for descendants that were born more than a lifespan
# ago.
@ -291,15 +328,15 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
val = d.get_start_date()
val = d.get_year() - years
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()
if child_death_ref:
child_death = self.db.get_event_from_handle(child_death_ref.ref)
dobj = child_death.get_date_object()
if dobj.get_start_date() != gen.lib.Date.EMPTY:
return (dobj.copy_offset_ymd(- _MIN_GENERATION_YEARS),
dobj.copy_offset_ymd(- _MIN_GENERATION_YEARS + _MAX_AGE_PROB_ALIVE))
date1, date2 = descendants_too_old (child, years + _MIN_GENERATION_YEARS)
return (dobj.copy_offset_ymd(- self.MIN_GENERATION_YEARS),
dobj.copy_offset_ymd(- self.MIN_GENERATION_YEARS + self.MAX_AGE_PROB_ALIVE))
date1, date2 = descendants_too_old (child, years + self.MIN_GENERATION_YEARS)
if date1 and date2:
return date1, date2
return (None, None)
@ -309,7 +346,7 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
date1, date2 = None, None
try:
date1, date2 = descendants_too_old(person, _MIN_GENERATION_YEARS)
date1, date2 = descendants_too_old(person, self.MIN_GENERATION_YEARS)
except RuntimeError:
raise Errors.DatabaseError(
_("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()
if dobj.get_start_date() != gen.lib.Date.EMPTY:
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()
if father_death_ref and father_death_ref.get_role() == gen.lib.EventRoleType.PRIMARY:
father_death = self.db.get_event_from_handle(
father_death_ref.ref)
dobj = father_death.get_date_object()
if dobj.get_start_date() != gen.lib.Date.EMPTY:
return (dobj.copy_offset_ymd(- year - _MAX_AGE_PROB_ALIVE),
dobj.copy_offset_ymd(- year - _MAX_AGE_PROB_ALIVE + _MAX_AGE_PROB_ALIVE))
date1, date2 = ancestors_too_old (father, year - _AVG_GENERATION_GAP)
return (dobj.copy_offset_ymd(- year - self.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 - self.AVG_GENERATION_GAP)
if date1 and date2:
return date1, date2
mother_handle = family.get_mother_handle()
@ -353,23 +390,23 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
dobj = mother_birth.get_date_object()
if dobj.get_start_date() != gen.lib.Date.EMPTY:
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()
if mother_death_ref and mother_death_ref.get_role() == gen.lib.EventRoleType.PRIMARY:
mother_death = self.db.get_event_from_handle(
mother_death_ref.ref)
dobj = mother_death.get_date_object()
if dobj.get_start_date() != gen.lib.Date.EMPTY:
return (dobj.copy_offset_ymd(- year - _MAX_AGE_PROB_ALIVE),
dobj.copy_offset_ymd(- year - _MAX_AGE_PROB_ALIVE + _MAX_AGE_PROB_ALIVE))
date1, date2 = ancestors_too_old (mother, year - _AVG_GENERATION_GAP)
return (dobj.copy_offset_ymd(- year - self.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 - self.AVG_GENERATION_GAP)
if date1 and date2:
return (date1, date2)
return (None, None)
# If there are ancestors that would be too old in the current year
# 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:
return (date1, date2)
#print " FAIL"