def get_parents_desc(database, person): """ Return text describing person's parents """ sa = SimpleAccess(database) narrator = Narrator(database, verbose=True, use_call_name=True, use_fulldate=True) narrator.set_subject(person) family_handle = person.get_main_parents_family_handle() if family_handle: family = database.get_family_from_handle(family_handle) mother_handle = family.get_mother_handle() father_handle = family.get_father_handle() if mother_handle: mother = database.get_person_from_handle(mother_handle) mother_name = sa.name(mother) else: mother_name = "" if father_handle: father = database.get_person_from_handle(father_handle) father_name = sa.name(father) else: father_name = "" return narrator.get_child_string(father_name, mother_name)
def run(database, document, person): """ Output a text biography of active person """ sa = SimpleAccess(database) sd = SimpleDoc(document) sd.title(_("Biography for %s") % sa.name(person)) sd.paragraph('') narrator = Narrator(database, verbose=True, use_call_name=True, use_fulldate=True) narrator.set_subject(person) # Birth Details text = narrator.get_born_string() if text: sd.paragraph(text) text = narrator.get_baptised_string() if text: sd.paragraph(text) text = narrator.get_christened_string() if text: sd.paragraph(text) text = get_parents_desc(database, person) if text: sd.paragraph(text) sd.paragraph('') # Family Details for family in sa.parent_in(person): text = narrator.get_married_string(family) if text: sd.paragraph(text) sd.paragraph('') # Death Details text = narrator.get_died_string(True) if text: sd.paragraph(text) text = narrator.get_buried_string() if text: sd.paragraph(text) sd.paragraph('') # Sources sd.header1(_('Sources')) for source in get_sources(database, person): sd.paragraph(source)
def __init__(self, database, options, user): """ Create the AncestorReport object that produces the Ahnentafel report. The arguments are: database - the Gramps database instance options - instance of the Options class for this report user - a gen.user.User() instance This report needs the following parameters (class variables) that come in the options class. gen - Maximum number of generations to include. pagebbg - Whether to include page breaks between generations. name_format - Preferred format to display names incl_private - Whether to include private data namebrk - Whether a line break should follow the name inc_id - Whether to include Gramps IDs living_people - How to handle living people years_past_death - Consider as living this many years after death """ Report.__init__(self, database, options, user) self.map = {} menu = options.menu self.set_locale(menu.get_option_by_name('trans').get_value()) stdoptions.run_date_format_option(self, menu) stdoptions.run_private_data_option(self, menu) stdoptions.run_living_people_option(self, menu, self._locale) self.database = CacheProxyDb(self.database) self.max_generations = menu.get_option_by_name('maxgen').get_value() self.pgbrk = menu.get_option_by_name('pagebbg').get_value() self.opt_namebrk = menu.get_option_by_name('namebrk').get_value() self.want_ids = menu.get_option_by_name('inc_id').get_value() pid = menu.get_option_by_name('pid').get_value() self.center_person = self.database.get_person_from_gramps_id(pid) if self.center_person is None: raise ReportError(_("Person %s is not in the Database") % pid) stdoptions.run_name_format_option(self, menu) self.__narrator = Narrator(self.database, use_fulldate=True, nlocale=self._locale)
def run(database, document, person): """ Output a text biography of active person """ sa = SimpleAccess(database) sd = SimpleDoc(document) sd.title("Biography for %s" % sa.name(person)) sd.paragraph('') narrator = Narrator(database, verbose=True, use_call_name=True, use_fulldate=True) narrator.set_subject(person) # Birth Details text = narrator.get_born_string() if text: sd.paragraph(text) text = narrator.get_baptised_string() if text: sd.paragraph(text) text = narrator.get_christened_string() if text: sd.paragraph(text) text = get_parents_desc(database, person) if text: sd.paragraph(text) sd.paragraph('') # Family Details for family in sa.parent_in(person): text = narrator.get_married_string(family) if text: sd.paragraph(text) sd.paragraph('') # Death Details text = narrator.get_died_string(True) if text: sd.paragraph(text) text = narrator.get_buried_string() if text: sd.paragraph(text) sd.paragraph('') # Sources sd.header1('Sources') for source in get_sources(database, person): sd.paragraph(source)
def __init__(self, database, options, user): """ Create the AncestorReport object that produces the Ahnentafel report. The arguments are: database - the GRAMPS database instance options - instance of the Options class for this report user - a gen.user.User() instance This report needs the following parameters (class variables) that come in the options class. gen - Maximum number of generations to include. pagebbg - Whether to include page breaks between generations. name_format - Preferred format to display names incl_private - Whether to include private data """ Report.__init__(self, database, options, user) self.map = {} menu = options.menu stdoptions.run_private_data_option(self, menu) self.max_generations = menu.get_option_by_name('maxgen').get_value() self.pgbrk = menu.get_option_by_name('pagebbg').get_value() self.opt_namebrk = menu.get_option_by_name('namebrk').get_value() pid = menu.get_option_by_name('pid').get_value() self.center_person = database.get_person_from_gramps_id(pid) if (self.center_person == None): raise ReportError(_("Person %s is not in the Database") % pid) lang = menu.get_option_by_name('trans').get_value() rlocale = self.set_locale(lang) stdoptions.run_name_format_option(self, menu) self.__narrator = Narrator(self.database, use_fulldate=True, nlocale=rlocale)
def __init__(self, database, options, user): """ Create the AncestorReport object that produces the Ahnentafel report. The arguments are: database - the GRAMPS database instance options - instance of the Options class for this report user - a gen.user.User() instance This report needs the following parameters (class variables) that come in the options class. gen - Maximum number of generations to include. pagebbg - Whether to include page breaks between generations. name_format - Preferred format to display names incl_private - Whether to include private data """ Report.__init__(self, database, options, user) self.map = {} menu = options.menu stdoptions.run_private_data_option(self, menu) self.max_generations = menu.get_option_by_name('maxgen').get_value() self.pgbrk = menu.get_option_by_name('pagebbg').get_value() self.opt_namebrk = menu.get_option_by_name('namebrk').get_value() pid = menu.get_option_by_name('pid').get_value() self.center_person = database.get_person_from_gramps_id(pid) if (self.center_person == None) : raise ReportError(_("Person %s is not in the Database") % pid ) lang = menu.get_option_by_name('trans').get_value() rlocale = self.set_locale(lang) stdoptions.run_name_format_option(self, menu) self.__narrator = Narrator(self.database, use_fulldate=True, nlocale=rlocale)
def __init__(self, database, options, user): """ Create the DetDescendantReport object that produces the report. The arguments are: database - the GRAMPS database instance options - instance of the Options class for this report user - a gen.user.User() instance 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. pageben - Whether to include page break before End Notes. fulldates - Whether to use full dates instead of just year. listc - Whether to list children. incnotes - Whether to include notes. usecall - Whether to use the call name as the first name. repplace - Whether to replace missing Places with ___________. repdate - Whether to replace missing Dates with ___________. computeage - Whether to compute age. omitda - Whether to omit duplicate ancestors (e.g. when distant cousins marry). verbose - Whether to use complete sentences. numbering - The descendancy numbering system to be utilized. desref - Whether to add descendant references in child list. incphotos - Whether to include images. incnames - Whether to include other names. incevents - Whether to include events. incaddresses - Whether to include addresses. incsrcnotes - Whether to include source notes in the Endnotes section. Only works if Include sources is selected. incmates - Whether to include information about spouses incattrs - Whether to include attributes incpaths - Whether to include the path of descendancy from the start-person to each descendant. incssign - Whether to include a sign ('+') before the descendant number in the child-list to indicate a child has succession. pid - The Gramps ID of the center person for the report. name_format - Preferred format to display names incmateref - Whether to print mate information or reference incl_private - Whether to include private data """ Report.__init__(self, database, options, user) self.map = {} self._user = user menu = options.menu get_option_by_name = menu.get_option_by_name get_value = lambda name: get_option_by_name(name).get_value() stdoptions.run_private_data_option(self, menu) self.db = self.database self.max_generations = get_value('gen') self.pgbrk = get_value('pagebbg') self.pgbrkenotes = get_value('pageben') self.fulldate = get_value('fulldates') use_fulldate = self.fulldate self.listchildren = get_value('listc') self.inc_notes = get_value('incnotes') use_call = get_value('usecall') blankplace = get_value('repplace') blankdate = get_value('repdate') self.calcageflag = get_value('computeage') self.dubperson = get_value('omitda') self.verbose = get_value('verbose') self.numbering = get_value('numbering') self.childref = get_value('desref') self.addimages = get_value('incphotos') self.inc_names = get_value('incnames') self.inc_events = get_value('incevents') self.inc_addr = get_value('incaddresses') self.inc_sources = get_value('incsources') self.inc_srcnotes = get_value('incsrcnotes') self.inc_mates = get_value('incmates') self.inc_attrs = get_value('incattrs') self.inc_paths = get_value('incpaths') self.inc_ssign = get_value('incssign') self.inc_materef = get_value('incmateref') pid = get_value('pid') self.center_person = self.db.get_person_from_gramps_id(pid) if (self.center_person == None) : raise ReportError(_("Person %s is not in the Database") % pid ) self.gen_handles = {} self.prev_gen_handles = {} self.gen_keys = [] self.dnumber = {} self.dmates = {} if blankdate: empty_date = EMPTY_ENTRY else: empty_date = "" if blankplace: empty_place = EMPTY_ENTRY else: empty_place = "" self._locale = self.set_locale(get_value('trans')) stdoptions.run_name_format_option(self, menu) self.__narrator = Narrator(self.db, self.verbose, use_call, use_fulldate, empty_date, empty_place, nlocale=self._locale, get_endnote_numbers=self.endnotes) self.bibli = Bibliography(Bibliography.MODE_DATE|Bibliography.MODE_PAGE)
class DetDescendantReport(Report): def __init__(self, database, options, user): """ Create the DetDescendantReport object that produces the report. The arguments are: database - the GRAMPS database instance options - instance of the Options class for this report user - a gen.user.User() instance 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. pageben - Whether to include page break before End Notes. fulldates - Whether to use full dates instead of just year. listc - Whether to list children. incnotes - Whether to include notes. usecall - Whether to use the call name as the first name. repplace - Whether to replace missing Places with ___________. repdate - Whether to replace missing Dates with ___________. computeage - Whether to compute age. omitda - Whether to omit duplicate ancestors (e.g. when distant cousins marry). verbose - Whether to use complete sentences. numbering - The descendancy numbering system to be utilized. desref - Whether to add descendant references in child list. incphotos - Whether to include images. incnames - Whether to include other names. incevents - Whether to include events. incaddresses - Whether to include addresses. incsrcnotes - Whether to include source notes in the Endnotes section. Only works if Include sources is selected. incmates - Whether to include information about spouses incattrs - Whether to include attributes incpaths - Whether to include the path of descendancy from the start-person to each descendant. incssign - Whether to include a sign ('+') before the descendant number in the child-list to indicate a child has succession. pid - The Gramps ID of the center person for the report. name_format - Preferred format to display names incmateref - Whether to print mate information or reference incl_private - Whether to include private data """ Report.__init__(self, database, options, user) self.map = {} self._user = user menu = options.menu get_option_by_name = menu.get_option_by_name get_value = lambda name: get_option_by_name(name).get_value() stdoptions.run_private_data_option(self, menu) self.db = self.database self.max_generations = get_value('gen') self.pgbrk = get_value('pagebbg') self.pgbrkenotes = get_value('pageben') self.fulldate = get_value('fulldates') use_fulldate = self.fulldate self.listchildren = get_value('listc') self.inc_notes = get_value('incnotes') use_call = get_value('usecall') blankplace = get_value('repplace') blankdate = get_value('repdate') self.calcageflag = get_value('computeage') self.dubperson = get_value('omitda') self.verbose = get_value('verbose') self.numbering = get_value('numbering') self.childref = get_value('desref') self.addimages = get_value('incphotos') self.inc_names = get_value('incnames') self.inc_events = get_value('incevents') self.inc_addr = get_value('incaddresses') self.inc_sources = get_value('incsources') self.inc_srcnotes = get_value('incsrcnotes') self.inc_mates = get_value('incmates') self.inc_attrs = get_value('incattrs') self.inc_paths = get_value('incpaths') self.inc_ssign = get_value('incssign') self.inc_materef = get_value('incmateref') pid = get_value('pid') self.center_person = self.db.get_person_from_gramps_id(pid) if (self.center_person == None) : raise ReportError(_("Person %s is not in the Database") % pid ) self.gen_handles = {} self.prev_gen_handles = {} self.gen_keys = [] self.dnumber = {} self.dmates = {} if blankdate: empty_date = EMPTY_ENTRY else: empty_date = "" if blankplace: empty_place = EMPTY_ENTRY else: empty_place = "" self._locale = self.set_locale(get_value('trans')) stdoptions.run_name_format_option(self, menu) self.__narrator = Narrator(self.db, self.verbose, use_call, use_fulldate, empty_date, empty_place, nlocale=self._locale, get_endnote_numbers=self.endnotes) self.bibli = Bibliography(Bibliography.MODE_DATE|Bibliography.MODE_PAGE) def apply_henry_filter(self,person_handle, index, pid, cur_gen=1): if (not person_handle) or (cur_gen > self.max_generations): return self.dnumber[person_handle] = pid self.map[index] = person_handle if len(self.gen_keys) < cur_gen: self.gen_keys.append([index]) else: self.gen_keys[cur_gen-1].append(index) person = self.db.get_person_from_handle(person_handle) index = 0 for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) for child_ref in family.get_child_ref_list(): ix = max(self.map) self.apply_henry_filter(child_ref.ref, ix+1, pid+HENRY[index], cur_gen+1) index += 1 # Filter for d'Aboville numbering def apply_daboville_filter(self,person_handle, index, pid, cur_gen=1): if (not person_handle) or (cur_gen > self.max_generations): return self.dnumber[person_handle] = pid self.map[index] = person_handle if len(self.gen_keys) < cur_gen: self.gen_keys.append([index]) else: self.gen_keys[cur_gen-1].append(index) person = self.db.get_person_from_handle(person_handle) index = 1 for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) for child_ref in family.get_child_ref_list(): ix = max(self.map) self.apply_daboville_filter(child_ref.ref, ix+1, pid+"."+str(index), cur_gen+1) index += 1 # Filter for Record-style (Modified Register) numbering def apply_mod_reg_filter_aux(self, person_handle, index, cur_gen=1): if (not person_handle) or (cur_gen > self.max_generations): return self.map[index] = person_handle if len(self.gen_keys) < cur_gen: self.gen_keys.append([index]) else: self.gen_keys[cur_gen-1].append(index) person = self.db.get_person_from_handle(person_handle) for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) for child_ref in family.get_child_ref_list(): ix = max(self.map) self.apply_mod_reg_filter_aux(child_ref.ref, ix+1, cur_gen+1) def apply_mod_reg_filter(self, person_handle): self.apply_mod_reg_filter_aux(person_handle, 1, 1) mod_reg_number = 1 for generation in range(len(self.gen_keys)): for key in self.gen_keys[generation]: person_handle = self.map[key] if person_handle not in self.dnumber: self.dnumber[person_handle] = mod_reg_number mod_reg_number += 1 def write_report(self): """ This function is called by the report system and writes the report. """ if self.numbering == "Henry": self.apply_henry_filter(self.center_person.get_handle(), 1, "1") elif self.numbering == "d'Aboville": self.apply_daboville_filter(self.center_person.get_handle(), 1, "1") elif self.numbering == "Record (Modified Register)": self.apply_mod_reg_filter(self.center_person.get_handle()) else: raise AttributeError("no such numbering: '%s'" % self.numbering) name = self._name_display.display_name( self.center_person.get_primary_name()) if not name: name = self._("Unknown") self.doc.start_paragraph("DDR-Title") # feature request 2356: avoid genitive form title = self._("Descendant Report for %(person_name)s") % { 'person_name' : name } mark = IndexMark(title, INDEX_TYPE_TOC, 1) self.doc.write_text(title, mark) self.doc.end_paragraph() generation = 0 self.numbers_printed = list() for generation in range(len(self.gen_keys)): if self.pgbrk and generation > 0: self.doc.page_break() self.doc.start_paragraph("DDR-Generation") text = self._("Generation %d") % (generation+1) mark = IndexMark(text, INDEX_TYPE_TOC, 2) self.doc.write_text(text, mark) self.doc.end_paragraph() if self.childref: self.prev_gen_handles = self.gen_handles.copy() self.gen_handles.clear() for key in self.gen_keys[generation]: person_handle = self.map[key] self.gen_handles[person_handle] = key self.write_person(key) if self.inc_sources: if self.pgbrkenotes: self.doc.page_break() # it ignores language set for Note type (use locale) endnotes.write_endnotes(self.bibli, self.db, self.doc, printnotes=self.inc_srcnotes, elocale=self._locale) def write_path(self, person): path = [] while True: #person changes in the loop family_handle = person.get_main_parents_family_handle() if family_handle: family = self.db.get_family_from_handle(family_handle) mother_handle = family.get_mother_handle() father_handle = family.get_father_handle() if mother_handle and mother_handle in self.dnumber: person = self.db.get_person_from_handle(mother_handle) person_name = self._name_display.display_name( person.get_primary_name()) path.append(person_name) elif father_handle and father_handle in self.dnumber: person = self.db.get_person_from_handle(father_handle) person_name = self._name_display.display_name( person.get_primary_name()) path.append(person_name) else: break else: break index = len(path) if index: self.doc.write_text("(") for name in path: if index == 1: self.doc.write_text(name + "-" + str(index) + ") ") else: # translators: needed for Arabic, ignore otherwise self.doc.write_text(name + "-" + str(index) + self._("; ")) index -= 1 def write_person(self, key): """Output birth, death, parentage, marriage and notes information """ person_handle = self.map[key] person = self.db.get_person_from_handle(person_handle) val = self.dnumber[person_handle] if val in self.numbers_printed: return else: self.numbers_printed.append(val) self.doc.start_paragraph("DDR-First-Entry","%s." % val) name = self._name_display.display(person) if not name: name = self._("Unknown") mark = ReportUtils.get_person_mark(self.db, person) self.doc.start_bold() self.doc.write_text(name, mark) if name[-1:] == '.': self.doc.write_text_citation("%s " % self.endnotes(person)) elif name: self.doc.write_text_citation("%s. " % self.endnotes(person)) self.doc.end_bold() if self.inc_paths: self.write_path(person) if self.dubperson: # Check for duplicate record (result of distant cousins marrying) for dkey in sorted(self.map): if dkey >= key: break if self.map[key] == self.map[dkey]: self.doc.write_text(self._( "%(name)s is the same person as [%(id_str)s].") % { 'name' :'', 'id_str': self.dnumber[self.map[dkey]], } ) self.doc.end_paragraph() return self.doc.end_paragraph() self.write_person_info(person) if (self.inc_mates or self.listchildren or self.inc_notes or self.inc_events or self.inc_attrs): for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) if self.inc_mates: self.__write_mate(person, family) if self.listchildren: self.__write_children(family) if self.inc_notes: self.__write_family_notes(family) first = True if self.inc_events: first = self.__write_family_events(family) if self.inc_attrs: self.__write_family_attrs(family, first) def write_event(self, event_ref): text = "" event = self.db.get_event_from_handle(event_ref.ref) if self.fulldate: date = self._get_date(event.get_date_object()) else: date = event.get_date_object().get_year() place = place_displayer.display_event(self.db, event) self.doc.start_paragraph('DDR-MoreDetails') event_name = self._get_type(event.get_type()) if date and place: text += self._('%(date)s, %(place)s') % { 'date' : date, 'place' : place } elif date: text += self._('%(date)s') % {'date' : date} elif place: text += self._('%(place)s') % { 'place' : place } if event.get_description(): if text: text += ". " text += event.get_description() text += self.endnotes(event) if text: text += ". " text = self._('%(event_name)s: %(event_text)s') % { 'event_name' : self._(event_name), 'event_text' : text } self.doc.write_text_citation(text) if self.inc_attrs: text = "" attr_list = event.get_attribute_list() attr_list.extend(event_ref.get_attribute_list()) for attr in attr_list: if text: # translators: needed for Arabic, ignore otherwise text += self._("; ") attrName = self._get_type(attr.get_type()) text += self._("%(type)s: %(value)s%(endnotes)s") % { 'type' : self._(attrName), 'value' : attr.get_value(), 'endnotes' : self.endnotes(attr) } text = " " + text self.doc.write_text_citation(text) self.doc.end_paragraph() if self.inc_notes: # if the event or event reference has a note attached to it, # get the text and format it correctly notelist = event.get_note_list() notelist.extend(event_ref.get_note_list()) for notehandle in notelist: note = self.db.get_note_from_handle(notehandle) self.doc.write_styled_note(note.get_styledtext(), note.get_format(),"DDR-MoreDetails", contains_html= note.get_type() == NoteType.HTML_CODE) def __write_parents(self, person): family_handle = person.get_main_parents_family_handle() if family_handle: family = self.db.get_family_from_handle(family_handle) mother_handle = family.get_mother_handle() father_handle = family.get_father_handle() if mother_handle: mother = self.db.get_person_from_handle(mother_handle) mother_name = self._name_display.display_name( mother.get_primary_name()) mother_mark = ReportUtils.get_person_mark(self.db, mother) else: mother_name = "" mother_mark = "" if father_handle: father = self.db.get_person_from_handle(father_handle) father_name = self._name_display.display_name( father.get_primary_name()) father_mark = ReportUtils.get_person_mark(self.db, father) else: father_name = "" father_mark = "" text = self.__narrator.get_child_string(father_name, mother_name) if text: self.doc.write_text(text) if father_mark: self.doc.write_text("", father_mark) if mother_mark: self.doc.write_text("", mother_mark) def write_marriage(self, person): """ Output marriage sentence. """ is_first = True for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) spouse_handle = ReportUtils.find_spouse(person, family) spouse = self.db.get_person_from_handle(spouse_handle) text = "" spouse_mark = ReportUtils.get_person_mark(self.db, spouse) text = self.__narrator.get_married_string(family, is_first, self._name_display) if text: self.doc.write_text_citation(text, spouse_mark) is_first = False def __write_mate(self, person, family): """ Write information about the person's spouse/mate. """ if person.get_gender() == Person.MALE: mate_handle = family.get_mother_handle() else: mate_handle = family.get_father_handle() if mate_handle: mate = self.db.get_person_from_handle(mate_handle) self.doc.start_paragraph("DDR-MoreHeader") name = self._name_display.display(mate) if not name: name = self._("Unknown") mark = ReportUtils.get_person_mark(self.db, mate) if family.get_relationship() == FamilyRelType.MARRIED: self.doc.write_text(self._("Spouse: %s") % name, mark) else: self.doc.write_text(self._("Relationship with: %s") % name, mark) if name[-1:] != '.': self.doc.write_text(".") self.doc.write_text_citation(self.endnotes(mate)) self.doc.end_paragraph() if not self.inc_materef: # Don't want to just print reference self.write_person_info(mate) else: # Check to see if we've married a cousin if mate_handle in self.dnumber: self.doc.start_paragraph('DDR-MoreDetails') self.doc.write_text_citation( self._("Ref: %(number)s. %(name)s") % {'number': self.dnumber[mate_handle], 'name': name}) self.doc.end_paragraph() else: self.dmates[mate_handle] = person.get_handle() self.write_person_info(mate) def __get_mate_names(self, family): mother_handle = family.get_mother_handle() if mother_handle: mother = self.db.get_person_from_handle(mother_handle) mother_name = self._name_display.display(mother) if not mother_name: mother_name = self._("Unknown") else: mother_name = self._("Unknown") father_handle = family.get_father_handle() if father_handle: father = self.db.get_person_from_handle(father_handle) father_name = self._name_display.display(father) if not father_name: father_name = self._("Unknown") else: father_name = self._("Unknown") return mother_name, father_name def __write_children(self, family): """ List the children for the given family. """ if not family.get_child_ref_list(): return mother_name, father_name = self.__get_mate_names(family) self.doc.start_paragraph("DDR-ChildTitle") self.doc.write_text( self._("Children of %(mother_name)s and %(father_name)s") % {'father_name': father_name, 'mother_name': mother_name } ) self.doc.end_paragraph() cnt = 1 for child_ref in family.get_child_ref_list(): child_handle = child_ref.ref child = self.db.get_person_from_handle(child_handle) child_name = self._name_display.display(child) if not child_name: child_name = self._("Unknown") child_mark = ReportUtils.get_person_mark(self.db, child) if self.childref and self.prev_gen_handles.get(child_handle): value = str(self.prev_gen_handles.get(child_handle)) child_name += " [%s]" % value if self.inc_ssign: prefix = " " for family_handle in child.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) if family.get_child_ref_list(): prefix = "+ " break else: prefix = "" if child_handle in self.dnumber: self.doc.start_paragraph("DDR-ChildList", prefix + str(self.dnumber[child_handle]) + " " + ReportUtils.roman(cnt).lower() + ".") else: self.doc.start_paragraph("DDR-ChildList", prefix + ReportUtils.roman(cnt).lower() + ".") cnt += 1 self.doc.write_text("%s. " % child_name, child_mark) self.__narrator.set_subject(child) self.doc.write_text_citation( self.__narrator.get_born_string() or self.__narrator.get_christened_string() or self.__narrator.get_baptised_string()) self.doc.write_text_citation( self.__narrator.get_died_string() or self.__narrator.get_buried_string()) self.doc.end_paragraph() def __write_family_notes(self, family): """ Write the notes for the given family. """ notelist = family.get_note_list() if len(notelist) > 0: mother_name, father_name = self.__get_mate_names(family) self.doc.start_paragraph("DDR-NoteHeader") self.doc.write_text( self._('Notes for %(mother_name)s and %(father_name)s:') % { 'mother_name' : mother_name, 'father_name' : father_name }) self.doc.end_paragraph() for notehandle in notelist: note = self.db.get_note_from_handle(notehandle) self.doc.write_styled_note(note.get_styledtext(), note.get_format(),"DDR-Entry") def __write_family_events(self, family): """ List the events for the given family. """ if not family.get_event_ref_list(): return mother_name, father_name = self.__get_mate_names(family) first = True for event_ref in family.get_event_ref_list(): if first: self.doc.start_paragraph('DDR-MoreHeader') self.doc.write_text( self._('More about %(mother_name)s and %(father_name)s:') % {'mother_name' : mother_name, 'father_name' : father_name }) self.doc.end_paragraph() first = False self.write_event(event_ref) return first def __write_family_attrs(self, family, first): """ List the attributes for the given family. """ attrs = family.get_attribute_list() if first and attrs: mother_name, father_name = self.__get_mate_names(family) self.doc.start_paragraph('DDR-MoreHeader') self.doc.write_text( self._('More about %(mother_name)s and %(father_name)s:') % {'mother_name' : mother_name, 'father_name' : father_name }) self.doc.end_paragraph() for attr in attrs: self.doc.start_paragraph('DDR-MoreDetails') attrName = self._get_type(attr.get_type()) text = self._("%(type)s: %(value)s%(endnotes)s") % { 'type' : self._(attrName), 'value' : attr.get_value(), 'endnotes' : self.endnotes(attr) } self.doc.write_text_citation( text ) self.doc.end_paragraph() if self.inc_notes: # if the attr or attr reference has a note attached to it, # get the text and format it correctly notelist = attr.get_note_list() for notehandle in notelist: note = self.db.get_note_from_handle(notehandle) self.doc.write_styled_note(note.get_styledtext(), note.get_format(), "DDR-MoreDetails") def write_person_info(self, person): name = self._name_display.display(person) if not name: name = self._("Unknown") self.__narrator.set_subject(person) plist = person.get_media_list() if self.addimages and len(plist) > 0: photo = plist[0] ReportUtils.insert_image(self.db, self.doc, photo, self._user) self.doc.start_paragraph("DDR-Entry") if not self.verbose: self.__write_parents(person) text = self.__narrator.get_born_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_baptised_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_christened_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_died_string(self.calcageflag) if text: self.doc.write_text_citation(text) text = self.__narrator.get_buried_string() if text: self.doc.write_text_citation(text) if self.verbose: self.__write_parents(person) self.write_marriage(person) self.doc.end_paragraph() notelist = person.get_note_list() if len(notelist) > 0 and self.inc_notes: self.doc.start_paragraph("DDR-NoteHeader") # feature request 2356: avoid genitive form self.doc.write_text(self._("Notes for %s") % name) self.doc.end_paragraph() for notehandle in notelist: note = self.db.get_note_from_handle(notehandle) self.doc.write_styled_note(note.get_styledtext(), note.get_format(),"DDR-Entry", contains_html= note.get_type() == NoteType.HTML_CODE) first = True if self.inc_names: for alt_name in person.get_alternate_names(): if first: self.doc.start_paragraph('DDR-MoreHeader') self.doc.write_text(self._('More about %(person_name)s:') % {'person_name' : name }) self.doc.end_paragraph() first = False self.doc.start_paragraph('DDR-MoreDetails') atype = self._get_type(alt_name.get_type()) aname = alt_name.get_regular_name() self.doc.write_text_citation( self._('%(name_kind)s: %(name)s%(endnotes)s') % {'name_kind' : self._(atype), 'name' : aname, 'endnotes' : self.endnotes(alt_name), }) self.doc.end_paragraph() if self.inc_events: for event_ref in person.get_primary_event_ref_list(): if first: self.doc.start_paragraph('DDR-MoreHeader') self.doc.write_text(self._('More about %(person_name)s:') % {'person_name' : name }) self.doc.end_paragraph() first = 0 self.write_event(event_ref) if self.inc_addr: for addr in person.get_address_list(): if first: self.doc.start_paragraph('DDR-MoreHeader') self.doc.write_text(self._('More about %(person_name)s:') % {'person_name' : name }) self.doc.end_paragraph() first = False self.doc.start_paragraph('DDR-MoreDetails') text = ReportUtils.get_address_str(addr) if self.fulldate: date = self._get_date(addr.get_date_object()) else: date = addr.get_date_object().get_year() self.doc.write_text(self._('Address: ')) if date: # translators: needed for Arabic, ignore otherwise self.doc.write_text(self._('%s, ') % date ) self.doc.write_text( text ) self.doc.write_text_citation( self.endnotes(addr) ) self.doc.end_paragraph() if self.inc_attrs: attrs = person.get_attribute_list() if first and attrs: self.doc.start_paragraph('DDR-MoreHeader') self.doc.write_text(self._('More about %(person_name)s:') % { 'person_name' : name }) self.doc.end_paragraph() first = False for attr in attrs: self.doc.start_paragraph('DDR-MoreDetails') attrName = self._get_type(attr.get_type()) text = self._("%(type)s: %(value)s%(endnotes)s") % { 'type' : self._(attrName), 'value' : attr.get_value(), 'endnotes' : self.endnotes(attr) } self.doc.write_text_citation( text ) self.doc.end_paragraph() def endnotes(self, obj): if not obj or not self.inc_sources: return "" txt = endnotes.cite_source(self.bibli, self.db, obj, self._locale) if txt: txt = '<super>' + txt + '</super>' return txt
class AncestorReport(Report): """ Ancestor Report class """ def __init__(self, database, options, user): """ Create the AncestorReport object that produces the Ahnentafel report. The arguments are: database - the Gramps database instance options - instance of the Options class for this report user - a gen.user.User() instance This report needs the following parameters (class variables) that come in the options class. gen - Maximum number of generations to include. pagebbg - Whether to include page breaks between generations. name_format - Preferred format to display names incl_private - Whether to include private data living_people - How to handle living people years_past_death - Consider as living this many years after death """ Report.__init__(self, database, options, user) self.map = {} menu = options.menu lang = menu.get_option_by_name('trans').get_value() rlocale = self.set_locale(lang) stdoptions.run_private_data_option(self, menu) stdoptions.run_living_people_option(self, menu, rlocale) self.database = CacheProxyDb(self.database) self.max_generations = menu.get_option_by_name('maxgen').get_value() self.pgbrk = menu.get_option_by_name('pagebbg').get_value() self.opt_namebrk = menu.get_option_by_name('namebrk').get_value() pid = menu.get_option_by_name('pid').get_value() self.center_person = self.database.get_person_from_gramps_id(pid) if (self.center_person == None): raise ReportError(_("Person %s is not in the Database") % pid) stdoptions.run_name_format_option(self, menu) self.__narrator = Narrator(self.database, use_fulldate=True, nlocale=rlocale) def apply_filter(self, person_handle, index, generation=1): """ Recursive function to walk back all parents of the current person. When max_generations are hit, we stop the traversal. """ # check for end of the current recursion level. This happens # if the person handle is None, or if the max_generations is hit if not person_handle or generation > self.max_generations: return # store the person in the map based off their index number # which is passed to the routine. self.map[index] = person_handle # retrieve the Person instance from the database from the # passed person_handle and find the parents from the list. # Since this report is for natural parents (birth parents), # we have to handle that parents may not person = self.database.get_person_from_handle(person_handle) if person is None: return father_handle = None mother_handle = None for family_handle in person.get_parent_family_handle_list(): family = self.database.get_family_from_handle(family_handle) # filter the child_ref_list to find the reference that matches # the passed person. There should be exactly one, but there is # nothing that prevents the same child in the list multiple times. ref = [ c for c in family.get_child_ref_list() if c.get_reference_handle() == person_handle ] if ref: # If the father_handle is not defined and the relationship is # BIRTH, then we have found the birth father. Same applies to # the birth mother. If for some reason, the we have multiple # people defined as the birth parents, we will select based on # priority in the list if not father_handle and \ ref[0].get_father_relation() == ChildRefType.BIRTH: father_handle = family.get_father_handle() if not mother_handle and \ ref[0].get_mother_relation() == ChildRefType.BIRTH: mother_handle = family.get_mother_handle() # Recursively call the function. It is okay if the handle is None, # since routine handles a handle of None self.apply_filter(father_handle, index * 2, generation + 1) self.apply_filter(mother_handle, (index * 2) + 1, generation + 1) def write_report(self): """ The routine the actually creates the report. At this point, the document is opened and ready for writing. """ # Call apply_filter to build the self.map array of people in the # database that match the ancestry. self.apply_filter(self.center_person.get_handle(), 1) # Write the title line. Set in INDEX marker so that this section will be # identified as a major category if this is included in a Book report. name = self._name_display.display_formal(self.center_person) # feature request 2356: avoid genitive form title = self._("Ahnentafel Report for %s") % name mark = IndexMark(title, INDEX_TYPE_TOC, 1) self.doc.start_paragraph("AHN-Title") self.doc.write_text(title, mark) self.doc.end_paragraph() # get the entries out of the map, and sort them. generation = 0 for key in sorted(self.map): # check the index number to see if we need to start a new generation if generation == log2(key): # generate a page break if requested if self.pgbrk and generation > 0: self.doc.page_break() generation += 1 # Create the Generation title, set an index marker gen_text = self._("Generation %d") % generation mark = None # don't need any with no page breaks if self.pgbrk: mark = IndexMark(gen_text, INDEX_TYPE_TOC, 2) self.doc.start_paragraph("AHN-Generation") self.doc.write_text(gen_text, mark) self.doc.end_paragraph() # Build the entry self.doc.start_paragraph("AHN-Entry", "%d." % key) person = self.database.get_person_from_handle(self.map[key]) if person is None: continue name = self._name_display.display(person) mark = utils.get_person_mark(self.database, person) # write the name in bold self.doc.start_bold() self.doc.write_text(name.strip(), mark) self.doc.end_bold() # terminate with a period if it is not already terminated. # This can happen if the person's name ends with something 'Jr.' if name[-1:] == '.': self.doc.write_text(" ") else: self.doc.write_text(". ") # Add a line break if requested (not implemented yet) if self.opt_namebrk: self.doc.write_text('\n') self.__narrator.set_subject(person) self.doc.write_text(self.__narrator.get_born_string()) self.doc.write_text(self.__narrator.get_baptised_string()) self.doc.write_text(self.__narrator.get_christened_string()) self.doc.write_text(self.__narrator.get_died_string()) self.doc.write_text(self.__narrator.get_buried_string()) self.doc.end_paragraph()
class MYDetDescendantReport(Report): def __init__(self, database, options, user): """ Create the DetDescendantReport object that produces the report. The arguments are: database - the GRAMPS database instance options - instance of the Options class for this report user - a gen.user.User() instance 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. pageben - Whether to include page break before End Notes. fulldates - Whether to use full dates instead of just year. listc - Whether to list children. incnotes - Whether to include notes. usecall - Whether to use the call name as the first name. repplace - Whether to replace missing Places with ___________. repdate - Whether to replace missing Dates with ___________. computeage - Whether to compute age. omitda - Whether to omit duplicate ancestors (e.g. when distant cousins marry). verbose - Whether to use complete sentences. numbering - The descendancy numbering system to be utilized. desref - Whether to add descendant references in child list. incphotos - Whether to include images. incnames - Whether to include other names. incevents - Whether to include events. incaddresses - Whether to include addresses. incsrcnotes - Whether to include source notes in the Endnotes section. Only works if Include sources is selected. incmates - Whether to include information about spouses incattrs - Whether to include attributes incpaths - Whether to include the path of descendancy from the start-person to each descendant. incssign - Whether to include a sign ('+') before the descendant number in the child-list to indicate a child has succession. pid - The Gramps ID of the center person for the report. name_format - Preferred format to display names incmateref - Whether to print mate information or reference incl_private - Whether to include private data """ Report.__init__(self, database, options, user) self.map = {} self._user = user menu = options.menu get_option_by_name = menu.get_option_by_name get_value = lambda name: get_option_by_name(name).get_value() stdoptions.run_private_data_option(self, menu) self.db = self.database self.max_generations = get_value('gen') self.pgbrk = get_value('pagebbg') self.pgbrkenotes = get_value('pageben') self.fulldate = get_value('fulldates') use_fulldate = self.fulldate self.listchildren = get_value('listc') self.inc_notes = get_value('incnotes') use_call = get_value('usecall') blankplace = get_value('repplace') blankdate = get_value('repdate') self.calcageflag = get_value('computeage') self.dubperson = get_value('omitda') self.verbose = get_value('verbose') self.numbering = get_value('numbering') self.childref = get_value('desref') self.addimages = get_value('incphotos') self.inc_names = get_value('incnames') self.inc_events = get_value('incevents') self.inc_addr = get_value('incaddresses') self.inc_sources = get_value('incsources') self.inc_srcnotes = get_value('incsrcnotes') self.inc_mates = get_value('incmates') self.inc_attrs = get_value('incattrs') self.inc_paths = get_value('incpaths') self.inc_ssign = get_value('incssign') self.inc_materef = get_value('incmateref') pid = get_value('pid') self.center_person = self.db.get_person_from_gramps_id(pid) if (self.center_person == None): raise ReportError(_("Person %s is not in the Database") % pid) self.gen_handles = {} self.prev_gen_handles = {} self.gen_keys = [] self.dnumber = {} self.dmates = {} if blankdate: empty_date = EMPTY_ENTRY else: empty_date = "" if blankplace: empty_place = EMPTY_ENTRY else: empty_place = "" self._locale = self.set_locale(get_value('trans')) stdoptions.run_name_format_option(self, menu) self.__narrator = Narrator(self.db, self.verbose, use_call, use_fulldate, empty_date, empty_place, nlocale=self._locale, get_endnote_numbers=self.endnotes) self.bibli = Bibliography(Bibliography.MODE_DATE | Bibliography.MODE_PAGE) def apply_henry_filter(self, person_handle, index, pid, cur_gen=1): if (not person_handle) or (cur_gen > self.max_generations): return self.dnumber[person_handle] = pid self.map[index] = person_handle if len(self.gen_keys) < cur_gen: self.gen_keys.append([index]) else: self.gen_keys[cur_gen - 1].append(index) person = self.db.get_person_from_handle(person_handle) index = 0 for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) for child_ref in family.get_child_ref_list(): ix = max(self.map) self.apply_henry_filter(child_ref.ref, ix + 1, pid + HENRY[index], cur_gen + 1) index += 1 # Filter for d'Aboville numbering def apply_daboville_filter(self, person_handle, index, pid, cur_gen=1): if (not person_handle) or (cur_gen > self.max_generations): return self.dnumber[person_handle] = pid self.map[index] = person_handle if len(self.gen_keys) < cur_gen: self.gen_keys.append([index]) else: self.gen_keys[cur_gen - 1].append(index) person = self.db.get_person_from_handle(person_handle) index = 1 for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) for child_ref in family.get_child_ref_list(): ix = max(self.map) self.apply_daboville_filter(child_ref.ref, ix + 1, pid + "." + str(index), cur_gen + 1) index += 1 # Filter for Record-style (Modified Register) numbering def apply_mod_reg_filter_aux(self, person_handle, index, cur_gen=1): if (not person_handle) or (cur_gen > self.max_generations): return self.map[index] = person_handle if len(self.gen_keys) < cur_gen: self.gen_keys.append([index]) else: self.gen_keys[cur_gen - 1].append(index) person = self.db.get_person_from_handle(person_handle) for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) for child_ref in family.get_child_ref_list(): ix = max(self.map) self.apply_mod_reg_filter_aux(child_ref.ref, ix + 1, cur_gen + 1) def apply_mod_reg_filter(self, person_handle): self.apply_mod_reg_filter_aux(person_handle, 1, 1) mod_reg_number = 1 for generation in range(len(self.gen_keys)): for key in self.gen_keys[generation]: person_handle = self.map[key] if person_handle not in self.dnumber: self.dnumber[person_handle] = mod_reg_number mod_reg_number += 1 def write_report(self): """ This function is called by the report system and writes the report. """ if self.numbering == "Henry": self.apply_henry_filter(self.center_person.get_handle(), 1, "1") elif self.numbering == "d'Aboville": self.apply_daboville_filter(self.center_person.get_handle(), 1, "1") elif self.numbering == "Record (Modified Register)": self.apply_mod_reg_filter(self.center_person.get_handle()) else: raise AttributeError("no such numbering: '%s'" % self.numbering) name = self._name_display.display_name( self.center_person.get_primary_name()) if not name: name = self._("Unknown") self.doc.start_paragraph("DDR-Title") # feature request 2356: avoid genitive form title = self._("Descendant Report for %(person_name)s") % { 'person_name': name } mark = IndexMark(title, INDEX_TYPE_TOC, 1) self.doc.write_text(title, mark) self.doc.end_paragraph() generation = 0 self.numbers_printed = list() for generation in range(len(self.gen_keys)): if self.pgbrk and generation > 0: self.doc.page_break() self.doc.start_paragraph("DDR-Generation") text = self._("Generation %d") % (generation + 1) mark = IndexMark(text, INDEX_TYPE_TOC, 2) self.doc.write_text(text, mark) self.doc.end_paragraph() if self.childref: self.prev_gen_handles = self.gen_handles.copy() self.gen_handles.clear() for key in self.gen_keys[generation]: person_handle = self.map[key] self.gen_handles[person_handle] = key self.write_person(key) if self.inc_sources: if self.pgbrkenotes: self.doc.page_break() # it ignores language set for Note type (use locale) endnotes.write_endnotes(self.bibli, self.db, self.doc, printnotes=self.inc_srcnotes, elocale=self._locale) def write_path(self, person): path = [] while True: #person changes in the loop family_handle = person.get_main_parents_family_handle() if family_handle: family = self.db.get_family_from_handle(family_handle) mother_handle = family.get_mother_handle() father_handle = family.get_father_handle() if mother_handle and mother_handle in self.dnumber: person = self.db.get_person_from_handle(mother_handle) person_name = self._name_display.display_name( person.get_primary_name()) path.append(person_name) elif father_handle and father_handle in self.dnumber: person = self.db.get_person_from_handle(father_handle) person_name = self._name_display.display_name( person.get_primary_name()) path.append(person_name) else: break else: break index = len(path) if index: self.doc.write_text("(") for name in path: if index == 1: self.doc.write_text(name + "-" + str(index) + ") ") else: # translators: needed for Arabic, ignore otherwise self.doc.write_text(name + "-" + str(index) + self._("; ")) index -= 1 def write_person(self, key): """Output birth, death, parentage, marriage and notes information """ person_handle = self.map[key] person = self.db.get_person_from_handle(person_handle) val = self.dnumber[person_handle] if val in self.numbers_printed: return else: self.numbers_printed.append(val) self.doc.start_paragraph("DDR-First-Entry", "%s." % val) name = self._name_display.display(person) if not name: name = self._("Unknown") mark = ReportUtils.get_person_mark(self.db, person) self.doc.start_bold() self.doc.write_text(name, mark) if name[-1:] == '.': self.doc.write_text_citation("%s " % self.endnotes(person)) elif name: self.doc.write_text_citation("%s. " % self.endnotes(person)) self.doc.end_bold() if self.inc_paths: self.write_path(person) if self.dubperson: # Check for duplicate record (result of distant cousins marrying) for dkey in sorted(self.map): if dkey >= key: break if self.map[key] == self.map[dkey]: self.doc.write_text( self._("%(name)s is the same person as [%(id_str)s].") % { 'name': '', 'id_str': self.dnumber[self.map[dkey]], }) self.doc.end_paragraph() return self.doc.end_paragraph() self.write_person_info(person) if (self.inc_mates or self.listchildren or self.inc_notes or self.inc_events or self.inc_attrs): for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) if self.inc_mates: self.__write_mate(person, family) if self.listchildren: self.__write_children(family) if self.inc_notes: self.__write_family_notes(family) first = True if self.inc_events: first = self.__write_family_events(family) if self.inc_attrs: self.__write_family_attrs(family, first) def write_event(self, event_ref): text = "" event = self.db.get_event_from_handle(event_ref.ref) if self.fulldate: date = self._get_date(event.get_date_object()) else: date = event.get_date_object().get_year() place = place_displayer.display_event(self.db, event) self.doc.start_paragraph('DDR-MoreDetails') event_name = self._get_type(event.get_type()) if date and place: text += self._('%(date)s, %(place)s') % { 'date': date, 'place': place } elif date: text += self._('%(date)s') % {'date': date} elif place: text += self._('%(place)s') % {'place': place} if event.get_description(): if text: text += ". " text += event.get_description() text += self.endnotes(event) if text: text += ". " text = self._('%(event_name)s: %(event_text)s') % { 'event_name': self._(event_name), 'event_text': text } self.doc.write_text_citation(text) if self.inc_attrs: text = "" attr_list = event.get_attribute_list() attr_list.extend(event_ref.get_attribute_list()) for attr in attr_list: if text: # translators: needed for Arabic, ignore otherwise text += self._("; ") attrName = attr.get_type().type2base() # translators: needed for French, ignore otherwise text += self._("%(type)s: %(value)s%(endnotes)s") % { 'type': self._(attrName), 'value': attr.get_value(), 'endnotes': self.endnotes(attr) } text = " " + text self.doc.write_text_citation(text) self.doc.end_paragraph() if self.inc_notes: # if the event or event reference has a note attached to it, # get the text and format it correctly notelist = event.get_note_list() notelist.extend(event_ref.get_note_list()) for notehandle in notelist: note = self.db.get_note_from_handle(notehandle) self.doc.write_styled_note( note.get_styledtext(), note.get_format(), "DDR-MoreDetails", contains_html=note.get_type() == NoteType.HTML_CODE) def __write_parents(self, person): family_handle = person.get_main_parents_family_handle() if family_handle: family = self.db.get_family_from_handle(family_handle) mother_handle = family.get_mother_handle() father_handle = family.get_father_handle() if mother_handle: mother = self.db.get_person_from_handle(mother_handle) mother_name = self._name_display.display_name( mother.get_primary_name()) mother_mark = ReportUtils.get_person_mark(self.db, mother) else: mother_name = "" mother_mark = "" if father_handle: father = self.db.get_person_from_handle(father_handle) father_name = self._name_display.display_name( father.get_primary_name()) father_mark = ReportUtils.get_person_mark(self.db, father) else: father_name = "" father_mark = "" text = self.__narrator.get_child_string(father_name, mother_name) if text: self.doc.write_text(text) if father_mark: self.doc.write_text("", father_mark) if mother_mark: self.doc.write_text("", mother_mark) def write_marriage(self, person): """ Output marriage sentence. """ is_first = True for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) spouse_handle = ReportUtils.find_spouse(person, family) spouse = self.db.get_person_from_handle(spouse_handle) text = "" spouse_mark = ReportUtils.get_person_mark(self.db, spouse) text = self.__narrator.get_married_string(family, is_first, self._name_display) if text: self.doc.write_text_citation(text, spouse_mark) is_first = False def __write_mate(self, person, family): """ Write information about the person's spouse/mate. """ if person.get_gender() == Person.MALE: mate_handle = family.get_mother_handle() else: mate_handle = family.get_father_handle() if mate_handle: mate = self.db.get_person_from_handle(mate_handle) self.doc.start_paragraph("DDR-MoreHeader") name = self._name_display.display(mate) if not name: name = self._("Unknown") mark = ReportUtils.get_person_mark(self.db, mate) if family.get_relationship() == FamilyRelType.MARRIED: self.doc.write_text(self._("Spouse: %s") % name, mark) else: self.doc.write_text( self._("Relationship with: %s") % name, mark) if name[-1:] != '.': self.doc.write_text(".") self.doc.write_text_citation(self.endnotes(mate)) self.doc.end_paragraph() if not self.inc_materef: # Don't want to just print reference self.write_person_info(mate) else: # Check to see if we've married a cousin if mate_handle in self.dnumber: self.doc.start_paragraph('DDR-MoreDetails') self.doc.write_text_citation( self._("Ref: %(number)s. %(name)s") % { 'number': self.dnumber[mate_handle], 'name': name }) self.doc.end_paragraph() else: self.dmates[mate_handle] = person.get_handle() self.write_person_info(mate) def __get_mate_names(self, family): mother_handle = family.get_mother_handle() if mother_handle: mother = self.db.get_person_from_handle(mother_handle) mother_name = self._name_display.display(mother) if not mother_name: mother_name = self._("Unknown") else: mother_name = self._("Unknown") father_handle = family.get_father_handle() if father_handle: father = self.db.get_person_from_handle(father_handle) father_name = self._name_display.display(father) if not father_name: father_name = self._("Unknown") else: father_name = self._("Unknown") return mother_name, father_name def __write_children(self, family): """ List the children for the given family. """ if not family.get_child_ref_list(): return mother_name, father_name = self.__get_mate_names(family) self.doc.start_paragraph("DDR-ChildTitle") self.doc.write_text( self._("Children of %(mother_name)s and %(father_name)s") % { 'father_name': father_name, 'mother_name': mother_name }) self.doc.end_paragraph() cnt = 1 for child_ref in family.get_child_ref_list(): child_handle = child_ref.ref child = self.db.get_person_from_handle(child_handle) child_name = self._name_display.display(child) if not child_name: child_name = self._("Unknown") child_mark = ReportUtils.get_person_mark(self.db, child) if self.childref and self.prev_gen_handles.get(child_handle): value = str(self.prev_gen_handles.get(child_handle)) child_name += " [%s]" % value if self.inc_ssign: prefix = " " for family_handle in child.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) if family.get_child_ref_list(): prefix = "+ " break else: prefix = "" if child_handle in self.dnumber: self.doc.start_paragraph( "DDR-ChildList", prefix + str(self.dnumber[child_handle]) + " " + ReportUtils.roman(cnt).lower() + ".") else: self.doc.start_paragraph( "DDR-ChildList", prefix + ReportUtils.roman(cnt).lower() + ".") cnt += 1 self.doc.write_text("%s. " % child_name, child_mark) self.__narrator.set_subject(child) self.doc.write_text_citation( self.__narrator.get_born_string() or self.__narrator.get_christened_string() or self.__narrator.get_baptised_string()) self.doc.write_text_citation( self.__narrator.get_died_string() or self.__narrator.get_buried_string()) self.doc.end_paragraph() def __write_family_notes(self, family): """ Write the notes for the given family. """ notelist = family.get_note_list() if len(notelist) > 0: mother_name, father_name = self.__get_mate_names(family) self.doc.start_paragraph("DDR-NoteHeader") self.doc.write_text( self._('Notes for %(mother_name)s and %(father_name)s:') % { 'mother_name': mother_name, 'father_name': father_name }) self.doc.end_paragraph() for notehandle in notelist: note = self.db.get_note_from_handle(notehandle) self.doc.write_styled_note(note.get_styledtext(), note.get_format(), "DDR-Entry") def __write_family_events(self, family): """ List the events for the given family. """ if not family.get_event_ref_list(): return mother_name, father_name = self.__get_mate_names(family) first = True for event_ref in family.get_event_ref_list(): if first: self.doc.start_paragraph('DDR-MoreHeader') self.doc.write_text( self._('More about %(mother_name)s and %(father_name)s:') % { 'mother_name': mother_name, 'father_name': father_name }) self.doc.end_paragraph() first = False self.write_event(event_ref) return first def __write_family_attrs(self, family, first): """ List the attributes for the given family. """ attrs = family.get_attribute_list() if first and attrs: mother_name, father_name = self.__get_mate_names(family) self.doc.start_paragraph('DDR-MoreHeader') self.doc.write_text( self._('More about %(mother_name)s and %(father_name)s:') % { 'mother_name': mother_name, 'father_name': father_name }) self.doc.end_paragraph() for attr in attrs: self.doc.start_paragraph('DDR-MoreDetails') attrName = self._get_type(attr.get_type()) text = self._("%(type)s: %(value)s%(endnotes)s") % { 'type': self._(attrName), 'value': attr.get_value(), 'endnotes': self.endnotes(attr) } self.doc.write_text_citation(text) self.doc.end_paragraph() if self.inc_notes: # if the attr or attr reference has a note attached to it, # get the text and format it correctly notelist = attr.get_note_list() for notehandle in notelist: note = self.db.get_note_from_handle(notehandle) self.doc.write_styled_note(note.get_styledtext(), note.get_format(), "DDR-MoreDetails") def write_person_info(self, person): name = self._name_display.display(person) if not name: name = self._("Unknown") self.__narrator.set_subject(person) plist = person.get_media_list() if self.addimages and len(plist) > 0: photo = plist[0] ReportUtils.insert_image(self.db, self.doc, photo, self._user) self.doc.start_paragraph("DDR-Entry") if not self.verbose: self.__write_parents(person) text = self.__narrator.get_born_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_baptised_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_christened_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_died_string(self.calcageflag) if text: self.doc.write_text_citation(text) text = self.__narrator.get_buried_string() if text: self.doc.write_text_citation(text) if self.verbose: self.__write_parents(person) self.write_marriage(person) self.doc.end_paragraph() notelist = person.get_note_list() if len(notelist) > 0 and self.inc_notes: self.doc.start_paragraph("DDR-NoteHeader") # feature request 2356: avoid genitive form self.doc.write_text(self._("Notes for %s") % name) self.doc.end_paragraph() for notehandle in notelist: note = self.db.get_note_from_handle(notehandle) self.doc.write_styled_note( note.get_styledtext(), note.get_format(), "DDR-Entry", contains_html=note.get_type() == NoteType.HTML_CODE) first = True if self.inc_names: for alt_name in person.get_alternate_names(): if first: self.doc.start_paragraph('DDR-MoreHeader') self.doc.write_text( self._('More about %(person_name)s:') % {'person_name': name}) self.doc.end_paragraph() first = False self.doc.start_paragraph('DDR-MoreDetails') atype = self._get_type(alt_name.get_type()) aname = alt_name.get_regular_name() self.doc.write_text_citation( self._('%(name_kind)s: %(name)s%(endnotes)s') % { 'name_kind': self._(atype), 'name': aname, 'endnotes': self.endnotes(alt_name), }) self.doc.end_paragraph() if self.inc_events: for event_ref in person.get_primary_event_ref_list(): if first: self.doc.start_paragraph('DDR-MoreHeader') self.doc.write_text( self._('More about %(person_name)s:') % {'person_name': name}) self.doc.end_paragraph() first = 0 self.write_event(event_ref) if self.inc_addr: for addr in person.get_address_list(): if first: self.doc.start_paragraph('DDR-MoreHeader') self.doc.write_text( self._('More about %(person_name)s:') % {'person_name': name}) self.doc.end_paragraph() first = False self.doc.start_paragraph('DDR-MoreDetails') text = ReportUtils.get_address_str(addr) if self.fulldate: date = self._get_date(addr.get_date_object()) else: date = addr.get_date_object().get_year() self.doc.write_text(self._('Address: ')) if date: # translators: needed for Arabic, ignore otherwise self.doc.write_text(self._('%s, ') % date) self.doc.write_text(text) self.doc.write_text_citation(self.endnotes(addr)) self.doc.end_paragraph() if self.inc_attrs: attrs = person.get_attribute_list() if first and attrs: self.doc.start_paragraph('DDR-MoreHeader') self.doc.write_text( self._('More about %(person_name)s:') % {'person_name': name}) self.doc.end_paragraph() first = False for attr in attrs: self.doc.start_paragraph('DDR-MoreDetails') attrName = attr.get_type().type2base() # translators: needed for French, ignore otherwise text = self._("%(type)s: %(value)s%(endnotes)s") % { 'type': self._(attrName), 'value': attr.get_value(), 'endnotes': self.endnotes(attr) } self.doc.write_text_citation(text) self.doc.end_paragraph() def endnotes(self, obj): if not obj or not self.inc_sources: return "" txt = endnotes.cite_source(self.bibli, self.db, obj, self._locale) if txt: txt = '<super>' + txt + '</super>' return txt
class AncestorReport(Report): """ Ancestor Report class """ def __init__(self, database, options, user): """ Create the AncestorReport object that produces the Ahnentafel report. The arguments are: database - the GRAMPS database instance options - instance of the Options class for this report user - a gen.user.User() instance This report needs the following parameters (class variables) that come in the options class. gen - Maximum number of generations to include. pagebbg - Whether to include page breaks between generations. name_format - Preferred format to display names incl_private - Whether to include private data """ Report.__init__(self, database, options, user) self.map = {} menu = options.menu stdoptions.run_private_data_option(self, menu) self.max_generations = menu.get_option_by_name('maxgen').get_value() self.pgbrk = menu.get_option_by_name('pagebbg').get_value() self.opt_namebrk = menu.get_option_by_name('namebrk').get_value() pid = menu.get_option_by_name('pid').get_value() self.center_person = database.get_person_from_gramps_id(pid) if (self.center_person == None) : raise ReportError(_("Person %s is not in the Database") % pid ) lang = menu.get_option_by_name('trans').get_value() rlocale = self.set_locale(lang) stdoptions.run_name_format_option(self, menu) self.__narrator = Narrator(self.database, use_fulldate=True, nlocale=rlocale) def apply_filter(self, person_handle, index, generation=1): """ Recursive function to walk back all parents of the current person. When max_generations are hit, we stop the traversal. """ # check for end of the current recursion level. This happens # if the person handle is None, or if the max_generations is hit if not person_handle or generation > self.max_generations: return # store the person in the map based off their index number # which is passed to the routine. self.map[index] = person_handle # retrieve the Person instance from the database from the # passed person_handle and find the parents from the list. # Since this report is for natural parents (birth parents), # we have to handle that parents may not person = self.database.get_person_from_handle(person_handle) father_handle = None mother_handle = None for family_handle in person.get_parent_family_handle_list(): family = self.database.get_family_from_handle(family_handle) # filter the child_ref_list to find the reference that matches # the passed person. There should be exactly one, but there is # nothing that prevents the same child in the list multiple times. ref = [ c for c in family.get_child_ref_list() if c.get_reference_handle() == person_handle] if ref: # If the father_handle is not defined and the relationship is # BIRTH, then we have found the birth father. Same applies to # the birth mother. If for some reason, the we have multiple # people defined as the birth parents, we will select based on # priority in the list if not father_handle and \ ref[0].get_father_relation() == ChildRefType.BIRTH: father_handle = family.get_father_handle() if not mother_handle and \ ref[0].get_mother_relation() == ChildRefType.BIRTH: mother_handle = family.get_mother_handle() # Recursively call the function. It is okay if the handle is None, # since routine handles a handle of None self.apply_filter(father_handle, index*2, generation+1) self.apply_filter(mother_handle, (index*2)+1, generation+1) def write_report(self): """ The routine the actually creates the report. At this point, the document is opened and ready for writing. """ # Call apply_filter to build the self.map array of people in the # database that match the ancestry. self.apply_filter(self.center_person.get_handle(), 1) # Write the title line. Set in INDEX marker so that this section will be # identified as a major category if this is included in a Book report. name = self._name_display.display_formal(self.center_person) # feature request 2356: avoid genitive form title = self._("Ahnentafel Report for %s") % name mark = IndexMark(title, INDEX_TYPE_TOC, 1) self.doc.start_paragraph("AHN-Title") self.doc.write_text(title, mark) self.doc.end_paragraph() # get the entries out of the map, and sort them. generation = 0 for key in sorted(self.map): # check the index number to see if we need to start a new generation if generation == log2(key): # generate a page break if requested if self.pgbrk and generation > 0: self.doc.page_break() generation += 1 # Create the Generation title, set an index marker gen_text = self._("Generation %d") % generation mark = None # don't need any with no page breaks if self.pgbrk: mark = IndexMark(gen_text, INDEX_TYPE_TOC, 2) self.doc.start_paragraph("AHN-Generation") self.doc.write_text(gen_text, mark) self.doc.end_paragraph() # Build the entry self.doc.start_paragraph("AHN-Entry","%d." % key) person = self.database.get_person_from_handle(self.map[key]) name = self._name_display.display(person) mark = ReportUtils.get_person_mark(self.database, person) # write the name in bold self.doc.start_bold() self.doc.write_text(name.strip(), mark) self.doc.end_bold() # terminate with a period if it is not already terminated. # This can happen if the person's name ends with something 'Jr.' if name[-1:] == '.': self.doc.write_text(" ") else: self.doc.write_text(". ") # Add a line break if requested (not implemented yet) if self.opt_namebrk: self.doc.write_text('\n') self.__narrator.set_subject(person) self.doc.write_text(self.__narrator.get_born_string()) self.doc.write_text(self.__narrator.get_baptised_string()) self.doc.write_text(self.__narrator.get_christened_string()) self.doc.write_text(self.__narrator.get_died_string()) self.doc.write_text(self.__narrator.get_buried_string()) self.doc.end_paragraph()
class DetAncestorReport(Report): """ the Detailed Ancestor Report """ def __init__(self, database, options, user): """ Create the DetAncestorReport object that produces the report. The arguments are: database - the Gramps database instance options - instance of the Options class for this report user - a gen.user.User() instance This report needs the following parameters (class variables) that come in the options class. gen - Maximum number of generations to include. inc_id - Whether to include Gramps IDs pagebgg - Whether to include page breaks between generations. pageben - Whether to include page break before End Notes. firstName - Whether to use first names instead of pronouns. fulldate - Whether to use full dates instead of just year. listchildren - Whether to list children. list_children_spouses - Whether to list the spouses of the children includenotes - Whether to include notes. incattrs - Whether to include attributes 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 marry). verbose - Whether to use complete sentences childref - Whether to add descendant references in child list. addimages - Whether to include images. pid - The Gramps ID of the center person for the report. name_format - Preferred format to display names other_events - Whether to include other events. incl_private - Whether to include private data living_people - How to handle living people years_past_death - Consider as living this many years after death """ Report.__init__(self, database, options, user) self.map = {} self._user = user menu = options.menu get_option_by_name = menu.get_option_by_name get_value = lambda name: get_option_by_name(name).get_value() self.set_locale(menu.get_option_by_name('trans').get_value()) stdoptions.run_date_format_option(self, menu) stdoptions.run_private_data_option(self, menu) stdoptions.run_living_people_option(self, menu, self._locale) self.database = CacheProxyDb(self.database) self._db = self.database self.max_generations = get_value('gen') self.pgbrk = get_value('pagebbg') self.pgbrkenotes = get_value('pageben') self.fulldate = get_value('fulldates') use_fulldate = self.fulldate self.listchildren = get_value('listc') self.list_children_spouses = get_value('listc_spouses') self.includenotes = get_value('incnotes') use_call = get_value('usecall') blankplace = get_value('repplace') blankdate = get_value('repdate') self.calcageflag = get_value('computeage') self.dupperson = get_value('omitda') self.verbose = get_value('verbose') self.childref = get_value('desref') self.addimages = get_value('incphotos') self.inc_names = get_value('incnames') self.inc_events = get_value('incevents') self.inc_addr = get_value('incaddresses') self.inc_sources = get_value('incsources') self.inc_srcnotes = get_value('incsrcnotes') self.inc_attrs = get_value('incattrs') self.initial_sosa = get_value('initial_sosa') self.want_ids = get_value('inc_id') pid = get_value('pid') self.other_events = get_value('incotherevents') self.center_person = self._db.get_person_from_gramps_id(pid) if self.center_person is None: raise ReportError(_("Person %s is not in the Database") % pid) stdoptions.run_name_format_option(self, menu) self._nd = self._name_display self.gen_handles = {} self.prev_gen_handles = {} if blankdate: empty_date = EMPTY_ENTRY else: empty_date = "" if blankplace: empty_place = EMPTY_ENTRY else: empty_place = "" self.__narrator = Narrator(self._db, self.verbose, use_call, use_fulldate, empty_date, empty_place, nlocale=self._locale, get_endnote_numbers=self.endnotes) self.bibli = Bibliography(Bibliography.MODE_DATE|Bibliography.MODE_PAGE) def apply_filter(self, person_handle, index): """ recurse up through the generations """ if (not person_handle) or (index >= 2**self.max_generations): return self.map[index] = person_handle person = self._db.get_person_from_handle(person_handle) family_handle = person.get_main_parents_family_handle() if family_handle: family = self._db.get_family_from_handle(family_handle) self.apply_filter(family.get_father_handle(), index*2) self.apply_filter(family.get_mother_handle(), (index*2)+1) def write_report(self): self.apply_filter(self.center_person.get_handle(), 1) name = self._nd.display_name(self.center_person.get_primary_name()) if not name: name = self._("Unknown") self.doc.start_paragraph("DAR-Title") # feature request 2356: avoid genitive form title = self._("Ancestral Report for %s") % name mark = IndexMark(title, INDEX_TYPE_TOC, 1) self.doc.write_text(title, mark) self.doc.end_paragraph() generation = 0 for key in sorted(self.map): if generation == 0 or key >= 2**generation: if self.pgbrk and generation > 0: self.doc.page_break() self.doc.start_paragraph("DAR-Generation") text = self._("Generation %d") % (generation+1) mark = IndexMark(text, INDEX_TYPE_TOC, 2) self.doc.write_text(text, mark) self.doc.end_paragraph() generation += 1 if self.childref: self.prev_gen_handles = self.gen_handles.copy() self.gen_handles.clear() person_handle = self.map[key] person = self._db.get_person_from_handle(person_handle) self.gen_handles[person_handle] = key dupperson = self.write_person(key) if dupperson == 0: # Is this a duplicate ind record if self.listchildren or self.inc_events: for family_handle in person.get_family_handle_list(): family = self._db.get_family_from_handle(family_handle) mother_handle = family.get_mother_handle() if (mother_handle is None or mother_handle not in iter(self.map.values()) or person.get_gender() == Person.FEMALE): # The second test above also covers the 1. person's # mate, which is not an ancestor and as such is not # included in the self.map dictionary if self.listchildren: self.write_children(family) if self.inc_events: self.write_family_events(family) if self.inc_sources: if self.pgbrkenotes: self.doc.page_break() # it ignores language set for Note type (use locale) endnotes.write_endnotes(self.bibli, self._db, self.doc, printnotes=self.inc_srcnotes, elocale=self._locale) def _get_s_s(self, key): """returns Sosa-Stradonitz (a.k.a. Kekule or Ahnentafel) number""" generation = int(math.floor(math.log(key, 2))) # 0 gen_start = pow(2, generation) # 1 new_gen_start = self.initial_sosa * gen_start # 3 return new_gen_start + (key - gen_start) # 3+0 def write_person(self, key): """ Output birth, death, parentage, marriage and notes information """ def write_more_header(first, name): """ convenience function """ if first: self.doc.start_paragraph('DAR-MoreHeader') self.doc.write_text(self._('More about %(person_name)s:' ) % {'person_name' : name}) self.doc.end_paragraph() return False person_handle = self.map[key] person = self._db.get_person_from_handle(person_handle) plist = person.get_media_list() self.__narrator.set_subject(person) if self.addimages and len(plist) > 0: photo = plist[0] utils.insert_image(self._db, self.doc, photo, self._user) self.doc.start_paragraph("DAR-First-Entry", "%d." % self._get_s_s(key)) name = self._nd.display(person) if not name: name = self._("Unknown") mark = utils.get_person_mark(self._db, person) self.doc.start_bold() self.doc.write_text(name, mark) if name[-1:] == '.': self.doc.write_text_citation("%s " % self.endnotes(person)) elif name: self.doc.write_text_citation("%s. " % self.endnotes(person)) self.doc.end_bold() if self.want_ids: self.doc.write_text('(%s) ' % person.get_gramps_id()) if self.dupperson: # Check for duplicate record (result of distant cousins marrying) for dkey in sorted(self.map): if dkey >= key: break if self.map[key] == self.map[dkey]: self.doc.write_text( self._("%(name)s is the same person as [%(id_str)s]." ) % {'name' : '', 'id_str' : str(dkey)}) self.doc.end_paragraph() return 1 # Duplicate person if not self.verbose: self.write_parents(person) text = self.__narrator.get_born_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_baptised_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_christened_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_died_string(self.calcageflag) if text: self.doc.write_text_citation(text) text = self.__narrator.get_buried_string() if text: self.doc.write_text_citation(text) if self.verbose: self.write_parents(person) if not key % 2 or key == 1: self.write_marriage(person) self.doc.end_paragraph() if key == 1: self.write_mate(person) notelist = person.get_note_list() if len(notelist) > 0 and self.includenotes: self.doc.start_paragraph("DAR-NoteHeader") # feature request 2356: avoid genitive form self.doc.write_text(self._("Notes for %s") % name) self.doc.end_paragraph() for notehandle in notelist: note = self._db.get_note_from_handle(notehandle) self.doc.write_styled_note( note.get_styledtext(), note.get_format(), "DAR-Entry", contains_html=(note.get_type() == NoteType.HTML_CODE) ) first = True if self.inc_names: for alt_name in person.get_alternate_names(): first = write_more_header(first, name) self.doc.start_paragraph('DAR-MoreDetails') atype = self._get_type(alt_name.get_type()) self.doc.write_text_citation( self._('%(type)s: %(value)s%(endnotes)s' ) % {'type' : self._(atype), 'value' : alt_name.get_regular_name(), 'endnotes' : self.endnotes(alt_name)}) self.doc.end_paragraph() if self.inc_events: birth_ref = person.get_birth_ref() death_ref = person.get_death_ref() for event_ref in person.get_primary_event_ref_list(): if event_ref == birth_ref or event_ref == death_ref: continue first = write_more_header(first, name) self.write_event(event_ref) if self.other_events: for event_ref in person.get_event_ref_list(): role = event_ref.get_role() if role in (EventRoleType.PRIMARY, EventRoleType.FAMILY): continue first = write_more_header(first, name) self.write_event(event_ref) if self.inc_addr: for addr in person.get_address_list(): first = write_more_header(first, name) self.doc.start_paragraph('DAR-MoreDetails') text = utils.get_address_str(addr) self.doc.write_text(self._('Address: ')) if self.fulldate: date = self._get_date(addr.get_date_object()) else: date = addr.get_date_object().get_year() if date: # translators: needed for Arabic, ignore otherwise self.doc.write_text(self._('%s, ') % date) self.doc.write_text(text) self.doc.write_text_citation(self.endnotes(addr)) self.doc.end_paragraph() if self.inc_attrs: attrs = person.get_attribute_list() if attrs: first = write_more_header(first, name) for attr in attrs: self.doc.start_paragraph('DAR-MoreDetails') attr_name = attr.get_type().type2base() # translators: needed for French, ignore otherwise text = self._("%(type)s: %(value)s%(endnotes)s" ) % {'type' : self._(attr_name), 'value' : attr.get_value(), 'endnotes' : self.endnotes(attr)} self.doc.write_text_citation(text) self.doc.end_paragraph() return 0 # Not duplicate person def write_event(self, event_ref): """ write out the event """ text = "" event = self._db.get_event_from_handle(event_ref.ref) if self.fulldate: date = self._get_date(event.get_date_object()) else: date = event.get_date_object().get_year() place = _pd.display_event(self._db, event) self.doc.start_paragraph('DAR-MoreDetails') if date and place: # translators: needed for Arabic, ignore otherwise text += self._('%(str1)s, %(str2)s' ) % {'str1' : date, 'str2' : place} elif date: text += '%s' % date elif place: text += '%s' % self._(place) if event.get_description(): if text: text += ". " text += event.get_description() text += self.endnotes(event) if text: text += ". " event_name = self._(self._get_type(event.get_type())) role = event_ref.get_role() if role in (EventRoleType.PRIMARY, EventRoleType.FAMILY): # translators: needed for French, ignore otherwise text = self._('%(str1)s: %(str2)s' ) % {'str1' : event_name, 'str2' : text} else: primaries = get_participant_from_event(self._db, event_ref.ref) text = self._('%(event_role)s at %(event_name)s ' 'of %(primary_person)s: %(event_text)s' ) % {'event_role' : self._(role.xml_str()), 'event_name' : event_name, 'primary_person' : primaries, 'event_text' : text} self.doc.write_text_citation(text) if self.inc_attrs: text = "" attr_list = event.get_attribute_list() attr_list.extend(event_ref.get_attribute_list()) for attr in attr_list: if text: # translators: needed for Arabic, ignore otherwise text += self._("; ") attr_name = attr.get_type().type2base() # translators: needed for French, ignore otherwise text += self._("%(type)s: %(value)s%(endnotes)s" ) % {'type' : self._(attr_name), 'value' : attr.get_value(), 'endnotes' : self.endnotes(attr)} text = " " + text self.doc.write_text_citation(text) self.doc.end_paragraph() if self.includenotes: # if the event or event reference has a note attached to it, # get the text and format it correctly notelist = event.get_note_list() notelist.extend(event_ref.get_note_list()) for notehandle in notelist: note = self._db.get_note_from_handle(notehandle) self.doc.write_styled_note( note.get_styledtext(), note.get_format(), "DAR-MoreDetails", contains_html=(note.get_type() == NoteType.HTML_CODE) ) def write_parents(self, person): """ write the parents """ family_handle = person.get_main_parents_family_handle() if family_handle: family = self._db.get_family_from_handle(family_handle) mother_handle = family.get_mother_handle() father_handle = family.get_father_handle() if mother_handle: mother = self._db.get_person_from_handle(mother_handle) mother_name = self._nd.display_name(mother.get_primary_name()) mother_mark = utils.get_person_mark(self._db, mother) else: mother_name = "" mother_mark = "" if father_handle: father = self._db.get_person_from_handle(father_handle) father_name = self._nd.display_name(father.get_primary_name()) father_mark = utils.get_person_mark(self._db, father) else: father_name = "" father_mark = "" text = self.__narrator.get_child_string(father_name, mother_name) if text: self.doc.write_text(text) if father_mark: self.doc.write_text("", father_mark) if mother_mark: self.doc.write_text("", mother_mark) def write_marriage(self, person): """ Output marriage sentence. """ is_first = True for family_handle in person.get_family_handle_list(): family = self._db.get_family_from_handle(family_handle) spouse_handle = utils.find_spouse(person, family) if spouse_handle: spouse = self._db.get_person_from_handle(spouse_handle) spouse_mark = utils.get_person_mark(self._db, spouse) else: spouse_mark = None text = self.__narrator.get_married_string(family, is_first, self._nd) if text: self.doc.write_text_citation(text, spouse_mark) if self.want_ids: self.doc.write_text(' (%s)' % family.get_gramps_id()) is_first = False def write_children(self, family): """ List children. :param family: Family :return: """ if not family.get_child_ref_list(): return mother_handle = family.get_mother_handle() if mother_handle: mother = self._db.get_person_from_handle(mother_handle) mother_name = self._nd.display(mother) if not mother_name: mother_name = self._("Unknown") else: mother_name = self._("Unknown") father_handle = family.get_father_handle() if father_handle: father = self._db.get_person_from_handle(father_handle) father_name = self._nd.display(father) if not father_name: father_name = self._("Unknown") else: father_name = self._("Unknown") self.doc.start_paragraph("DAR-ChildTitle") self.doc.write_text( self._("Children of %(mother_name)s and %(father_name)s" ) % {'father_name' : father_name, 'mother_name' : mother_name}) self.doc.end_paragraph() cnt = 1 for child_ref in family.get_child_ref_list(): child_handle = child_ref.ref child = self._db.get_person_from_handle(child_handle) child_name = self._nd.display(child) if not child_name: child_name = self._("Unknown") child_mark = utils.get_person_mark(self._db, child) if self.childref and self.prev_gen_handles.get(child_handle): value = int(self.prev_gen_handles.get(child_handle)) child_name += " [%d]" % self._get_s_s(value) self.doc.start_paragraph("DAR-ChildList", utils.roman(cnt).lower() + ".") cnt += 1 self.__narrator.set_subject(child) if child_name: self.doc.write_text("%s. " % child_name, child_mark) if self.want_ids: self.doc.write_text('(%s) ' % child.get_gramps_id()) self.doc.write_text_citation( self.__narrator.get_born_string() or self.__narrator.get_christened_string() or self.__narrator.get_baptised_string()) self.doc.write_text_citation( self.__narrator.get_died_string() or self.__narrator.get_buried_string()) # if the list_children_spouses option is selected: if self.list_children_spouses: # get the family of the child that contains the spouse # of the child. There may be more than one spouse for each # child family_handle_list = child.get_family_handle_list() # for the first spouse, this is true. # For subsequent spouses, make it false is_first_family = True for family_handle in family_handle_list: child_family = self.database.get_family_from_handle( family_handle ) self.doc.write_text_citation( self.__narrator.get_married_string( child_family, is_first_family, self._name_display ) ) is_first_family = False self.doc.end_paragraph() def write_family_events(self, family): """ write the family events """ if not family.get_event_ref_list(): return mother_handle = family.get_mother_handle() if mother_handle: mother = self._db.get_person_from_handle(mother_handle) mother_name = self._nd.display(mother) if not mother_name: mother_name = self._("Unknown") else: mother_name = self._("Unknown") father_handle = family.get_father_handle() if father_handle: father = self._db.get_person_from_handle(father_handle) father_name = self._nd.display(father) if not father_name: father_name = self._("Unknown") else: father_name = self._("Unknown") first = True for event_ref in family.get_event_ref_list(): if first: self.doc.start_paragraph('DAR-MoreHeader') self.doc.write_text( self._('More about %(mother_name)s and %(father_name)s:' ) % {'mother_name' : mother_name, 'father_name' : father_name}) self.doc.end_paragraph() first = False self.write_event(event_ref) def write_mate(self, person): """Output birth, death, parentage, marriage and notes information """ ind = None has_info = False for family_handle in person.get_family_handle_list(): family = self._db.get_family_from_handle(family_handle) ind_handle = None if person.get_gender() == Person.MALE: ind_handle = family.get_mother_handle() else: ind_handle = family.get_father_handle() if ind_handle: ind = self._db.get_person_from_handle(ind_handle) for event_ref in ind.get_primary_event_ref_list(): event = self._db.get_event_from_handle(event_ref.ref) if event: etype = event.get_type() if (etype == EventType.BAPTISM or etype == EventType.BURIAL or etype == EventType.BIRTH or etype == EventType.DEATH): has_info = True break if not has_info: family_handle = ind.get_main_parents_family_handle() if family_handle: fam = self._db.get_family_from_handle(family_handle) if fam.get_mother_handle() or fam.get_father_handle(): has_info = True break if has_info: self.doc.start_paragraph("DAR-MoreHeader") plist = ind.get_media_list() if self.addimages and len(plist) > 0: photo = plist[0] utils.insert_image(self._db, self.doc, photo, self._user) name = self._nd.display(ind) if not name: name = self._("Unknown") mark = utils.get_person_mark(self._db, ind) if family.get_relationship() == FamilyRelType.MARRIED: self.doc.write_text(self._("Spouse: %s" ) % name, mark) else: self.doc.write_text(self._("Relationship with: %s" ) % name, mark) if name[-1:] != '.': self.doc.write_text(".") if self.want_ids: self.doc.write_text(' (%s)' % ind.get_gramps_id()) self.doc.write_text_citation(self.endnotes(ind)) self.doc.end_paragraph() self.doc.start_paragraph("DAR-Entry") self.__narrator.set_subject(ind) text = self.__narrator.get_born_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_baptised_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_christened_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_died_string(self.calcageflag) if text: self.doc.write_text_citation(text) text = self.__narrator.get_buried_string() if text: self.doc.write_text_citation(text) self.write_parents(ind) self.doc.end_paragraph() def endnotes(self, obj): """ cite the endnotes for the object """ if not obj or not self.inc_sources: return "" txt = endnotes.cite_source(self.bibli, self._db, obj, self._locale) if txt: txt = '<super>' + txt + '</super>' return txt
def __init__(self, database, options, user): """ Create the DetDescendantReport object that produces the report. The arguments are: database - the Gramps database instance options - instance of the Options class for this report user - a gen.user.User() instance This report needs the following parameters (class variables) that come in the options class. gen - Maximum number of generations to include. inc_id - Whether to include Gramps IDs pagebgg - Whether to include page breaks between generations. pageben - Whether to include page break before End Notes. fulldates - Whether to use full dates instead of just year. listc - Whether to list children. list_children_spouses - Whether to list the spouses of the children incnotes - Whether to include notes. usecall - Whether to use the call name as the first name. repplace - Whether to replace missing Places with ___________. repdate - Whether to replace missing Dates with ___________. computeage - Whether to compute age. verbose - Whether to use complete sentences. numbering - The descendancy numbering system to be utilized. desref - Whether to add descendant references in child list. incphotos - Whether to include images. incnames - Whether to include other names. incevents - Whether to include events. incaddresses - Whether to include addresses. incsrcnotes - Whether to include source notes in the Endnotes section. Only works if Include sources is selected. incmates - Whether to include information about spouses incattrs - Whether to include attributes incpaths - Whether to include the path of descendancy from the start-person to each descendant. incssign - Whether to include a sign ('+') before the descendant number in the child-list to indicate a child has succession. pid - The Gramps ID of the center person for the report. name_format - Preferred format to display names incmateref - Whether to print mate information or reference incl_private - Whether to include private data living_people - How to handle living people years_past_death - Consider as living this many years after death structure - How to structure the report """ Report.__init__(self, database, options, user) self.map = {} self._user = user menu = options.menu get_option_by_name = menu.get_option_by_name get_value = lambda name: get_option_by_name(name).get_value() self.set_locale(get_value('trans')) stdoptions.run_date_format_option(self, menu) stdoptions.run_private_data_option(self, menu) stdoptions.run_living_people_option(self, menu, self._locale) self.database = CacheProxyDb(self.database) self._db = self.database self.max_generations = get_value('gen') self.pgbrk = get_value('pagebbg') self.pgbrkenotes = get_value('pageben') self.fulldate = get_value('fulldates') use_fulldate = self.fulldate self.listchildren = get_value('listc') self.list_children_spouses = get_value('listc_spouses') self.inc_notes = get_value('incnotes') use_call = get_value('usecall') blankplace = get_value('repplace') blankdate = get_value('repdate') self.calcageflag = get_value('computeage') self.verbose = get_value('verbose') self.numbering = get_value('numbering') self.childref = get_value('desref') self.addimages = get_value('incphotos') self.structure = get_value('structure') self.inc_names = get_value('incnames') self.inc_events = get_value('incevents') self.inc_addr = get_value('incaddresses') self.inc_sources = get_value('incsources') self.inc_srcnotes = get_value('incsrcnotes') self.inc_mates = get_value('incmates') self.inc_attrs = get_value('incattrs') self.inc_paths = get_value('incpaths') self.inc_ssign = get_value('incssign') self.inc_materef = get_value('incmateref') self.want_ids = get_value('inc_id') pid = get_value('pid') self.center_person = self._db.get_person_from_gramps_id(pid) if self.center_person is None: raise ReportError(_("Person %s is not in the Database") % pid) self.gen_handles = {} self.prev_gen_handles = {} self.gen_keys = [] self.dnumber = {} self.dmates = {} self.numbers_printed = list() if blankdate: empty_date = EMPTY_ENTRY else: empty_date = "" if blankplace: empty_place = EMPTY_ENTRY else: empty_place = "" stdoptions.run_name_format_option(self, menu) self.__narrator = Narrator(self._db, self.verbose, use_call, use_fulldate, empty_date, empty_place, nlocale=self._locale, get_endnote_numbers=self.endnotes) self.bibli = Bibliography(Bibliography.MODE_DATE|Bibliography.MODE_PAGE)
class DetAncestorReport(Report): def __init__(self, database, options, user): """ Create the DetAncestorReport object that produces the report. The arguments are: database - the GRAMPS database instance options - instance of the Options class for this report user - a gen.user.User() instance 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. pageben - Whether to include page break before End Notes. 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. incattrs - Whether to include attributes 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 marry). verbose - Whether to use complete sentences childref - Whether to add descendant references in child list. addimages - Whether to include images. pid - The Gramps ID of the center person for the report. name_format - Preferred format to display names incl_private - Whether to include private data """ Report.__init__(self, database, options, user) self.map = {} self._user = user menu = options.menu get_option_by_name = menu.get_option_by_name get_value = lambda name: get_option_by_name(name).get_value() stdoptions.run_private_data_option(self, menu) self.db = self.database self.max_generations = get_value('gen') self.pgbrk = get_value('pagebbg') self.pgbrkenotes = get_value('pageben') self.fulldate = get_value('fulldates') use_fulldate = self.fulldate self.listchildren = get_value('listc') self.includenotes = get_value('incnotes') use_call = get_value('usecall') blankplace = get_value('repplace') blankdate = get_value('repdate') self.calcageflag = get_value('computeage') self.dupperson = get_value('omitda') self.verbose = get_value('verbose') self.childref = get_value('desref') self.addimages = get_value('incphotos') self.inc_names = get_value('incnames') self.inc_events = get_value('incevents') self.inc_addr = get_value('incaddresses') self.inc_sources = get_value('incsources') self.inc_srcnotes = get_value('incsrcnotes') self.inc_attrs = get_value('incattrs') self.initial_sosa = get_value('initial_sosa') pid = get_value('pid') self.center_person = self.db.get_person_from_gramps_id(pid) if (self.center_person == None) : raise ReportError(_("Person %s is not in the Database") % pid ) lang = menu.get_option_by_name('trans').get_value() self._locale = self.set_locale(lang) stdoptions.run_name_format_option(self, menu) self.gen_handles = {} self.prev_gen_handles = {} if blankdate: empty_date = EMPTY_ENTRY else: empty_date = "" if blankplace: empty_place = EMPTY_ENTRY else: empty_place = "" self.__narrator = Narrator(self.db, self.verbose, use_call, use_fulldate, empty_date, empty_place, nlocale=self._locale, get_endnote_numbers=self.endnotes) self.bibli = Bibliography(Bibliography.MODE_DATE|Bibliography.MODE_PAGE) def apply_filter(self, person_handle, index): if (not person_handle) or (index >= 2**self.max_generations): return self.map[index] = person_handle person = self.db.get_person_from_handle(person_handle) family_handle = person.get_main_parents_family_handle() if family_handle: family = self.db.get_family_from_handle(family_handle) self.apply_filter(family.get_father_handle(), index*2) self.apply_filter(family.get_mother_handle(), (index*2)+1) def write_report(self): self.apply_filter(self.center_person.get_handle(), 1) name = self._name_display.display_name( self.center_person.get_primary_name()) if not name: name = self._("Unknown") self.doc.start_paragraph("DAR-Title") # feature request 2356: avoid genitive form title = self._("Ancestral Report for %s") % name mark = IndexMark(title, INDEX_TYPE_TOC, 1) self.doc.write_text(title, mark) self.doc.end_paragraph() generation = 0 for key in sorted(self.map): if generation == 0 or key >= 2**generation: if self.pgbrk and generation > 0: self.doc.page_break() self.doc.start_paragraph("DAR-Generation") text = self._("Generation %d") % (generation+1) mark = IndexMark(text, INDEX_TYPE_TOC, 2) self.doc.write_text(text, mark) self.doc.end_paragraph() generation += 1 if self.childref: self.prev_gen_handles = self.gen_handles.copy() self.gen_handles.clear() person_handle = self.map[key] person = self.db.get_person_from_handle(person_handle) self.gen_handles[person_handle] = key dupperson = self.write_person(key) if dupperson == 0: # Is this a duplicate ind record if self.listchildren or self.inc_events: for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) mother_handle = family.get_mother_handle() if (mother_handle is None or mother_handle not in iter(self.map.values()) or person.get_gender() == Person.FEMALE): # The second test above also covers the 1. person's # mate, which is not an ancestor and as such is not # included in the self.map dictionary if self.listchildren: self.write_children(family) if self.inc_events: self.write_family_events(family) if self.inc_sources: if self.pgbrkenotes: self.doc.page_break() # it ignores language set for Note type (use locale) endnotes.write_endnotes(self.bibli, self.db, self.doc, printnotes=self.inc_srcnotes, elocale=self._locale) def _get_s_s(self, key): """returns Sosa-Stradonitz (a.k.a. Kekule or Ahnentafel) number""" generation = int(math.floor(math.log(key,2))) # 0 gen_start = pow(2, generation) # 1 new_gen_start = self.initial_sosa * gen_start # 3 return new_gen_start + (key - gen_start) # 3+0 def write_person(self, key): """Output birth, death, parentage, marriage and notes information """ person_handle = self.map[key] person = self.db.get_person_from_handle(person_handle) plist = person.get_media_list() self.__narrator.set_subject(person) if self.addimages and len(plist) > 0: photo = plist[0] ReportUtils.insert_image(self.db, self.doc, photo, self._user) self.doc.start_paragraph("DAR-First-Entry", "%d." % self._get_s_s(key)) name = self._name_display.display(person) if not name: name = self._("Unknown") mark = ReportUtils.get_person_mark(self.db, person) self.doc.start_bold() self.doc.write_text(name, mark) if name[-1:] == '.': self.doc.write_text_citation("%s " % self.endnotes(person)) elif name: self.doc.write_text_citation("%s. " % self.endnotes(person)) self.doc.end_bold() if self.dupperson: # Check for duplicate record (result of distant cousins marrying) for dkey in sorted(self.map): if dkey >= key: break if self.map[key] == self.map[dkey]: self.doc.write_text( self._("%(name)s is the same person as [%(id_str)s].") % { 'name' : '', 'id_str' : str(dkey) }) self.doc.end_paragraph() return 1 # Duplicate person if not self.verbose: self.write_parents(person) text = self.__narrator.get_born_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_baptised_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_christened_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_died_string(self.calcageflag) if text: self.doc.write_text_citation(text) text = self.__narrator.get_buried_string() if text: self.doc.write_text_citation(text) if self.verbose: self.write_parents(person) if not key % 2 or key == 1: self.write_marriage(person) self.doc.end_paragraph() if key == 1: self.write_mate(person) notelist = person.get_note_list() if len(notelist) > 0 and self.includenotes: self.doc.start_paragraph("DAR-NoteHeader") # feature request 2356: avoid genitive form self.doc.write_text(self._("Notes for %s") % name) self.doc.end_paragraph() for notehandle in notelist: note = self.db.get_note_from_handle(notehandle) self.doc.write_styled_note(note.get_styledtext(), note.get_format(), "DAR-Entry", contains_html = note.get_type() == NoteType.HTML_CODE ) first = True if self.inc_names: for alt_name in person.get_alternate_names(): if first: self.doc.start_paragraph('DAR-MoreHeader') self.doc.write_text(self._('More about %(person_name)s:') % {'person_name': name}) self.doc.end_paragraph() first = False self.doc.start_paragraph('DAR-MoreDetails') atype = self._get_type(alt_name.get_type()) self.doc.write_text_citation( self._('%(name_kind)s: %(name)s%(endnotes)s') % { 'name_kind' : self._(atype), 'name' : alt_name.get_regular_name(), 'endnotes' : self.endnotes(alt_name), } ) self.doc.end_paragraph() if self.inc_events: birth_ref = person.get_birth_ref() death_ref = person.get_death_ref() for event_ref in person.get_primary_event_ref_list(): if event_ref == birth_ref or event_ref == death_ref: continue if first: self.doc.start_paragraph('DAR-MoreHeader') self.doc.write_text( self._('More about %(person_name)s:') % {'person_name' : name}) self.doc.end_paragraph() first = 0 self.write_event(event_ref) if self.inc_addr: for addr in person.get_address_list(): if first: self.doc.start_paragraph('DAR-MoreHeader') self.doc.write_text( self._('More about %(person_name)s:') % {'person_name' : name}) self.doc.end_paragraph() first = False self.doc.start_paragraph('DAR-MoreDetails') text = ReportUtils.get_address_str(addr) self.doc.write_text(self._('Address: ')) if self.fulldate: date = self._get_date(addr.get_date_object()) else: date = addr.get_date_object().get_year() if date: # translators: needed for Arabic, ignore otherwise self.doc.write_text(self._('%s, ') % date ) self.doc.write_text( text ) self.doc.write_text_citation( self.endnotes(addr) ) self.doc.end_paragraph() if self.inc_attrs: attrs = person.get_attribute_list() if first and attrs: self.doc.start_paragraph('DAR-MoreHeader') self.doc.write_text( self._('More about %(person_name)s:') % { 'person_name' : name }) self.doc.end_paragraph() first = False for attr in attrs: self.doc.start_paragraph('DAR-MoreDetails') attrName = self._get_type(attr.get_type()) text = self._("%(type)s: %(value)s%(endnotes)s") % { 'type' : self._(attrName), 'value' : attr.get_value(), 'endnotes' : self.endnotes(attr) } self.doc.write_text_citation( text ) self.doc.end_paragraph() return 0 # Not duplicate person def write_event(self, event_ref): text = "" event = self.db.get_event_from_handle(event_ref.ref) if self.fulldate: date = self._get_date(event.get_date_object()) else: date = event.get_date_object().get_year() place = place_displayer.display_event(self.db, event) self.doc.start_paragraph('DAR-MoreDetails') evtName = self._get_type(event.get_type()) if date and place: text += self._('%(date)s, %(place)s') % { 'date' : date, 'place' : place } elif date: text += self._('%(date)s') % {'date' : date} elif place: text += self._('%(place)s') % { 'place' : place } if event.get_description(): if text: text += ". " text += event.get_description() text += self.endnotes(event) if text: text += ". " text = self._('%(event_name)s: %(event_text)s') % { 'event_name' : self._(evtName), 'event_text' : text } self.doc.write_text_citation(text) if self.inc_attrs: text = "" attr_list = event.get_attribute_list() attr_list.extend(event_ref.get_attribute_list()) for attr in attr_list: if text: # translators: needed for Arabic, ignore otherwise text += self._("; ") attrName = self._get_type(attr.get_type()) text += self._("%(type)s: %(value)s%(endnotes)s") % { 'type' : self._(attrName), 'value' : attr.get_value(), 'endnotes' : self.endnotes(attr) } text = " " + text self.doc.write_text_citation(text) self.doc.end_paragraph() if self.includenotes: # if the event or event reference has a note attached to it, # get the text and format it correctly notelist = event.get_note_list() notelist.extend(event_ref.get_note_list()) for notehandle in notelist: note = self.db.get_note_from_handle(notehandle) self.doc.write_styled_note(note.get_styledtext(), note.get_format(), "DAR-MoreDetails", contains_html = (note.get_type() == NoteType.HTML_CODE) ) def write_parents(self, person): family_handle = person.get_main_parents_family_handle() if family_handle: family = self.db.get_family_from_handle(family_handle) mother_handle = family.get_mother_handle() father_handle = family.get_father_handle() if mother_handle: mother = self.db.get_person_from_handle(mother_handle) mother_name = self._name_display.display_name( mother.get_primary_name()) mother_mark = ReportUtils.get_person_mark(self.db, mother) else: mother_name = "" mother_mark = "" if father_handle: father = self.db.get_person_from_handle(father_handle) father_name = self._name_display.display_name( father.get_primary_name()) father_mark = ReportUtils.get_person_mark(self.db, father) else: father_name = "" father_mark = "" text = self.__narrator.get_child_string(father_name, mother_name) if text: self.doc.write_text(text) if father_mark: self.doc.write_text("", father_mark) if mother_mark: self.doc.write_text("", mother_mark) def write_marriage(self, person): """ Output marriage sentence. """ is_first = True for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) spouse_handle = ReportUtils.find_spouse(person,family) spouse = self.db.get_person_from_handle(spouse_handle) spouse_mark = ReportUtils.get_person_mark(self.db, spouse) text = "" text = self.__narrator.get_married_string(family, is_first, self._name_display) if text: self.doc.write_text_citation(text, spouse_mark) is_first = False def write_children(self, family): """ List children. """ if not family.get_child_ref_list(): return mother_handle = family.get_mother_handle() if mother_handle: mother = self.db.get_person_from_handle(mother_handle) mother_name = self._name_display.display(mother) if not mother_name: mother_name = self._("Unknown") else: mother_name = self._("Unknown") father_handle = family.get_father_handle() if father_handle: father = self.db.get_person_from_handle(father_handle) father_name = self._name_display.display(father) if not father_name: father_name = self._("Unknown") else: father_name = self._("Unknown") self.doc.start_paragraph("DAR-ChildTitle") self.doc.write_text( self._("Children of %(mother_name)s and %(father_name)s") % {'father_name': father_name, 'mother_name': mother_name} ) self.doc.end_paragraph() cnt = 1 for child_ref in family.get_child_ref_list(): child_handle = child_ref.ref child = self.db.get_person_from_handle(child_handle) child_name = self._name_display.display(child) if not child_name: child_name = self._("Unknown") child_mark = ReportUtils.get_person_mark(self.db, child) if self.childref and self.prev_gen_handles.get(child_handle): value = int(self.prev_gen_handles.get(child_handle)) child_name += " [%d]" % self._get_s_s(value) self.doc.start_paragraph("DAR-ChildList", ReportUtils.roman(cnt).lower() + ".") cnt += 1 self.__narrator.set_subject(child) if child_name: self.doc.write_text("%s. " % child_name, child_mark) self.doc.write_text_citation( self.__narrator.get_born_string() or self.__narrator.get_christened_string() or self.__narrator.get_baptised_string()) self.doc.write_text_citation( self.__narrator.get_died_string() or self.__narrator.get_buried_string()) self.doc.end_paragraph() def write_family_events(self, family): if not family.get_event_ref_list(): return mother_handle = family.get_mother_handle() if mother_handle: mother = self.db.get_person_from_handle(mother_handle) mother_name = self._name_display.display(mother) if not mother_name: mother_name = self._("Unknown") else: mother_name = self._("Unknown") father_handle = family.get_father_handle() if father_handle: father = self.db.get_person_from_handle(father_handle) father_name = self._name_display.display(father) if not father_name: father_name = self._("Unknown") else: father_name = self._("Unknown") first = 1 for event_ref in family.get_event_ref_list(): if first: self.doc.start_paragraph('DAR-MoreHeader') self.doc.write_text( self._('More about %(mother_name)s and %(father_name)s:') % {'mother_name' : mother_name, 'father_name' : father_name }) self.doc.end_paragraph() first = 0 self.write_event(event_ref) def write_mate(self, person): """Output birth, death, parentage, marriage and notes information """ ind = None has_info = False for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) ind_handle = None if person.get_gender() == Person.MALE: ind_handle = family.get_mother_handle() else: ind_handle = family.get_father_handle() if ind_handle: ind = self.db.get_person_from_handle(ind_handle) for event_ref in ind.get_primary_event_ref_list(): event = self.db.get_event_from_handle(event_ref.ref) if event: etype = event.get_type() if (etype == EventType.BAPTISM or etype == EventType.BURIAL or etype == EventType.BIRTH or etype == EventType.DEATH): has_info = True break if not has_info: family_handle = ind.get_main_parents_family_handle() if family_handle: f = self.db.get_family_from_handle(family_handle) if f.get_mother_handle() or f.get_father_handle(): has_info = True break if has_info: self.doc.start_paragraph("DAR-MoreHeader") plist = ind.get_media_list() if self.addimages and len(plist) > 0: photo = plist[0] ReportUtils.insert_image(self.db, self.doc, photo, self._user) name = self._name_display.display(ind) if not name: name = self._("Unknown") mark = ReportUtils.get_person_mark(self.db, ind) if family.get_relationship() == FamilyRelType.MARRIED: self.doc.write_text(self._("Spouse: %s") % name, mark) else: self.doc.write_text(self._("Relationship with: %s") % name, mark) if name[-1:] != '.': self.doc.write_text(".") self.doc.write_text_citation(self.endnotes(ind)) self.doc.end_paragraph() self.doc.start_paragraph("DAR-Entry") self.__narrator.set_subject(ind) text = self.__narrator.get_born_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_baptised_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_christened_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_died_string(self.calcageflag) if text: self.doc.write_text_citation(text) text = self.__narrator.get_buried_string() if text: self.doc.write_text_citation(text) self.write_parents(ind) self.doc.end_paragraph() def endnotes(self, obj): if not obj or not self.inc_sources: return "" txt = endnotes.cite_source(self.bibli, self.db, obj, self._locale) if txt: txt = '<super>' + txt + '</super>' return txt
def __init__(self, database, options, user): """ Create the DetAncestorReport object that produces the report. The arguments are: database - the GRAMPS database instance options - instance of the Options class for this report user - a gen.user.User() instance 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. pageben - Whether to include page break before End Notes. 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. incattrs - Whether to include attributes 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 marry). verbose - Whether to use complete sentences childref - Whether to add descendant references in child list. addimages - Whether to include images. pid - The Gramps ID of the center person for the report. name_format - Preferred format to display names incl_private - Whether to include private data """ Report.__init__(self, database, options, user) self.map = {} self._user = user menu = options.menu get_option_by_name = menu.get_option_by_name get_value = lambda name: get_option_by_name(name).get_value() stdoptions.run_private_data_option(self, menu) self.db = self.database self.max_generations = get_value('gen') self.pgbrk = get_value('pagebbg') self.pgbrkenotes = get_value('pageben') self.fulldate = get_value('fulldates') use_fulldate = self.fulldate self.listchildren = get_value('listc') self.includenotes = get_value('incnotes') use_call = get_value('usecall') blankplace = get_value('repplace') blankdate = get_value('repdate') self.calcageflag = get_value('computeage') self.dupperson = get_value('omitda') self.verbose = get_value('verbose') self.childref = get_value('desref') self.addimages = get_value('incphotos') self.inc_names = get_value('incnames') self.inc_events = get_value('incevents') self.inc_addr = get_value('incaddresses') self.inc_sources = get_value('incsources') self.inc_srcnotes = get_value('incsrcnotes') self.inc_attrs = get_value('incattrs') self.initial_sosa = get_value('initial_sosa') pid = get_value('pid') self.center_person = self.db.get_person_from_gramps_id(pid) if (self.center_person == None) : raise ReportError(_("Person %s is not in the Database") % pid ) lang = menu.get_option_by_name('trans').get_value() self._locale = self.set_locale(lang) stdoptions.run_name_format_option(self, menu) self.gen_handles = {} self.prev_gen_handles = {} if blankdate: empty_date = EMPTY_ENTRY else: empty_date = "" if blankplace: empty_place = EMPTY_ENTRY else: empty_place = "" self.__narrator = Narrator(self.db, self.verbose, use_call, use_fulldate, empty_date, empty_place, nlocale=self._locale, get_endnote_numbers=self.endnotes) self.bibli = Bibliography(Bibliography.MODE_DATE|Bibliography.MODE_PAGE)
def __init__(self, database, options, user): """ Create the DetAncestorReport object that produces the report. The arguments are: database - the Gramps database instance options - instance of the Options class for this report user - a gen.user.User() instance This report needs the following parameters (class variables) that come in the options class. gen - Maximum number of generations to include. inc_id - Whether to include Gramps IDs pagebgg - Whether to include page breaks between generations. pageben - Whether to include page break before End Notes. firstName - Whether to use first names instead of pronouns. fulldate - Whether to use full dates instead of just year. listchildren - Whether to list children. list_children_spouses - Whether to list the spouses of the children includenotes - Whether to include notes. incattrs - Whether to include attributes 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 marry). verbose - Whether to use complete sentences childref - Whether to add descendant references in child list. addimages - Whether to include images. pid - The Gramps ID of the center person for the report. name_format - Preferred format to display names other_events - Whether to include other events. incl_private - Whether to include private data living_people - How to handle living people years_past_death - Consider as living this many years after death """ Report.__init__(self, database, options, user) self.map = {} self._user = user menu = options.menu get_option_by_name = menu.get_option_by_name get_value = lambda name: get_option_by_name(name).get_value() self.set_locale(menu.get_option_by_name('trans').get_value()) stdoptions.run_date_format_option(self, menu) stdoptions.run_private_data_option(self, menu) stdoptions.run_living_people_option(self, menu, self._locale) self.database = CacheProxyDb(self.database) self._db = self.database self.max_generations = get_value('gen') self.pgbrk = get_value('pagebbg') self.pgbrkenotes = get_value('pageben') self.fulldate = get_value('fulldates') use_fulldate = self.fulldate self.listchildren = get_value('listc') self.list_children_spouses = get_value('listc_spouses') self.includenotes = get_value('incnotes') use_call = get_value('usecall') blankplace = get_value('repplace') blankdate = get_value('repdate') self.calcageflag = get_value('computeage') self.dupperson = get_value('omitda') self.verbose = get_value('verbose') self.childref = get_value('desref') self.addimages = get_value('incphotos') self.inc_names = get_value('incnames') self.inc_events = get_value('incevents') self.inc_addr = get_value('incaddresses') self.inc_sources = get_value('incsources') self.inc_srcnotes = get_value('incsrcnotes') self.inc_attrs = get_value('incattrs') self.initial_sosa = get_value('initial_sosa') self.want_ids = get_value('inc_id') pid = get_value('pid') self.other_events = get_value('incotherevents') self.center_person = self._db.get_person_from_gramps_id(pid) if self.center_person is None: raise ReportError(_("Person %s is not in the Database") % pid) stdoptions.run_name_format_option(self, menu) self._nd = self._name_display self.gen_handles = {} self.prev_gen_handles = {} if blankdate: empty_date = EMPTY_ENTRY else: empty_date = "" if blankplace: empty_place = EMPTY_ENTRY else: empty_place = "" self.__narrator = Narrator(self._db, self.verbose, use_call, use_fulldate, empty_date, empty_place, nlocale=self._locale, get_endnote_numbers=self.endnotes) self.bibli = Bibliography(Bibliography.MODE_DATE|Bibliography.MODE_PAGE)