diff --git a/src/Report.py b/src/Report.py index baf987dd5..470b401ef 100644 --- a/src/Report.py +++ b/src/Report.py @@ -2,6 +2,7 @@ # Gramps - a GTK+/GNOME based genealogy program # # Copyright (C) 2001 David R. Hampton +# Copyright (C) 2001-2003 Donald N. Allingham # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -154,12 +155,15 @@ class Report: """Done with the progress bar. It can be destroyed now.""" Utils.destroy_passed_object(self.ptop) -class ReportDialog: + +class BareReportDialog: """ - The ReportDialog base class. This is a base class for generating - customized dialogs to solicit options for a report. It cannot be - used as is, but it can be easily sub-classed to create a functional - dialog. + The BareReportDialog base class. This is a base class for generating + customized dialogs to solicit some options for a report. This class + cannot be meaningfully used on its own since normally more options will + have to be solicited. The ReportDialog class adds this functionality. + The intended use of this class is either for ReportDialog or for being + subclassed by Bare Reports that are part of the Book. """ frame_pad = 5 @@ -167,7 +171,7 @@ class ReportDialog: def __init__(self,database,person): """Initialize a dialog to request that the user select options - for a basic report.""" + for a basic *bare* report.""" # Save info about who the report is about. self.db = database @@ -225,16 +229,18 @@ class ReportDialog: self.setup_other_frames() self.window.show_all() - # Allow for post processing of the format frame, since the - # show_all task calls events that may reset values - - if self.format_menu: - self.doc_type_changed(self.format_menu.get_menu().get_active()) - self.setup_post_process() - - - def setup_post_process(self): - pass + #------------------------------------------------------------------------ + # + # Customization hooks for stand-alone reports (subclass ReportDialog) + # + #------------------------------------------------------------------------ + def setup_target_frame(self): pass + def setup_format_frame(self): pass + def setup_style_frame(self): pass + def setup_paper_frame(self): pass + def setup_html_frame(self): pass + def setup_paper_frame(self): pass + def setup_output_notebook(self): pass #------------------------------------------------------------------------ # @@ -253,43 +259,6 @@ class ReportDialog: Report for %s'.""" return(name) - def get_target_browser_title(self): - """The title of the window that will be created when the user - clicks the 'Browse' button in the 'Save As' File Entry - widget.""" - return("%s - GRAMPS" % _("Save Report As")) - - def get_target_is_directory(self): - """Is the user being asked to input the name of a file or a - directory in the 'Save As' File Entry widget. This item - currently only selects the Filename/Directory prompt, and - whether or not the browser accepts filenames. In the future it - may also control checking of the selected filename.""" - return None - - def get_stylesheet_savefile(self): - """Where should new styles for this report be saved? This is - the name of an XML file that will be located in the ~/.gramps - directory. This file does not have to exist; it will be - created when needed. All subclasses should probably override - this function.""" - return "basic_report.xml" - - def get_default_basename(self): - """What should the default name be? - """ - path = self.get_stylesheet_savefile() - return path.split('.')[0] - - def get_print_pagecount_map(self): - """Return the data used to fill out the 'pagecount' option - menu in the print options box. The first value is a mapping - of string:value pairs. The strings will be used to label - individual menu items, and the values are what will be - returned if a given menu item is selected. The second value - is the name of menu item to pre-select.""" - return (None, None) - def get_report_filters(self): """Return the data used to fill out the 'filter' combo box in the report options box. The return value is the list of @@ -323,27 +292,6 @@ class ReportDialog: textbox.""" return (None, None, None) - #------------------------------------------------------------------------ - # - # Functions related getting/setting the default directory for a dialog. - # - #------------------------------------------------------------------------ - def get_default_directory(self): - """Get the name of the directory to which the target dialog - box should default. This value can be set in the preferences - panel.""" - return GrampsCfg.report_dir - - def set_default_directory(self, value): - """Save the name of the current directory, so that any future - reports will default to the most recently used directory. - This also changes the directory name that will appear in the - preferences panel, but does not change the preference in disk. - This means that the last directory used will only be - remembered for this session of gramps unless the user saves - his/her preferences.""" - GrampsCfg.report_dir = value - #------------------------------------------------------------------------ # # Functions related to extending the options @@ -386,85 +334,6 @@ class ReportDialog: if tooltip: self.add_tooltip(widget,tooltip) - #------------------------------------------------------------------------ - # - # Functions to create a default output style. - # - #------------------------------------------------------------------------ - def make_default_style(self): - """Create the default style to be used by the associated report. This - routine is a default implementation and should be overridden.""" - font = TextDoc.FontStyle() - font.set(face=TextDoc.FONT_SANS_SERIF,size=16,bold=1) - para = TextDoc.ParagraphStyle() - para.set_font(font) - para.set_header_level(1) - para.set(pad=0.5) - self.default_style.add_style("Title",para) - - def build_style_menu(self): - """Build a menu of style sets that are available for use in - this report. This menu will always have a default style - available, and will have any other style set name that the - user has previously created for this report. This menu is - created here instead of inline with the rest of the style - frame, because it must be recreated to reflect any changes - whenever the user closes the style editor dialog.""" - style_sheet_map = self.style_sheet_list.get_style_sheet_map() - myMenu = Utils.build_string_optmenu(style_sheet_map, "default") - self.style_menu.set_menu(myMenu) - - #------------------------------------------------------------------------ - # - # Functions related to selecting/changing the current file format. - # - #------------------------------------------------------------------------ - def make_doc_menu(self): - """Build a menu of document types that are appropriate for - this report. This menu will be generated based upon the type - of document (text, draw, graph, etc. - a subclass), whether or - not the document requires table support, etc.""" - pass - - def make_document(self): - """Create a document of the type selected by the user.""" - pass - - def doc_type_changed(self, obj): - """This routine is called when the user selects a new file - formats for the report. It adjust the various dialog sections - to reflect the appropriate values for the currently selected - file format. For example, a HTML document doesn't need any - paper size/orientation options, but it does need a template - file. Those chances are made here.""" - - # Is this to be a printed report or an electronic report - # (i.e. a set of web pages) - - if obj.get_data("paper") == 1: - self.notebook_page = 0 - else: - self.notebook_page = 1 - - if self.output_notebook == None: - return - - self.output_notebook.set_current_page(self.notebook_page) - - if not self.get_target_is_directory(): - fname = self.target_fileentry.get_full_path(0) - (path,ext) = os.path.splitext(fname) - - ext_val = obj.get_data('ext') - if ext_val: - fname = path + ext_val - self.target_fileentry.set_filename(fname) - - # Does this report format use styles? - if self.style_button: - self.style_button.set_sensitive(obj.get_data("styles")) - self.style_menu.set_sensitive(obj.get_data("styles")) - #------------------------------------------------------------------------ # # Functions related to setting up the dialog window. @@ -489,248 +358,7 @@ class ReportDialog: label.set_use_markup(gtk.TRUE) self.window.vbox.pack_start(label,gtk.TRUE,gtk.TRUE,ReportDialog.border_pad) - def setup_target_frame(self): - """Set up the target frame of the dialog. This function - relies on several target_xxx() customization functions to - determine whether the target is a directory or file, what the - title of any browser window should be, and what default - directory should be used.""" - - # Save Frame - - label = gtk.Label("%s" % _('Document Options')) - label.set_use_markup(1) - label.set_alignment(0.0,0.5) - self.tbl.set_border_width(12) - self.tbl.attach(label,0,4,self.col,self.col+1) - self.col += 1 - - hid = self.get_stylesheet_savefile() - if hid[-4:]==".xml": - hid = hid[0:-4] - self.target_fileentry = gnome.ui.FileEntry(hid,_("Save As")) - - if self.get_target_is_directory(): - self.target_fileentry.set_directory_entry(1) - label = gtk.Label("%s:" % _("Directory")) - else: - label = gtk.Label("%s:" % _("Filename")) - label.set_alignment(0.0,0.5) - - self.tbl.attach(label,1,2,self.col,self.col+1,gtk.SHRINK|gtk.FILL) - self.tbl.attach(self.target_fileentry,2,4,self.col,self.col+1) - self.col += 1 - - path = self.get_default_directory() - self.target_fileentry.set_default_path(path) - - def setup_format_frame(self): - """Set up the format frame of the dialog. This function - relies on the make_doc_menu() function to do all the hard - work.""" - - self.format_menu = gtk.OptionMenu() - self.make_doc_menu() - label = gtk.Label("%s:" % _("Output Format")) - label.set_alignment(0.0,0.5) - self.tbl.attach(label,1,2,self.col,self.col+1,gtk.SHRINK|gtk.FILL) - self.tbl.attach(self.format_menu,2,4,self.col,self.col+1) - self.col += 1 - - type = self.format_menu.get_menu().get_active() - ext = type.get_data('ext') - if ext == None: - ext = "" - if type: - path = self.get_default_directory() - if self.get_target_is_directory(): - self.target_fileentry.set_filename(path) - else: - base = self.get_default_basename() - path = os.path.normpath("%s/%s%s" % (path,base,ext)) - self.target_fileentry.set_filename(path) - - - def setup_style_frame(self): - """Set up the style frame of the dialog. This function relies - on other routines create the default style for this report, - and to read in any user defined styles for this report. It - the builds a menu of all the available styles for the user to - choose from.""" - - # Styles Frame - label = gtk.Label("%s:" % _("Styles")) - label.set_alignment(0.0,0.5) - - self.style_menu = gtk.OptionMenu() - self.style_button = gtk.Button("%s..." % _("Style Editor")) - self.style_button.connect('clicked',self.on_style_edit_clicked) - - self.tbl.attach(label,1,2,self.col,self.col+1,gtk.SHRINK|gtk.FILL) - self.tbl.attach(self.style_menu,2,3,self.col,self.col+1) - self.tbl.attach(self.style_button,3,4,self.col,self.col+1,gtk.SHRINK|gtk.FILL) - self.col += 1 - - # Build the default style set for this report. - self.default_style = TextDoc.StyleSheet() - self.make_default_style() - - # Build the initial list of available styles sets. This - # includes the default style set and any style sets saved from - # previous invocations of gramps. - self.style_sheet_list = TextDoc.StyleSheetList(self.get_stylesheet_savefile(), - self.default_style) - - # Now build the actual menu. - self.build_style_menu() - - def setup_output_notebook(self): - """Set up the output notebook of the dialog. This sole - purpose of this function is to grab a pointer for later use in - the callback from when the file format is changed.""" - - self.output_notebook = gtk.Notebook() - self.output_notebook.set_show_tabs(0) - self.output_notebook.set_show_border(0) - self.output_notebook.set_border_width(12) - self.output_notebook.set_current_page(self.notebook_page) - self.window.vbox.add(self.output_notebook) - - def size_changed(self,obj): - paper = self.papersize_menu.get_menu().get_active().get_data('i') - if paper.get_width() <= 0: - self.pwidth.set_sensitive(1) - self.pheight.set_sensitive(1) - else: - self.pwidth.set_sensitive(0) - self.pheight.set_sensitive(0) - self.pwidth.set_text("%.2f" % paper.get_width()) - self.pheight.set_text("%.2f" % paper.get_height()) - - def setup_paper_frame(self): - """Set up the paper selection frame of the dialog. This - function relies on a paper_xxx() customization functions to - determine whether the pagecount menu should appear and what - its strings should be.""" - - (pagecount_map, start_text) = self.get_print_pagecount_map() - - if pagecount_map: - self.paper_table = gtk.Table(3,6) - else: - self.paper_table = gtk.Table(4,6) - self.paper_table.set_col_spacings(12) - self.paper_table.set_row_spacings(6) - self.paper_table.set_border_width(0) - self.output_notebook.append_page(self.paper_table,gtk.Label(_("Paper Options"))) - paper_label = gtk.Label("%s" % _("Paper Options")) - paper_label.set_use_markup(gtk.TRUE) - paper_label.set_alignment(0.0,0.5) - self.paper_table.attach(paper_label,0,6,0,1,gtk.SHRINK|gtk.FILL) - - self.papersize_menu = gtk.OptionMenu() - self.papersize_menu.connect('changed',self.size_changed) - - self.orientation_menu = gtk.OptionMenu() - l = gtk.Label("%s:" % _("Size")) - l.set_alignment(0.0,0.5) - - self.paper_table.attach(l,1,2,1,2,gtk.SHRINK|gtk.FILL) - self.paper_table.attach(self.papersize_menu,2,3,1,2) - l = gtk.Label("%s:" % _("Height")) - l.set_alignment(0.0,0.5) - self.paper_table.attach(l,3,4,1,2,gtk.SHRINK|gtk.FILL) - - self.pheight = gtk.Entry() - self.pheight.set_sensitive(0) - self.paper_table.attach(self.pheight,4,5,1,2) - - l = gtk.Label(_("cm")) - l.set_alignment(0.0,0.5) - self.paper_table.attach(l,5,6,1,2,gtk.SHRINK|gtk.FILL) - - l = gtk.Label("%s:" % _("Orientation")) - l.set_alignment(0.0,0.5) - self.paper_table.attach(l,1,2,2,3,gtk.SHRINK|gtk.FILL) - self.paper_table.attach(self.orientation_menu,2,3,2,3) - l = gtk.Label("%s:" % _("Width")) - l.set_alignment(0.0,0.5) - self.paper_table.attach(l,3,4,2,3,gtk.SHRINK|gtk.FILL) - - self.pwidth = gtk.Entry() - self.pwidth.set_sensitive(0) - self.paper_table.attach(self.pwidth,4,5,2,3) - - l = gtk.Label(_("cm")) - l.set_alignment(0.0,0.5) - self.paper_table.attach(l,5,6,2,3,gtk.SHRINK|gtk.FILL) - - PaperMenu.make_paper_menu(self.papersize_menu) - PaperMenu.make_orientation_menu(self.orientation_menu) - - # The optional pagecount stuff. - if pagecount_map: - self.pagecount_menu = gtk.OptionMenu() - myMenu = Utils.build_string_optmenu(pagecount_map, start_text) - self.pagecount_menu.set_menu(myMenu) - l = gtk.Label("%s:" % _("Page Count")) - l.set_alignment(0.0,0.5) - self.paper_table.attach(l,1,2,3,4,gtk.SHRINK|gtk.FILL) - self.paper_table.attach(self.pagecount_menu,2,3,3,4) - - def html_file_enable(self,obj): - text = obj.get_text() - if _template_map.has_key(text): - if _template_map[text]: - self.html_fileentry.set_sensitive(0) - else: - self.html_fileentry.set_sensitive(1) - else: - self.html_fileentry.set_sensitive(0) - - def setup_html_frame(self): - """Set up the html frame of the dialog. This sole purpose of - this function is to grab a pointer for later use in the parse - html frame function.""" - - self.html_table = gtk.Table(3,3) - self.html_table.set_col_spacings(12) - self.html_table.set_row_spacings(6) - self.html_table.set_border_width(0) - html_label = gtk.Label("%s" % _("HTML Options")) - html_label.set_alignment(0.0,0.5) - html_label.set_use_markup(gtk.TRUE) - self.html_table.attach(html_label,0,3,0,1) - - self.output_notebook.append_page(self.html_table,gtk.Label(_("HTML Options"))) - - l = gtk.Label("%s:" % _("Template")) - l.set_alignment(0.0,0.5) - self.html_table.attach(l,1,2,1,2,gtk.SHRINK|gtk.FILL) - - self.template_combo = gtk.Combo() - template_list = [ _default_template ] - tlist = _template_map.keys() - tlist.sort() - - for template in tlist: - if template != _user_template: - template_list.append(template) - template_list.append(_user_template) - - self.template_combo.set_popdown_strings(template_list) - self.template_combo.entry.set_editable(0) - self.template_combo.entry.connect('changed',self.html_file_enable) - - self.html_table.attach(self.template_combo,2,3,1,2) - l = gtk.Label("%s:" % _("User Template")) - l.set_alignment(0.0,0.5) - self.html_table.attach(l,1,2,2,3,gtk.SHRINK|gtk.FILL) - self.html_fileentry = gnome.ui.FileEntry("HTML_Template",_("Choose File")) - self.html_fileentry.set_sensitive(0) - self.html_table.attach(self.html_fileentry,2,3,2,3) - def setup_report_options_frame(self): """Set up the report options frame of the dialog. This function relies on several report_xxx() customization @@ -880,6 +508,536 @@ class ReportDialog: table.attach(widget,2,3,row,row+1) row = row + 1 + #------------------------------------------------------------------------ + # + # Functions related to retrieving data from the dialog window + # + #------------------------------------------------------------------------ + def parse_report_options_frame(self): + """Parse the report options frame of the dialog. Save the + user selected choices for later use. Note that this routine + retrieves a value from all fields in the frame, regardless of + whether or not they are displayed on the screen. The subclass + will know which ones it has enabled. This is for simplicity + of programming.""" + + if self.generations_spinbox: + self.max_gen = self.generations_spinbox.get_value_as_int() + else: + self.max_gen = 0 + + if self.pagebreak_checkbox: + self.pg_brk = self.pagebreak_checkbox.get_active() + else: + self.pg_brk = 0 + + if self.filter_combo: + self.filter = self.filter_menu.get_active().get_data("filter") + else: + self.filter = None + + if self.extra_menu: + self.report_menu = self.extra_menu.get_menu().get_active().get_data("d") + else: + self.report_menu = None + + if self.extra_textbox: + b = self.extra_textbox.get_buffer() + text_val = b.get_text(b.get_start_iter(),b.get_end_iter(),gtk.FALSE) + self.report_text = string.split(text_val,'\n') + else: + self.report_text = "" + + def parse_other_frames(self): + """Do nothing. This sole purpose of this function is to give + subclass a place to hang a routine to parser any other frames + that are unique to that specific report.""" + pass + + #------------------------------------------------------------------------ + # + # Callback functions from the dialog + # + #------------------------------------------------------------------------ + def on_cancel(self,obj): + self.window.destroy() + + def on_ok_clicked(self, obj): + """The user is satisfied with the dialog choices. Validate + the output file name before doing anything else. If there is + a file name, gather the options and create the report.""" + + # Is there a filename? This should also test file permissions, etc. + if not self.parse_target_frame(): + return + + # Preparation + self.parse_format_frame() + self.parse_style_frame() + self.parse_paper_frame() + self.parse_html_frame() + self.parse_report_options_frame() + self.parse_other_frames() + + # Create the output document. + self.make_document() + + # Create the report object and product the report. + try: + self.make_report() + except (IOError,OSError),msg: + ErrorDialog(str(msg)) + + # Clean up the dialog object + self.window.destroy() + + #------------------------------------------------------------------------ + # + # Functions related to creating the actual report document. + # + #------------------------------------------------------------------------ + def make_report(self): + """Create the contents of the report. This is the meat and + potatoes of reports. The whole purpose of the dialog is to + get to this routine so that data is written to a file. This + routine should either write the data directly to the file, or + better yet, should create a subclass of a Report that will + write the data to a file.""" + pass + + #------------------------------------------------------------------------ + # + # Miscellaneous functions. + # + #------------------------------------------------------------------------ + def add_tooltip(self,widget,string): + """Adds a tooltip to the specified widget""" + if not widget or not string: + return + tip = gtk.Tooltips() + tip.set_tip(widget,string) + + +class ReportDialog(BareReportDialog): + """ + The ReportDialog base class. This is a base class for generating + customized dialogs to solicit options for a report. It cannot be + used as is, but it can be easily sub-classed to create a functional + dialog for a stand-alone report. + """ + + def __init__(self,database,person): + """Initialize a dialog to request that the user select options + for a basic *stand-alone* report.""" + + BareReportDialog.__init__(self,database,person) + + # Allow for post processing of the format frame, since the + # show_all task calls events that may reset values + + if self.format_menu: + self.doc_type_changed(self.format_menu.get_menu().get_active()) + self.setup_post_process() + + def setup_post_process(self): + pass + + + #------------------------------------------------------------------------ + # + # Customization hooks for subclasses + # + #------------------------------------------------------------------------ + def get_target_browser_title(self): + """The title of the window that will be created when the user + clicks the 'Browse' button in the 'Save As' File Entry + widget.""" + return("%s - GRAMPS" % _("Save Report As")) + + def get_target_is_directory(self): + """Is the user being asked to input the name of a file or a + directory in the 'Save As' File Entry widget. This item + currently only selects the Filename/Directory prompt, and + whether or not the browser accepts filenames. In the future it + may also control checking of the selected filename.""" + return None + + def get_stylesheet_savefile(self): + """Where should new styles for this report be saved? This is + the name of an XML file that will be located in the ~/.gramps + directory. This file does not have to exist; it will be + created when needed. All subclasses should probably override + this function.""" + return "basic_report.xml" + + def get_default_basename(self): + """What should the default name be? + """ + path = self.get_stylesheet_savefile() + return path.split('.')[0] + + def get_print_pagecount_map(self): + """Return the data used to fill out the 'pagecount' option + menu in the print options box. The first value is a mapping + of string:value pairs. The strings will be used to label + individual menu items, and the values are what will be + returned if a given menu item is selected. The second value + is the name of menu item to pre-select.""" + return (None, None) + + #------------------------------------------------------------------------ + # + # Functions related getting/setting the default directory for a dialog. + # + #------------------------------------------------------------------------ + def get_default_directory(self): + """Get the name of the directory to which the target dialog + box should default. This value can be set in the preferences + panel.""" + return GrampsCfg.report_dir + + def set_default_directory(self, value): + """Save the name of the current directory, so that any future + reports will default to the most recently used directory. + This also changes the directory name that will appear in the + preferences panel, but does not change the preference in disk. + This means that the last directory used will only be + remembered for this session of gramps unless the user saves + his/her preferences.""" + GrampsCfg.report_dir = value + + #------------------------------------------------------------------------ + # + # Functions to create a default output style. + # + #------------------------------------------------------------------------ + def make_default_style(self): + """Create the default style to be used by the associated report. This + routine is a default implementation and should be overridden.""" + font = TextDoc.FontStyle() + font.set(face=TextDoc.FONT_SANS_SERIF,size=16,bold=1) + para = TextDoc.ParagraphStyle() + para.set_font(font) + para.set_header_level(1) + para.set(pad=0.5) + self.default_style.add_style("Title",para) + + def build_style_menu(self): + """Build a menu of style sets that are available for use in + this report. This menu will always have a default style + available, and will have any other style set name that the + user has previously created for this report. This menu is + created here instead of inline with the rest of the style + frame, because it must be recreated to reflect any changes + whenever the user closes the style editor dialog.""" + style_sheet_map = self.style_sheet_list.get_style_sheet_map() + myMenu = Utils.build_string_optmenu(style_sheet_map, "default") + self.style_menu.set_menu(myMenu) + + #------------------------------------------------------------------------ + # + # Functions related to selecting/changing the current file format. + # + #------------------------------------------------------------------------ + def make_doc_menu(self): + """Build a menu of document types that are appropriate for + this report. This menu will be generated based upon the type + of document (text, draw, graph, etc. - a subclass), whether or + not the document requires table support, etc.""" + pass + + def make_document(self): + """Create a document of the type selected by the user.""" + pass + + def doc_type_changed(self, obj): + """This routine is called when the user selects a new file + formats for the report. It adjust the various dialog sections + to reflect the appropriate values for the currently selected + file format. For example, a HTML document doesn't need any + paper size/orientation options, but it does need a template + file. Those chances are made here.""" + + # Is this to be a printed report or an electronic report + # (i.e. a set of web pages) + + if obj.get_data("paper") == 1: + self.notebook_page = 0 + else: + self.notebook_page = 1 + + if self.output_notebook == None: + return + + self.output_notebook.set_current_page(self.notebook_page) + + if not self.get_target_is_directory(): + fname = self.target_fileentry.get_full_path(0) + (path,ext) = os.path.splitext(fname) + + ext_val = obj.get_data('ext') + if ext_val: + fname = path + ext_val + self.target_fileentry.set_filename(fname) + + # Does this report format use styles? + if self.style_button: + self.style_button.set_sensitive(obj.get_data("styles")) + self.style_menu.set_sensitive(obj.get_data("styles")) + + + #------------------------------------------------------------------------ + # + # Functions related to setting up the dialog window. + # + #------------------------------------------------------------------------ + def setup_target_frame(self): + """Set up the target frame of the dialog. This function + relies on several target_xxx() customization functions to + determine whether the target is a directory or file, what the + title of any browser window should be, and what default + directory should be used.""" + + # Save Frame + + label = gtk.Label("%s" % _('Document Options')) + label.set_use_markup(1) + label.set_alignment(0.0,0.5) + self.tbl.set_border_width(12) + self.tbl.attach(label,0,4,self.col,self.col+1) + self.col += 1 + + hid = self.get_stylesheet_savefile() + if hid[-4:]==".xml": + hid = hid[0:-4] + self.target_fileentry = gnome.ui.FileEntry(hid,_("Save As")) + + if self.get_target_is_directory(): + self.target_fileentry.set_directory_entry(1) + label = gtk.Label("%s:" % _("Directory")) + else: + label = gtk.Label("%s:" % _("Filename")) + label.set_alignment(0.0,0.5) + + self.tbl.attach(label,1,2,self.col,self.col+1,gtk.SHRINK|gtk.FILL) + self.tbl.attach(self.target_fileentry,2,4,self.col,self.col+1) + self.col += 1 + + path = self.get_default_directory() + self.target_fileentry.set_default_path(path) + + + def setup_format_frame(self): + """Set up the format frame of the dialog. This function + relies on the make_doc_menu() function to do all the hard + work.""" + + self.format_menu = gtk.OptionMenu() + self.make_doc_menu() + label = gtk.Label("%s:" % _("Output Format")) + label.set_alignment(0.0,0.5) + self.tbl.attach(label,1,2,self.col,self.col+1,gtk.SHRINK|gtk.FILL) + self.tbl.attach(self.format_menu,2,4,self.col,self.col+1) + self.col += 1 + + type = self.format_menu.get_menu().get_active() + ext = type.get_data('ext') + if ext == None: + ext = "" + if type: + path = self.get_default_directory() + if self.get_target_is_directory(): + self.target_fileentry.set_filename(path) + else: + base = self.get_default_basename() + path = os.path.normpath("%s/%s%s" % (path,base,ext)) + self.target_fileentry.set_filename(path) + + + def setup_style_frame(self): + """Set up the style frame of the dialog. This function relies + on other routines create the default style for this report, + and to read in any user defined styles for this report. It + the builds a menu of all the available styles for the user to + choose from.""" + + # Styles Frame + label = gtk.Label("%s:" % _("Styles")) + label.set_alignment(0.0,0.5) + + self.style_menu = gtk.OptionMenu() + self.style_button = gtk.Button("%s..." % _("Style Editor")) + self.style_button.connect('clicked',self.on_style_edit_clicked) + + self.tbl.attach(label,1,2,self.col,self.col+1,gtk.SHRINK|gtk.FILL) + self.tbl.attach(self.style_menu,2,3,self.col,self.col+1) + self.tbl.attach(self.style_button,3,4,self.col,self.col+1,gtk.SHRINK|gtk.FILL) + self.col += 1 + + # Build the default style set for this report. + self.default_style = TextDoc.StyleSheet() + self.make_default_style() + + # Build the initial list of available styles sets. This + # includes the default style set and any style sets saved from + # previous invocations of gramps. + self.style_sheet_list = TextDoc.StyleSheetList(self.get_stylesheet_savefile(), + self.default_style) + + # Now build the actual menu. + self.build_style_menu() + + def setup_output_notebook(self): + """Set up the output notebook of the dialog. This sole + purpose of this function is to grab a pointer for later use in + the callback from when the file format is changed.""" + + self.output_notebook = gtk.Notebook() + self.output_notebook.set_show_tabs(0) + self.output_notebook.set_show_border(0) + self.output_notebook.set_border_width(12) + self.output_notebook.set_current_page(self.notebook_page) + self.window.vbox.add(self.output_notebook) + + def size_changed(self,obj): + paper = self.papersize_menu.get_menu().get_active().get_data('i') + if paper.get_width() <= 0: + self.pwidth.set_sensitive(1) + self.pheight.set_sensitive(1) + else: + self.pwidth.set_sensitive(0) + self.pheight.set_sensitive(0) + self.pwidth.set_text("%.2f" % paper.get_width()) + self.pheight.set_text("%.2f" % paper.get_height()) + + + def setup_paper_frame(self): + """Set up the paper selection frame of the dialog. This + function relies on a paper_xxx() customization functions to + determine whether the pagecount menu should appear and what + its strings should be.""" + + (pagecount_map, start_text) = self.get_print_pagecount_map() + + if pagecount_map: + self.paper_table = gtk.Table(3,6) + else: + self.paper_table = gtk.Table(4,6) + self.paper_table.set_col_spacings(12) + self.paper_table.set_row_spacings(6) + self.paper_table.set_border_width(0) + self.output_notebook.append_page(self.paper_table,gtk.Label(_("Paper Options"))) + + paper_label = gtk.Label("%s" % _("Paper Options")) + paper_label.set_use_markup(gtk.TRUE) + paper_label.set_alignment(0.0,0.5) + self.paper_table.attach(paper_label,0,6,0,1,gtk.SHRINK|gtk.FILL) + + self.papersize_menu = gtk.OptionMenu() + self.papersize_menu.connect('changed',self.size_changed) + + self.orientation_menu = gtk.OptionMenu() + l = gtk.Label("%s:" % _("Size")) + l.set_alignment(0.0,0.5) + + self.paper_table.attach(l,1,2,1,2,gtk.SHRINK|gtk.FILL) + self.paper_table.attach(self.papersize_menu,2,3,1,2) + l = gtk.Label("%s:" % _("Height")) + l.set_alignment(0.0,0.5) + self.paper_table.attach(l,3,4,1,2,gtk.SHRINK|gtk.FILL) + + self.pheight = gtk.Entry() + self.pheight.set_sensitive(0) + self.paper_table.attach(self.pheight,4,5,1,2) + + l = gtk.Label(_("cm")) + l.set_alignment(0.0,0.5) + self.paper_table.attach(l,5,6,1,2,gtk.SHRINK|gtk.FILL) + + l = gtk.Label("%s:" % _("Orientation")) + l.set_alignment(0.0,0.5) + self.paper_table.attach(l,1,2,2,3,gtk.SHRINK|gtk.FILL) + self.paper_table.attach(self.orientation_menu,2,3,2,3) + l = gtk.Label("%s:" % _("Width")) + l.set_alignment(0.0,0.5) + self.paper_table.attach(l,3,4,2,3,gtk.SHRINK|gtk.FILL) + + self.pwidth = gtk.Entry() + self.pwidth.set_sensitive(0) + self.paper_table.attach(self.pwidth,4,5,2,3) + + l = gtk.Label(_("cm")) + l.set_alignment(0.0,0.5) + self.paper_table.attach(l,5,6,2,3,gtk.SHRINK|gtk.FILL) + + PaperMenu.make_paper_menu(self.papersize_menu) + PaperMenu.make_orientation_menu(self.orientation_menu) + + # The optional pagecount stuff. + if pagecount_map: + self.pagecount_menu = gtk.OptionMenu() + myMenu = Utils.build_string_optmenu(pagecount_map, start_text) + self.pagecount_menu.set_menu(myMenu) + l = gtk.Label("%s:" % _("Page Count")) + l.set_alignment(0.0,0.5) + self.paper_table.attach(l,1,2,3,4,gtk.SHRINK|gtk.FILL) + self.paper_table.attach(self.pagecount_menu,2,3,3,4) + + + def html_file_enable(self,obj): + text = obj.get_text() + if _template_map.has_key(text): + if _template_map[text]: + self.html_fileentry.set_sensitive(0) + else: + self.html_fileentry.set_sensitive(1) + else: + self.html_fileentry.set_sensitive(0) + + + def setup_html_frame(self): + """Set up the html frame of the dialog. This sole purpose of + this function is to grab a pointer for later use in the parse + html frame function.""" + + self.html_table = gtk.Table(3,3) + self.html_table.set_col_spacings(12) + self.html_table.set_row_spacings(6) + self.html_table.set_border_width(0) + html_label = gtk.Label("%s" % _("HTML Options")) + html_label.set_alignment(0.0,0.5) + html_label.set_use_markup(gtk.TRUE) + self.html_table.attach(html_label,0,3,0,1) + + self.output_notebook.append_page(self.html_table,gtk.Label(_("HTML Options"))) + + l = gtk.Label("%s:" % _("Template")) + l.set_alignment(0.0,0.5) + self.html_table.attach(l,1,2,1,2,gtk.SHRINK|gtk.FILL) + + self.template_combo = gtk.Combo() + template_list = [ _default_template ] + tlist = _template_map.keys() + tlist.sort() + + for template in tlist: + if template != _user_template: + template_list.append(template) + template_list.append(_user_template) + + self.template_combo.set_popdown_strings(template_list) + self.template_combo.entry.set_editable(0) + self.template_combo.entry.connect('changed',self.html_file_enable) + + self.html_table.attach(self.template_combo,2,3,1,2) + l = gtk.Label("%s:" % _("User Template")) + l.set_alignment(0.0,0.5) + self.html_table.attach(l,1,2,2,3,gtk.SHRINK|gtk.FILL) + self.html_fileentry = gnome.ui.FileEntry("HTML_Template",_("Choose File")) + self.html_fileentry.set_sensitive(0) + self.html_table.attach(self.html_fileentry,2,3,2,3) + + #------------------------------------------------------------------------ # # Functions related to retrieving data from the dialog window @@ -971,46 +1129,6 @@ class ReportDialog: else: self.template_name = None - def parse_report_options_frame(self): - """Parse the report options frame of the dialog. Save the - user selected choices for later use. Note that this routine - retrieves a value from all fields in the frame, regardless of - whether or not they are displayed on the screen. The subclass - will know which ones it has enabled. This is for simplicity - of programming.""" - - if self.generations_spinbox: - self.max_gen = self.generations_spinbox.get_value_as_int() - else: - self.max_gen = 0 - - if self.pagebreak_checkbox: - self.pg_brk = self.pagebreak_checkbox.get_active() - else: - self.pg_brk = 0 - - if self.filter_combo: - self.filter = self.filter_menu.get_active().get_data("filter") - else: - self.filter = None - - if self.extra_menu: - self.report_menu = self.extra_menu.get_menu().get_active().get_data("d") - else: - self.report_menu = None - - if self.extra_textbox: - b = self.extra_textbox.get_buffer() - text_val = b.get_text(b.get_start_iter(),b.get_end_iter(),gtk.FALSE) - self.report_text = string.split(text_val,'\n') - else: - self.report_text = "" - - def parse_other_frames(self): - """Do nothing. This sole purpose of this function is to give - subclass a place to hang a routine to parser any other frames - that are unique to that specific report.""" - pass #------------------------------------------------------------------------ # @@ -1024,64 +1142,6 @@ class ReportDialog: menu for selecting a style.""" StyleEditor.StyleListDisplay(self.style_sheet_list,self.build_style_menu) - def on_cancel(self,obj): - self.window.destroy() - - def on_ok_clicked(self, obj): - """The user is satisfied with the dialog choices. Validate - the output file name before doing anything else. If there is - a file name, gather the options and create the report.""" - - # Is there a filename? This should also test file permissions, etc. - if not self.parse_target_frame(): - return - - # Preparation - self.parse_format_frame() - self.parse_style_frame() - self.parse_paper_frame() - self.parse_html_frame() - self.parse_report_options_frame() - self.parse_other_frames() - - # Create the output document. - self.make_document() - - # Create the report object and product the report. - try: - self.make_report() - except (IOError,OSError),msg: - ErrorDialog(str(msg)) - - # Clean up the dialog object - self.window.destroy() - - #------------------------------------------------------------------------ - # - # Functions related to creating the actual report document. - # - #------------------------------------------------------------------------ - def make_report(self): - """Create the contents of the report. This is the meat and - potatoes of reports. The whole purpose of the dialog is to - get to this routine so that data is written to a file. This - routine should either write the data directly to the file, or - better yet, should create a subclass of a Report that will - write the data to a file.""" - pass - - #------------------------------------------------------------------------ - # - # Miscellaneous functions. - # - #------------------------------------------------------------------------ - def add_tooltip(self,widget,string): - """Adds a tooltip to the specified widget""" - if not widget or not string: - return - tip = gtk.Tooltips() - tip.set_tip(widget,string) - class TextReportDialog(ReportDialog): """A class of ReportDialog customized for text based reports.""" diff --git a/src/plugins/BookReport.py b/src/plugins/BookReport.py index 252fc9615..2565ce1b2 100644 --- a/src/plugins/BookReport.py +++ b/src/plugins/BookReport.py @@ -210,11 +210,11 @@ class BookReportSelector: # # #------------------------------------------------------------------------ -class ReportOptionsDialog(Report.TextReportDialog): +class ReportOptionsDialog(Report.BareReportDialog): def __init__(self,database,person,rep_title): self.rep_title = rep_title - Report.TextReportDialog.__init__(self,database,person) + Report.BareReportDialog.__init__(self,database,person) def get_title(self): """The window title for this dialog""" @@ -224,16 +224,6 @@ class ReportOptionsDialog(Report.TextReportDialog): """The header line at the top of the dialog contents""" return _("%s for GRAMPS Book") % self.rep_title - def setup_paper_frame(self): pass - - def setup_html_frame(self): pass - - def setup_style_frame(self): pass - - def html_file_enable(self,obj): pass - - def setup_target_frame(self): pass - def setup_format_frame(self): center_label = gtk.Label("%s" % _("Center Person")) center_label.set_use_markup(gtk.TRUE) @@ -370,8 +360,10 @@ register_report( report, _("Book Report"), category=_("Text Reports"), - status=(_("Experimental")), + status=(_("Unstable")), description=_("Creates a book containg several reports."), - xpm=get_xpm_image() + xpm=get_xpm_image(), + author_name="Alex Roitman", + author_email="shura@alex.neuro.umn.edu" )