Mise à jour du plugin SyntheticReport pour Gramps

La prochaine cousinade approche à grand pas. Du coup, je me relance dans la généalogie. Au menu : site web et livret. Pour le livret, il m’a fallut mettre à jour mon plugin pour Gramps.

syntheticreport.py

#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000  Donald N. Allingham
# Copyright (C) 2003  Guilhem BONNEFILLE
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

"""Reports/Text Reports/Synthetic Report"""


#-------------------------------------------------------------------------
#
# Standard Python modules
#
#-------------------------------------------------------------------------
import os

#-------------------------------------------------------------------------
#
# internationalization
#
#-------------------------------------------------------------------------
from gettext import gettext as _

#------------------------------------------------------------------------
#
# GRAMPS modules
#
#------------------------------------------------------------------------
import gen.lib
import BaseDoc
import DateHandler
from gen.plug import PluginManager
from gen.plug.menu import BooleanOption, FilterOption, PersonOption
from ReportBase import Report, ReportUtils, MenuReportOptions, CATEGORY_TEXT
from ReportBase import Bibliography, Endnotes
from BasicUtils import name_displayer as _nd
from Utils import media_path_full
from QuestionDialog import WarningDialog

#-------------------------------------------------------------------------
#
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
import gtk.glade

#------------------------------------------------------------------------
#
# 
#
#------------------------------------------------------------------------
class SyntheticReport(Report):
    single_row = 1

    #--------------------------------------------------------------------
    #
    # 
    #
    #--------------------------------------------------------------------
    def __init__(self, database, options_class):
        """
        Create the SyntheticReport object that produces the report.
        
        The arguments are:

        database        - the GRAMPS database instance
        person          - currently selected person
        options_class   - instance of the Options class for this report

        This report needs the following parameters (class variables)
        that come in the options class.
        
        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.
        cites     - Whether or not to include source informaiton.
        """

        Report.__init__(self, database, options_class)

        menu = options_class.menu
        self.use_srcs = menu.get_option_by_name('cites').get_value()

        self.single_row = menu.get_option_by_name('single_row').get_value()

        filter_option = options_class.menu.get_option_by_name('filter')
        self.filter = filter_option.get_filter()
        self.bibli = None

    #--------------------------------------------------------------------
    #
    # 
    #
    #--------------------------------------------------------------------
    def compute_event(self,date_ref):
	event = self.database.get_event_from_handle(date_ref.ref)
	date = DateHandler.get_date( event )
	place_handle = event.get_place_handle()
	place = ""
    	if place_handle:
        	place = self.database.get_place_from_handle(place_handle).get_title()
        if date == "":
            if place == "":
                val = ""
            else:
                val = " in " + place + ". "
        else:
            if place == "":
                val = date + ". "
            else:
                val = date + " in " + place + ". "

        return val

    #--------------------------------------------------------------------
    #
    # 
    #
    #--------------------------------------------------------------------
    def write_person_single_row_with_breaks(self,name,birth,death,father,mother):
        # format them on the doc
        # First row :
        # Name
        # Birth
        # Father
        self.doc.start_row()

        self.doc.start_cell("NormalCell")
        self.doc.start_paragraph("Normal")
        self.doc.write_text(name)
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell("NormalCell")
        self.doc.start_paragraph("Normal")
        val = "N: %s\n\nD: %s" % (birth,death)
        self.doc.write_text(val)
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell("NormalCell")
        self.doc.start_paragraph("Normal")
        val = "%s\n\n%s" % (father,mother)
        self.doc.write_text(val)
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.end_row()

    #--------------------------------------------------------------------
    #
    # 
    #
    #--------------------------------------------------------------------
    def write_person_single_row(self,name,birth,death,father,mother):
        # format them on the doc
        # First row :
        # Name
        # Birth
        # Death
        # Father
        # Mother
        self.doc.start_row()

        self.doc.start_cell("NormalCell")
        self.doc.start_paragraph("Normal")
        self.doc.write_text(name)
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell("NormalCell")
        self.doc.start_paragraph("Normal")
        self.doc.write_text(birth)
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell("NormalCell")
        self.doc.start_paragraph("Normal")
        self.doc.write_text(death)
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell("NormalCell")
        self.doc.start_paragraph("Normal")
        self.doc.write_text(father)
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell("NormalCell")
        self.doc.start_paragraph("Normal")
        self.doc.write_text(mother)
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.end_row()

    #--------------------------------------------------------------------
    #
    # 
    #
    #--------------------------------------------------------------------
    def write_person_two_rows(self,name,birth,death,father,mother):
        # format them on the doc
        # First row :
        # Name
        # Birth
        # Father
        self.doc.start_row()

        self.doc.start_cell("UpCell")
        self.doc.start_paragraph("Normal")
        self.doc.write_text(name)
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell("UpCell")
        self.doc.start_paragraph("Normal")
        val = "N: %s" % birth
        self.doc.write_text(val)
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell("UpCell")
        self.doc.start_paragraph("Normal")
        self.doc.write_text(father)
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.end_row()

        # Second row :
        # None
        # Death
        # Mother
        self.doc.start_row()

        self.doc.start_cell("DownCell")
        self.doc.start_paragraph("Normal")
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell("DownCell")
        self.doc.start_paragraph("Normal")
        val = "D: %s" % death
        self.doc.write_text(val)
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.start_cell("DownCell")
        self.doc.start_paragraph("Normal")
        self.doc.write_text(mother)
        self.doc.end_paragraph()
        self.doc.end_cell()

        self.doc.end_row()

    #--------------------------------------------------------------------
    #
    # 
    #
    #--------------------------------------------------------------------
    def write_person(self,person):
        if person == None:
            return
        # Prepare informations
        name = _nd.display_name(person.get_primary_name())

	# Dates
	birth_ref = person.get_birth_ref()
	birth_val = "  "
	if birth_ref:
		birth_val = self.compute_event(birth_ref)
	death_ref = person.get_death_ref()
	death_val = "  "
	if death_ref:
		death_val = self.compute_event(death_ref)

	# Parents
        family_handle = person.get_main_parents_family_handle()
        if family_handle:
            family = self.database.get_family_from_handle(family_handle)
            father_inst_id = family.get_father_handle()
            if father_inst_id:
                father_inst = self.database.get_person_from_handle(
                    father_inst_id)
                father_name = _nd.display(father_inst)
                fmark = ReportUtils.get_person_mark(self.database,father_inst)
            else:
                father_name = ""
                fmark = None
            mother_inst_id = family.get_mother_handle()
            if mother_inst_id:
                mother_inst = self.database.get_person_from_handle(
                    mother_inst_id) 
                mother_name = _nd.display(mother_inst)
                mmark = ReportUtils.get_person_mark(self.database,mother_inst)
            else:
                mother_name = ""
                mmark = None
        else:
            father_name = ""
            fmark = None
            mother_name = ""
            mmark = None

        if self.single_row == 1:
          self.write_person_single_row(name,birth_val,death_val,
                                       father_name,mother_name)
        else:
          self.write_person_two_rows(name,birth_val,death_val,
                                     father_name,mother_name)

    #--------------------------------------------------------------------
    #
    # 
    #
    #--------------------------------------------------------------------
    def write_title_single_row(self):

        self.doc.start_row()
        self.doc.start_cell("TableHead")
        self.doc.start_paragraph("TableTitle")
        self.doc.write_text("%s:" % _("Name"))
        self.doc.end_paragraph()
        self.doc.end_cell()
        self.doc.start_cell("TableHead")
        self.doc.start_paragraph("TableTitle")
        self.doc.write_text("%s:" % _("Birth"))
        self.doc.end_paragraph()
        self.doc.end_cell()
        self.doc.start_cell("TableHead")
        self.doc.start_paragraph("TableTitle")
        self.doc.write_text("%s:" % _("Death"))
        self.doc.end_paragraph()
        self.doc.end_cell()
        self.doc.start_cell("TableHead")
        self.doc.start_paragraph("TableTitle")
        self.doc.write_text("%s:" % _("Father"))
        self.doc.end_paragraph()
        self.doc.end_cell()
        self.doc.start_cell("TableHead")
        self.doc.start_paragraph("TableTitle")
        self.doc.write_text("%s:" % _("Mother"))
        self.doc.end_paragraph()
        self.doc.end_cell()
        self.doc.end_row()

    #--------------------------------------------------------------------
    #
    # 
    #
    #--------------------------------------------------------------------
    def write_title_two_rows(self):

        self.doc.start_row()
        self.doc.start_cell("TableHead")
        self.doc.start_paragraph("TableTitle")
        self.doc.write_text("%s:" % _("Name"))
        self.doc.end_paragraph()
        self.doc.end_cell()
        self.doc.start_cell("TableHead")
        self.doc.start_paragraph("TableTitle")
        self.doc.write_text("%s:" % _("Birth"))
        self.doc.end_paragraph()
        self.doc.end_cell()
        self.doc.start_cell("TableHead")
        self.doc.start_paragraph("TableTitle")
        self.doc.write_text("%s:" % _("Father"))
        self.doc.end_paragraph()
        self.doc.end_cell()
        self.doc.end_row()

        self.doc.start_row()
        self.doc.start_cell("TableHead")
        self.doc.start_paragraph("Normal")
        self.doc.end_paragraph()
        self.doc.end_cell()
        self.doc.start_cell("TableHead")
        self.doc.start_paragraph("TableTitle")
        self.doc.write_text("%s:" % _("Death"))
        self.doc.end_paragraph()
        self.doc.end_cell()
        self.doc.start_cell("TableHead")
        self.doc.start_paragraph("TableTitle")
        self.doc.write_text("%s:" % _("Mother"))
        self.doc.end_paragraph()
        self.doc.end_cell()
        self.doc.end_row()

    #--------------------------------------------------------------------
    #
    # 
    #
    #--------------------------------------------------------------------
    def write_report(self):
        plist = self.database.get_person_handles(sort_handles=False)
        if self.filter:
            ind_list = self.filter.apply(self.database,plist)
        else:
            ind_list = plist

        # Header
        self.doc.start_table("Report","IndTable")

        if self.single_row == 1:
          self.write_title_single_row()
        else:
          self.write_title_two_rows()

	# Body
        count = 0
        for person_handle in ind_list:
            person = self.database.get_person_from_handle(person_handle)
            self.write_person(person)
            count = count + 1

        # Footer
        self.doc.end_table()
            
