def by_birthdate(self, first_id, second_id): """Sort routine for comparing two people by birth dates. If the birth dates are equal, sorts by name""" first = self.database.get_person_from_handle(first_id) second = self.database.get_person_from_handle(second_id) birth1 = get_birth_or_fallback(self.database, first) if birth1: date1 = birth1.get_date_object() else: date1 = Date() birth2 = get_birth_or_fallback(self.database, second) if birth2: date2 = birth2.get_date_object() else: date2 = Date() dsv1 = date1.get_sort_value() dsv2 = date2.get_sort_value() val = cmp(dsv1, dsv2) if val == 0: return self.by_last_name(first_id, second_id) return val
def dump_dates(self, person): birth = get_birth_or_fallback(self.dbstate.db, person) death = get_death_or_fallback(self.dbstate.db, person) if birth: birth_date = DateHandler.get_date(birth) if death: death_date = DateHandler.get_date(death) if birth or death: self.append_text(' (') birth_place = "" if birth: bplace_handle = birth.get_place_handle() if bplace_handle: birth_place = self.dbstate.db.get_place_from_handle( bplace_handle).get_title() death_place = "" if death: dplace_handle = death.get_place_handle() if dplace_handle: death_place = self.dbstate.db.get_place_from_handle( dplace_handle).get_title() if birth: if birth_place: self.append_text( "%(event_abbrev)s %(birth_date)s - %(place)s" % { 'event_abbrev': birth.type.get_abbreviation(), 'birth_date': birth_date, 'place': birth_place, }) else: self.append_text( "%(event_abbrev)s %(birth_date)s" % { 'event_abbrev': birth.type.get_abbreviation(), 'birth_date': birth_date }) if death: if birth: self.append_text(', ') if death_place: self.append_text( "%(event_abbrev)s %(death_date)s - %(place)s" % { 'event_abbrev': death.type.get_abbreviation(), 'death_date': death_date, 'place': death_place, }) else: self.append_text( "%(event_abbrev)s %(death_date)s" % { 'event_abbrev': death.type.get_abbreviation(), 'death_date': death_date }) self.append_text(')')
def write_person(self, person_handle): """ Write information about the given person. """ person = self.database.get_person_from_handle(person_handle) name = self._name_display.display(person) mark = ReportUtils.get_person_mark(self.database, person) birth_date = "" birth = get_birth_or_fallback(self.database, person) if birth: birth_date = DateHandler.get_date(birth) death_date = "" death = get_death_or_fallback(self.database, person) if death: death_date = DateHandler.get_date(death) dates = _(" (%(birth_date)s - %(death_date)s)") % { 'birth_date' : birth_date, 'death_date' : death_date } self.doc.start_paragraph('KIN-Normal') self.doc.write_text(name, mark) self.doc.write_text(dates) self.doc.end_paragraph()
def dump_string(self, person, family=None): string = self.__date_place(get_birth_or_fallback( self.database, person)) tmp = self.__date_place(get_death_or_fallback(self.database, person)) if string and tmp: string += ", " string += tmp if string: string = " (" + string + ")" if family and self.showmarriage: tmp = self.__date_place( get_marriage_or_fallback(self.database, family)) if tmp: string += ", " + tmp if family and self.showdivorce: tmp = self.__date_place( get_divorce_or_fallback(self.database, family)) if tmp: string += ", " + tmp self.doc.write_text(string)
def find_year_range(self): """ Finds the range of years that will be displayed on the chart. Returns a tuple of low and high years. If no dates are found, the function returns (None, None). """ low = None high = None def min_max_year(low, high, year): if year is not None and year != 0: if low is not None: low = min(low, year) else: low = year if high is not None: high = max(high, year) else: high = year return (low, high) self._user.begin_progress(_('Timeline'), _('Finding date range...'), len(self.plist)) for p_id in self.plist: p = self.database.get_person_from_handle(p_id) birth = get_birth_or_fallback(self.database, p) if birth: b = birth.get_date_object().to_calendar( self.calendar).get_year() (low, high) = min_max_year(low, high, b) death = get_death_or_fallback(self.database, p) if death: d = death.get_date_object().to_calendar( self.calendar).get_year() (low, high) = min_max_year(low, high, d) self._user.step_progress() # round the dates to the nearest decade if low is not None: low = int((low / 10)) * 10 else: low = high if high is not None: high = int(((high + 9) / 10)) * 10 else: high = low # Make sure the difference is a multiple of 50 so all year ranges land # on a decade. if low is not None and high is not None: low -= 50 - ((high - low) % 50) self._user.end_progress() return (low, high)
def column_birth_day(self, data): birth = get_birth_or_fallback(self.db, data) if birth: if birth.get_type() == gen.lib.EventType.BIRTH: return DateHandler.get_date(birth) else: return '<i>%s</i>' % cgi.escape(DateHandler.get_date(birth)) else: return u""
def column_birth_sort(self, data): """ Return a sort key to use for the birth column. As python int can be larger than C int, we cast int to a string of 10 long prepended with 0 as needed. This gives correct string sort for years in the millenia around today """ birth = get_birth_or_fallback(self.db, data) if birth: return '%012d' % birth.get_date_object().get_sort_value() else: return '%012d' % 0
def by_birthdate_key(self, first_id): """Sort routine for comparing two people by birth dates. If the birth dates are equal, sorts by name""" first = self.database.get_person_from_handle(first_id) birth1 = get_birth_or_fallback(self.database, first) if birth1: date1 = birth1.get_date_object() else: date1 = Date() dsv1 = date1.get_sort_value() return "%08d" % dsv1 + self.by_last_name_key(first_id)
def load_parent(self, handle, name_obj, birth_obj, birth_label, death_obj, death_label, btn_index, btn_add, btn_del, btn_edit): # is a parent used here: is_used = handle is not None # now we display the area: if is_used: db = self.db person = db.get_person_from_handle(handle) name = "%s [%s]" % (name_displayer.display(person), person.gramps_id) birth = get_birth_or_fallback(db, person) self.callman.register_handles({'person': [handle]}) if birth: #if event changes it view needs to update self.callman.register_handles({'event': [birth.get_handle()]}) birth_label.set_label("%s:" % birth.get_type()) death = get_death_or_fallback(db, person) if death: #if event changes it view needs to update self.callman.register_handles({'event': [death.get_handle()]}) death_label.set_label("%s:" % death.get_type()) btn_edit.set_tooltip_text(_('Edit %s') % name) btn_index.hide() btn_add.hide() btn_del.show() btn_edit.show() else: name = "" birth = None death = None btn_index.show() btn_add.show() btn_del.hide() btn_edit.hide() if name_obj: name_obj.set_text(name) if birth: birth_str = DateHandler.displayer.display(birth.get_date_object()) else: birth_str = "" birth_obj.set_text(birth_str) if death: death_str = DateHandler.displayer.display(death.get_date_object()) else: death_str = "" death_obj.set_text(death_str)
def get_date_strings(self, person): "returns tuple of birth/christening and death/burying date strings" birth_event = get_birth_or_fallback(self.database, person) if birth_event: birth = self.get_event_string(birth_event) else: birth = "" death_event = get_death_or_fallback(self.database, person) if death_event: death = self.get_event_string(death_event) else: death = "" return (birth, death)
def add_child(self, child): """ Add a child to the model. """ name = name_displayer.display(child) birth = get_birth_or_fallback(self.dbstate.db, child) birth_date, birth_sort, birth_place = self.get_date_place(birth) death = get_death_or_fallback(self.dbstate.db, child) death_date, death_sort, death_place = self.get_date_place(death) self.model.add((child.get_handle(), name, birth_date, birth_sort, death_date, death_sort))
def add_person(self, person): """ Add a person to the Graph. The node id will be the person's gramps id. """ p_id = person.get_gramps_id() name = name_displayer.display_formal(person) birth_evt = get_birth_or_fallback(self.__db, person) if birth_evt: birth = DateHandler.get_date(birth_evt) else: birth = "" death_evt = get_death_or_fallback(self.__db, person) if death_evt: death = DateHandler.get_date(death_evt) else: death = "" label = "%s \\n(%s - %s)" % (name, birth, death) (shape, style, color, fill) = self.get_gender_style(person) self.doc.add_node(p_id, label, shape, color, style, fill)
def info_string(self, person): birth = get_birth_or_fallback(self.dbstate.db, person) if birth and birth.get_type() != gen.lib.EventType.BIRTH: sdate = DateHandler.get_date(birth) if sdate: bdate = "<i>%s</i>" % cgi.escape(sdate) else: bdate = "" elif birth: bdate = cgi.escape(DateHandler.get_date(birth)) else: bdate = "" death = get_death_or_fallback(self.dbstate.db, person) if death and death.get_type() != gen.lib.EventType.DEATH: sdate = DateHandler.get_date(death) if sdate: ddate = "<i>%s</i>" % cgi.escape(sdate) else: ddate = "" elif death: ddate = cgi.escape(DateHandler.get_date(death)) else: ddate = "" if bdate and ddate: value = _("(b. %(birthdate)s, d. %(deathdate)s)") % { 'birthdate': bdate, 'deathdate': ddate } elif bdate: value = _("(b. %s)") % (bdate) elif ddate: value = _("(d. %s)") % (ddate) else: value = "" return value
def parse_format(self, _out): """Parse the $ variables. """ if not self.is_a(): return attrib_parse = AttributeParse(self._in) next_char = self._in.next self._in.step2() if next_char == "n": #Person's name _out.add_variable( self.__parse_name(self.friend.person)) elif next_char == "s": #Souses name _out.add_variable( self.__parse_name(self.friend.spouse)) elif next_char == "i": #Person's Id _out.add_variable( self.__parse_id(self.friend.person)) elif next_char == "j": #Marriage Id _out.add_variable( self.__parse_id(self.friend.family)) elif next_char == "b": #Person's Birth date if self.empty_item(self.friend.person, _out): return self.__parse_date( get_birth_or_fallback(self.friend.database, self.friend.person), _out) elif next_char == "d": #Person's Death date if self.empty_item(self.friend.person, _out): return self.__parse_date( get_death_or_fallback(self.friend.database, self.friend.person), _out) elif next_char == "m": #Marriage date if self.empty_item(self.friend.family, _out): return self.__parse_date( self.get_event_by_type(self.friend.family, gen.lib.EventType.MARRIAGE), _out) elif next_char == "v": #Divorce date if self.empty_item(self.friend.family, _out): return self.__parse_date( self.get_event_by_type(self.friend.family, gen.lib.EventType.DIVORCE), _out) elif next_char == "T": #Todays date date_f = DateFormat(self._in) from gen.lib.date import Today date = Today() if self.empty_item(date, _out): return _out.add_variable( date_f.parse_format(date) ) elif next_char == "B": #Person's birth place if self.empty_item(self.friend.person, _out): return self.__parse_place( get_birth_or_fallback(self.friend.database, self.friend.person), _out) elif next_char == "D": #Person's death place if self.empty_item(self.friend.person, _out): return self.__parse_place( get_death_or_fallback(self.friend.database, self.friend.person), _out) elif next_char == "M": #Marriage place if self.empty_item(self.friend.family, _out): return self.__parse_place( self.get_event_by_type(self.friend.family, gen.lib.EventType.MARRIAGE), _out) elif next_char == "V": #Divorce place if self.empty_item(self.friend.family, _out): return self.__parse_place( self.get_event_by_type(self.friend.family, gen.lib.EventType.DIVORCE), _out) elif next_char == "a": #Person's Atribute if self.empty_attribute(self.friend.person, _out): return attrib_parse.parse_format(_out, self.friend.person.get_attribute_list()) elif next_char == "u": #Marriage Atribute if self.empty_attribute(self.friend.family, _out): return attrib_parse.parse_format(_out, self.friend.family.get_attribute_list()) elif next_char == "e": #person event _out.add_variable( self.__parse_event(self.friend.person, attrib_parse)) elif next_char == "t": #person event _out.add_variable( self.__parse_event(self.friend.family, attrib_parse))
def generate_timeline(self, low, high): st_size = self.name_size() style_sheet = self.doc.get_style_sheet() font = style_sheet.get_paragraph_style('TLG-Name').get_font() incr = pt2cm(font.get_size()) pad = incr * 0.75 x1, x2, y1, y2 = (0, 0, 0, 0) start = st_size + 0.5 stop = self.doc.get_usable_width() - 0.5 size = (stop - start) self.header = 2.0 # Sort the people as requested self._user.begin_progress(_('Timeline'), _('Sorting dates...'), 0) self.plist.sort(key=self.sort_func) self._user.end_progress() self.doc.start_page() self.build_grid(low, high, start, stop) index = 1 current = 1 length = len(self.plist) self._user.begin_progress(_('Timeline'), _('Calculating timeline...'), length) for p_id in self.plist: p = self.database.get_person_from_handle(p_id) birth = get_birth_or_fallback(self.database, p) if birth: b = birth.get_date_object().to_calendar( self.calendar).get_year() else: b = None death = get_death_or_fallback(self.database, p) if death: d = death.get_date_object().to_calendar( self.calendar).get_year() else: d = None n = name_displayer.display_formal(p) self.doc.draw_text('TLG-text', n, incr + pad, self.header + (incr + pad) * index) y1 = self.header + (pad + incr) * index y2 = self.header + ((pad + incr) * index) + incr y3 = (y1 + y2) / 2.0 w = 0.05 if b: start_offset = ((float(b - low) / float(high - low)) * (size)) x1 = start + start_offset path = [(x1, y1), (x1 + w, y3), (x1, y2), (x1 - w, y3)] self.doc.draw_path('TLG-line', path) if d: start_offset = ((float(d - low) / float(high - low)) * (size)) x1 = start + start_offset path = [(x1, y1), (x1 + w, y3), (x1, y2), (x1 - w, y3)] self.doc.draw_path('TLG-solid', path) if b and d: start_offset = ( (float(b - low) / float(high - low)) * size) + w stop_offset = ((float(d - low) / float(high - low)) * size) - w x1 = start + start_offset x2 = start + stop_offset self.doc.draw_line('open', x1, y3, x2, y3) if (y2 + incr) >= self.doc.get_usable_height(): if current != length: self.doc.end_page() self.doc.start_page() self.build_grid(low, high, start, stop) index = 1 x1, x2, y1, y2 = (0, 0, 0, 0) else: index += 1 current += 1 self._user.step_progress() self.doc.end_page() self._user.end_progress()
def writePeople(self): self.doc.add_comment('') # If we're going to attempt to include images, then use the HTML style # of .gv file. bUseHtmlOutput = False if self._incimages: bUseHtmlOutput = True # loop through all the people we need to output for handle in self._people: person = self._db.get_person_from_handle(handle) name = name_displayer.display_name(person.get_primary_name()) # figure out what colour to use gender = person.get_gender() colour = self._colorunknown if gender == gen.lib.Person.MALE: colour = self._colormales elif gender == gen.lib.Person.FEMALE: colour = self._colorfemales # see if we have surname colours that match this person surname = person.get_primary_name().get_surname().encode( 'iso-8859-1', 'xmlcharrefreplace') if surname in self._surnamecolors: colour = self._surnamecolors[surname] # see if we have a birth/death or fallback dates we can use if self._incdates or self._incplaces: bth_event = get_birth_or_fallback(self._db, person) dth_event = get_death_or_fallback(self._db, person) else: bth_event = None dth_event = None # output the birth or fallback event birthStr = None if bth_event and self._incdates: if not bth_event.private or self._incprivate: date = bth_event.get_date_object() if self._just_years and date.get_year_valid(): birthStr = '%i' % date.get_year() else: birthStr = _dd.display(date) # get birth place (one of: city, state, or country) we can use birthplace = None if bth_event and self._incplaces: if not bth_event.private or self._incprivate: place = self._db.get_place_from_handle( bth_event.get_place_handle()) if place: location = place.get_main_location() if location.get_city: birthplace = location.get_city() elif location.get_state: birthplace = location.get_state() elif location.get_country: birthplace = location.get_country() # see if we have a deceased date we can use deathStr = None if dth_event and self._incdates: if not dth_event.private or self._incprivate: date = dth_event.get_date_object() if self._just_years and date.get_year_valid(): deathStr = '%i' % date.get_year() else: deathStr = _dd.display(date) # get death place (one of: city, state, or country) we can use deathplace = None if dth_event and self._incplaces: if not dth_event.private or self._incprivate: place = self._db.get_place_from_handle( dth_event.get_place_handle()) if place: location = place.get_main_location() if location.get_city: deathplace = location.get_city() elif location.get_state: deathplace = location.get_state() elif location.get_country: deathplace = location.get_country() # see if we have an image to use for this person imagePath = None if self._incimages: mediaList = person.get_media_list() if len(mediaList) > 0: mediaHandle = mediaList[0].get_reference_handle() media = self._db.get_object_from_handle(mediaHandle) mediaMimeType = media.get_mime_type() if mediaMimeType[0:5] == "image": imagePath = ThumbNails.get_thumbnail_path( Utils.media_path_full(self._db, media.get_path()), rectangle=mediaList[0].get_rectangle()) # put the label together and output this person label = u"" lineDelimiter = '\\n' if bUseHtmlOutput: lineDelimiter = '<BR/>' # if we have an image, then start an HTML table; remember to close the table afterwards! if imagePath: label = (u'<TABLE BORDER="0" CELLSPACING="2" CELLPADDING="0" ' u'CELLBORDER="0"><TR><TD><IMG SRC="%s"/></TD>' % imagePath) if self._imageonside == 0: label += u'</TR><TR>' label += '<TD>' # at the very least, the label must have the person's name label += name if birthStr or deathStr: label += '%s(' % lineDelimiter if birthStr: label += '%s' % birthStr label += ' - ' if deathStr: label += '%s' % deathStr label += ')' if birthplace or deathplace: if birthplace == deathplace: deathplace = None # no need to print the same name twice label += '%s' % lineDelimiter if birthplace: label += '%s' % birthplace if birthplace and deathplace: label += ' / ' if deathplace: label += '%s' % deathplace # see if we have a table that needs to be terminated if imagePath: label += '</TD></TR></TABLE>' shape = "box" style = "solid" border = colour fill = colour # do not use colour if this is B&W outline if self._colorize == 'outline': border = "" fill = "" if gender == person.FEMALE and self._useroundedcorners: style = "rounded" elif gender == person.UNKNOWN: shape = "hexagon" # if we're filling the entire node: if self._colorize == 'filled': style += ",filled" border = "" # we're done -- add the node self.doc.add_node(person.get_gramps_id(), label=label, shape=shape, color=border, style=style, fillcolor=fill, htmloutput=bUseHtmlOutput)
def format_person(self, person, line_count, use_markup=False): """fromat how info about a person should be presented """ if not person: return "" if use_markup: if person.handle in self._markup_cache: if line_count in self._markup_cache[person.handle]: return self._markup_cache[person.handle][line_count] name = escape(name_displayer.display(person)) else: if person.handle in self._text_cache: if line_count in self._text_cache[person.handle]: return self._text_cache[person.handle][line_count] name = name_displayer.display(person) text = name if line_count >= 3: birth = get_birth_or_fallback(self.dbstate.db, person) if birth and use_markup and birth.get_type() != \ gen.lib.EventType.BIRTH: bdate = "<i>%s</i>" % escape(DateHandler.get_date(birth)) bplace = "<i>%s</i>" % escape( self.get_place_name(birth.get_place_handle())) elif birth and use_markup: bdate = escape(DateHandler.get_date(birth)) bplace = escape(self.get_place_name(birth.get_place_handle())) elif birth: bdate = DateHandler.get_date(birth) bplace = self.get_place_name(birth.get_place_handle()) else: bdate = "" bplace = "" death = get_death_or_fallback(self.dbstate.db, person) if death and use_markup and death.get_type() != \ gen.lib.EventType.DEATH: ddate = "<i>%s</i>" % escape(DateHandler.get_date(death)) dplace = "<i>%s</i>" % escape( self.get_place_name(death.get_place_handle())) elif death and use_markup: ddate = escape(DateHandler.get_date(death)) dplace = escape(self.get_place_name(death.get_place_handle())) elif death: ddate = DateHandler.get_date(death) dplace = self.get_place_name(death.get_place_handle()) else: ddate = "" dplace = "" if line_count < 5: text = "%s\n* %s\n+ %s" % (name, bdate, ddate) else: text = "%s\n* %s\n %s\n+ %s\n %s" % (name, bdate, bplace, ddate, dplace) if use_markup: if not person.handle in self._markup_cache: self._markup_cache[person.handle] = {} self._markup_cache[person.handle][line_count] = text else: if not person.handle in self._text_cache: self._text_cache[person.handle] = {} self._text_cache[person.handle][line_count] = text return text