From 2c166c0dfdcc5b418245f354e513643041ee2733 Mon Sep 17 00:00:00 2001 From: Alex Roitman Date: Sun, 2 Jan 2005 22:22:11 +0000 Subject: [PATCH] * src/Report.py: Add support for a semi-common 'dispf'. * src/ReportOptions.py: Add support for a semi-common 'dispf'. * src/Utils.py (cm2pt): Add function. * src/plugins/AncestorChart.py: Convert to new scheme. * src/plugins/AncestorChart2.py: Convert to new scheme. * src/plugins/DesGraph.py: Convert to new scheme. svn: r3858 --- gramps2/ChangeLog | 8 + gramps2/src/Report.py | 19 +- gramps2/src/ReportOptions.py | 32 +- gramps2/src/Utils.py | 9 +- gramps2/src/plugins/AncestorChart.py | 321 +++++------------ gramps2/src/plugins/AncestorChart2.py | 486 ++++++++------------------ gramps2/src/plugins/DesGraph.py | 302 ++++------------ 7 files changed, 349 insertions(+), 828 deletions(-) diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index fb802cbe9..8cf3080c7 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,3 +1,11 @@ +2005-01-02 Alex Roitman + * src/Report.py: Add support for a semi-common 'dispf'. + * src/ReportOptions.py: Add support for a semi-common 'dispf'. + * src/Utils.py (cm2pt): Add function. + * src/plugins/AncestorChart.py: Convert to new scheme. + * src/plugins/AncestorChart2.py: Convert to new scheme. + * src/plugins/DesGraph.py: Convert to new scheme. + 2005-01-01 Don Allingham * src/EditPerson.py: move strip_id from Utils * src/GrampsCfg.py: use ComboBox for toolbar selection diff --git a/gramps2/src/Report.py b/gramps2/src/Report.py index f2b9ce13a..b376b5524 100644 --- a/gramps2/src/Report.py +++ b/gramps2/src/Report.py @@ -691,12 +691,8 @@ class BareReportDialog: swin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC) self.extra_textbox = gtk.TextView() swin.add(self.extra_textbox) - - try: - self.extra_textbox.get_buffer().set_text(string,len(string)) - except TypeError: - self.extra_textbox.get_buffer().set_text(string) + self.extra_textbox.get_buffer().set_text('\n'.join(string)) self.extra_textbox.set_editable(1) self.add_tooltip(self.extra_textbox,et_tip) table.attach(self.extra_textbox_label, 1, 2, row, row+1, @@ -809,8 +805,9 @@ class BareReportDialog: b = self.extra_textbox.get_buffer() text_val = unicode(b.get_text(b.get_start_iter(),b.get_end_iter(),gtk.FALSE)) self.report_text = text_val.split('\n') + self.options.handler.set_display_format(self.report_text) else: - self.report_text = "" + self.report_text = [] def parse_other_frames(self): """Do nothing. This sole purpose of this function is to give @@ -1560,6 +1557,7 @@ class CommandLineReport: 'filter' : ["=num","Filter number."], 'gen' : ["=num","Number of generations to follow."], 'pagebbg' : ["=0/1","Page break between generations."], + 'dispf' : ["=str","Display format for the outputbox."], } # Add report-specific options @@ -1612,7 +1610,14 @@ class CommandLineReport: self.options_help['gen'].append("Whatever Number You Wish") self.options_help['pagebbg'].append([ "No page break","Page break"]) - self.options_help['page_breaks'].append(True) + self.options_help['pagebbg'].append(True) + + if self.options_dict.has_key('dispf'): + dispf = ''.join(self.options_dict['dispf']).replace('\\n','\n') + self.option_class.handler.set_display_format(dispf) + + self.options_help['dispf'].append( + "Any string -- may use keyword substitutions") self.option_class.handler.output = self.options_dict['of'] self.options_help['of'].append(os.path.expanduser("~/whatever_name")) diff --git a/gramps2/src/ReportOptions.py b/gramps2/src/ReportOptions.py index 4865195c8..070120b15 100644 --- a/gramps2/src/ReportOptions.py +++ b/gramps2/src/ReportOptions.py @@ -203,7 +203,7 @@ class OptionListCollection: if not filename or not os.path.isfile(filename): filename = const.report_options - self.file = os.path.expanduser(filename) + self.filename = os.path.expanduser(filename) self.last_paper_name = self.default_paper_name self.last_orientation = self.default_orientation @@ -300,7 +300,7 @@ class OptionListCollection: """ Saves the current OptionListCollection to the associated file. """ - f = open(self.file,"w") + f = open(self.filename,"w") f.write("\n") f.write('\n') @@ -357,7 +357,7 @@ class OptionListCollection: try: p = make_parser() p.setContentHandler(OptionParser(self)) - p.parse('file://' + self.file) + p.parse('file://' + self.filename) except (IOError,OSError,SAXParseException): pass @@ -565,15 +565,27 @@ class OptionHandler: self.style_name = style_name def get_filter_number(self): - try: + if self.default_options_dict.has_key('filter'): return self.options_dict.get('filter', self.default_options_dict['filter']) - except KeyError: + else: return None def set_filter_number(self,val): self.options_dict['filter'] = val + def get_display_format(self): + if self.default_options_dict.has_key('dispf'): + return self.options_dict.get('dispf', + self.default_options_dict['dispf']) + else: + return [] + + def set_display_format(self,val): + if type(val) != list: + val = val.split('\n') + self.options_dict['dispf'] = val + def get_format_name(self): return self.format_name @@ -674,6 +686,8 @@ class ReportOptions: 'gen' - Maximum number of generations to consider. 'pagebbg' - Whether or not make page breaks between generations. + + 'dispf' - Display format for the option box -- graphic reports. A self.enable_dict dictionary MUST be defined here, whose keys @@ -815,3 +829,11 @@ class ReportOptions: This method MUST NOT be overridden by subclasses. """ return self.handler.get_filter_number() + + def get_display_format(self): + """ + Return display format for the option box of graphical report. + + This method MUST NOT be overridden by subclasses. + """ + return self.handler.get_display_format() diff --git a/gramps2/src/Utils.py b/gramps2/src/Utils.py index ebdb5af7c..c516d88d7 100644 --- a/gramps2/src/Utils.py +++ b/gramps2/src/Utils.py @@ -440,11 +440,14 @@ def roman(num): #------------------------------------------------------------------------- # -# Convert points to cm +# Convert points to cm and back # #------------------------------------------------------------------------- -def pt2cm(val): - return (float(val)/28.3465) +def pt2cm(pt): + return (float(pt)/28.3465) + +def cm2pt(cm): + return (float(cm)/2.54)*72 #------------------------------------------------------------------------- # diff --git a/gramps2/src/plugins/AncestorChart.py b/gramps2/src/plugins/AncestorChart.py index dc8665f25..47809e6cb 100644 --- a/gramps2/src/plugins/AncestorChart.py +++ b/gramps2/src/plugins/AncestorChart.py @@ -27,8 +27,7 @@ # python modules # #------------------------------------------------------------------------ -import os -import string +from gettext import gettext as _ #------------------------------------------------------------------------ # @@ -44,51 +43,58 @@ import gtk #------------------------------------------------------------------------ import BaseDoc import Report -import Errors -from QuestionDialog import ErrorDialog from SubstKeywords import SubstKeywords -from gettext import gettext as _ +from Utils import pt2cm +import const +import ReportOptions +#------------------------------------------------------------------------ +# +# Constants +# +#------------------------------------------------------------------------ _BORN = _('b.') _DIED = _('d.') -#------------------------------------------------------------------------ -# -# pt2cm - convert points to centimeters -# -#------------------------------------------------------------------------ -def pt2cm(pt): - return (float(pt)/72.0)*(254.0/100.0) - #------------------------------------------------------------------------ # # AncestorChart # #------------------------------------------------------------------------ -class AncestorChart: +class AncestorChart(Report.Report): + + def __init__(self,database,person,options_class): + """ + Creates AncestorChart 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. + + gen - Maximum number of generations to include. + pagebbg - Whether to include page breaks between generations. + dispf - Display format for the output box. + """ + Report.Report.__init__(self,database,person,options_class) + + (self.max_generations,self.pgbrk) \ + = options_class.get_report_generations() + self.display = options_class.handler.options_dict['dispf'] - def __init__(self,database,person,max,display,doc,output,newpage=0): - self.database = database - self.doc = doc - self.doc.creator(database.get_researcher().get_name()) self.map = {} self.text = {} - self.start = person - self.max_generations = max - self.output = output + self.box_width = 0 self.height = 0 self.lines = 0 - self.display = display - self.newpage = newpage - if output: - self.standalone = 1 - self.doc.open(output) - else: - self.standalone = 0 self.calc() - def filter(self,person_handle,index): + def apply_filter(self,person_handle,index): """traverse the ancestors recursively until either the end of a line is found, or until we reach the maximum number of generations that we want to deal with""" @@ -115,14 +121,11 @@ class AncestorChart: family_handle = person.get_main_parents_family_handle() if family_handle: family = self.database.get_family_from_handle(family_handle) - self.filter(family.get_father_handle(),index*2) - self.filter(family.get_mother_handle(),(index*2)+1) + self.apply_filter(family.get_father_handle(),index*2) + self.apply_filter(family.get_mother_handle(),(index*2)+1) def write_report(self): - if self.newpage: - self.doc.page_break() - generation = 1 done = 0 page = 1 @@ -137,8 +140,6 @@ class AncestorChart: self.print_page(index, generation, page) page = page + 1 generation = generation + 3 - if self.standalone: - self.doc.close() def calc(self): """ @@ -146,7 +147,7 @@ class AncestorChart: that and the page dimensions, calculate the proper place to put the elements on a page. """ - self.filter(self.start.get_handle(),1) + self.apply_filter(self.start_person.get_handle(),1) self.height = self.lines*pt2cm((125.0*self.font.get_size())/100.0) self.box_width = pt2cm(self.box_width+20) @@ -196,7 +197,7 @@ class AncestorChart: if self.map.has_key(start) and index <= 15: text = self.text[start] - name = string.join(text,"\n") + name = "\n".join(text) self.doc.draw_box("AC-box",name,self.x[level],self.y[index-1]) if index > 1: @@ -219,222 +220,60 @@ class AncestorChart: # # #------------------------------------------------------------------------ -def _make_default_style(default_style): - """Make the default output style for the Ancestor Chart report.""" - f = BaseDoc.FontStyle() - f.set_size(9) - f.set_type_face(BaseDoc.FONT_SANS_SERIF) - p = BaseDoc.ParagraphStyle() - p.set_font(f) - p.set_description(_('The basic style used for the text display.')) - default_style.add_style("AC-Normal",p) +class AncestorChartOptions(ReportOptions.ReportOptions): -#------------------------------------------------------------------------ -# -# AncestorChartDialog -# -#------------------------------------------------------------------------ -class AncestorChartDialog(Report.DrawReportDialog): + """ + Defines options and provides handling interface. + """ - report_options = {} - - def __init__(self,database,person): - Report.DrawReportDialog.__init__(self,database,person,self.report_options) + def __init__(self,name,person_id=None): + ReportOptions.ReportOptions.__init__(self,name,person_id) - def get_title(self): - """The window title for this dialog""" - return "%s - %s - GRAMPS" % (_("Ancestor Chart"),_("Graphical Reports")) + def enable_options(self): + # Semi-common options that should be enabled for this report + self.enable_dict = { + 'gen' : 10, + 'pagebbg' : 0, + 'dispf' : [ "$n", "%s $b" % _BORN, "%s $d" % _DIED ], + } - def get_header(self, name): - """The header line at the top of the dialog contents.""" - return _("Ancestor Chart for %s") % name + def make_default_style(self,default_style): + """Make the default output style for the Ancestor Chart report.""" + f = BaseDoc.FontStyle() + f.set_size(9) + f.set_type_face(BaseDoc.FONT_SANS_SERIF) + p = BaseDoc.ParagraphStyle() + p.set_font(f) + p.set_description(_('The basic style used for the text display.')) + default_style.add_style("AC-Normal",p) - def get_target_browser_title(self): - """The title of the window created when the 'browse' button is - clicked in the 'Save As' frame.""" - return _("Save Ancestor Chart") - - def get_stylesheet_savefile(self): - """Where to save user defined styles for this report.""" - return _style_file - - def get_report_generations(self): - """Default to 10 generations, no page breaks.""" - return (10, 0) - - def get_report_extra_textbox_info(self): + def get_textbox_info(self): """Label the textbox and provide the default contents.""" - return (_("Display Format"), "$n\n%s $b\n%s $d" % (_BORN,_DIED), + return (_("Display Format"), self.options_dict['dispf'], _("Allows you to customize the data in the boxes in the report")) - def make_default_style(self): - _make_default_style(self.default_style) - - def make_report(self): - """Create the object that will produce the Ancestor Chart. - All user dialog has already been handled and the output file - opened.""" - - try: - MyReport = AncestorChart(self.db, self.person, - self.max_gen, self.report_text, self.doc,self.target_path) - MyReport.write_report() - except Errors.ReportError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except Errors.FilterError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except: - import DisplayTrace - DisplayTrace.DisplayTrace() - -#------------------------------------------------------------------------ -# -# entry point -# -#------------------------------------------------------------------------ -def report(database,person): - AncestorChartDialog(database,person) - -#------------------------------------------------------------------------ -# -# Set up sane defaults for the book_item -# -#------------------------------------------------------------------------ -_style_file = "ancestor_chart.xml" -_style_name = "default" - -_person_handle = "" -_max_gen = 10 -_disp_format = [ "$n", "%s $b" % _BORN, "%s $d" % _DIED ] -_options = ( _person_handle, _max_gen, _disp_format ) - -#------------------------------------------------------------------------ -# -# Book Item Options dialog -# -#------------------------------------------------------------------------ -class AncestorChartBareDialog(Report.BareReportDialog): - - def __init__(self,database,person,opt,stl): - - self.options = opt - self.db = database - if self.options[0]: - self.person = self.db.get_person_from_handle(self.options[0]) - else: - self.person = person - self.style_name = stl - - Report.BareReportDialog.__init__(self,database,self.person) - - self.max_gen = int(self.options[1]) - self.disp_format = string.join(self.options[2],'\n') - self.new_person = None - - self.generations_spinbox.set_value(self.max_gen) - self.extra_textbox.get_buffer().set_text( - self.disp_format,len(self.disp_format)) - - self.window.run() - - #------------------------------------------------------------------------ - # - # Customization hooks - # - #------------------------------------------------------------------------ - def get_title(self): - """The window title for this dialog""" - return "%s - GRAMPS Book" % (_("Ancestor Chart")) - - def get_header(self, name): - """The header line at the top of the dialog contents""" - return _("Ancestor Chart for GRAMPS Book") - - def get_stylesheet_savefile(self): - """Where to save styles for this report.""" - return _style_file - - def get_report_generations(self): - """Default to 10 generations, no page breaks.""" - return (10, 0) - - def get_report_extra_textbox_info(self): - """Label the textbox and provide the default contents.""" - return (_("Display Format"), "$n\n%s $b\n%s $d" % (_BORN,_DIED), - _("Allows you to customize the data in the boxes in the report")) - - def make_default_style(self): - _make_default_style(self.default_style) - - def on_cancel(self, obj): - pass - - def on_ok_clicked(self, obj): - """The user is satisfied with the dialog choices. Parse all options - and close the window.""" - - # Preparation - self.parse_style_frame() - self.parse_report_options_frame() - - if self.new_person: - self.person = self.new_person - self.options = ( self.person.get_handle(), self.max_gen, self.report_text ) - self.style_name = self.selected_style.get_name() - -#------------------------------------------------------------------------ -# -# Function to write Book Item -# -#------------------------------------------------------------------------ -def write_book_item(database,person,doc,options,newpage=0): - """Write the Ancestor Chart using options set. - All user dialog has already been handled and the output file opened.""" - try: - if options[0]: - person = database.get_person_from_handle(options[0]) - max_gen = int(options[1]) - disp_format = options[2] - return AncestorChart(database, person, max_gen, - disp_format, doc, None, newpage ) - except Errors.ReportError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except Errors.FilterError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except: - import DisplayTrace - DisplayTrace.DisplayTrace() + def add_user_options(self,dialog): + """ + Override the base class add_user_options task to add a menu that allows + the user to select the sort method. + """ + dialog.get_report_extra_textbox_info = self.get_textbox_info #------------------------------------------------------------------------ # # # #------------------------------------------------------------------------ -from Plugins import register_report, register_book_item - +from Plugins import register_report register_report( - report, - _("Ancestor Chart"), - category=_("Graphical Reports"), - status=(_("Beta")), - description=_("Produces a graphical ancestral tree graph"), - author_name="Donald N. Allingham", - author_email="dallingham@users.sourceforge.net" + name = 'ancestor_chart', + category = const.CATEGORY_DRAW, + report_class = AncestorChart, + options_class = AncestorChartOptions, + modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI, + translated_name = _("Ancestor Chart"), + status = _("Beta"), + author_name = "Donald N. Allingham", + author_email = "dallingham@users.sourceforge.net", + description = _("Produces a graphical ancestral tree graph"), ) - -# (name,category,options_dialog,write_book_item,options,style_name,style_file,make_default_style) -register_book_item( - _("Ancestor Chart"), - _("Graphics"), - AncestorChartBareDialog, - write_book_item, - _options, - _style_name, - _style_file, - _make_default_style - ) - diff --git a/gramps2/src/plugins/AncestorChart2.py b/gramps2/src/plugins/AncestorChart2.py index b3c3b6c7e..bc519eb7a 100644 --- a/gramps2/src/plugins/AncestorChart2.py +++ b/gramps2/src/plugins/AncestorChart2.py @@ -27,11 +27,14 @@ # python modules # #------------------------------------------------------------------------ -import os -import string import math -import types +from gettext import gettext as _ +#------------------------------------------------------------------------ +# +# gtk +# +#------------------------------------------------------------------------ import gtk #------------------------------------------------------------------------ @@ -41,39 +44,33 @@ import gtk #------------------------------------------------------------------------ import BaseDoc import Report -import Errors -from QuestionDialog import ErrorDialog from SubstKeywords import SubstKeywords -from gettext import gettext as _ +from Utils import pt2cm, cm2pt +import const +import ReportOptions +#------------------------------------------------------------------------ +# +# Constants +# +#------------------------------------------------------------------------ _BORN = _('b.') _DIED = _('d.') +#------------------------------------------------------------------------ +# +# log2val +# +#------------------------------------------------------------------------ def log2(val): return int(math.log10(val)/math.log10(2)) -#------------------------------------------------------------------------ -# -# pt2cm - convert points to centimeters -# -#------------------------------------------------------------------------ -def pt2cm(pt): - return (float(pt)/72.0)*(254.0/100.0) - -#------------------------------------------------------------------------ -# -# cm2pt - convert centimeters to points -# -#------------------------------------------------------------------------ -def cm2pt(cm): - return (float(cm)/2.54)*72 - #------------------------------------------------------------------------ # # Layout class # #------------------------------------------------------------------------ -class GenChart : +class GenChart: def __init__(self,generations): self.generations = generations @@ -157,7 +154,7 @@ class GenChart : def not_blank(self,line): for i in line: - if i and type(i) == types.TupleType: + if i and type(i) == tuple: return 1 return 0 @@ -166,33 +163,48 @@ class GenChart : # AncestorChart # #------------------------------------------------------------------------ -class AncestorChart: +class AncestorChart(Report.Report): + + def __init__(self,database,person,options_class): + """ + Creates AncestorChart 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. + + gen - Maximum number of generations to include. + pagebbg - Whether to include page breaks between generations. + dispf - Display format for the output box. + singlep - Whether to scale to fit on a single page. + compress - Whether to compress chart. + title - Title of the report displayed on top. + """ + Report.Report.__init__(self,database,person,options_class) + + (self.max_generations,self.pgbrk) \ + = options_class.get_report_generations() + self.display = options_class.handler.options_dict['dispf'] + self.force_fit = options_class.handler.options_dict['singlep'] + self.compress = options_class.handler.options_dict['compress'] + self.title = options_class.handler.options_dict['title'].strip() - def __init__(self,database,person,max,display,doc,output,scale,compress, - title,newpage=0): - self.database = database - self.doc = doc - self.title = title.strip() - self.doc.creator(database.get_researcher().get_name()) self.map = {} self.text = {} - self.start = person - self.max_generations = max - self.output = output + self.box_width = 0 self.box_height = 0 self.lines = 0 - self.display = display - self.newpage = newpage - self.force_fit = scale - self.compress = compress - if output: - self.doc.open(output) - self.standalone = output + self.font = self.doc.style_list["AC2-Normal"].get_font() self.tfont = self.doc.style_list["AC2-Title"].get_font() - self.filter(self.start.get_handle(),1) + self.apply_filter(self.start_person.get_handle(),1) keys = self.map.keys() keys.sort() @@ -203,7 +215,7 @@ class AncestorChart: self.genchart.set(key,self.map[key]) self.calc() - def filter(self,person_handle,index): + def apply_filter(self,person_handle,index): """traverse the ancestors recursively until either the end of a line is found, or until we reach the maximum number of generations that we want to deal with""" @@ -229,14 +241,11 @@ class AncestorChart: family_handle = person.get_main_parents_family_handle() if family_handle: family = self.database.get_family_from_handle(family_handle) - self.filter(family.get_father_handle(),index*2) - self.filter(family.get_mother_handle(),(index*2)+1) + self.apply_filter(family.get_father_handle(),index*2) + self.apply_filter(family.get_mother_handle(),(index*2)+1) def write_report(self): - if self.newpage: - self.doc.page_break() - generation = 1 done = 0 page = 1 @@ -259,8 +268,6 @@ class AncestorChart: startx += self.generations_per_page coly += 1 starty += maxh - if self.standalone: - self.doc.close() def calc(self): """ @@ -351,9 +358,9 @@ class AncestorChart: for x in range(startx,stopx): value = self.genchart.get_xy(x,y) if value: - if type(value) == types.TupleType: + if type(value) == tuple: (person,index) = value - text = string.join(self.text[index],"\n") + text = '\n'.join(self.text[index]) self.doc.draw_box("AC2-box",text,phys_x*self.delta, phys_y*self.box_height+self.offset) elif value == 2: @@ -396,7 +403,7 @@ class AncestorChart: value = self.genchart.get_xy(x,y) if not value: continue - if type(value) == types.TupleType: + if type(value) == tuple: (person,index) = value if self.genchart.get(index*2): (px,py) = self.genchart.index_to_xy(index*2) @@ -414,311 +421,110 @@ class AncestorChart: # # #------------------------------------------------------------------------ -def _make_default_style(default_style): - """Make the default output style for the Ancestor Chart report.""" - f = BaseDoc.FontStyle() - f.set_size(9) - f.set_type_face(BaseDoc.FONT_SANS_SERIF) - p = BaseDoc.ParagraphStyle() - p.set_font(f) - p.set_description(_('The basic style used for the text display.')) - default_style.add_style("AC2-Normal",p) +class AncestorChartOptions(ReportOptions.ReportOptions): - f = BaseDoc.FontStyle() - f.set_size(16) - f.set_type_face(BaseDoc.FONT_SANS_SERIF) - p = BaseDoc.ParagraphStyle() - p.set_font(f) - p.set_alignment(BaseDoc.PARA_ALIGN_CENTER) - p.set_description(_('The basic style used for the title display.')) - default_style.add_style("AC2-Title",p) + """ + Defines options and provides handling interface. + """ -#------------------------------------------------------------------------ -# -# AncestorChartDialog -# -#------------------------------------------------------------------------ -class AncestorChartDialog(Report.DrawReportDialog): + def __init__(self,name,person_id=None): + ReportOptions.ReportOptions.__init__(self,name,person_id) - report_options = {} - - def __init__(self,database,person): - Report.DrawReportDialog.__init__(self,database,person,self.report_options) + def set_new_options(self): + # Options specific for this report + self.options_dict = { + 'singlep' : 1, + 'compress' : 1, + 'title' : '', + } + self.options_help = { + 'singlep' : ("=0/1","Whether to scale to fit on a single page.", + ["Do not scale to fit","Scale to fit"], + True), + 'compress' : ("=0/1","Whether to compress chart.", + ["Do not compress chart","Compress chart"], + True), + 'title' : ("=str","Title string for the report", + "Whatever String You Wish"), + } - def add_user_options(self): - self.title=gtk.Entry() - self.title.set_text(self.get_header(self.person.get_primary_name().get_name())) - self.title.show() - self.add_option(_('Title'),self.title) - self.compress = gtk.CheckButton(_('Co_mpress chart')) - self.compress.set_active(1) - self.compress.show() - self.add_option('',self.compress) - self.scale = gtk.CheckButton(_('Sc_ale to fit on a single page')) - self.scale.set_active(1) - self.scale.show() - self.add_option('',self.scale) + def enable_options(self): + # Semi-common options that should be enabled for this report + self.enable_dict = { + 'gen' : 10, + 'pagebbg' : 0, + 'dispf' : [ "$n", "%s $b" % _BORN, "%s $d" % _DIED ], + } - def get_title(self): - """The window title for this dialog""" - return "%s - %s - GRAMPS" % (_("Ancestor Chart"),_("Graphical Reports")) - - def get_header(self, name): - """The header line at the top of the dialog contents.""" - return _("Ancestor Chart for %s") % name - - def get_target_browser_title(self): - """The title of the window created when the 'browse' button is - clicked in the 'Save As' frame.""" - return _("Save Ancestor Chart") - - def get_stylesheet_savefile(self): - """Where to save user defined styles for this report.""" - return _style_file - - def get_report_generations(self): - """Default to 10 generations, no page breaks.""" - return (10, 0) - - def get_report_extra_textbox_info(self): + def get_textbox_info(self): """Label the textbox and provide the default contents.""" - return (_("Display Format"), "$n\n%s $b\n%s $d" % (_BORN,_DIED), + return (_("Display Format"), self.options_dict['dispf'], _("Allows you to customize the data in the boxes in the report")) - def make_default_style(self): - _make_default_style(self.default_style) + def add_user_options(self,dialog): + """ + Override the base class add_user_options task to add a menu that allows + the user to select the sort method. + """ + dialog.get_report_extra_textbox_info = self.get_textbox_info - def make_report(self): - """Create the object that will produce the Ancestor Chart. - All user dialog has already been handled and the output file - opened.""" - - try: - MyReport = AncestorChart(self.db, self.person, - self.max_gen, self.report_text, - self.doc,self.target_path, - self.scale.get_active(), - self.compress.get_active(), - self.title.get_text() - ) - MyReport.write_report() - except Errors.ReportError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except Errors.FilterError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except: - import DisplayTrace - DisplayTrace.DisplayTrace() - -#------------------------------------------------------------------------ -# -# entry point -# -#------------------------------------------------------------------------ -def report(database,person): - AncestorChartDialog(database,person) - -#------------------------------------------------------------------------ -# -# Set up sane defaults for the book_item -# -#------------------------------------------------------------------------ -_style_file = "ancestor_chart2.xml" -_style_name = "default" - -_person_handle = "" -_max_gen = 10 -_disp_format = [ "$n", "%s $b" % _BORN, "%s $d" % _DIED ] -_compress = 1 -_scale = 1 -_title = "" -_options = ( _person_handle, _max_gen, _disp_format, _title, _compress, _scale) - -#------------------------------------------------------------------------ -# -# Book Item Options dialog -# -#------------------------------------------------------------------------ -class AncestorChartBareDialog(Report.BareReportDialog): - - def __init__(self,database,person,opt,stl): - - self.options = opt - self.db = database - if self.options[0]: - self.person = self.db.get_person_from_handle(self.options[0]) - else: - self.person = person - self.style_name = stl - - Report.BareReportDialog.__init__(self,database,self.person) - - self.max_gen = int(self.options[1]) - self.disp_format = string.join(self.options[2],'\n') - if self.options[3]: - self.the_title = self.options[3] - else: - self.the_title = self.get_the_title(self.person) - self.do_compress = int(self.options[4]) - self.do_scale = int(self.options[5]) - self.new_person = None - - self.generations_spinbox.set_value(self.max_gen) - self.extra_textbox.get_buffer().set_text( - self.disp_format,len(self.disp_format)) - self.compress.set_active(self.do_compress) - self.scale.set_active(self.do_scale) - self.scale.set_sensitive(self.do_compress) - self.title.set_text(self.the_title) - - self.window.run() - - #------------------------------------------------------------------------ - # - # Customization hooks - # - #------------------------------------------------------------------------ - def add_user_options(self): - self.title=gtk.Entry() - self.title.set_text(self.get_the_title(self.person)) - self.title.show() - self.add_option(_('Title'),self.title) - self.compress = gtk.CheckButton(_('Co_mpress chart')) - self.compress.set_active(1) - self.compress.show() - self.add_option('',self.compress) self.scale = gtk.CheckButton(_('Sc_ale to fit on a single page')) - self.scale.set_active(1) - self.scale.set_sensitive(1) - self.scale.show() - self.add_option('',self.scale) + self.scale.set_active(self.options_dict['singlep']) + dialog.add_option('',self.scale) - def get_title(self): - """The window title for this dialog""" - return "%s - GRAMPS Book" % (_("Ancestor Chart")) + self.compress = gtk.CheckButton(_('Co_mpress chart')) + self.compress.set_active(self.options_dict['compress']) + dialog.add_option('',self.compress) - def get_the_title(self,person): - """The header line at the top of the dialog contents.""" - return _("Ancestor Chart for %s") % person.get_primary_name().get_name() - - def get_header(self,name): - """The header line at the top of the dialog contents""" - return _("Ancestor Chart for GRAMPS Book") - - def get_stylesheet_savefile(self): - """Where to save styles for this report.""" - return _style_file - - def get_report_generations(self): - """Default to 10 generations, no page breaks.""" - return (10, 0) - - def get_report_extra_textbox_info(self): - """Label the textbox and provide the default contents.""" - return (_("Display Format"), "$n\n%s $b\n%s $d" % (_BORN,_DIED), - _("Allows you to customize the data in the boxes in the report")) - - def make_default_style(self): - _make_default_style(self.default_style) - - def parse_report_options_frame (self): - # Call base class - Report.BareReportDialog.parse_report_options_frame (self) - self.do_compress = self.compress.get_active() - self.do_scale = self.scale.get_active() - self.the_title = self.title.get_text() - - def on_center_person_change_clicked(self,obj): - import SelectPerson - sel_person = SelectPerson.SelectPerson(self.db,_('Select Person')) - new_person = sel_person.run() - if new_person: - self.new_person = new_person - - self.the_title = self.get_the_title(self.new_person) - self.title.set_text(self.the_title) - - new_name = new_person.getPrimaryName().getRegularName() - if new_name: - self.person_label.set_text( "%s" % new_name ) - self.person_label.set_use_markup(gtk.TRUE) - - def on_cancel(self, obj): - pass - - def on_ok_clicked(self, obj): - """The user is satisfied with the dialog choices. Parse all options - and close the window.""" - - # Preparation - self.parse_style_frame() - self.parse_report_options_frame() - - if self.new_person: - self.person = self.new_person - self.options = ( self.person.get_handle(), self.max_gen, self.report_text, - self.the_title, self.do_compress, self.do_scale ) - self.style_name = self.selected_style.get_name() - -#------------------------------------------------------------------------ -# -# Function to write Book Item -# -#------------------------------------------------------------------------ -def write_book_item(database,person,doc,options,newpage=0): - """Write the Ancestor Chart using options set. - All user dialog has already been handled and the output file opened.""" - try: - if options[0]: - person = database.get_person_from_handle(options[0]) - max_gen = int(options[1]) - disp_format = options[2] - if options[3]: - title = options[3] + self.title_box = gtk.Entry() + if self.options_dict['title']: + self.title_box.set_text(self.options_dict['title']) else: - title = "" - compress = int(options[4]) - scale = int(options[5]) - return AncestorChart(database, person, max_gen, - disp_format, doc, None, - scale, compress, title, newpage ) - except Errors.ReportError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except Errors.FilterError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except: - import DisplayTrace - DisplayTrace.DisplayTrace() + self.title_box.set_text(dialog.get_header(dialog.person.get_primary_name().get_name())) + dialog.add_option(_('Title'),self.title_box) + + def parse_user_options(self,dialog): + """ + Parses the custom options that we have added. + """ + self.options_dict['singlep'] = int(self.scale.get_active ()) + self.options_dict['compress'] = int(self.compress.get_active ()) + self.options_dict['title'] = unicode(self.title_box.get_text()).strip() + + def make_default_style(self,default_style): + """Make the default output style for the Ancestor Chart report.""" + f = BaseDoc.FontStyle() + f.set_size(9) + f.set_type_face(BaseDoc.FONT_SANS_SERIF) + p = BaseDoc.ParagraphStyle() + p.set_font(f) + p.set_description(_('The basic style used for the text display.')) + default_style.add_style("AC2-Normal",p) + + f = BaseDoc.FontStyle() + f.set_size(16) + f.set_type_face(BaseDoc.FONT_SANS_SERIF) + p = BaseDoc.ParagraphStyle() + p.set_font(f) + p.set_alignment(BaseDoc.PARA_ALIGN_CENTER) + p.set_description(_('The basic style used for the title display.')) + default_style.add_style("AC2-Title",p) #------------------------------------------------------------------------ # # # #------------------------------------------------------------------------ -from Plugins import register_report, register_book_item - +from Plugins import register_report register_report( - report, - _("Ancestor Chart (Wall Chart)"), - category=_("Graphical Reports"), - status=(_("Beta")), - description=_("Produces a graphical ancestral tree graph"), - author_name="Donald N. Allingham", - author_email="dallingham@users.sourceforge.net" - ) - -# (name,category,options_dialog,write_book_item,options,style_name,style_file,make_default_style) -register_book_item( - _("Ancestor Chart (Wall Chart)"), - _("Graphics"), - AncestorChartBareDialog, - write_book_item, - _options, - _style_name, - _style_file, - _make_default_style + name = 'ancestor_chart2', + category = const.CATEGORY_DRAW, + report_class = AncestorChart, + options_class = AncestorChartOptions, + modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI, + translated_name = _("Ancestor Chart (Wall Chart)"), + status = _("Beta"), + author_name = "Donald N. Allingham", + author_email = "dallingham@users.sourceforge.net", + description = _("Produces a graphical ancestral tree graph"), ) diff --git a/gramps2/src/plugins/DesGraph.py b/gramps2/src/plugins/DesGraph.py index adba97346..c9caabbc4 100644 --- a/gramps2/src/plugins/DesGraph.py +++ b/gramps2/src/plugins/DesGraph.py @@ -27,7 +27,7 @@ # standard python modules # #------------------------------------------------------------------------ -import string +from gettext import gettext as _ #------------------------------------------------------------------------ # @@ -44,55 +44,52 @@ import gtk import GraphLayout import Report import BaseDoc -import Errors - from SubstKeywords import SubstKeywords -from gettext import gettext as _ -from QuestionDialog import ErrorDialog +from Utils import pt2cm +import const +import ReportOptions +#------------------------------------------------------------------------ +# +# Constants +# +#------------------------------------------------------------------------ _BORN = _('b.') _DIED = _('d.') - -#------------------------------------------------------------------------ -# -# constants -# -#------------------------------------------------------------------------ _sep = 0.5 #------------------------------------------------------------------------ # -# pt2cm - convert points to centimeters +# DescendantGraph # #------------------------------------------------------------------------ -def pt2cm(pt): - return (float(pt)/72.0)*2.54 +class DescendantGraph(Report.Report): -#------------------------------------------------------------------------ -# -# DescendantReport -# -#------------------------------------------------------------------------ -class DescendantReport: + def __init__(self,database,person,options_class): + """ + Creates DescendantGraph 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. + + dispf - Display format for the output box. + """ + Report.Report.__init__(self,database,person,options_class) + + self.display = options_class.handler.options_dict['dispf'] - def __init__(self,database,person,display,doc,output,newpage=0): - self.database = database - self.doc = doc - self.doc.creator(database.get_researcher().get_name()) self.map = {} self.text = {} - self.start = person - self.output = output + self.box_width = 0 self.height = 0 self.lines = 0 - self.display = display - self.newpage = newpage - if output: - self.standalone = 1 - self.doc.open(output) - else: - self.standalone = 0 plist = self.database.get_person_handles(sort_handles=False) self.layout = GraphLayout.DescendLine(self.database,plist,person.get_handle()) @@ -214,16 +211,10 @@ class DescendantReport: else: l3.append((nx1,-ny2,-nx2,ny2)) - if self.newpage: - self.doc.page_break() - for r in range(len(self.pg)): for c in range(len(self.pg[r])): self.print_page(self.pg[r][c],self.ln[r][c],r,c) - if self.standalone: - self.doc.close() - def calc(self): """calc - calculate the maximum width that a box needs to be. From that and the page dimensions, calculate the proper place to put @@ -243,8 +234,6 @@ class DescendantReport: g = BaseDoc.GraphicsStyle() self.doc.add_draw_style("line",g) - if self.standalone: - self.doc.init() def print_page(self, plist,elist,r,c): self.doc.start_page() @@ -257,7 +246,7 @@ class DescendantReport: if plist: for (p_id,x,y) in plist: - name = string.join(self.text[p_id],"\n") + name = '\n'.join(self.text[p_id]) x = (x-1)*delta + left + _sep y = (y-1)*(self.height+_sep)+top self.doc.draw_box("box",name,x,y) @@ -307,209 +296,58 @@ class DescendantReport: # # #------------------------------------------------------------------------ -def _make_default_style(default_style): - """Make the default output style for the Descendant Graph report.""" - f = BaseDoc.FontStyle() - f.set_size(9) - f.set_type_face(BaseDoc.FONT_SANS_SERIF) - p = BaseDoc.ParagraphStyle() - p.set_font(f) - p.set_description(_('The basic style used for the text display.')) - default_style.add_style("DG-Normal",p) +class DescendantGraphOptions(ReportOptions.ReportOptions): -#------------------------------------------------------------------------ -# -# DescendantReportDialog -# -#------------------------------------------------------------------------ -class DescendantReportDialog(Report.DrawReportDialog): + """ + Defines options and provides handling interface. + """ - def __init__(self,database,person): - Report.DrawReportDialog.__init__(self,database,person) + def __init__(self,name,person_id=None): + ReportOptions.ReportOptions.__init__(self,name,person_id) - def get_title(self): - return "%s - %s - GRAMPS" % (_("Descendant Graph"),_("Graphical Reports")) + def enable_options(self): + # Semi-common options that should be enabled for this report + self.enable_dict = { + 'dispf' : [ "$n", "%s $b" % _BORN, "%s $d" % _DIED ], + } - def get_header(self,name): - return _("Descendant Graph for %s") % name - - def get_target_browser_title(self): - return _("Save Descendant Graph") - - def get_stylesheet_savefile(self): - return _style_file - - def get_report_generations(self): - """Default to 10 generations, no page breaks.""" - return (0, 0) - - def get_report_extra_textbox_info(self): + def get_textbox_info(self): """Label the textbox and provide the default contents.""" - return (_("Display Format"), "$n\n%s $b\n%s $d" % (_BORN,_DIED), - _("Allows you to customize the data in the boxes in the report")) - - def make_default_style(self): - _make_default_style(self.default_style) - - def make_report(self): - """Create the object that will produce the Descendant Graph. - All user dialog has already been handled and the output file - opened.""" - try: - MyReport = DescendantReport(self.db, self.person, - self.report_text, self.doc, self.target_path) - MyReport.write_report() - except Errors.ReportError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except Errors.FilterError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except: - import DisplayTrace - DisplayTrace.DisplayTrace() - -#------------------------------------------------------------------------ -# -# -# -#------------------------------------------------------------------------ -def report(database,person): - DescendantReportDialog(database,person) - -#------------------------------------------------------------------------ -# -# Set up sane defaults for the book_item -# -#------------------------------------------------------------------------ -_style_file = "descendant_graph.xml" -_style_name = "default" - -_person_handle = "" -_disp_format = [ "$n", "%s $b" % _BORN, "%s $d" % _DIED ] -_options = ( _person_handle, _disp_format ) - -#------------------------------------------------------------------------ -# -# Book Item Options dialog -# -#------------------------------------------------------------------------ -class DescendantGraphBareDialog(Report.BareReportDialog): - - def __init__(self,database,person,opt,stl): - - self.options = opt - self.db = database - if self.options[0]: - self.person = self.db.get_person_from_handle(self.options[0]) - else: - self.person = person - self.style_name = stl - - Report.BareReportDialog.__init__(self,database,self.person) - - self.disp_format = string.join(self.options[1],'\n') - self.new_person = None - - self.extra_textbox.get_buffer().set_text( - self.disp_format,len(self.disp_format)) - - self.window.run() - - #------------------------------------------------------------------------ - # - # Customization hooks - # - #------------------------------------------------------------------------ - def get_title(self): - """The window title for this dialog""" - return "%s - GRAMPS Book" % (_("Descendant Graph")) - - def get_header(self, name): - """The header line at the top of the dialog contents""" - return _("Descendant Graph for GRAMPS Book") - - def get_stylesheet_savefile(self): - """Where to save styles for this report.""" - return _style_file - - def get_report_generations(self): - """No generations, no page breaks.""" - return (0, 0) - - def get_report_extra_textbox_info(self): - """Label the textbox and provide the default contents.""" - return (_("Display Format"), "$n\n%s $b\n%s $d" % (_BORN,_DIED), + return (_("Display Format"), self.options_dict['dispf'], _("Allows you to customize the data in the boxes in the report")) - def make_default_style(self): - _make_default_style(self.default_style) + def add_user_options(self,dialog): + """ + Override the base class add_user_options task to add a menu that allows + the user to select the sort method. + """ + dialog.get_report_extra_textbox_info = self.get_textbox_info - def on_cancel(self, obj): - pass - - def on_ok_clicked(self, obj): - """The user is satisfied with the dialog choices. Parse all options - and close the window.""" - - # Preparation - self.parse_style_frame() - self.parse_report_options_frame() - - if self.new_person: - self.person = self.new_person - self.options = ( self.person.get_handle(), self.report_text ) - self.style_name = self.selected_style.get_name() - -#------------------------------------------------------------------------ -# -# Function to write Book Item -# -#------------------------------------------------------------------------ -def write_book_item(database,person,doc,options,newpage=0): - """Write the Ancestor Chart using options set. - All user dialog has already been handled and the output file opened.""" - try: - if options[0]: - person = database.get_person_from_handle(options[0]) - disp_format = options[1] - return DescendantReport(database, person, - disp_format, doc, None, newpage ) - except Errors.ReportError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except Errors.FilterError, msg: - (m1,m2) = msg.messages() - ErrorDialog(m1,m2) - except: - import DisplayTrace - DisplayTrace.DisplayTrace() + def make_default_style(self,default_style): + """Make the default output style for the Descendant Graph report.""" + f = BaseDoc.FontStyle() + f.set_size(9) + f.set_type_face(BaseDoc.FONT_SANS_SERIF) + p = BaseDoc.ParagraphStyle() + p.set_font(f) + p.set_description(_('The basic style used for the text display.')) + default_style.add_style("DG-Normal",p) #------------------------------------------------------------------------ # # # #------------------------------------------------------------------------ -from Plugins import register_report, register_book_item - +from Plugins import register_report register_report( - report, - _("Descendant Graph"), - category=_("Graphical Reports"), - description=_("Generates a graph of descendants of the active person"), - status=(_("Alpha")), - author_name="Donald N. Allingham", - author_email="dallingham@users.sourceforge.net" - ) - -# (name,category,options_dialog,write_book_item,options,style_name,style_file,make_default_style) -register_book_item( - _("Descendant Graph"), - _("Graphics"), - DescendantGraphBareDialog, - write_book_item, - _options, - _style_name, - _style_file, - _make_default_style + name = 'descendant_graph', + category = const.CATEGORY_DRAW, + report_class = DescendantGraph, + options_class = DescendantGraphOptions, + modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI, + translated_name = _("Descendant Graph"), + status = _("Alpha"), + author_name = "Donald N. Allingham", + author_email = "dallingham@users.sourceforge.net", + description = _("Generates a graph of descendants of the active person"), )