#------------------------------------------------------------------------
#
# IndivCompleteOptions
#
#------------------------------------------------------------------------
class SyntheticOptions(MenuReportOptions):
    """
    Defines options and provides handling interface.
    """
    def __init__(self, name, dbase):
        self.__db = dbase
        self.__pid = None
        self.__filter = None
        MenuReportOptions.__init__(self, name, dbase)
        
    def add_menu_options(self, menu):
        ################################
        category_name = _("Report Options")
        ################################
        
        self.__filter = FilterOption(_("Filter"), 0)
        self.__filter.set_help(
                           _("Select the filter to be applied to the report"))
        menu.add_option(category_name, "filter", self.__filter)
        self.__filter.connect('value-changed', self.__filter_changed)

        self.__pid = PersonOption(_("Filter Person"))
        self.__pid.set_help(_("The center person for the filter"))
        menu.add_option(category_name, "pid", self.__pid)
        self.__pid.connect('value-changed', self.__update_filters)
        
        self.__update_filters()
        
        cites = BooleanOption(_("Include Source Information"), True)
        cites.set_help(_("Whether to cite sources."))
        menu.add_option(category_name, "cites", cites)
        
#    def add_user_options(self):
        single_row = BooleanOption(_('Only one line per person'), False)
        menu.add_option(category_name, "single_row", single_row)

    def __update_filters(self):
        """
        Update the filter list based on the selected person
        """
        gid = self.__pid.get_value()
        person = self.__db.get_person_from_gramps_id(gid)
        filter_list = ReportUtils.get_person_filters(person, True)
        self.__filter.set_filters(filter_list)
        
    def __filter_changed(self):
        """
        Handle filter change. If the filter is not specific to a person,
        disable the person option
        """
        filter_value = self.__filter.get_value()
        if filter_value in [0, 2, 3, 4, 5]:
            # Filters 0, 2, 3, 4 and 5 rely on the center person
            self.__pid.set_available(True)
        else:
            # The rest don't
            self.__pid.set_available(False)

    def make_default_style(self,default_style):
        """Make the default output style for the Individual Complete Report."""
        # Paragraph Styles
        font = BaseDoc.FontStyle()
        font.set_bold(1)
        font.set_type_face(BaseDoc.FONT_SANS_SERIF)
        font.set_size(16)
        p = BaseDoc.ParagraphStyle()
        p.set_alignment(BaseDoc.PARA_ALIGN_CENTER)
        p.set_top_margin(ReportUtils.pt2cm(8))
        p.set_bottom_margin(ReportUtils.pt2cm(8))
        p.set_font(font)
        p.set_description(_("The style used for the title of the page."))
        default_style.add_paragraph_style("Title",p)
    
        font = BaseDoc.FontStyle()
        font.set_bold(1)
        font.set_type_face(BaseDoc.FONT_SANS_SERIF)
        font.set_size(12)
        font.set_italic(1)
        p = BaseDoc.ParagraphStyle()
        p.set_font(font)
        p.set_top_margin(ReportUtils.pt2cm(8))
        p.set_left_margin(ReportUtils.pt2cm(8))
        p.set_description(_("The style used for category labels."))
        default_style.add_paragraph_style("TableTitle",p)

        font = BaseDoc.FontStyle()
        font.set_size(10)
        p = BaseDoc.ParagraphStyle()
        p.set_font(font)
        p.set_top_margin(ReportUtils.pt2cm(8))
        p.set_left_margin(ReportUtils.pt2cm(8))
        p.set_description(_('The basic style used for the text display.'))
        default_style.add_paragraph_style("Normal",p)
        
        # Table Styles
        tbl = BaseDoc.TableStyle()
        tbl.set_width(100)
        tbl.set_columns(3)
        tbl.set_column_width(0,30)
        tbl.set_column_width(1,40)
        tbl.set_column_width(2,30)
        default_style.add_table_style("IndTable",tbl)

        cell = BaseDoc.TableCellStyle()
        cell.set_top_border(1)
        cell.set_bottom_border(1)
        cell.set_right_border(1)
        cell.set_left_border(1)
        default_style.add_cell_style("TableHead",cell)

        cell = BaseDoc.TableCellStyle()
