Example #1
0
 def open(self):
     """
     overwrite method, htmlbackend creates a html object that is written on
     close
     """
     try:
         DocBackend.open(self)
     except IOError as msg:
         errmsg = "%s\n%s" % (_("Could not create %s") % self._filename,
                              msg)
         raise ReportError(errmsg)
     except:
         raise ReportError(_("Could not create %s") % self._filename)
     if not os.path.isdir(self.datadirfull()):
         try:
             os.mkdir(self.datadirfull())
         except IOError as msg:
             errmsg = "%s\n%s" % (_("Could not create %s") %
                                  self.datadirfull(), msg)
             raise ReportError(errmsg)
         except:
             raise ReportError(
                 _("Could not create %s") % self.datadirfull())
     self.html_page, self.html_header, self.html_body = Html.page(
         lang=xml_lang(), title=self.title)
Example #2
0
    def start_page(self):
        self.page += 1
        if self.page != 1:
            name = "%s-%d.svg" % (self.root, self.page)
        else:
            name = "%s.svg" % self.root

        try:
            self.file = open(name, "w", encoding="utf-8")
        except IOError as msg:
            raise ReportError(_("Could not create %s") % name, msg)
        except:
            raise ReportError(_("Could not create %s") % name)

        self.buffer = StringIO()

        width = self.paper.get_size().get_width()
        height = self.paper.get_size().get_height()

        self.file.write(
            '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'
            '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" '
            '"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">\n'
            '<svg width="%4.2fcm" height="%4.2fcm" '
            'xmlns="http://www.w3.org/2000/svg">\n'
            '<rect width="%4.2fcm" height="%4.2fcm" '
            'style="fill: %s;"/>\n' % (width, height, width, height, self._bg))
Example #3
0
    def open(self, filename):
        if filename[-4:] != ".rtf":
            self.filename = filename + ".rtf"
        else:
            self.filename = filename

        try:
            self.file = open(self.filename, "w")
        except IOError as msg:
            errmsg = "%s\n%s" % (_("Could not create %s") % self.filename, msg)
            raise ReportError(errmsg)
        except:
            raise ReportError(_("Could not create %s") % self.filename)

        style_sheet = self.get_style_sheet()

        self.file.write(
            '{\\rtf1\\ansi\\ansicpg1252\\deff0\n'
            '{\\fonttbl\n'
            '{\\f0\\froman\\fcharset0\\fprq0 Times New Roman;}\n'
            '{\\f1\\fswiss\\fcharset0\\fprq0 Arial;}}\n'
            '{\colortbl\n'
            )

        self.color_map = {}
        index = 1
        self.color_map[(0, 0, 0)] = 0
        self.file.write('\\red0\\green0\\blue0;')
        for style_name in style_sheet.get_paragraph_style_names():
            style = style_sheet.get_paragraph_style(style_name)
            fgcolor = style.get_font().get_color()
            bgcolor = style.get_background_color()
            if fgcolor not in self.color_map:
                self.color_map[fgcolor] = index
                self.file.write('\\red%d\\green%d\\blue%d;' % fgcolor)
                index += 1
            if bgcolor not in self.color_map:
                self.file.write('\\red%d\\green%d\\blue%d;' % bgcolor)
                self.color_map[bgcolor] = index
                index += 1
        self.file.write('}\n')
        self.file.write(
            '\\kerning0\\cf0\\viewkind1' +
            '\\paperw%d' % twips(self.paper.get_size().get_width()) +
            '\\paperh%d' % twips(self.paper.get_size().get_height()) +
            '\\margl%d' % twips(self.paper.get_left_margin()) +
            '\\margr%d' % twips(self.paper.get_right_margin()) +
            '\\margt%d' % twips(self.paper.get_top_margin()) +
            '\\margb%d' % twips(self.paper.get_bottom_margin()) +
            '\\widowctl\n'
            )
        self.in_table = 0
        self.text = ""
