From 1c7d6d60c5edabc052fefe689b622346e0e2d113 Mon Sep 17 00:00:00 2001 From: Alex Roitman Date: Sat, 1 Jan 2005 19:58:53 +0000 Subject: [PATCH] * src/plugins/DetAncestralReport.py: Minor cleanup. * src/plugins/DetDescendantReport.py: Convert to new scheme. * src/plugins/FamilyGroup.py: Convert to new scheme. svn: r3854 --- ChangeLog | 5 + src/plugins/DetAncestralReport.py | 20 +- src/plugins/DetDescendantReport.py | 1004 +++++++++------------------- src/plugins/FamilyGroup.py | 574 ++++++---------- 4 files changed, 519 insertions(+), 1084 deletions(-) diff --git a/ChangeLog b/ChangeLog index 71cf51e8a..a1f765317 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-01-01 Alex Roitman + * src/plugins/DetAncestralReport.py: Minor cleanup. + * src/plugins/DetDescendantReport.py: Convert to new scheme. + * src/plugins/FamilyGroup.py: Convert to new scheme. + 2004-12-31 Don Allingham * src/gramps.glade: remove name display options * src/GrampsCfg.py: remove name displaying functions diff --git a/src/plugins/DetAncestralReport.py b/src/plugins/DetAncestralReport.py index 73c43e8fc..5c1684f35 100644 --- a/src/plugins/DetAncestralReport.py +++ b/src/plugins/DetAncestralReport.py @@ -27,7 +27,6 @@ # standard python modules # #------------------------------------------------------------------------ -import os from gettext import gettext as _ #------------------------------------------------------------------------ @@ -105,11 +104,6 @@ class DetAncestorReport(Report.Report): self.genIDs = {} self.prevGenIDs= {} - #-------------------------------------------------------------------- - # - # - # - #-------------------------------------------------------------------- def apply_filter(self,person_handle,index): if (not person_handle) or (index >= 2**self.max_generations): return @@ -596,16 +590,16 @@ class DetAncestorReport(Report.Report): mother = self.database.get_person_from_handle(fam.get_mother_handle()) spouse = mother.get_primary_name().get_regular_name() if fam_num == 1: - heshe= _("He") + heshe = _("He") elif fam_num < len(famList): - heshe= _(",") - else: heshe= _("and he") + heshe = _(",") + else: heshe = _("and he") else: if fam_num == 1: - heshe= _("She") + heshe = _("She") elif fam_num < len(famList): - heshe= _(",") - else: heshe= _("and she") + heshe = _(",") + else: heshe = _("and she") if fam.get_father_handle(): father = self.database.get_person_from_handle(fam.get_father_handle()) @@ -692,7 +686,7 @@ class DetAncestorReport(Report.Report): self.doc.start_paragraph("DAR-Entry") - if self.firstName: + if not self.firstName: firstName = heshe self.doc.write_text(person) diff --git a/src/plugins/DetDescendantReport.py b/src/plugins/DetDescendantReport.py index e2574972b..342a79ac3 100644 --- a/src/plugins/DetDescendantReport.py +++ b/src/plugins/DetDescendantReport.py @@ -22,18 +22,33 @@ "Generate files/Detailed Descendant Report" -import RelLib -import os -import Errors - -from QuestionDialog import ErrorDialog +#------------------------------------------------------------------------ +# +# standard python modules +# +#------------------------------------------------------------------------ from gettext import gettext as _ +#------------------------------------------------------------------------ +# +# Gnome/GTK modules +# +#------------------------------------------------------------------------ +import gtk + +#------------------------------------------------------------------------ +# +# GRAMPS modules +# +#------------------------------------------------------------------------ +import RelLib +import Errors +from QuestionDialog import ErrorDialog import Report import BaseDoc - -import gtk -import gnome.ui +import ReportOptions +import const +from DateHandler import displayer as _dd #------------------------------------------------------------------------ # @@ -42,39 +57,54 @@ import gnome.ui #------------------------------------------------------------------------ class DetDescendantReport(Report.Report): - #-------------------------------------------------------------------- - # - # - # - #-------------------------------------------------------------------- - def __init__(self,database,person,max,pgbrk,rptOpt,doc,output,newpage=0): + def __init__(self,database,person,options_class): + """ + Creates the DetDescendantReport object that produces the report. + + The arguments are: + + database - the GRAMPS database instance + person - currently selected person + options_class - instance of the Options class for this report + + This report needs the following parameters (class variables) + that come in the options class. + + gen - Maximum number of generations to include. + pagebgg - Whether to include page breaks between generations. + firstName - Whether to use first names instead of pronouns. + fullDate - Whether to use full dates instead of just year. + listChildren - Whether to list children. + includeNotes - Whether to include notes. + blankPlace - Whether to replace missing Places with ___________. + blankDate - Whether to replace missing Dates with ___________. + calcAgeFlag - Whether to compute age. + dupPerson - Whether to omit duplicate ancestors (e.g. when distant cousins mary). + childRef - Whether to add descendant references in child list. + addImages - Whether to include images. + """ + Report.Report.__init__(self,database,person,options_class) + self.map = {} - self.database = database - self.start = person - self.max_generations = max - self.pgbrk = pgbrk - self.rptOpt = rptOpt - self.doc = doc - self.newpage = newpage + + (self.max_generations,self.pgbrk) \ + = options_class.get_report_generations() + + self.firstName = options_class.handler.options_dict['firstnameiop'] + self.fullDate = options_class.handler.options_dict['fulldates'] + self.listChildren = options_class.handler.options_dict['listc'] + self.includeNotes = options_class.handler.options_dict['incnotes'] + self.blankPlace = options_class.handler.options_dict['repplace'] + self.blankDate = options_class.handler.options_dict['repdate'] + self.calcAgeFlag = options_class.handler.options_dict['computeage'] + self.dupPerson = options_class.handler.options_dict['omitda'] + self.childRef = options_class.handler.options_dict['desref'] + self.addImages = options_class.handler.options_dict['incphotos'] + self.genIDs = {} self.prevGenIDs= {} self.genKeys = [] - if output: - self.standalone = 1 - try: - self.doc.open(output) - self.doc.init() - except IOError,msg: - ErrorDialog(_("Could not open %s") % output + "\n" + msg) - else: - self.standalone = 0 - - #-------------------------------------------------------------------- - # - # - # - #-------------------------------------------------------------------- def apply_filter(self,person_handle,index,cur_gen=1): if (not person_handle) or (cur_gen > self.max_generations): return @@ -93,7 +123,63 @@ class DetDescendantReport(Report.Report): ix = max(self.map.keys()) self.apply_filter(child_handle, ix+1, cur_gen+1) - def write_children(self, family, rptOptions): + def calcAge(self, ind): + """ Calulate age + APHRASE= + at the age of NUMBER UNIT(S) + UNIT= year | month | day + UNITS= years | months | days + null + """ + + birth_handle = ind.get_birth_handle() + if birth_handle: + birth = self.database.get_event_from_handle(birth_handle).get_date_object() + birth_year_valid = birth.get_year_valid() + else: + birth_year_valid = None + death_handle = ind.get_death_handle() + if death_handle: + death = self.database.get_event_from_handle(death_handle).get_date_object() + death_year_valid = death.get_year_valid() + else: + death_year_valid = None + + the_text = "" + if birth_year_valid and death_year_valid: + age = death.get_year() - birth.get_year() + units = 3 # year + if birth.get_month_valid() and death.get_month_valid(): + if birth.get_month() > death.get_month(): + age = age -1 + if birth.get_day_valid() and death.get_day_valid(): + if birth.get_month() == death.get_month() and birth.get_day() > death.get_day(): + age = age -1 + if age == 0: + age = death.get_month() - birth.get_month() # calc age in months + if birth.get_day() > death.get_day(): + age = age - 1 + units = 2 # month + if age == 0: + age = death.get-day() + 31 - birth.get_day() # calc age in days + units = 1 # day + if age > 1: + if units == 1: + the_text = _(" at the age of %d days") % age + elif units == 2: + the_text = _(" at the age of %d months") % age + else: + the_text = _(" at the age of %d years") % age + else: + if units == 1: + the_text = _(" at the age of %d day") % age + elif units == 2: + the_text = _(" at the age of %d month") % age + else: + the_text = _(" at the age of %d year") % age + return the_text + + def write_children(self, family): """ List children Statement formats: Child of MOTHER and FATHER is: @@ -144,7 +230,7 @@ class DetDescendantReport(Report.Report): name = child.get_primary_name().get_regular_name() birth_handle = child.get_birth_handle() death_handle = child.get_death_handle() - if rptOptions.childRef == reportOptions.Yes: + if self.childRef: if self.prevGenIDs.get(child_handle) != None: name= "[" + str(self.prevGenIDs.get(child_handle)) + "] "+ name @@ -232,19 +318,19 @@ class DetDescendantReport(Report.Report): self.doc.end_paragraph() - def write_person(self, key, rptOptions): + def write_person(self, key): """Output birth, death, parentage, marriage and notes information """ person_handle = self.map[key] person = self.database.get_person_from_handle(person_handle) - if rptOptions.addImages == reportOptions.Yes: + if self.addImages: self.insert_images(person) self.doc.start_paragraph("DDR-First-Entry","%s." % str(key)) name = person.get_primary_name().get_regular_name() - if rptOptions.firstName == reportOptions.Yes: + if self.firstName: firstName = person.get_primary_name().get_first_name() elif person.get_gender() == RelLib.Person.male: firstName = _("He") @@ -255,7 +341,7 @@ class DetDescendantReport(Report.Report): self.doc.write_text(name) self.doc.end_bold() - if rptOptions.dupPersons == reportOptions.Yes: + if self.dupPerson: # Check for duplicate record (result of distant cousins marrying) keys = self.map.keys() keys.sort() @@ -270,15 +356,15 @@ class DetDescendantReport(Report.Report): # Check birth record birth_handle = person.get_birth_handle() if birth_handle: - self.write_birth(person, rptOptions) - self.write_death(person, firstName, rptOptions) + self.write_birth(person) + self.write_death(person, firstName) self.write_parents(person, firstName) - self.write_marriage(person, rptOptions) + self.write_marriage(person) self.doc.end_paragraph() - self.write_mate(person, rptOptions) + self.write_mate(person) - if person.get_note() and rptOptions.includeNotes == reportOptions.Yes: + if person.get_note() and self.includeNotes: self.doc.start_paragraph("DDR-NoteHeader") self.doc.start_bold() self.doc.write_text(_("Notes for %s" % name)) @@ -288,7 +374,7 @@ class DetDescendantReport(Report.Report): return 0 # Not duplicate person - def write_birth(self, person, rptOptions): + def write_birth(self, person): """ Check birth record Statement formats name precedes this was born on DATE. @@ -310,14 +396,14 @@ class DetDescendantReport(Report.Report): place = self.database.get_place_from_handle(birth.get_place_handle()).get_title() if place[-1:] == '.': place = place[:-1] - elif rptOptions.blankDate == reportOptions.Yes: + elif self.blankDate: place = "______________" else: place = "" if date_txt: if date_obj.get_day_valid() and date_obj.get_month_valid() and \ - rptOptions.fullDate == reportOptions.Yes: + self.fullDate: if place: self.doc.write_text(_(" was born on %s in %s.") % (date_txt, place)) else: @@ -332,7 +418,7 @@ class DetDescendantReport(Report.Report): else: self.doc.write_text(_(".")) - def write_death(self, person, firstName, rptOptions): + def write_death(self, person, firstName): """ Write obit sentence Statement format: DPHRASE APHRASE BPHRASE DPHRASE= @@ -368,20 +454,20 @@ class DetDescendantReport(Report.Report): place = self.database.get_place_from_handle(place_handle).get_title() if place[-1:] == '.': place = place[:-1] - elif rptOptions.blankPlace == reportOptions.Yes: + elif self.blankPlace: place = "_____________" else: place = "" if date_txt: if date_obj.get_day() and date_obj.get_month() and \ - rptOptions.fullDate == reportOptions.Yes: + self.fullDate: fulldate = date_txt - elif date_obj.get_month() and rptOptions.fullDate == reportOptions.Yes: + elif date_obj.get_month() and self.fullDate: fulldate = "%s %s" % (date_obj.get_month(), date_obj.get_year()) else: fulldate = "" - elif rptOptions.blankDate == reportOptions.Yes: + elif self.blankDate: fulldate = "_____________" else: fulldate = "" @@ -399,8 +485,8 @@ class DetDescendantReport(Report.Report): elif place: t = _(" %s died in %s") % (firstName, place) - if rptOptions.calcAgeFlag == reportOptions.Yes: - t = t + rptOptions.calcAge(person) + if self.calcAgeFlag: + t = t + self.calcAge(person) if t: self.doc.write_text(t) @@ -420,9 +506,9 @@ class DetDescendantReport(Report.Report): fulldate= "" if date_txt: if date_obj.get_day_valid() and date_obj.get_month_valid() and \ - rptOptions.fullDate == reportOptions.Yes: - fulldate= date_txt - elif rptOptions.blankDate == reportOptions.Yes: + self.fullDate: + fulldate = date_txt + elif self.blankDate: fulldate= "___________" if fulldate and place: @@ -487,7 +573,7 @@ class DetDescendantReport(Report.Report): (firstName, mother)) - def write_marriage(self, person, rptOptions): + def write_marriage(self, person): """ Output marriage sentence HE/SHE married SPOUSE on FULLDATE in PLACE. HE/SHE married SPOUSE on FULLDATE. @@ -537,16 +623,16 @@ class DetDescendantReport(Report.Report): if marriage: if marriage.get_place_handle(): place = self.database.get_place_from_handle(marriage.get_place_handle()).get_title() - elif rptOptions.blankPlace == reportOptions.Yes: + elif self.blankPlace: place= "____________" date_obj = marriage.get_date_object() if date_obj: if date_obj.get_year_valid(): if date_obj.get_day_valid() and date_obj.get_month_valid() and \ - rptOptions.fullDate == reportOptions.Yes: + self.fullDate: fulldate = marriage.get_date() - elif rptOptions.blankDate == reportOptions.Yes: + elif self.blankDate: fulldate = "__________" if spouse: @@ -575,7 +661,7 @@ class DetDescendantReport(Report.Report): if fam_num == len(famList): self.doc.write_text(".") - def write_mate(self, person, rptOptions): + def write_mate(self, person): """Output birth, death, parentage, marriage and notes information """ for fam_id in person.get_family_handle_list(): @@ -597,23 +683,20 @@ class DetDescendantReport(Report.Report): mateFirstName = mate.get_primary_name().get_first_name() if mate: - if rptOptions.addImages == reportOptions.Yes: + if self.addImages: self.insert_images(mate) self.doc.start_paragraph("DDR-Entry") - if rptOptions.firstName == reportOptions.No: + if not self.firstName: mateFirstName = heshe self.doc.write_text(mateName) - self.write_birth(mate, rptOptions) - self.write_death(mate, mateFirstName, rptOptions) + self.write_birth(mate) + self.write_death(mate, mateFirstName) self.write_parents(mate, mateFirstName) self.doc.end_paragraph() - #if rptOptions.listChildren == reportOptions.Yes \ - # and mate.get_gender() == RelLib.Person.male: - # self.write_children(fam, rptOptions) #-------------------------------------------------------------------- # @@ -636,22 +719,17 @@ class DetDescendantReport(Report.Report): # #-------------------------------------------------------------------- def write_report(self): - if self.newpage: - self.doc.page_break() - - rptOpt = self.rptOpt - self.cur_gen= 1 - self.apply_filter(self.start.get_handle(),1) + self.apply_filter(self.start_person.get_handle(),1) - name = self.start.get_primary_name().get_regular_name() + name = self.start_person.get_primary_name().get_regular_name() - famList = self.start.get_family_handle_list() + famList = self.start_person.get_family_handle_list() spouseName= "" if len(famList): for fam_id in famList: fam = self.database.get_family_from_handle(fam_id) - if self.start.get_gender() == RelLib.Person.male: + if self.start_person.get_gender() == RelLib.Person.male: mother_handle = fam.get_mother_handle() if mother_handle: spouseName = self.database.get_person_from_handle(mother_handle).get_primary_name().get_first_name() @@ -680,7 +758,7 @@ class DetDescendantReport(Report.Report): t = _("%s Generation") % DetDescendantReport.gen[generation+1] self.doc.write_text(t) self.doc.end_paragraph() - if rptOpt.childRef == reportOptions.Yes: + if self.childRef: self.prevGenIDs= self.genIDs.copy() self.genIDs.clear() @@ -689,684 +767,226 @@ class DetDescendantReport(Report.Report): person_handle = self.map[key] person = self.database.get_person_from_handle(person_handle) self.genIDs[person_handle]= key - dupPerson= self.write_person(key, rptOpt) + dupPerson= self.write_person(key) if dupPerson == 0: # Is this a duplicate ind record - if rptOpt.listChildren == reportOptions.Yes and \ + if self.listChildren and \ len(person.get_family_handle_list()) > 0: family_handle = person.get_family_handle_list()[0] family = self.database.get_family_from_handle(family_handle) - self.write_children(family, rptOpt) - - #if rptOpt.addImages == reportOptions.Yes: - # self.append_images(person) - - if self.standalone: - self.doc.close() + self.write_children(family) #------------------------------------------------------------------------ # # # #------------------------------------------------------------------------ -def _make_default_style(default_style): - """Make the default output style for the Detailed Descendant Report""" - font = BaseDoc.FontStyle() - font.set(face=BaseDoc.FONT_SANS_SERIF,size=16,bold=1) - para = BaseDoc.ParagraphStyle() - para.set_font(font) - para.set_header_level(1) - para.set(pad=0.5) - para.set_description(_('The style used for the title of the page.')) - default_style.add_style("DDR-Title",para) +class DetDescendantOptions(ReportOptions.ReportOptions): - font = BaseDoc.FontStyle() - font.set(face=BaseDoc.FONT_SANS_SERIF,size=14,italic=1) - para = BaseDoc.ParagraphStyle() - para.set_font(font) - para.set_header_level(2) - para.set(pad=0.5) - para.set_description(_('The style used for the generation header.')) - default_style.add_style("DDR-Generation",para) + """ + Defines options and provides handling interface. + """ - font = BaseDoc.FontStyle() - font.set(face=BaseDoc.FONT_SANS_SERIF,size=10,italic=0, bold=0) - para = BaseDoc.ParagraphStyle() - para.set_font(font) - #para.set_header_level(3) - para.set_left_margin(1.0) # in centimeters - para.set(pad=0.5) - para.set_description(_('The style used for the children list title.')) - default_style.add_style("DDR-ChildTitle",para) + def __init__(self,name,person_id=None): + ReportOptions.ReportOptions.__init__(self,name,person_id) - font = BaseDoc.FontStyle() - font.set(face=BaseDoc.FONT_SANS_SERIF,size=9) - para = BaseDoc.ParagraphStyle() - para.set_font(font) - para.set(first_indent=0.0,lmargin=1.0,pad=0.25) - para.set_description(_('The style used for the children list.')) - default_style.add_style("DDR-ChildList",para) + def set_new_options(self): + # Options specific for this report + self.options_dict = { + 'firstnameiop' : 0, + 'fulldates' : 1, + 'listc' : 1, + 'incnotes' : 1, + 'repplace' : 0, + 'repdate' : 0, + 'computeage' : 1, + 'omitda' : 1, + 'desref' : 1, + 'incphotos' : 0, + } + self.options_help = { + 'firstnameiop' : ("=0/1","Whether to use first names instead of pronouns", + ["Do not use first names","Use first names"], + True), + 'fulldates' : ("=0/1","Whether to use full dates instead of just year.", + ["Do not use full dates","Use full dates"], + True), + 'listc' : ("=0/1","Whether to list children.", + ["Do not list children","List children"], + True), + 'incnotes' : ("=0/1","Whether to include notes.", + ["Do not include notes","Include notes"], + True), + 'repplace' : ("=0/1","Whether to replace missing Places with blanks.", + ["Do not replace missing Places","Replace missing Places"], + True), + 'repdate' : ("=0/1","Whether to replace missing Dates with blanks.", + ["Do not replace missing Dates","Replace missing Dates"], + True), + 'computeage' : ("=0/1","Whether to compute age.", + ["Do not compute age","Compute age"], + True), + 'omitda' : ("=0/1","Whether to omit duplicate ancestors.", + ["Do not omit duplicates","Omit duplicates"], + True), + 'desref' : ("=0/1","Whether to add descendant references in child list.", + ["Do not add references","Add references"], + True), + 'incphotos' : ("=0/1","Whether to include images.", + ["Do not include images","Include images"], + True), + } - para = BaseDoc.ParagraphStyle() - para.set(first_indent=0.0,lmargin=1.0,pad=0.25) - para.set_description(_('The style used for the notes section header.')) - default_style.add_style("DDR-NoteHeader",para) + def enable_options(self): + # Semi-common options that should be enabled for this report + self.enable_dict = { + 'gen' : 10, + 'pagebbg' : 0, + } - para = BaseDoc.ParagraphStyle() - para.set(first_indent=0.5,lmargin=0.0,pad=0.25) - default_style.add_style("DDR-Entry",para) + def make_default_style(self,default_style): + """Make the default output style for the Detailed Descendant Report""" + font = BaseDoc.FontStyle() + font.set(face=BaseDoc.FONT_SANS_SERIF,size=16,bold=1) + para = BaseDoc.ParagraphStyle() + para.set_font(font) + para.set_header_level(1) + para.set(pad=0.5) + para.set_description(_('The style used for the title of the page.')) + default_style.add_style("DDR-Title",para) - para = BaseDoc.ParagraphStyle() - para.set(first_indent=-1.0,lmargin=1.0,pad=0.25) - para.set_description(_('The style used for the first personal entry.')) - default_style.add_style("DDR-First-Entry",para) + font = BaseDoc.FontStyle() + font.set(face=BaseDoc.FONT_SANS_SERIF,size=14,italic=1) + para = BaseDoc.ParagraphStyle() + para.set_font(font) + para.set_header_level(2) + para.set(pad=0.5) + para.set_description(_('The style used for the generation header.')) + default_style.add_style("DDR-Generation",para) -#------------------------------------------------------------------------ -# -# -# -#------------------------------------------------------------------------ -class DetDescendantReportDialog(Report.TextReportDialog): + font = BaseDoc.FontStyle() + font.set(face=BaseDoc.FONT_SANS_SERIF,size=10,italic=0, bold=0) + para = BaseDoc.ParagraphStyle() + para.set_font(font) + #para.set_header_level(3) + para.set_left_margin(1.0) # in centimeters + para.set(pad=0.5) + para.set_description(_('The style used for the children list title.')) + default_style.add_style("DDR-ChildTitle",para) - report_options = {} + font = BaseDoc.FontStyle() + font.set(face=BaseDoc.FONT_SANS_SERIF,size=9) + para = BaseDoc.ParagraphStyle() + para.set_font(font) + para.set(first_indent=0.0,lmargin=1.0,pad=0.25) + para.set_description(_('The style used for the children list.')) + default_style.add_style("DDR-ChildList",para) - def __init__(self,database,person): - Report.TextReportDialog.__init__(self,database,person,self.report_options) - self.database = database + para = BaseDoc.ParagraphStyle() + para.set(first_indent=0.0,lmargin=1.0,pad=0.25) + para.set_description(_('The style used for the notes section header.')) + default_style.add_style("DDR-NoteHeader",para) - #------------------------------------------------------------------------ - # - # Customization hooks - # - #------------------------------------------------------------------------ - def get_title(self): - """The window title for this dialog""" - return _("Gramps - Ahnentafel Report") + para = BaseDoc.ParagraphStyle() + para.set(first_indent=0.5,lmargin=0.0,pad=0.25) + default_style.add_style("DDR-Entry",para) - def get_header(self, name): - """The header line at the top of the dialog contents""" - return _("Detailed Descendant Report for %s") % name + para = BaseDoc.ParagraphStyle() + para.set(first_indent=-1.0,lmargin=1.0,pad=0.25) + para.set_description(_('The style used for the first personal entry.')) + default_style.add_style("DDR-First-Entry",para) - def get_target_browser_title(self): - """The title of the window created when the 'browse' button is - clicked in the 'Save As' frame.""" - return _("Save Descendant Report") - - def get_stylesheet_savefile(self): - """Where to save styles for this report.""" - return "det_descendant_report.xml" - - #------------------------------------------------------------------------ - # - # Create output styles appropriate to this report. - # - #------------------------------------------------------------------------ - def make_default_style(self): - _make_default_style(self.default_style) - - #------------------------------------------------------------------------ - # - # Create the contents of the report. - # - #------------------------------------------------------------------------ - def make_report(self): - """Create the object that will produce the Detailed Descendant - Report. All user dialog has already been handled and the - output file opened.""" - - try: - MyReport = DetDescendantReport(self.db, self.person, - self.max_gen, self.pg_brk, self.rptOpt, self.doc, self.target_path ) - MyReport.write_report() - except Errors.ReportError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except Errors.FilterError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except: - import DisplayTrace - DisplayTrace.DisplayTrace() - -#*** Begin change - def add_user_options(self): - # Create a GTK Checkbox widgets + def add_user_options(self,dialog): + """ + Override the base class add_user_options task to add a menu that allows + the user to select the sort method. + """ # Pronoun instead of first name self.first_name_option = gtk.CheckButton(_("Use first names instead of pronouns")) - self.first_name_option.set_active(0) + self.first_name_option.set_active(self.options_dict['firstnameiop']) # Full date usage self.full_date_option = gtk.CheckButton(_("Use full dates instead of only the year")) - self.full_date_option.set_active(1) + self.full_date_option.set_active(self.options_dict['fulldates']) # Children List self.list_children_option = gtk.CheckButton(_("List children")) - self.list_children_option.set_active(1) + self.list_children_option.set_active(self.options_dict['listc']) # Print notes self.include_notes_option = gtk.CheckButton(_("Include notes")) - self.include_notes_option.set_active(1) + self.include_notes_option.set_active(self.options_dict['incnotes']) # Replace missing Place with ___________ self.place_option = gtk.CheckButton(_("Replace Place with ______")) - self.place_option.set_active(0) + self.place_option.set_active(self.options_dict['repplace']) # Replace missing dates with __________ self.date_option = gtk.CheckButton(_("Replace Dates with ______")) - self.date_option.set_active(0) + self.date_option.set_active(self.options_dict['repdate']) # Add "Died at the age of NN" in text self.age_option = gtk.CheckButton(_("Compute age")) - self.age_option.set_active(1) - - # Omit duplicate persons, occurs when distant cousins marry - self.dupPersons_option = gtk.CheckButton(_("Omit duplicate people")) - self.dupPersons_option.set_active(1) - - #Add descendant reference in child list - self.childRef_option = gtk.CheckButton(_("Add descendant reference in child list")) - self.childRef_option.set_active(1) - - #Add photo/image reference - self.image_option = gtk.CheckButton(_("Include Photo/Images from Gallery")) - self.image_option.set_active(0) - - # Add new options. The first argument is the tab name for grouping options. - # if you want to put everyting in the generic "Options" category, use - # self.add_option(text,widget) instead of self.add_frame_option(category,text,widget) - - self.add_frame_option('Content','',self.first_name_option) - self.add_frame_option('Content','',self.full_date_option) - self.add_frame_option('Content','',self.list_children_option) - self.add_frame_option('Content','',self.include_notes_option) - self.add_frame_option('Content','',self.place_option) - self.add_frame_option('Content','',self.date_option) - self.add_frame_option('Content','',self.age_option) - self.add_frame_option('Content','',self.dupPersons_option) - self.add_frame_option('Content','',self.childRef_option) - self.add_frame_option('Content','',self.image_option) - - - def parse_report_options_frame(self): - """Parse the report options frame of the dialog. Save the user selected choices for later use.""" - - # call the parent task to handle normal options - Report.ReportDialog.parse_report_options_frame(self) - - # get values from the widgets - if self.first_name_option.get_active(): - self.firstName = reportOptions.Yes - else: - self.firstName = reportOptions.No - - if self.full_date_option.get_active(): - self.fullDate = reportOptions.Yes - else: - self.fullDate = reportOptions.No - - if self.list_children_option.get_active(): - self.listChildren = reportOptions.Yes - else: - self.listChildren = reportOptions.No - - if self.include_notes_option.get_active(): - self.includeNotes = reportOptions.Yes - else: - self.includeNotes = reportOptions.No - - if self.place_option.get_active(): - self.blankPlace = reportOptions.Yes - else: - self.blankPlace = reportOptions.No - - if self.date_option.get_active(): - self.blankDate = reportOptions.Yes - else: - self.blankDate = reportOptions.No - - if self.age_option.get_active(): - self.calcAgeFlag = reportOptions.Yes - else: - self.calcAgeFlag = reportOptions.No - - if self.dupPersons_option.get_active(): - self.dupPersons = reportOptions.Yes - else: - self.dupPersons = reportOptions.No - - if self.childRef_option.get_active(): - self.childRef = reportOptions.Yes - else: - self.childRef = reportOptions.No - - if self.image_option.get_active(): - self.addImages = reportOptions.Yes - else: - self.addImages = reportOptions.No - - rptOpt = reportOptions(self.database) - rptOpt.firstName= self.firstName - rptOpt.fullDate= self.fullDate - rptOpt.listChildren= self.listChildren - rptOpt.includeNotes= self.includeNotes - rptOpt.blankPlace= self.blankPlace - rptOpt.blankDate= self.blankDate - rptOpt.calcAgeFlag= self.calcAgeFlag - rptOpt.dupPersons= self.dupPersons - rptOpt.childRef= self.childRef - rptOpt.addImages= self.addImages - self.rptOpt = rptOpt - -#*** End of change - - -#------------------------------------------------------------------------ -# -# Standalone report function -# -#------------------------------------------------------------------------ -def report(database,person): - DetDescendantReportDialog(database,person) - -#------------------------------------------------------------------------ -# -# Set up sane defaults for the book_item -# -#------------------------------------------------------------------------ -_style_file = "det_descendant_report.xml" -_style_name = "default" - -_person_handle = "" -_max_gen = 10 -_pg_brk = 0 -_first_name = 0 -_full_date = 1 -_list_children = 1 -_include_notes = 1 -_place = 0 -_date = 1 -_age = 1 -_dup_persons = 1 -_child_ref = 1 -_images = 0 - -_options = ( _person_handle, _max_gen, _pg_brk, - _first_name, _full_date, _list_children, _include_notes, - _place, _date, _age, _dup_persons, _child_ref, _images ) - -#------------------------------------------------------------------------ -# -# Book Item Options dialog -# -#------------------------------------------------------------------------ -class DetDescendantBareReportDialog(Report.BareReportDialog): - def __init__(self,database,person,opt,stl): - self.options = opt - self.db = database - if self.options[0]: - self.person = self.db.get_person_from_handle(self.options[0]) - else: - self.person = person - - self.max_gen = int(self.options[1]) - self.pg_brk = int(self.options[2]) - self.first_name = int(self.options[3]) - self.full_date = int(self.options[4]) - self.list_children = int(self.options[5]) - self.include_notes = int(self.options[6]) - self.place = int(self.options[7]) - self.date = int(self.options[8]) - self.age = int(self.options[9]) - self.dup_persons = int(self.options[10]) - self.child_ref = int(self.options[11]) - self.images = int(self.options[12]) - - self.style_name = stl - - Report.BareReportDialog.__init__(self,database,self.person) - - self.new_person = None - - self.window.run() - - #------------------------------------------------------------------------ - # - # Customization hooks - # - #------------------------------------------------------------------------ - def make_default_style(self): - _make_default_style(self.default_style) - - def get_title(self): - """The window title for this dialog""" - return "%s - GRAMPS Book" % (_("Detailed Descendant Report")) - - def get_header(self, name): - """The header line at the top of the dialog contents""" - return _("Detailed Descendant Report for GRAMPS Book") - - def get_stylesheet_savefile(self): - """Where to save styles for this report.""" - return _style_file - - def add_user_options(self): - # Create a GTK Checkbox widgets - - # Pronoun instead of first name - self.first_name_option = gtk.CheckButton(_("Use first names instead of pronouns")) - self.first_name_option.set_active(self.first_name) - - # Full date usage - self.full_date_option = gtk.CheckButton(_("Use full dates instead of only the year")) - self.full_date_option.set_active(self.full_date) - - # Children List - self.list_children_option = gtk.CheckButton(_("List children")) - self.list_children_option.set_active(self.list_children) - - # Print notes - self.include_notes_option = gtk.CheckButton(_("Include notes")) - self.include_notes_option.set_active(self.include_notes) - - # Replace missing Place with ___________ - self.place_option = gtk.CheckButton(_("Replace Place with ______")) - self.place_option.set_active(self.place) - - # Replace missing dates with __________ - self.date_option = gtk.CheckButton(_("Replace Dates with ______")) - self.date_option.set_active(self.date) - - # Add "Died at the age of NN" in text - self.age_option = gtk.CheckButton(_("Compute age")) - self.age_option.set_active(self.age) + self.age_option.set_active(self.options_dict['computeage']) # Omit duplicate persons, occurs when distant cousins marry self.dupPersons_option = gtk.CheckButton(_("Omit duplicate ancestors")) - self.dupPersons_option.set_active(self.dup_persons) + self.dupPersons_option.set_active(self.options_dict['omitda']) #Add descendant reference in child list self.childRef_option = gtk.CheckButton(_("Add descendant reference in child list")) - self.childRef_option.set_active(self.child_ref) + self.childRef_option.set_active(self.options_dict['desref']) #Add photo/image reference self.image_option = gtk.CheckButton(_("Include Photo/Images from Gallery")) - self.image_option.set_active(self.images) + self.image_option.set_active(self.options_dict['incphotos']) # Add new options. The first argument is the tab name for grouping options. # if you want to put everyting in the generic "Options" category, use # self.add_option(text,widget) instead of self.add_frame_option(category,text,widget) - self.add_frame_option('Content','',self.first_name_option) - self.add_frame_option('Content','',self.full_date_option) - self.add_frame_option('Content','',self.list_children_option) - self.add_frame_option('Content','',self.include_notes_option) - self.add_frame_option('Content','',self.place_option) - self.add_frame_option('Content','',self.date_option) - self.add_frame_option('Content','',self.age_option) - self.add_frame_option('Content','',self.dupPersons_option) - self.add_frame_option('Content','',self.childRef_option) - self.add_frame_option('Content','',self.image_option) + dialog.add_frame_option(_('Content'),'',self.first_name_option) + dialog.add_frame_option(_('Content'),'',self.full_date_option) + dialog.add_frame_option(_('Content'),'',self.list_children_option) + dialog.add_frame_option(_('Content'),'',self.include_notes_option) + dialog.add_frame_option(_('Content'),'',self.place_option) + dialog.add_frame_option(_('Content'),'',self.date_option) + dialog.add_frame_option(_('Content'),'',self.age_option) + dialog.add_frame_option(_('Content'),'',self.dupPersons_option) + dialog.add_frame_option(_('Content'),'',self.childRef_option) + dialog.add_frame_option(_('Content'),'',self.image_option) - def parse_report_options_frame(self): - """Parse the report options frame of the dialog. Save the user selected choices for later use.""" + def parse_user_options(self,dialog): + """ + Parses the custom options that we have added. + """ - # call the parent task to handle normal options - Report.BareReportDialog.parse_report_options_frame(self) - - # get values from the widgets - if self.first_name_option.get_active(): - self.first_name = reportOptions.Yes - else: - self.first_name = reportOptions.No - - if self.full_date_option.get_active(): - self.full_date = reportOptions.Yes - else: - self.full_date = reportOptions.No - - if self.list_children_option.get_active(): - self.list_children = reportOptions.Yes - else: - self.list_children = reportOptions.No - - if self.include_notes_option.get_active(): - self.include_notes = reportOptions.Yes - else: - self.include_notes = reportOptions.No - - if self.place_option.get_active(): - self.place = reportOptions.Yes - else: - self.place = reportOptions.No - - if self.date_option.get_active(): - self.date = reportOptions.Yes - else: - self.date = reportOptions.No - - if self.age_option.get_active(): - self.age = reportOptions.Yes - else: - self.age = reportOptions.No - - if self.dupPersons_option.get_active(): - self.dup_persons = reportOptions.Yes - else: - self.dup_persons = reportOptions.No - - if self.childRef_option.get_active(): - self.child_ref = reportOptions.Yes - else: - self.child_ref = reportOptions.No - - if self.image_option.get_active(): - self.images = reportOptions.Yes - else: - self.images = reportOptions.No - - def on_cancel(self, obj): - pass - - def on_ok_clicked(self, obj): - """The user is satisfied with the dialog choices. Parse all options - and close the window.""" - - # Preparation - self.parse_style_frame() - self.parse_report_options_frame() - - if self.new_person: - self.person = self.new_person - self.options = ( self.person.get_handle(), self.max_gen, self.pg_brk, - self.first_name, self.full_date, self.list_children, - self.include_notes, self.place, self.date, self.age, - self.dup_persons, self.child_ref, self.images ) - self.style_name = self.selected_style.get_name() - -#------------------------------------------------------------------------ -# -# Function to write Book Item -# -#------------------------------------------------------------------------ -def write_book_item(database,person,doc,options,newpage=0): - """Write the Detailed Descendant Report using options set. - All user dialog has already been handled and the output file opened.""" - try: - if options[0]: - person = database.get_person_from_handle(options[0]) - max_gen = int(options[1]) - pg_brk = int(options[2]) - rptOpt = reportOptions(database) - rptOpt.firstName = int(options[3]) - rptOpt.fullDate = int(options[4]) - rptOpt.listChildren = int(options[5]) - rptOpt.includeNotes = int(options[6]) - rptOpt.blankPlace = int(options[7]) - rptOpt.blankDate = int(options[8]) - rptOpt.calcAgeFlag = int(options[9]) - rptOpt.dupPersons = int(options[10]) - rptOpt.childRef = int(options[11]) - rptOpt.addImages = int(options[12]) - return DetDescendantReport(database, person, - max_gen, pg_brk, rptOpt, doc, None, newpage) - except Errors.ReportError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except Errors.FilterError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except: - import DisplayTrace - DisplayTrace.DisplayTrace() + self.options_dict['firstnameiop'] = int(self.first_name_option.get_active()) + self.options_dict['fulldates'] = int(self.full_date_option.get_active()) + self.options_dict['listc'] = int(self.list_children_option.get_active()) + self.options_dict['incnotes'] = int(self.include_notes_option.get_active()) + self.options_dict['repplace'] = int(self.place_option.get_active()) + self.options_dict['repdate'] = int(self.date_option.get_active()) + self.options_dict['computeage'] = int(self.age_option.get_active()) + self.options_dict['omitda'] = int(self.dupPersons_option.get_active()) + self.options_dict['desref'] = int(self.childRef_option.get_active()) + self.options_dict['incphotos'] = int(self.image_option.get_active()) #------------------------------------------------------------------------ # # # #------------------------------------------------------------------------ -from Plugins import register_report, register_book_item - +from Plugins import register_report register_report( - report, - _("Detailed Descendant Report"), + name = 'det_descendant_report', + category = const.CATEGORY_TEXT, + report_class = DetDescendantReport, + options_class = DetDescendantOptions, + modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI, + translated_name = _("Detailed Descendant Report"), status=(_("Beta")), - category=_("Text Reports"), description= _("Produces a detailed descendant report"), author_name="Bruce DeGrasse", author_email="bdegrasse1@attbi.com" ) - -# (name,category,options_dialog,write_book_item,options,style_name,style_file,make_default_style) -register_book_item( - _("Detailed Descendant Report"), - _("Text"), - DetDescendantBareReportDialog, - write_book_item, - _options, - _style_name, - _style_file, - _make_default_style - ) - -#------------------------------------------------------------------------ -# -# -# -#------------------------------------------------------------------------ -class reportOptions: - Yes=1 - No= 0 - Left= 2 - Right= 3 - - def __init__(self,database): - self.database = database - ### Initialize report options### - - #Use first name in place of he or she in text - self.firstName= reportOptions.Yes - - #Use year only, not full date/month - self.fullDate= reportOptions.Yes - - #Do not list children - self.listChildren= reportOptions.Yes - - #Add stepchildren to the list of children - #self.addStepChildren= reportOptions.Yes - - #Print notes - self.includeNotes= reportOptions.No - - #Selectively print notes (omit private information) - #self.omitPrivInfo= reportOptions.No - - #generate header for each page, specify text - #self.noHeader= reportOptions.Yes - - #Inculde reference notes - self.noRefNotes= reportOptions.No - - #Replace missing Place with ___________ - self.blankPlace= reportOptions.No - - #Replace missing dates with __________ - self.blankDate= reportOptions.No - - #Omit country code - #self.noCountryInfo= reportOptions.No - - #Put title before or after name (Dr., Lt., etc.) - #self.titleAfter= reportOptions.Yes - - #Add "Died at the age of NN" in text - self.calcAgeFlag= reportOptions.Yes - - #Add Photos and Images to report - self.addImages= reportOptions.No - #self.imageAttrTag= "DetDescendantReport" - - #Omit sensitive information such as birth, christening, marriage - # for living after XXXXX date. - - #Omit duplicate persons, occurs when distant cousins marry - self.dupPersons= reportOptions.Yes - - #Add descendant reference in child list - self.childRef= reportOptions.Yes - - def calcAge(self, ind): - """ Calulate age - APHRASE= - at the age of NUMBER UNIT(S) - UNIT= year | month | day - UNITS= years | months | days - null - """ - - birth_handle = ind.get_birth_handle() - if birth_handle: - birth = self.database.get_event_from_handle(birth_handle).get_date_object() - birth_year_valid = birth.get_year_valid() - else: - birth_year_valid = None - death_handle = ind.get_death_handle() - if death_handle: - death = self.database.get_event_from_handle(death_handle).get_date_object() - death_year_valid = death.get_year_valid() - else: - death_year_valid = None - - self.t= "" - if birth_year_valid and death_year_valid: - self.age = death.get_year() - birth.get_year() - self.units= 3 # year - if birth.get_month_valid() and death.get_month_valid(): - if birth.get_month() > death.get_month(): - self.age = self.age -1 - if birth.get_day_valid() and death.get_day_valid(): - if birth.get_month() == death.get_month() and birth.get_day() > death.get_day(): - self.age = self.age -1 - if self.age == 0: - self.age = death.get_month() - birth.get_month() # calc age in months - if birth.get_day() > death.get_day(): - self.age = self.age - 1 - self.units= 2 # month - if self.age == 0: - self.age = death.get-day() + 31 - birth.get_day() # calc age in days - self.units = 1 # day - if self.age > 1: - if self.units == 1: - self.t= _(" at the age of %d days") % self.age - elif self.units == 2: - self.t= _(" at the age of %d months") % self.age - else: - self.t= _(" at the age of %d years") % self.age - else: - if self.units == 1: - self.t= _(" at the age of %d day") % self.age - elif self.units == 2: - self.t= _(" at the age of %d month") % self.age - else: - self.t= _(" at the age of %d year") % self.age - return self.t diff --git a/src/plugins/FamilyGroup.py b/src/plugins/FamilyGroup.py index fac512652..68ffb3495 100644 --- a/src/plugins/FamilyGroup.py +++ b/src/plugins/FamilyGroup.py @@ -27,9 +27,15 @@ # python modules # #------------------------------------------------------------------------ -import os +from gettext import gettext as _ +#------------------------------------------------------------------------ +# +# Gnome/GTK modules +# +#------------------------------------------------------------------------ import gtk + #------------------------------------------------------------------------ # # GRAMPS @@ -40,33 +46,57 @@ import Report import BaseDoc import Errors import Utils -from gettext import gettext as _ from QuestionDialog import ErrorDialog +import ReportOptions +import const +from DateHandler import displayer as _dd #------------------------------------------------------------------------ # # FamilyGroup # #------------------------------------------------------------------------ -class FamilyGroup: +class FamilyGroup(Report.Report): - def __init__(self,database,family_handle,doc,output,newpage=0): - self.db = database + def __init__(self,database,person,options_class): + #,family_handle,doc,output,newpage=0): + """ + Creates the DetAncestorReport object that produces the report. - if family_handle: - self.family = self.db.get_family_from_handle(family_handle) + The arguments are: + + database - the GRAMPS database instance + person - currently selected person + options_class - instance of the Options class for this report + + This report needs the following parameters (class variables) + that come in the options class. + + family_handle - Handle of the family to write report on. + """ + Report.Report.__init__(self,database,person,options_class) + + spouse_id = options_class.handler.options_dict['spouse_id'] + if spouse_id: + family_list = person.get_family_handle_list() + for family_handle in family_list: + family = database.get_family_from_handle(family_handle) + if person.get_handle() == family.get_father_handle(): + this_spouse_id = family.get_mother_handle() + else: + this_spouse_id = family.get_father_handle() + if spouse_id == this_spouse_id: + self.family = family + break else: self.family = None - self.output = output - self.doc = doc - self.newpage = newpage - if output: - self.standalone = 1 - self.doc.open(output) - self.doc.init() - else: - self.standalone = 0 + self.setup() + + def setup(self): + """ + Define the table styles used by the report. + """ cell = BaseDoc.TableCellStyle() cell.set_padding(0.2) cell.set_top_border(1) @@ -126,16 +156,12 @@ class FamilyGroup: table.set_column_width(3,40) self.doc.add_table_style('FGR-ChildTable',table) - def end(self): - if self.standalone: - self.doc.close() - def dump_parent(self,person_handle): if not person_handle: return - person = self.db.get_person_from_handle(person_handle) + person = self.database.get_person_from_handle(person_handle) if person.get_gender() == RelLib.Person.male: id = _("Husband") @@ -156,21 +182,21 @@ class FamilyGroup: bdate = "" bplace = "" if birth_handle: - birth = self.db.get_event_from_handle(birth_handle) + birth = self.database.get_event_from_handle(birth_handle) bdate = birth.get_date() bplace_handle = birth.get_place_handle() if bplace_handle: - bplace = self.db.get_place_from_handle(bplace_handle).get_title() + bplace = self.database.get_place_from_handle(bplace_handle).get_title() death_handle = person.get_death_handle() ddate = "" dplace = "" if death_handle: - death = self.db.get_event_from_handle(death_handle) + death = self.database.get_event_from_handle(death_handle) ddate = death.get_date() dplace_handle = death.get_place_handle() if dplace_handle: - dplace = self.db.get_place_from_handle(dplace_handle).get_title() + dplace = self.database.get_place_from_handle(dplace_handle).get_title() self.doc.start_row() self.doc.start_cell("FGR-TextContents") @@ -212,13 +238,13 @@ class FamilyGroup: father_name = "" mother_name = "" if family_handle: - family = self.db.get_family_from_handle(family_handle) + family = self.database.get_family_from_handle(family_handle) father_handle = family.get_father_handle() if father_handle: - father_name = self.db.get_person_from_handle(father_handle).get_primary_name().get_regular_name() + father_name = self.database.get_person_from_handle(father_handle).get_primary_name().get_regular_name() mother_handle = family.get_mother_handle() if mother_handle: - mother_name = self.db.get_person_from_handle(mother_handle).get_primary_name().get_regular_name() + mother_name = self.database.get_person_from_handle(mother_handle).get_primary_name().get_regular_name() self.doc.start_row() self.doc.start_cell("FGR-TextContents") @@ -255,7 +281,7 @@ class FamilyGroup: date = event.get_date() place_handle = event.get_place_handle() if place_handle: - place = self.db.get_place_from_handle(place_handle).get_title() + place = self.database.get_place_from_handle(place_handle).get_title() self.doc.start_row() self.doc.start_cell(text) @@ -281,7 +307,7 @@ class FamilyGroup: def dump_child(self,index,person_handle): - person = self.db.get_person_from_handle(person_handle) + person = self.database.get_person_from_handle(person_handle) self.doc.start_row() self.doc.start_cell('FGR-TextChild1') self.doc.start_paragraph('FGR-ChildText') @@ -301,12 +327,12 @@ class FamilyGroup: families = len(person.get_family_handle_list()) birth_handle = person.get_birth_handle() if birth_handle: - birth = self.db.get_event_from_handle(birth_handle) + birth = self.database.get_event_from_handle(birth_handle) else: birth = None death_handle = person.get_death_handle() if death_handle: - death = self.db.get_event_from_handle(death_handle) + death = self.database.get_event_from_handle(death_handle) else: death = None self.dump_child_event('FGR-TextChild1',_('Birth'),birth) @@ -317,10 +343,10 @@ class FamilyGroup: index = 1 for family_handle in person.get_family_handle_list(): - family = self.db.get_family_from_handle(family_handle) + family = self.database.get_family_from_handle(family_handle) for event_handle in family.get_event_list(): if event_handle: - event = self.db.get_event_from_handle(event_handle) + event = self.database.get_event_from_handle(event_handle) if event.get_name() == "Marriage": m = event break @@ -344,7 +370,7 @@ class FamilyGroup: self.doc.start_cell('FGR-TextContentsEnd',2) self.doc.start_paragraph('FGR-Normal') if spouse_id: - spouse = self.db.get_person_from_handle(spouse_id) + spouse = self.database.get_person_from_handle(spouse_id) self.doc.write_text(spouse.get_primary_name().get_regular_name()) self.doc.end_paragraph() self.doc.end_cell() @@ -355,15 +381,8 @@ class FamilyGroup: else: self.dump_child_event('FGR-TextChild1',_("Married"),m) - #-------------------------------------------------------------------- - # - # - # - #-------------------------------------------------------------------- - def write_report(self): - if self.newpage: - self.doc.page_break() + def write_report(self): self.doc.start_paragraph('FGR-Title') self.doc.write_text(_("Family Group Report")) self.doc.end_paragraph() @@ -391,349 +410,146 @@ class FamilyGroup: self.dump_child(index,child_handle) index = index + 1 self.doc.end_table() - self.end() - - -#------------------------------------------------------------------------ -# -# FamilyGroupDialog -# -#------------------------------------------------------------------------ -class FamilyGroupDialog(Report.TextReportDialog): - - report_options = {} - - def __init__(self,database,person): - self.db = database - Report.TextReportDialog.__init__(self,database,person,self.report_options) - - def get_title(self): - """The window title for this dialog""" - return "%s - %s - GRAMPS" % (_("Family Group Report"),_("Text Reports")) - - def get_header(self, name): - """The header line at the top of the dialog contents""" - return _("Family Group Report for %s") % name - - def get_target_browser_title(self): - """The title of the window created when the 'browse' button is - clicked in the 'Save As' frame.""" - return _("Save Family Group Report") - - def get_stylesheet_savefile(self): - """Where to save styles for this report.""" - return "family_group.xml" - - def doc_uses_tables(self): - """This report requires table support.""" - return 1 - - def get_report_generations(self): - """No generation options.""" - return (0, 0) - - def get_report_extra_menu_info(self): - spouse_map = _build_spouse_map(self.db,self.person) - return (_("Spouse"), spouse_map, None, None) - - #------------------------------------------------------------------------ - # - # Create output styles appropriate to this report. - # - #------------------------------------------------------------------------ - def make_default_style(self): - _make_default_style(self.default_style) - - #------------------------------------------------------------------------ - # - # Create the contents of the report. - # - #------------------------------------------------------------------------ - def make_report(self): - """Create the object that will produce the Ancestor Chart. - All user dialog has already been handled and the output file - opened.""" - try: - MyReport = FamilyGroup(self.db, self.report_menu, - self.doc, self.target_path) - MyReport.write_report() - except Errors.ReportError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except Errors.FilterError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except: - import DisplayTrace - DisplayTrace.DisplayTrace() - -#------------------------------------------------------------------------ -# -# Standalone report function -# -#------------------------------------------------------------------------ -def report(database,person): - FamilyGroupDialog(database,person) - -#------------------------------------------------------------------------ -# -# Set up sane defaults for the book_item -# -#------------------------------------------------------------------------ -_style_file = "family_group.xml" -_style_name = "default" - -_person_handle = "" -_spouse_name = "" -_options = ( _person_handle, _spouse_name ) - -#------------------------------------------------------------------------ -# -# Book Item Options dialog -# -#------------------------------------------------------------------------ -class FamilyGroupBareDialog(Report.BareReportDialog): - - def __init__(self,database,person,opt,stl): - - self.options = opt - self.db = database - if self.options[0]: - self.person = self.db.get_person_from_handle(self.options[0]) - else: - self.person = person - self.style_name = stl - - Report.BareReportDialog.__init__(self,database,self.person) - - self.spouse_name = self.options[1] - - self.new_person = None - - self.spouse_map = _build_spouse_map(self.db,self.person) - if self.extra_menu: - myMenu = Utils.build_string_optmenu(self.spouse_map,self.spouse_name) - self.extra_menu.set_menu(myMenu) - self.extra_menu.set_sensitive(len(self.spouse_map) > 1) - - self.window.run() - - #------------------------------------------------------------------------ - # - # Customization hooks - # - #------------------------------------------------------------------------ - def make_default_style(self): - _make_default_style(self.default_style) - - def get_title(self): - """The window title for this dialog""" - return "%s - GRAMPS Book" % (_("Family Group Report")) - - def get_header(self, name): - """The header line at the top of the dialog contents""" - return _("Family Group Report for GRAMPS Book") - - def get_stylesheet_savefile(self): - """Where to save styles for this report.""" - return _style_file - - def get_report_generations(self): - """No generation options.""" - return (0, 0) - - def doc_uses_tables(self): - """This report requires table support.""" - return 1 - - def get_report_extra_menu_info(self): - self.spouse_map = _build_spouse_map(self.db,self.person) - return (_("Spouse"), self.spouse_map, None, None) - - def on_center_person_change_clicked(self,obj): - import SelectPerson - sel_person = SelectPerson.SelectPerson(self.db,_('Select Person')) - new_person = sel_person.run() - if new_person: - self.new_person = new_person - self.new_spouse_map = _build_spouse_map(self.db,self.new_person) - - if self.new_spouse_map: - if not self.extra_menu: - old_person = self.person - self.person = self.new_person - self.setup_report_options_frame() - self.window.show_all() - self.person = old_person - myMenu = Utils.build_string_optmenu(self.new_spouse_map,None) - self.extra_menu.set_menu(myMenu) - self.extra_menu.set_sensitive(len(self.new_spouse_map) > 1) - else: - if self.extra_menu: - myMenu = Utils.build_string_optmenu(self.new_spouse_map,None) - self.extra_menu.set_menu(myMenu) - self.extra_menu.set_sensitive(gtk.FALSE) - self.window.show_all() - self.extra_menu = None - - new_name = new_person.get_primary_name().get_regular_name() - if new_name: - self.person_label.set_text( "%s" % new_name ) - self.person_label.set_use_markup(gtk.TRUE) - - - def on_cancel(self, obj): - pass - - def on_ok_clicked(self, obj): - """The user is satisfied with the dialog choices. Parse all options - and close the window.""" - - if self.new_person: - self.person = self.new_person - self.spouse_map = self.new_spouse_map - - self.parse_style_frame() - self.parse_report_options_frame() - - if self.spouse_map: - spouse_number = self.extra_menu.get_history() - spouse_names = self.spouse_map.keys() - spouse_names.sort() - self.spouse_name = spouse_names[spouse_number] - else: - self.spouse_name = "" - - self.options = ( self.person.get_handle(), self.spouse_name ) - self.style_name = self.selected_style.get_name() - -#------------------------------------------------------------------------ -# -# Function to write Book Item -# -#------------------------------------------------------------------------ -def write_book_item(database,person,doc,options,newpage=0): - """Write the Family Group Report using options set. - All user dialog has already been handled and the output file opened.""" - try: - if options[0]: - person = database.get_person_from_handle(options[0]) - spouse_name = options[1] - spouse_map = _build_spouse_map(database,person) - if spouse_map: - if spouse_map.has_key(spouse_name): - family = spouse_map[spouse_name] - else: - spouse_names = spouse_map.keys() - spouse_names.sort() - family = spouse_map[spouse_names[0]] - else: - family = None - return FamilyGroup(database, family, doc, None, newpage ) - except Errors.ReportError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except Errors.FilterError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except: - import DisplayTrace - DisplayTrace.DisplayTrace() - - -#------------------------------------------------------------------------ -# -# Functions shared between the dialogs -# -#------------------------------------------------------------------------ -def _make_default_style(default_style): - """Make default output style for the Family Group Report.""" - para = BaseDoc.ParagraphStyle() - font = BaseDoc.FontStyle() - font.set_size(4) - para.set_font(font) - default_style.add_style('FGR-blank',para) - - font = BaseDoc.FontStyle() - font.set_type_face(BaseDoc.FONT_SANS_SERIF) - font.set_size(16) - font.set_bold(1) - para = BaseDoc.ParagraphStyle() - para.set_font(font) - para.set_description(_("The style used for the title of the page.")) - default_style.add_style('FGR-Title',para) - - font = BaseDoc.FontStyle() - font.set_type_face(BaseDoc.FONT_SERIF) - font.set_size(10) - font.set_bold(0) - para = BaseDoc.ParagraphStyle() - para.set_font(font) - para.set_description(_('The basic style used for the text display.')) - default_style.add_style('FGR-Normal',para) - - font = BaseDoc.FontStyle() - font.set_type_face(BaseDoc.FONT_SANS_SERIF) - font.set_size(10) - font.set_bold(1) - para = BaseDoc.ParagraphStyle() - para.set_font(font) - para.set_description(_('The style used for the text related to the children.')) - default_style.add_style('FGR-ChildText',para) - - font = BaseDoc.FontStyle() - font.set_type_face(BaseDoc.FONT_SANS_SERIF) - font.set_size(12) - font.set_bold(1) - para = BaseDoc.ParagraphStyle() - para.set_font(font) - para.set_description(_("The style used for the parent's name")) - default_style.add_style('FGR-ParentName',para) - -def _build_spouse_map(database,person): - """Create a mapping of all spouse names:families to be put - into the 'extra' option menu in the report options box. If - the selected person has never been married then this routine - will return a placebo label and disable the OK button.""" - spouse_map = {} - family_list = person.get_family_handle_list() - for family_handle in family_list: - family = database.get_family_from_handle(family_handle) - if person.get_handle() == family.get_father_handle(): - spouse_id = family.get_mother_handle() - else: - spouse_id = family.get_father_handle() - if spouse_id: - spouse = database.get_person_from_handle(spouse_id) - name = spouse.get_primary_name().get_name() - else: - name= _("unknown") - spouse_map[name] = family_handle - return spouse_map #------------------------------------------------------------------------ # # # #------------------------------------------------------------------------ -from Plugins import register_report, register_book_item +class FamilyGroupOptions(ReportOptions.ReportOptions): + """ + Defines options and provides handling interface. + """ + + def __init__(self,name,person_id=None): + ReportOptions.ReportOptions.__init__(self,name,person_id) + + def set_new_options(self): + # Options specific for this report + self.options_dict = { + 'spouse_id' : '', + } + + self.options_help = { + 'spouse_id' : ("=ID","Gramps ID of the person's spouse.", + "Use show=id to get ID list.", + #[item[0] for item in self.get_spouses(None,None)], + #False + ), + } + + def get_spouses(self,database,person): + """ + Create a mapping of all spouse names:families to be put + into the 'extra' option menu in the report options box. If + the selected person has never been married then this routine + will return a placebo label and disable the OK button. + """ + spouses = [] + family_list = person.get_family_handle_list() + for family_handle in family_list: + family = database.get_family_from_handle(family_handle) + if person.get_handle() == family.get_father_handle(): + spouse_id = family.get_mother_handle() + else: + spouse_id = family.get_father_handle() + if spouse_id: + spouse = database.get_person_from_handle(spouse_id) + name = spouse.get_primary_name().get_name() + else: + name = _("unknown") + spouses.append((spouse_id,name)) + return spouses + + def add_user_options(self,dialog): + """ + Override the base class add_user_options task to add a menu that allows + the user to select the sort method. + """ + + spouses = self.get_spouses(dialog.db,dialog.person) + spouse_id = self.options_dict['spouse_id'] + + self.spouse_menu = gtk.combo_box_new_text() + index = 0 + spouse_index = 0 + for item in spouses: + self.spouse_menu.append_text(item[1]) + if item[0] == spouse_id: + spouse_index = index + index = index + 1 + self.spouse_menu.set_active(spouse_index) + + dialog.add_option(_("Spouse"),self.spouse_menu) + + def parse_user_options(self,dialog): + """ + Parses the custom options that we have added. + """ + spouses = self.get_spouses(dialog.db,dialog.person) + spouse_index = self.spouse_menu.get_active() + self.options_dict['spouse_id'] = spouses[spouse_index][0] + + def make_default_style(self,default_style): + """Make default output style for the Family Group Report.""" + para = BaseDoc.ParagraphStyle() + font = BaseDoc.FontStyle() + font.set_size(4) + para.set_font(font) + default_style.add_style('FGR-blank',para) + + font = BaseDoc.FontStyle() + font.set_type_face(BaseDoc.FONT_SANS_SERIF) + font.set_size(16) + font.set_bold(1) + para = BaseDoc.ParagraphStyle() + para.set_font(font) + para.set_description(_("The style used for the title of the page.")) + default_style.add_style('FGR-Title',para) + + font = BaseDoc.FontStyle() + font.set_type_face(BaseDoc.FONT_SERIF) + font.set_size(10) + font.set_bold(0) + para = BaseDoc.ParagraphStyle() + para.set_font(font) + para.set_description(_('The basic style used for the text display.')) + default_style.add_style('FGR-Normal',para) + + font = BaseDoc.FontStyle() + font.set_type_face(BaseDoc.FONT_SANS_SERIF) + font.set_size(10) + font.set_bold(1) + para = BaseDoc.ParagraphStyle() + para.set_font(font) + para.set_description(_('The style used for the text related to the children.')) + default_style.add_style('FGR-ChildText',para) + + font = BaseDoc.FontStyle() + font.set_type_face(BaseDoc.FONT_SANS_SERIF) + font.set_size(12) + font.set_bold(1) + para = BaseDoc.ParagraphStyle() + para.set_font(font) + para.set_description(_("The style used for the parent's name")) + default_style.add_style('FGR-ParentName',para) + +#------------------------------------------------------------------------ +# +# +# +#------------------------------------------------------------------------ +from Plugins import register_report register_report( - report, - _("Family Group Report"), - category=_("Text Reports"), - status=(_("Beta")), + name = 'family_group', + category = const.CATEGORY_TEXT, + report_class = FamilyGroup, + options_class = FamilyGroupOptions, + modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI, + translated_name = _("Family Group Report"), + status = _("Beta"), + author_name = "Donald N. Allingham", + author_email = "dallingham@users.sourceforge.net", description=_("Creates a family group report, showing information on a set of parents and their children."), ) - -# (name,category,options_dialog,write_book_item,options,style_name,style_file,make_default_style) -register_book_item( - _("Family Group Report"), - _("Text"), - FamilyGroupBareDialog, - write_book_item, - _options, - _style_name, - _style_file, - _make_default_style - )