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:
@@ -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
|
||||||
|
@@ -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:
|
||||||
|
@@ -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"
|
||||||
|
Reference in New Issue
Block a user