Example #4
0
    def __init__(self, database, options, user):
        """
        Create the NumberOfAncestorsReport 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

        Menu options:
        name_format   - Preferred format to display names
        incl_private  - Whether to include private data
        """
        Report.__init__(self, database, options, user)

        stdoptions.run_private_data_option(self, options.menu)
        self.__db = self.database

        pid = options.menu.get_option_by_name('pid').get_value()
        self.__person = self.__db.get_person_from_gid(pid)
        if self.__person is None:
            raise ReportError(_("Person %s is not in the Database") % pid)

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

        stdoptions.run_name_format_option(self, options.menu)
Example #5
0
    def __init__(self, database, options, user):
        Report.__init__(self, database, options, user)
        menu = options.menu
        self._user = user

        stdoptions.run_private_data_option(self, menu)

        get_value = lambda name: menu.get_option_by_name(name).get_value()

        self.year = get_value('year')
        self.name_format = get_value('name_format')
        self.country = get_value('country')
        self.anniversaries = get_value('anniversaries')
        self.start_dow = get_value('start_dow')
        self.maiden_name = get_value('maiden_name')
        self.alive = get_value('alive')
        self.birthdays = get_value('birthdays')
        self.text1 = get_value('text1')
        self.text2 = get_value('text2')
        self.text3 = get_value('text3')
        self.filter_option = menu.get_option_by_name('filter')
        self.filter = self.filter_option.get_filter()
        pid = get_value('pid')
        self.center_person = self.database.get_person_from_gid(pid)
        if (self.center_person == None):
            raise ReportError(_("Person %s is not in the Database") % pid)

        self._locale = self.set_locale(get_value('trans'))
Example #6
0
    def copy_file(self, from_fname, to_fname, to_dir=''):
        """
        Copy a file from a source to a (report) destination. If to_dir is not
        present, then the destination directory will be created.

        Normally 'to_fname' will be just a filename, without directory path.

        'to_dir' is the relative path name in the destination root. It will
        be prepended before 'to_fname'.
        """
        #build absolute path
        dest = os.path.join(self._backend.datadirfull(), to_dir, to_fname)

        destdir = os.path.dirname(dest)
        if not os.path.isdir(destdir):
            os.makedirs(destdir)

        if from_fname != dest:
            shutil.copyfile(from_fname, dest)
        elif self.warn_dir:
            raise ReportError(
                _("Possible destination error"),
                _("You appear to have set your target directory "
                  "to a directory used for data storage. This "
                  "could create problems with file management. "
                  "It is recommended that you consider using "
                  "a different directory to store your generated "
                  "web pages."))
            self.warn_dir = False
Example #7
0
    def __init__(self, database, options, user):
        Report.__init__(self, database, options, user)
        self._user = user
        menu = options.menu
        mgobn = lambda name: options.menu.get_option_by_name(name).get_value()

        stdoptions.run_private_data_option(self, menu)
        # (this report has its own "living people" option ("alive") already)

        self.titletext = mgobn('titletext')
        self.relationships = mgobn('relationships')
        self.year = mgobn('year')
        self.country = mgobn('country')
        self.anniversaries = mgobn('anniversaries')
        self.start_dow = mgobn('start_dow')
        self.maiden_name = mgobn('maiden_name')
        self.alive = mgobn('alive')
        self.birthdays = mgobn('birthdays')
        self.text1 = mgobn('text1')
        self.text2 = mgobn('text2')
        self.text3 = mgobn('text3')
        self.filter_option = menu.get_option_by_name('filter')
        self.filter = self.filter_option.get_filter()
        pid = mgobn('pid')

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

        stdoptions.run_name_format_option(self, menu)

        self.center_person = self.database.get_person_from_gid(pid)
        if (self.center_person == None):
            raise ReportError(_("Person %s is not in the Database") % pid)