#        cell.set_top_border(1)
        cell.set_bottom_border(1)
        cell.set_right_border(1)
        cell.set_left_border(1)
        default_style.add_cell_style("NormalCell",cell)

        cell = BaseDoc.TableCellStyle()
        cell.set_top_border(1)
        cell.set_right_border(1)
        cell.set_left_border(1)
        default_style.add_cell_style("UpCell",cell)

        cell = BaseDoc.TableCellStyle()
        cell.set_bottom_border(1)
        cell.set_right_border(1)
        cell.set_left_border(1)
        default_style.add_cell_style("DownCell",cell)
        
        Endnotes.add_endnote_styles(default_style)

#------------------------------------------------------------------------
#
# 
#
#------------------------------------------------------------------------
def get_xpm_image():
    return [
        "48 48 33 1",
        " 	c None",
        ".	c #312D2A",
        "+	c #4773AA",
        "@	c #A8A7A5",
        "#	c #BABAB6",
        "$	c #CECECE",
        "%	c #ECDECB",
        "&	c #5C5C60",
        "*	c #7C7262",
        "=	c #F2EADE",
        "-	c #867A6F",
        ";	c #8E887E",
        ">	c #E2CAA2",
        ",	c #565354",
        "'	c #4C4E51",
        ")	c #6D655E",
        "!	c #B69970",
        "~	c #F6F2EE",
        "{	c #9E9286",
        "]	c #416CA3",
        "^	c #3D4557",
        "/	c #A29E96",
        "(	c #FAFAFA",
        "_	c #BA7458",
        ":	c #C67C5E",
        "<	c #BDA37E",
        "[	c #CECABE",
        "}	c #A26E62",
        "|	c #E6E2E2",
        "1	c #423E43",
        "2	c #966A60",
        "3	c #D2D2D2",
        "4	c #E5D2B8",
        "                                                ",
        "                                                ",
        "             ;-;-----***)*))))&,&)*             ",
        "             -##############@#@/;&,*            ",
        "             -#((((((((((((((=|$#;;{,           ",
        "             ;#(((((((((((((((~|3/*[{1          ",
        "             -#((((((((((((((((~|3,|[;.         ",
        "             -#((((((((@/@@@@@@/@/'(|[;.        ",
        "             -#((((((((((((((((((~'((|[;.       ",
        "             -#(((((((((((]+]+]]+('=((|[;1      ",
        "             -#(((((((((((]+]}2&+('|=((|[{,     ",
        "             *#(((((((((((]+}<:-+('[|~((|#{)    ",
        "             *#(((((((((((+]2_:)+('...1'&*-)*   ",
        "             -#(((((((((((]&1(_&+(3@#//--)&1)   ",
        "             *#~((((((((((+]1}/^]((|$##/;--'1   ",
        "             *#(((((((((((]]^)11,(((|$[#@/;)1   ",
        "             *#(((((((((((]^.^^&&((~=|$[#@/*.   ",
        "             *#(((((((((((((~(((((((|$[$[#/-.   ",
        "             *#~(((((((((((((((((~~~~||$[[@;.   ",
        "             )#((((@@@@@@/@@/@/@@@@///{;[[[;.   ",
        "             )#(((((((((((((((((~~~~==|$$[#;.   ",
        "             )#((((@/@@/@@@@@@@@@//////{4>3{.   ",
        "             )#(((((((((((((((~~~~==|=||%$[{.   ",
        "             )#((((@@@@@/@@@///////////{43>/.   ",
        "             )#((((((((((((((~~~~~==|||%>4[!.   ",
        "             )#((((@/@@@@@//~~~~======%%%43{.   ",
        "             )#((((((((((((~~~~=|==||=%%%44!.   ",
        "             ,#((((@@/@@/@/@////////{/{{%4$!.   ",
        "             )#~((((((((~~~~~~==||%=%=%%44>/.   ",
        "             ,#((((/@@//@///////////{{{{%4>!.   ",
        "             )#((((((((~~~=~||=|%%%%%4%%%44{.   ",
        "             ,#((((@@@/@/////////{{{{{{{444!.   ",
        "             &#(((((~~~~~|~|||%%|%%%%44444%!.   ",
        "             ,#(((~/@//////////{{{{{{;{;4>4!.   ",
        "             ,#(((~~~~=~|==|%|=%%%4%%44444>!.   ",
        "             &#(((~//////////{{{{{{{;{;{4>><.   ",
        "             ,#(~~~~~~==||%|%%%%%%44444>4>>!.   ",
        "             '#~~~~///////{{{{{{{;!;{;;;>>>!.   ",
        "             ,#~~~~||=||%|%=%%4%444>44>>>>>!.   ",
        "             '#~~~~====%=%=%4%%444444>>>>>>!.   ",
        "             '@~~====|%=%%%%%4%444>>4>>>>>>!.   ",
        "             ,@~======%%%%%%>%%4444>>>>>>>>!.   ",
        "             '#====||=%%%%4%44444>4>>>>>>>>!.   ",
        "             ,@##@<#<<#@<<<<<<<<<<!<!!:!!!!!.   ",
        "             ................................   ",
        "                                                ",
        "                                                ",
        "                                                "]

#------------------------------------------------------------------------
#
# 
#
#------------------------------------------------------------------------
pmgr = PluginManager.get_instance()
pmgr.register_report(
    name = 'indiv_synthetic',
    category = CATEGORY_TEXT,
    report_class = SyntheticReport,
    options_class = SyntheticOptions,
    modes = PluginManager.REPORT_MODE_GUI | \
            PluginManager.REPORT_MODE_BKI | \
            PluginManager.REPORT_MODE_CLI,
    translated_name = _("Synthetic report"),
    status=(_("Beta")),
    author_name="G. Bonnefille",
    author_email="guyou@users.sourceforge.net",
    description=_("Produces a synthetic report around the selected person.")
    )


A glisser dans ~/.gramps/plugins/.