Пример #1
0
class TagReport(Report):
    """ Tag Report """
    def __init__(self, database, options, user):
        """
        Create the TagReport 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.

        tag             - The tag each object must match to be included.
        name_format     - Preferred format to display names of people
        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)
        menu = options.menu

        lang = menu.get_option_by_name('trans').get_value()
        rlocale = self.set_locale(lang)

        stdoptions.run_private_data_option(self, menu)
        living_opt = stdoptions.run_living_people_option(self, menu, rlocale)
        self.database = CacheProxyDb(self.database)

        self._lv = menu.get_option_by_name('living_people').get_value()
        for (value, description) in living_opt.get_items(xml_items=True):
            if value == self._lv:
                living_desc = self._(description)
                break
        self.living_desc = self._("(Living people: %(option_name)s)") % {
            'option_name': living_desc
        }

        self.tag = menu.get_option_by_name('tag').get_value()
        if not self.tag:
            raise ReportError(
                _('Tag Report'),
                _('You must first create a tag before running this report.'))

        stdoptions.run_name_format_option(self, menu)

    def write_report(self):
        self.doc.start_paragraph("TR-Title")
        # feature request 2356: avoid genitive form
        title = self._("Tag Report for %s Items") % self.tag
        mark = IndexMark(title, INDEX_TYPE_TOC, 1)
        self.doc.write_text(title, mark)
        self.doc.end_paragraph()
        if self._lv != LivingProxyDb.MODE_INCLUDE_ALL:
            self.doc.start_paragraph("TR-ReportSubtitle")
            self.doc.write_text(self.living_desc)
            self.doc.end_paragraph()

        self.write_people()
        self.write_families()
        self.write_events()
        self.write_places()
        self.write_notes()
        self.write_media()
        self.write_repositories()
        self.write_sources()
        self.write_citations()

    def write_people(self):
        """ write the people associated with the tag """
        plist = self.database.iter_person_handles()
        filter_class = GenericFilterFactory('Person')
        a_filter = filter_class()
        a_filter.add_rule(rules.person.HasTag([self.tag]))
        ind_list = a_filter.apply(self.database, plist)

        if not ind_list:
            return

        self.doc.start_paragraph("TR-Heading")
        header = self._("People")
        mark = IndexMark(header, INDEX_TYPE_TOC, 2)
        self.doc.write_text(header, mark)
        self.doc.end_paragraph()

        self.doc.start_table('PeopleTable', 'TR-Table')

        self.doc.start_row()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Id"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Name"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Birth"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Death"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.end_row()

        for person_handle in ind_list:
            person = self.database.get_person_from_handle(person_handle)

            self.doc.start_row()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(person.get_gid())
            self.doc.end_paragraph()
            self.doc.end_cell()

            name = self._name_display.display(person)
            mark = utils.get_person_mark(self.database, person)
            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(name, mark)
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            birth_ref = person.get_birth_ref()
            if birth_ref:
                event = self.database.get_event_from_handle(birth_ref.ref)
                self.doc.write_text(self._get_date(event.get_date_object()))
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            death_ref = person.get_death_ref()
            if death_ref:
                event = self.database.get_event_from_handle(death_ref.ref)
                self.doc.write_text(self._get_date(event.get_date_object()))
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.end_row()

        self.doc.end_table()

    def write_families(self):
        """ write the families associated with the tag """
        flist = self.database.iter_family_handles()
        filter_class = GenericFilterFactory('Family')
        a_filter = filter_class()
        a_filter.add_rule(rules.family.HasTag([self.tag]))
        fam_list = a_filter.apply(self.database, flist)

        if not fam_list:
            return

        self.doc.start_paragraph("TR-Heading")
        header = self._("Families")
        mark = IndexMark(header, INDEX_TYPE_TOC, 2)
        self.doc.write_text(header, mark)
        self.doc.end_paragraph()

        self.doc.start_table('FamilyTable', 'TR-Table')

        self.doc.start_row()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Id"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Father"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Mother"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Relationship"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.end_row()

        for family_handle in fam_list:
            family = self.database.get_family_from_handle(family_handle)

            self.doc.start_row()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(family.get_gid())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            father_handle = family.get_father_handle()
            if father_handle:
                father = self.database.get_person_from_handle(father_handle)
                mark = utils.get_person_mark(self.database, father)
                self.doc.write_text(self._name_display.display(father), mark)
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            mother_handle = family.get_mother_handle()
            if mother_handle:
                mother = self.database.get_person_from_handle(mother_handle)
                mark = utils.get_person_mark(self.database, mother)
                self.doc.write_text(self._name_display.display(mother), mark)
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            relation = family.get_relationship()
            self.doc.write_text(str(relation))
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.end_row()

        self.doc.end_table()

    def write_events(self):
        """ write the events associated with the tag """
        elist = self.database.get_event_handles()
        filter_class = GenericFilterFactory('Event')
        a_filter = filter_class()
        a_filter.add_rule(rules.event.HasTag([self.tag]))
        event_list = a_filter.apply(self.database, elist)

        if not event_list:
            return

        self.doc.start_paragraph("TR-Heading")
        header = self._("Events")
        mark = IndexMark(header, INDEX_TYPE_TOC, 2)
        self.doc.write_text(header, mark)
        self.doc.end_paragraph()

        self.doc.start_table('EventTable', 'TR-Table')

        self.doc.start_row()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Id"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Type"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Participants"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Date"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.end_row()

        for event_handle in event_list:
            event = self.database.get_event_from_handle(event_handle)

            self.doc.start_row()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(event.get_gid())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(self._(self._get_type(event.get_type())))
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(
                get_participant_from_event(self.database, event_handle))
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            date = self._get_date(event.get_date_object())
            if date:
                self.doc.write_text(date)
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.end_row()

        self.doc.end_table()

    def write_places(self):
        """ write the places associated with the tag """
        plist = self.database.get_place_handles()
        filter_class = GenericFilterFactory('Place')
        a_filter = filter_class()
        a_filter.add_rule(rules.place.HasTag([self.tag]))
        place_list = a_filter.apply(self.database, plist)

        if not place_list:
            return

        self.doc.start_paragraph("TR-Heading")
        header = self._("Places")
        mark = IndexMark(header, INDEX_TYPE_TOC, 2)
        self.doc.write_text(header, mark)
        self.doc.end_paragraph()

        self.doc.start_table('PlaceTable', 'TR-Table')

        self.doc.start_row()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Id"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Title"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Name"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Type"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.end_row()

        for place_handle in place_list:
            place = self.database.get_place_from_handle(place_handle)
            place_title = _pd.display(self.database, place)

            self.doc.start_row()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(place.get_gid())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(place_title)
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(place.get_name())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(str(place.get_type()))
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.end_row()

        self.doc.end_table()

    def write_notes(self):
        """ write the notes associated with the tag """
        nlist = self.database.get_note_handles()
        filter_class = GenericFilterFactory('Note')
        a_filter = filter_class()
        a_filter.add_rule(rules.note.HasTag([self.tag]))
        note_list = a_filter.apply(self.database, nlist)

        if not note_list:
            return

        self.doc.start_paragraph("TR-Heading")
        header = self._("Notes")
        mark = IndexMark(header, INDEX_TYPE_TOC, 2)
        self.doc.write_text(header, mark)
        self.doc.end_paragraph()

        self.doc.start_table('NoteTable', 'TR-Table')

        self.doc.start_row()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Id"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Type"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell', 2)
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Text"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.end_row()

        for note_handle in note_list:
            note = self.database.get_note_from_handle(note_handle)

            self.doc.start_row()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(note.get_gid())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            note_type = note.get_type()
            self.doc.write_text(str(note_type))
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell', 2)
            self.doc.write_styled_note(
                note.get_styledtext(),
                note.get_format(),
                'TR-Note',
                contains_html=((note.get_type() == NoteType.HTML_CODE)))
            self.doc.end_cell()

            self.doc.end_row()

        self.doc.end_table()

    def write_media(self):
        """ write the media associated with the tag """
        mlist = self.database.get_media_handles(sort_handles=True)
        filter_class = GenericFilterFactory('Media')
        a_filter = filter_class()
        a_filter.add_rule(rules.media.HasTag([self.tag]))
        media_list = a_filter.apply(self.database, mlist)

        if not media_list:
            return

        self.doc.start_paragraph("TR-Heading")
        header = self._("Media")
        mark = IndexMark(header, INDEX_TYPE_TOC, 2)
        self.doc.write_text(header, mark)
        self.doc.end_paragraph()

        self.doc.start_table('MediaTable', 'TR-Table')

        self.doc.start_row()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Id"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Title"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Type"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Date"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.end_row()

        for media_handle in media_list:
            media = self.database.get_media_from_handle(media_handle)

            self.doc.start_row()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(media.get_gid())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            title = media.get_description()
            self.doc.write_text(str(title))
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            mime_type = media.get_mime_type()
            self.doc.write_text(str(mime_type))
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            date = self._get_date(media.get_date_object())
            if date:
                self.doc.write_text(date)
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.end_row()

        self.doc.end_table()

    def write_repositories(self):
        """ write the repositories associated with the tag """
        rlist = self.database.get_repository_handles()
        filter_class = GenericFilterFactory('Repository')
        a_filter = filter_class()
        a_filter.add_rule(rules.repository.HasTag([self.tag]))
        repo_list = a_filter.apply(self.database, rlist)

        if not repo_list:
            return

        self.doc.start_paragraph("TR-Heading")
        header = self._("Repositories")
        mark = IndexMark(header, INDEX_TYPE_TOC, 2)
        self.doc.write_text(header, mark)
        self.doc.end_paragraph()

        self.doc.start_table('ReopTable', 'TR-Table')

        self.doc.start_row()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Id"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Name"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Type"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Email Address"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.end_row()

        for repo_handle in repo_list:
            repo = self.database.get_repository_from_handle(repo_handle)

            self.doc.start_row()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(repo.get_gid())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(repo.get_name())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(str(repo.get_type()))
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            home_page = ''
            for url in repo.get_url_list():
                if url.get_type() == UrlType.EMAIL:
                    home_page = url.get_path()
                    break
            self.doc.write_text(home_page)
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.end_row()

        self.doc.end_table()

    def write_sources(self):
        """ write the sources associated with the tag """
        slist = self.database.get_source_handles(sort_handles=True)
        filter_class = GenericFilterFactory('Source')
        a_filter = filter_class()
        a_filter.add_rule(rules.source.HasTag([self.tag]))
        source_list = a_filter.apply(self.database, slist)

        if not source_list:
            return

        self.doc.start_paragraph("TR-Heading")
        header = self._("Source")
        mark = IndexMark(header, INDEX_TYPE_TOC, 2)
        self.doc.write_text(header, mark)
        self.doc.end_paragraph()

        self.doc.start_table('SourceTable', 'TR-Table')

        self.doc.start_row()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Id"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Title"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Author"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Publication Information"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.end_row()

        for source_handle in source_list:
            source = self.database.get_source_from_handle(source_handle)

            self.doc.start_row()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(source.get_gid())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(source.get_title())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(source.get_author())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(source.get_publication_info())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.end_row()

        self.doc.end_table()

    def write_citations(self):
        """ write the citations associated with the tag """
        clist = self.database.get_citation_handles(sort_handles=True)
        filter_class = GenericFilterFactory('Citation')
        a_filter = filter_class()
        a_filter.add_rule(rules.citation.HasTag([self.tag]))
        citation_list = a_filter.apply(self.database, clist)

        if not citation_list:
            return

        self.doc.start_paragraph("TR-Heading")
        header = self._("Citations")
        mark = IndexMark(header, INDEX_TYPE_TOC, 2)
        self.doc.write_text(header, mark)
        self.doc.end_paragraph()

        self.doc.start_table('CitationTable', 'TR-Table')

        self.doc.start_row()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Id"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Volume/Page"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Date"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell('TR-TableCell')
        self.doc.start_paragraph('TR-Normal-Bold')
        self.doc.write_text(self._("Source"))
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.end_row()

        for citation_handle in citation_list:
            citation = self.database.get_citation_from_handle(citation_handle)

            self.doc.start_row()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(citation.get_gid())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            self.doc.write_text(citation.get_page())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            date = self._get_date(citation.get_date_object())
            if date:
                self.doc.write_text(date)
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.start_cell('TR-TableCell')
            self.doc.start_paragraph('TR-Normal')
            source_handle = citation.get_reference_handle()
            source = self.database.get_source_from_handle(source_handle)
            self.doc.write_text(source.get_title())
            self.doc.end_paragraph()
            self.doc.end_cell()

            self.doc.end_row()

        self.doc.end_table()
Пример #2
0
class TimeLine(Report):
    """ TimeLine Report """
    def __init__(self, database, options, user):
        """
        Create the Timeline object that produces the report.

        The arguments are:

        database        - the GRAMPS database instance
        options         - instance of the Options class for this report
        user            - instance of gen.user.User()

        This report needs the following parameters (class variables)
        that come in the options class.

        filter    - Filter to be applied to the people of the database.
                    The option class carries its number, and the function
                    returning the list of filters.
        sortby        - Sorting method to be used.
        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._user = user
        menu = options.menu

        lang = options.menu.get_option_by_name('trans').get_value()
        rlocale = self.set_locale(lang)

        stdoptions.run_private_data_option(self, menu)
        living_opt = stdoptions.run_living_people_option(self, menu, rlocale)
        self.database = CacheProxyDb(self.database)

        self.filter = menu.get_option_by_name('filter').get_filter()
        self.fil_name = "(%s)" % self.filter.get_name(rlocale)

        living_value = menu.get_option_by_name('living_people').get_value()
        for (value, description) in living_opt.get_items(xml_items=True):
            if value == living_value:
                living_desc = self._(description)
                break
        self.living_desc = self._("(Living people: %(option_name)s)") % {
            'option_name': living_desc
        }

        stdoptions.run_name_format_option(self, menu)

        sort_func_num = menu.get_option_by_name('sortby').get_value()
        sort_functions = _get_sort_functions(Sort(self.database))
        self.sort_name = self._(sort_functions[sort_func_num][0])
        self.sort_func = sort_functions[sort_func_num][1]
        self.calendar = config.get('preferences.calendar-format-report')
        self.plist = []
        self.header = 2.6

    def write_report(self):
        # Apply the filter
        with self._user.progress(_('Timeline'), _('Applying filter...'),
                                 self.database.get_number_of_people()) as step:
            self.plist = self.filter.apply(self.database,
                                           self.database.iter_person_handles(),
                                           step)

        # Find the range of dates to include
        (low, high) = self.find_year_range()

        # Generate the actual timeline
        self.generate_timeline(low, high)

    def generate_timeline(self, low, high):
        """ generate the timeline """
        st_size = self.name_size()
        style_sheet = self.doc.get_style_sheet()
        font = style_sheet.get_paragraph_style('TLG-Name').get_font()
        incr = utils.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.6

        # Sort the people as requested
        with self._user.progress(_('Timeline'), _('Sorting dates...'),
                                 0) as step:
            self.plist.sort(key=self.sort_func)

        self.doc.start_page()
        self.build_grid(low, high, start, stop, True)

        index = 1
        current = 1

        length = len(self.plist)

        with self._user.progress(_('Timeline'), _('Calculating timeline...'),
                                 length) as step:

            for p_id in self.plist:
                person = self.database.get_person_from_handle(p_id)
                birth = get_birth_or_fallback(self.database, person)
                if birth:
                    bth = birth.get_date_object()
                    bth = bth.to_calendar(self.calendar).get_year()
                else:
                    bth = None

                death = get_death_or_fallback(self.database, person)
                if death:
                    dth = death.get_date_object()
                    dth = dth.to_calendar(self.calendar).get_year()
                else:
                    dth = None

                dname = self._name_display.display(person)
                mark = utils.get_person_mark(self.database, person)
                self.doc.draw_text('TLG-text', dname, incr + pad,
                                   self.header + (incr + pad) * index, mark)

                _y1 = self.header + (pad + incr) * index
                _y2 = self.header + ((pad + incr) * index) + incr
                _y3 = (_y1 + _y2) / 2.0
                w05 = 0.05

                if bth:
                    start_offset = ((float(bth - low) / float(high - low)) *
                                    size)
                    _x1 = start + start_offset
                    path = [(_x1, _y1), (_x1 + w05, _y3), (_x1, _y2),
                            (_x1 - w05, _y3)]
                    self.doc.draw_path('TLG-line', path)

                if dth:
                    start_offset = ((float(dth - low) / float(high - low)) *
                                    size)
                    _x1 = start + start_offset
                    path = [(_x1, _y1), (_x1 + w05, _y3), (_x1, _y2),
                            (_x1 - w05, _y3)]
                    self.doc.draw_path('TLG-solid', path)

                if bth and dth:
                    start_offset = (
                        (float(bth - low) / float(high - low)) * size) + w05
                    stop_offset = (
                        (float(dth - low) / float(high - low)) * size) - w05

                    _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
                step()
            self.doc.end_page()

    def build_grid(self, year_low, year_high, start_pos, stop_pos, toc=False):
        """
        Draws the grid outline for the chart. Sets the document label,
        draws the vertical lines, and adds the year labels. Arguments
        are:

        year_low  - lowest year on the chart
        year_high - highest year on the chart
        start_pos - x position of the lowest leftmost grid line
        stop_pos  - x position of the rightmost grid line
        """
        self.draw_title(toc)
        self.draw_columns(start_pos, stop_pos)
        if year_high is not None and year_low is not None:
            self.draw_year_headings(year_low, year_high, start_pos, stop_pos)
        else:
            self.draw_no_date_heading()

    def draw_columns(self, start_pos, stop_pos):
        """
        Draws the columns out of vertical lines.

        start_pos - x position of the lowest leftmost grid line
        stop_pos  - x position of the rightmost grid line
        """
        top_y = self.header
        bottom_y = self.doc.get_usable_height()
        delta = (stop_pos - start_pos) / 5
        for val in range(0, 6):
            xpos = start_pos + (val * delta)
            self.doc.draw_line('TLG-grid', xpos, top_y, xpos, bottom_y)

    def draw_title(self, toc):
        """
        Draws the title for the page.
        """
        width = self.doc.get_usable_width()
        title = "%(str1)s -- %(str2)s" % {
            'str1': self._("Timeline Chart"),
            # feature request 2356: avoid genitive form
            'str2': self._("Sorted by %s") % self.sort_name
        }
        title3 = self.living_desc
        mark = None
        if toc:
            mark = IndexMark(title, INDEX_TYPE_TOC, 1)
        self.doc.center_text('TLG-title', title, width / 2.0, 0, mark)
        style_sheet = self.doc.get_style_sheet()
        title_font = style_sheet.get_paragraph_style('TLG-Title').get_font()
        title_y = 1.2 - (utils.pt2cm(title_font.get_size()) * 1.2)
        self.doc.center_text('TLG-title', self.fil_name, width / 2.0, title_y)
        title_y = 1.8 - (utils.pt2cm(title_font.get_size()) * 1.2)
        self.doc.center_text('TLG-title', title3, width / 2.0, title_y)

    def draw_year_headings(self, year_low, year_high, start_pos, stop_pos):
        """
        Draws the column headings (years) for the page.
        """
        style_sheet = self.doc.get_style_sheet()
        label_font = style_sheet.get_paragraph_style('TLG-Label').get_font()
        label_y = self.header - (utils.pt2cm(label_font.get_size()) * 1.2)
        incr = (year_high - year_low) / 5
        delta = (stop_pos - start_pos) / 5
        for val in range(0, 6):
            xpos = start_pos + (val * delta)
            year_str = str(int(year_low + (incr * val)))
            self.doc.center_text('TLG-label', year_str, xpos, label_y)

    def draw_no_date_heading(self):
        """
        Draws a single heading that says "No Date Information"
        """
        width = self.doc.get_usable_width()
        style_sheet = self.doc.get_style_sheet()
        label_font = style_sheet.get_paragraph_style('TLG-Label').get_font()
        label_y = self.header - (utils.pt2cm(label_font.get_size()) * 1.2)
        self.doc.center_text('TLG-label', self._("No Date Information"),
                             width / 2.0, label_y)

    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):
            """ convenience function """
            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)

        with self._user.progress(_('Timeline'), _('Finding date range...'),
                                 len(self.plist)) as step:

            for p_id in self.plist:
                person = self.database.get_person_from_handle(p_id)
                birth = get_birth_or_fallback(self.database, person)
                if birth:
                    bth = birth.get_date_object()
                    bth = bth.to_calendar(self.calendar).get_year()
                    (low, high) = min_max_year(low, high, bth)

                death = get_death_or_fallback(self.database, person)
                if death:
                    dth = death.get_date_object()
                    dth = dth.to_calendar(self.calendar).get_year()
                    (low, high) = min_max_year(low, high, dth)
                step()

            # 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)

        return (low, high)

    def name_size(self):
        """ get the length of the name """
        self.plist = self.filter.apply(self.database,
                                       self.database.iter_person_handles())

        style_sheet = self.doc.get_style_sheet()
        gstyle = style_sheet.get_draw_style('TLG-text')
        pname = gstyle.get_paragraph_style()
        pstyle = style_sheet.get_paragraph_style(pname)
        font = pstyle.get_font()

        size = 0
        for p_id in self.plist:
            person = self.database.get_person_from_handle(p_id)
            dname = self._name_display.display(person)
            size = max(self.doc.string_width(font, dname), size)
        return utils.pt2cm(size)