Example #8
0
    def __init__(self, database, options, user):
        """
        Create HourGlass object that produces the report.

        name_format   - Preferred format to display names
        incl_private  - Whether to include private data
        incid         - Whether to include 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)
        menu = options.menu

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

        stdoptions.run_private_data_option(self, menu)
        stdoptions.run_living_people_option(self, menu, locale)
        self.database = CacheProxyDb(self.database)
        self.__db = self.database

        self.__used_people = []
        self.__family_father = []  # links allocated from family to father
        self.__family_mother = []  # links allocated from family to mother

        self.max_descend = menu.get_option_by_name('maxdescend').get_value()
        self.max_ascend = menu.get_option_by_name('maxascend').get_value()
        pid = menu.get_option_by_name('pid').get_value()
        self.center_person = self.__db.get_person_from_gid(pid)
        if self.center_person is None:
            raise ReportError(_("Person %s is not in the Database") % pid)

        # Would be nice to get rid of these 2 hard-coded arrays of colours
        # and instead allow the user to pick-and-choose whatever colour they
        # want.  When/if this is done, take a look at the colour-selection
        # widget and code used in the FamilyLines graph.  FIXME
        colored = {
            'male': 'dodgerblue4',
            'female': 'deeppink',
            'unknown': 'black',
            'family': 'darkgreen'
        }
        filled = {
            'male': 'lightblue',
            'female': 'lightpink',
            'unknown': 'lightgray',
            'family': 'lightyellow'
        }

        self.colorize = menu.get_option_by_name('color').get_value()
        if self.colorize == 'colored':
            self.colors = colored
        elif self.colorize == 'filled':
            self.colors = filled
        self.roundcorners = menu.get_option_by_name('roundcorners').get_value()

        self.includeid = menu.get_option_by_name('incid').get_value()

        stdoptions.run_name_format_option(self, menu)
Example #9
0
    def __init__(self, database, options, user):
        """
        Create the FanChart 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.

        maxgen       - Maximum number of generations to include.
        circle       - Draw a full circle, half circle, or quarter circle.
        background   - Background color is generation dependent or white.
        radial       - Print radial texts roundabout or as upright as possible.
        draw_empty   - draw background when there is no information
        same_style   - use the same style for all generation
        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 = options.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.circle = menu.get_option_by_name('circle').get_value()
        self.background = menu.get_option_by_name('background').get_value()
        self.radial = menu.get_option_by_name('radial').get_value()
        pid = menu.get_option_by_name('pid').get_value()
        self.draw_empty = menu.get_option_by_name('draw_empty').get_value()
        self.same_style = menu.get_option_by_name('same_style').get_value()
        self.center_person = self.database.get_person_from_gid(pid)
        if self.center_person is None:
            raise ReportError(_("Person %s is not in the Database") % pid)

        self.graphic_style = []
        self.text_style = []
        for i in range(0, self.max_generations):
            self.graphic_style.append('FC-Graphic' + '%02d' % i)
            self.text_style.append('FC-Text' + '%02d' % i)

        self.calendar = 0

        self.height = 0
        self.map = [None] * 2**self.max_generations
        self.text = {}
