* 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
This commit is contained in:
		| @@ -1,3 +1,11 @@ | ||||
| 2005-01-02 Alex Roitman  <shura@alex.neuro.umn.edu> | ||||
| 	* 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  <dallingham@users.sourceforge.net> | ||||
| 	* src/EditPerson.py: move strip_id from Utils | ||||
| 	* src/GrampsCfg.py: use ComboBox for toolbar selection | ||||
|   | ||||
| @@ -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")) | ||||
|   | ||||
| @@ -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("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n") | ||||
|         f.write('<reportoptions>\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() | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
|   | ||||
| @@ -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 | ||||
|     ) | ||||
|  | ||||
|   | ||||
| @@ -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( "<i>%s</i>" % 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"), | ||||
|     ) | ||||
|   | ||||
| @@ -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"), | ||||
|     ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user