From a303f53386a6404838b173e2666aa4a9e431eaa7 Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Tue, 4 Dec 2007 02:54:39 +0000 Subject: [PATCH] 2007-12-03 Douglas S.Blank * src/plugins/CalculateEstimatedDates.py: Refinements, use results tab * src/PluginUtils/_PluginWindows.py: Tool support for a results tab svn: r9441 --- ChangeLog | 4 ++ src/PluginUtils/_PluginWindows.py | 54 ++++++++++++++- src/plugins/CalculateEstimatedDates.py | 91 ++++++++++++++++++-------- 3 files changed, 119 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index cbfd22e0e..4155b1bce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2007-12-03 Douglas S.Blank + * src/plugins/CalculateEstimatedDates.py: Refinements, use results tab + * src/PluginUtils/_PluginWindows.py: Tool support for a results tab + 2007-12-02 Douglas S.Blank * src/gen/lib/date.py: added new method copy_ymd() * src/plugins/CalculateEstimatedDates.py: new tool based on diff --git a/src/PluginUtils/_PluginWindows.py b/src/PluginUtils/_PluginWindows.py index 9fc5ca950..742d26e41 100644 --- a/src/PluginUtils/_PluginWindows.py +++ b/src/PluginUtils/_PluginWindows.py @@ -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("%s" % _(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("%s" % _(key)) + l = gtk.Label("%s" % key) l.set_use_markup(True) self.notebook.append_page(table,l) - row = 0 for (text,widget) in flist: if text: diff --git a/src/plugins/CalculateEstimatedDates.py b/src/plugins/CalculateEstimatedDates.py index f272ad350..ba0405155 100644 --- a/src/plugins/CalculateEstimatedDates.py +++ b/src/plugins/CalculateEstimatedDates.py @@ -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"