Example #10
0
    def __init__(self, database, options, user):
        """
        Create the KinshipReport 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.

        maxdescend    - Maximum generations of descendants to include.
        maxascend     - Maximum generations of ancestors to include.
        incspouses    - Whether to include spouses.
        inccousins    - Whether to include cousins.
        incaunts      - Whether to include aunts/uncles/nephews/nieces.
        pid           - The GID of the center person for the report.
        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)
        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.__db = self.database

        self.max_descend = menu.get_option_by_name('maxdescend').get_value()
        self.max_ascend = menu.get_option_by_name('maxascend').get_value()
        self.inc_spouses = menu.get_option_by_name('incspouses').get_value()
        self.inc_cousins = menu.get_option_by_name('inccousins').get_value()
        self.inc_aunts = menu.get_option_by_name('incaunts').get_value()
        pid = menu.get_option_by_name('pid').get_value()
        self.person = self.database.get_person_from_gid(pid)
        if self.person is None:
            raise ReportError(_("Person %s is not in the Database") % pid)

        stdoptions.run_name_format_option(self, menu)

        self.rel_calc = get_relationship_calculator(reinit=True,
                                                    clocale=rlocale)

        self.kinship_map = {}
        self.spouse_map = {}
Example #11
0
    def open(self, filename):
        if filename[-4:] != ".txt":
            self.filename = filename + ".txt"
        else:
            self.filename = filename

        try:
            self.file = open(self.filename, "w", errors='backslashreplace')
        except Exception as msg:
            raise ReportError(_("Could not create %s") % self.filename, msg)

        self.in_cell = 0
        self.text = ""
Example #12
0
    def __init__(self, database, options, user):
        """
        Create the EndOfLineReport 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.
        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)

        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)

        pid = menu.get_option_by_name('pid').get_value()
        self.center_person = self.database.get_person_from_gid(pid)
        if self.center_person is None:
            raise ReportError(_("Person %s is not in the Database") % pid)

        stdoptions.run_name_format_option(self, menu)

        # eol_map is a map whose:
        #   keys are the generations of the people
        #   values are a map whose:
        #      keys are person handles
        #      values are an array whose:
        #         elements are an array of ancestor person handles that link
        #         the eol person handle to the person or interest
        # eol_map[generation][person_handle][pedigree_idx][ancestor_handle_idx]
        #
        # There is an array of pedigrees because one person could show up twice
        # in one generation (descendants marrying). Most people only have one
        # pedigree.
        #
        # eol_map is populated by get_eol() which calls itself recursively.
        self.eol_map = {}
        self.get_eol(self.center_person, 1, [])
Example #13
0
    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)
Example #14
0
    def write_report(self):
        """
        Build the actual report.
        """

        records = find_records(self.database,
                               self.filter,
                               self.top_size,
                               self.callname,
                               trans_text=self._,
                               name_format=self._nf,
                               living_mode=self._lv)

        self.doc.start_paragraph('REC-Title')
        title = self._("Records")
        mark = IndexMark(title, INDEX_TYPE_TOC, 1)
        self.doc.write_text(title, mark)
        self.doc.end_paragraph()

        self.doc.start_paragraph('REC-Subtitle')
        filter_name = self.filter.get_name(self._locale)
        self.doc.write_text("(%s)" % filter_name)
        self.doc.end_paragraph()
        if self._lv != LivingProxyDb.MODE_INCLUDE_ALL:
            self.doc.start_paragraph('REC-Subtitle')
            self.doc.write_text(self.living_desc)
            self.doc.end_paragraph()

        for (text, varname, top) in records:
            if not self.include[varname]:
                continue

            self.doc.start_paragraph('REC-Heading')
            self.doc.write_text(self._(text))
            self.doc.end_paragraph()

            last_value = None
            rank = 0
            for (number, (sort, value, name, handletype,
                          handle)) in enumerate(top):
                mark = None
                if handletype == 'Person':
                    person = self.database.get_person_from_handle(handle)
                    mark = utils.get_person_mark(self.database, person)
                elif handletype == 'Family':
                    family = self.database.get_family_from_handle(handle)
                    # librecords.py checks that the family has both
                    # a father and a mother and also that each one is
                    # in the filter if any filter was used, so we don't
                    # have to do any similar checking here, it's been done
                    f_handle = family.get_father_handle()
                    dad = self.database.get_person_from_handle(f_handle)
                    f_mark = utils.get_person_mark(self.database, dad)
                    m_handle = family.get_mother_handle()
                    mom = self.database.get_person_from_handle(m_handle)
                    m_mark = utils.get_person_mark(self.database, mom)
                else:
                    raise ReportError(
                        _("Option '%(opt_name)s' is present "
                          "in %(file)s\n  but is not known to "
                          "the module.  Ignoring...") % {
                              'opt_name': handletype,
                              'file': 'libnarrate.py'
                          })
                    # since the error is very unlikely I reused the string
                if value != last_value:
                    last_value = value
                    rank = number
                self.doc.start_paragraph('REC-Normal')
                self.doc.write_text(
                    self._("%(number)s. ") % {'number': rank + 1})
                self.doc.write_markup(str(name), name.get_tags(), mark)
                if handletype == 'Family':
                    self.doc.write_text('', f_mark)
                    self.doc.write_text('', m_mark)
                if isinstance(value, Span):
                    tvalue = value.get_repr(dlocale=self._locale)
                else:
                    tvalue = value
                self.doc.write_text(" (%s)" % tvalue)
                self.doc.end_paragraph()

        self.doc.start_paragraph('REC-Footer')
        self.doc.write_text(self.footer)
        self.doc.end_paragraph()
Example #15
0
    def __init__(self, database, options, user):
        """
        Create the DescendantReport 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.
        name_format   - Preferred format to display names
        dups          - Whether to include duplicate descendant trees
        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()
        self._locale = self.set_locale(lang)

        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('gen').get_value()
        pid = menu.get_option_by_name('pid').get_value()
        self.center_person = self.database.get_person_from_gid(pid)
        if self.center_person is None:
            raise ReportError(_("Person %s is not in the Database") % pid)

        #Initialize the Printinfo class
        self._showdups = menu.get_option_by_name('dups').get_value()
        numbering = menu.get_option_by_name('numbering').get_value()
        if numbering == "Simple":
            obj = PrintSimple(self._showdups)
        elif numbering == "Henry":
            obj = PrintHenry()
        elif numbering == "Modified Henry":
            obj = PrintHenry(modified=True)
        elif numbering == "d'Aboville":
            obj = PrintDAboville()
        elif numbering == "de Villiers/Pama":
            obj = PrintVilliers()
        elif numbering == "Meurgey de Tupigny":
            obj = PrintMeurgey()
        else:
            raise AttributeError("no such numbering: '%s'" % numbering)

        marrs = menu.get_option_by_name('marrs').get_value()
        divs = menu.get_option_by_name('divs').get_value()

        stdoptions.run_name_format_option(self, menu)

        self.obj_print = Printinfo(self.doc, self.database, obj, marrs, divs,
                                   self._name_display, self._locale)
Example #16
0
    def __init__(self, database, options, user):
        """
        Create the PlaceReport object produces the Place report.

        The arguments are:

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

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

        places          - List of places to report on.
        center          - Center of report, person or event
        incl_private    - Whether to include private data
        name_format     - Preferred format to display names
        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 = 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._db = 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
        }

        places = menu.get_option_by_name('places').get_value()
        self.center = menu.get_option_by_name('center').get_value()

        stdoptions.run_name_format_option(self, menu)
        self._nd = self._name_display

        filter_option = menu.get_option_by_name('filter')
        self.filter = filter_option.get_filter()

        self.sort = Sort(self._db)

        self.place_handles = []
        if self.filter.get_name() != '':
            # Use the selected filter to provide a list of place handles
            plist = self._db.iter_place_handles()
            self.place_handles = self.filter.apply(self._db, plist)

        if places:
            # Add places selected individually
            self.place_handles += self.__get_place_handles(places)

        if not self.place_handles:
            raise ReportError(
                _('Place Report'),
                _('Please select at least one place before running this.'))

        self.place_handles.sort(key=self.sort.by_place_title_key)
Example #17
0
    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 GID 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()

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

        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.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.other_events = get_value('incotherevents')

        self.center_person = self._db.get_person_from_gid(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)
Example #18
0
    def run(self):
        """Create the output file.
        The derived class overrides EXT and create_cairo_surface
        """
        # get paper dimensions
        paper_width = self.paper.get_size().get_width() * DPI / 2.54
        paper_height = self.paper.get_size().get_height() * DPI / 2.54
        page_width = round(self.paper.get_usable_width() * DPI / 2.54)
        page_height = round(self.paper.get_usable_height() * DPI / 2.54)
        left_margin = self.paper.get_left_margin() * DPI / 2.54
        top_margin = self.paper.get_top_margin() * DPI / 2.54

        # create cairo context and pango layout
        filename = self._backend.filename
        # Cairo can't reliably handle unicode filenames on Linux or
        # Windows, so open the file for it.
        with open(filename, 'wb') as fd:
            try:
                surface = self.create_cairo_surface(fd, paper_width,
                                                    paper_height)
                surface.set_fallback_resolution(300, 300)
                cr = cairo.Context(surface)
                fontmap = PangoCairo.font_map_new()
                fontmap.set_resolution(DPI)
                pango_context = fontmap.create_context()
                options = cairo.FontOptions()
                options.set_hint_metrics(cairo.HINT_METRICS_OFF)
                PangoCairo.context_set_font_options(pango_context, options)
                layout = Pango.Layout(pango_context)
                PangoCairo.update_context(cr, pango_context)
                # paginate the document
                self.paginate_document(layout, page_width, page_height, DPI,
                                       DPI)
                body_pages = self._pages

                # build the table of contents and alphabetical index
                toc_page = None
                index_page = None
                toc = []
                index = {}
                for page_nr, page in enumerate(body_pages):
                    if page.has_toc():
                        toc_page = page_nr
                    if page.has_index():
                        index_page = page_nr
                    for mark in page.get_marks():
                        if mark.type == INDEX_TYPE_ALP:
                            if mark.key in index:
                                if page_nr + 1 not in index[mark.key]:
                                    index[mark.key].append(page_nr + 1)
                            else:
                                index[mark.key] = [page_nr + 1]
                        elif mark.type == INDEX_TYPE_TOC:
                            toc.append([mark, page_nr + 1])

                # paginate the table of contents
                rebuild_required = False
                if toc_page is not None:
                    toc_pages = self.__generate_toc(layout, page_width,
                                                    page_height, toc)
                    offset = len(toc_pages) - 1
                    if offset > 0:
                        self.__increment_pages(toc, index, toc_page, offset)
                        rebuild_required = True
                else:
                    toc_pages = []

                # paginate the index
                if index_page is not None:
                    index_pages = self.__generate_index(
                        layout, page_width, page_height, index)
                    offset = len(index_pages) - 1
                    if offset > 0:
                        self.__increment_pages(toc, index, index_page, offset)
                        rebuild_required = True
                else:
                    index_pages = []

                # rebuild the table of contents and index if required
                if rebuild_required:
                    if toc_page is not None:
                        toc_pages = self.__generate_toc(
                            layout, page_width, page_height, toc)
                    if index_page is not None:
                        index_pages = self.__generate_index(
                            layout, page_width, page_height, index)

                # render the pages
                if toc_page is not None:
                    body_pages = body_pages[:toc_page] + toc_pages + \
                                 body_pages[toc_page+1:]
                if index_page is not None:
                    body_pages = body_pages[:index_page] + index_pages + \
                                 body_pages[index_page+1:]
                self._pages = body_pages
                for page_nr in range(len(self._pages)):
                    cr.save()
                    cr.translate(left_margin, top_margin)
                    self.draw_page(page_nr, cr, layout, page_width,
                                   page_height, DPI, DPI)
                    cr.show_page()
                    cr.restore()

                # close the surface (file)
                surface.finish()

            except IOError as msg:
                errmsg = "%s\n%s" % (_("Could not create %s") % filename, msg)
                raise ReportError(errmsg)
            except Exception as err:
                errmsg = "%s\n%s" % (_("Could not create %s") % filename, err)
                raise ReportError(errmsg)
Example #19
0
    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 GID 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._locale = self.set_locale(get_value('trans'))

        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.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.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')

        pid = get_value('pid')
        self.center_person = self._db.get_person_from_gid(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)