diff --git a/gramps/cli/plug/__init__.py b/gramps/cli/plug/__init__.py index a172fc098..b2adf9314 100644 --- a/gramps/cli/plug/__init__.py +++ b/gramps/cli/plug/__init__.py @@ -6,7 +6,7 @@ # Copyright (C) 2008 Raphael Ackermann # Copyright (C) 2008-2011 Brian G. Matherly # Copyright (C) 2010 Jakim Friant -# Copyright (C) 2011 Paul Franklin +# Copyright (C) 2011-2012 Paul Franklin # # 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 @@ -224,6 +224,7 @@ class CommandLineReport(object): self.database = database self.category = category self.format = None + self.raw_name = name self.option_class = option_class(name, database) if category == CATEGORY_GRAPHVIZ: # Need to include GraphViz options @@ -241,6 +242,7 @@ class CommandLineReport(object): self.init_standard_options(noopt) self.init_report_options() self.parse_options() + self.init_report_options_help() self.show_options() def init_standard_options(self, noopt): @@ -340,6 +342,17 @@ class CommandLineReport(object): for name in menu.get_all_option_names(): option = menu.get_option_by_name(name) self.options_dict[name] = option.get_value() + + def init_report_options_help(self): + """ + Initialize help for the options that are defined by each report. + (And also any docgen options, if defined by the docgen.) + """ + if not hasattr(self.option_class, "menu"): + return + menu = self.option_class.menu + for name in menu.get_all_option_names(): + option = menu.get_option_by_name(name) self.options_help[name] = [ "", option.get_help() ] if isinstance(option, PersonOption): @@ -419,56 +432,35 @@ class CommandLineReport(object): else: menu = self.option_class.menu menu_opt_names = menu.get_all_option_names() - for opt in self.options_str_dict: - if opt in self.options_dict: - self.options_dict[opt] = \ - _convert_str_to_match_type(self.options_str_dict[opt], - self.options_dict[opt]) - self.option_class.handler.options_dict[opt] = \ - self.options_dict[opt] - - if menu and opt in menu_opt_names: - option = menu.get_option_by_name(opt) - option.set_value(self.options_dict[opt]) - - else: - print(_("Ignoring unknown option: %s") % opt) - print(_(" Valid options are:"), ", ".join( - list(self.options_dict.keys()))) - print((_(" Use '%(donottranslate)s' to see description " - "and acceptable values") % - {'donottranslate' : "show=option"})) + format_str = self.options_str_dict.pop('off', None) + if _format_str: + self.options_dict['off'] = _format_str self.option_class.handler.output = self.options_dict['of'] self.css_filename = None _chosen_format = None - if self.category == CATEGORY_TEXT: - for plugin in self.__textdoc_plugins: - if plugin.get_extension() == self.options_dict['off']: - self.format = plugin.get_basedoc() - self.css_filename = self.options_dict['css'] + + self.doc_option_class = None + if self.category in [CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK]: + if self.category == CATEGORY_TEXT: + plugins = self.__textdoc_plugins + self.css_filename = self.options_dict['css'] + elif self.category == CATEGORY_DRAW: + plugins = self.__drawdoc_plugins + elif self.category == CATEGORY_BOOK: + plugins = self.__bookdoc_plugins + for plugin in plugins: + if plugin.get_extension() == self.options_dict['off']: + self.format = plugin.get_basedoc() + self.doc_option_class = plugin.get_doc_option_class() if self.format is None: # Pick the first one as the default. - self.format = self.__textdoc_plugins[0].get_basedoc() - _chosen_format = self.__textdoc_plugins[0].get_extension() - elif self.category == CATEGORY_DRAW: - for plugin in self.__drawdoc_plugins: - if plugin.get_extension() == self.options_dict['off']: - self.format = plugin.get_basedoc() - if self.format is None: - # Pick the first one as the default. - self.format = self.__drawdoc_plugins[0].get_basedoc() - _chosen_format = self.__drawdoc_plugins[0].get_extension() - elif self.category == CATEGORY_BOOK: - for plugin in self.__bookdoc_plugins: - if plugin.get_extension() == self.options_dict['off']: - self.format = plugin.get_basedoc() - if self.format is None: - # Pick the first one as the default. - self.format = self.__bookdoc_plugins[0].get_basedoc() - _chosen_format = self.__bookdoc_plugins[0].get_extension() + plugin = plugins[0] + self.format = plugin.get_basedoc() + self.doc_option_class = plugin.get_doc_option_class() + _chosen_format = plugin.get_extension() elif self.category == CATEGORY_GRAPHVIZ: for graph_format in graphdoc.FORMATS: if graph_format['ext'] == self.options_dict['off']: @@ -480,7 +472,7 @@ class CommandLineReport(object): _chosen_format = graphdoc.FORMATS[0]["ext"] else: self.format = None - if _chosen_format and 'off' in self.options_str_dict: + if _chosen_format and _format_str: print((_("Ignoring '%(notranslate1)s=%(notranslate2)s' " "and using '%(notranslate1)s=%(notranslate3)s'.") % {'notranslate1' : "off", @@ -489,6 +481,31 @@ class CommandLineReport(object): print((_("Use '%(notranslate)s' to see valid values.") % {'notranslate' : "show=off"})) + self.do_doc_options() + + for opt in self.options_str_dict: + if opt in self.options_dict: + self.options_dict[opt] = \ + _convert_str_to_match_type(self.options_str_dict[opt], + self.options_dict[opt]) + + self.option_class.handler.options_dict[opt] = \ + self.options_dict[opt] + + if menu and opt in menu_opt_names: + option = menu.get_option_by_name(opt) + option.set_value(self.options_dict[opt]) + + else: + print(_("Ignoring unknown option: %s") % opt ) + print(_(" Valid options are:"), ", ".join( + self.options_dict.keys())) + print(_(" Use '%(donottranslate)s' to see description " + "and acceptable values") % + {'donottranslate' : "show=option"}) + + self.option_class.handler.output = self.options_dict['of'] + for paper in paper_sizes: if paper.get_name() == self.options_dict['papers']: self.paper = paper @@ -513,6 +530,35 @@ class CommandLineReport(object): style_name = self.option_class.handler.get_default_stylesheet_name() self.selected_style = self.style_list.get_style_sheet(style_name) + def do_doc_options(self): + self.doc_options = None + if not self.doc_option_class: + return # this docgen type has no options + try: + if (issubclass(self.doc_option_class, object) or # new class + isinstance(self.doc_option_class, ClassType)): # old class + self.doc_options = self.doc_option_class(self.raw_name, + self.database) + doc_options_dict = self.doc_options.options_dict + except TypeError: + self.doc_options = self.doc_option_class + self.doc_options.load_previous_values() + docgen_menu = self.doc_options.menu + report_menu = self.option_class.menu # "help" checks the option type + for oname in docgen_menu.get_option_names('Document Options'): + docgen_opt = docgen_menu.get_option('Document Options', oname) + if oname in self.options_str_dict and oname in doc_options_dict: + doc_options_dict[oname] = \ + _convert_str_to_match_type(self.options_str_dict[oname], + doc_options_dict[oname]) + self.options_str_dict.pop(oname) + if oname in doc_options_dict: + docgen_opt.set_value(doc_options_dict[oname]) + report_menu.add_option('Document Options', oname, docgen_opt) + for oname in doc_options_dict: # enable "help" + self.options_dict[oname] = doc_options_dict[oname] + self.options_help[oname] = self.doc_options.options_help[oname][:3] + def show_options(self): """ Print available options on the CLI. @@ -529,7 +575,8 @@ class CommandLineReport(object): optmsg = " %s%s%s (%s)" % (key, tabs, opt[1], opt[0]) print(optmsg.encode(sys.getfilesystemencoding())) else: - optmsg = " %s" % key + optmsg = " %s%s%s" % (key, tabs, + _('(no help available)')) print(optmsg.encode(sys.getfilesystemencoding())) print((_(" Use '%(donottranslate)s' to see description " "and acceptable values") % @@ -573,10 +620,17 @@ def cl_report(database, name, category, report_class, options_class, # write report try: if category in [CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK]: - clr.option_class.handler.doc = clr.format( - clr.selected_style, - PaperStyle(clr.paper,clr.orien,clr.marginl, - clr.marginr,clr.margint,clr.marginb)) + if clr.doc_options: + clr.option_class.handler.doc = clr.format( + clr.selected_style, + PaperStyle(clr.paper,clr.orien,clr.marginl, + clr.marginr,clr.margint,clr.marginb), + clr.doc_options) + else: + clr.option_class.handler.doc = clr.format( + clr.selected_style, + PaperStyle(clr.paper,clr.orien,clr.marginl, + clr.marginr,clr.margint,clr.marginb)) elif category == CATEGORY_GRAPHVIZ: clr.option_class.handler.doc = clr.format( clr.option_class, diff --git a/gramps/gen/plug/_docgenplugin.py b/gramps/gen/plug/_docgenplugin.py index 9ef0e6406..28512daf8 100644 --- a/gramps/gen/plug/_docgenplugin.py +++ b/gramps/gen/plug/_docgenplugin.py @@ -2,6 +2,7 @@ # Gramps - a GTK+/GNOME based genealogy program # # Copyright (C) 2008 Brian G. Matherly +# Copyright (C) 2012 Paul Franklin # # 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 @@ -30,7 +31,8 @@ class DocGenPlugin(Plugin): """ This class represents a plugin for generating documents from Gramps """ - def __init__(self, name, description, basedoc, paper, style, extension): + def __init__(self, name, description, basedoc, + paper, style, extension, docoptclass, basedocname): """ @param name: A friendly name to call this plugin. Example: "Plain Text" @@ -50,6 +52,11 @@ class DocGenPlugin(Plugin): @param extension: The extension for the output file. Example: "txt" @type extension: str + @param docoptclass: either None or a subclass of DocOptions + @type docoptclass: either None or a DocOptions subclass + @param basedocname: The BaseDoc name of this plugin. + Example: "AsciiDoc" + @type basedocname: string @return: nothing """ Plugin.__init__(self, name, description, basedoc.__module__) @@ -57,6 +64,8 @@ class DocGenPlugin(Plugin): self.__paper = paper self.__style = style self.__extension = extension + self.__docoptclass = docoptclass + self.__basedocname = basedocname def get_basedoc(self): """ @@ -90,6 +99,22 @@ class DocGenPlugin(Plugin): """ return self.__extension + def get_doc_option_class(self): + """ + Get the DocOptions subclass for this plugin, if any + + @return: the DocOptions subclass passed into __init__ + """ + return self.__docoptclass + + def get_basedocname(self): + """ + Get the BaseDoc name for this plugin. + + @return: the BaseDoc name passed into __init__ + """ + return self.__basedocname + def get_text_support(self): """ Check if the plugin supports the TextDoc interface. diff --git a/gramps/gen/plug/_manager.py b/gramps/gen/plug/_manager.py index 97933b953..7359b1dfa 100644 --- a/gramps/gen/plug/_manager.py +++ b/gramps/gen/plug/_manager.py @@ -4,6 +4,7 @@ # Copyright (C) 2000-2005 Donald N. Allingham # Copyright (C) 2008 Brian G. Matherly # Copyright (C) 2009 Benny Malengier +# Copyright (C) 2012 Paul Franklin # # 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 @@ -90,6 +91,7 @@ class BasePluginManager(object): self.__failmsg_list = [] self.__external_opt_dict = {} self.__success_list = [] + self.__docgen_names = [] self.__mod2text = {} self.__modules = {} @@ -526,21 +528,40 @@ class BasePluginManager(object): ## So, only do import when docgen.get_basedoc() is requested if self.__docgen_plugins == []: #The modules still need to be imported + hiddenplugins = config.get("plugin.hiddenplugins") for pdata in self.get_reg_docgens(): - if pdata.id in config.get("plugin.hiddenplugins"): + if pdata.id in hiddenplugins: continue mod = self.load_plugin(pdata) if mod: + oclass = None + if pdata.options: + oclass = getattr(mod, pdata.basedocclass + 'Options') dgp = DocGenPlugin(name=pdata.name, description = pdata.description, basedoc = getattr(mod, pdata.basedocclass), paper = pdata.paper, style = pdata.style, - extension = pdata.extension ) + extension = pdata.extension, + docoptclass = oclass, + basedocname = pdata.basedocclass ) self.__docgen_plugins.append(dgp) return self.__docgen_plugins + def get_docgen_names(self): + """ + Get the list of docgen plugin names. + + @return: a list of DocGenPlugin names + """ + if self.__docgen_names == []: + hiddenplugins = config.get("plugin.hiddenplugins") + for pdata in self.get_reg_docgens(): + if pdata.id not in hiddenplugins: + self.__docgen_names.append(pdata.basedocclass) + return self.__docgen_names + def register_option(self, option, guioption): """ Register an external option. diff --git a/gramps/gen/plug/_options.py b/gramps/gen/plug/_options.py index 37c2d7494..770cc01bd 100644 --- a/gramps/gen/plug/_options.py +++ b/gramps/gen/plug/_options.py @@ -55,6 +55,8 @@ except: #------------------------------------------------------------------------- from ..utils.cast import get_type_converter from .menu import Menu +from ..plug import BasePluginManager +PLUGMAN = BasePluginManager.get_instance() #------------------------------------------------------------------------- # @@ -134,6 +136,7 @@ class OptionListCollection(object): self.filename = os.path.expanduser(filename) self.option_list_map = {} + self.docgen_names = PLUGMAN.get_docgen_names() self.init_common() self.parse() @@ -173,7 +176,7 @@ class OptionListCollection(object): @param name: name associated with the module to add or replace. @type name: str @param option_list: list of options - @type option_list: str + @type option_list: OptionList """ self.option_list_map[name] = option_list @@ -199,25 +202,42 @@ class OptionListCollection(object): self.write_common(f) - for module_name in self.get_module_names(): + for module_name in sorted(self.get_module_names()): # enable a diff option_list = self.get_option_list(module_name) + module_docgen_opts = {} + for docgen_name in self.docgen_names: + module_docgen_opts[docgen_name] = [] f.write('\n' % quoteattr(module_name)) options = option_list.get_options() - for option_name, option_data in options.items(): + for option_name in sorted(options.keys()): # enable a diff + option_data = options[option_name] if isinstance(option_data, (list, tuple)): - f.write(' \n') + if option_data and option_data[0] in self.docgen_names: + module_docgen_opts[option_data[0]].append( + (option_name, option_data[1])) + else: + f.write(' \n') else: - f.write(' \n') @@ -341,10 +361,6 @@ class OptionHandler(object): bad_opts = [] for option_name, option_data in options.items(): if option_name not in self.options_dict: - print("Option '%s' is present in %s but is not known "\ - "to the module." % (option_name, - self.option_list_collection.filename)) - print("Ignoring...") bad_opts.append(option_name) continue try: @@ -355,7 +371,16 @@ class OptionHandler(object): except TypeError: pass + docgen_names = self.option_list_collection.docgen_names for option_name in bad_opts: + option_data = options[option_name] + if not ( isinstance(option_data, list) and + option_data and + option_data[0] in docgen_names ): + print( _("Option '%(opt_name)s' is present in %(file)s\n" + " but is not known to the module. Ignoring...") % \ + { 'opt_name' : option_name, + 'file' : self.option_list_collection.filename } ) options.pop(option_name) # Then we set common options from whatever was found diff --git a/gramps/gen/plug/report/__init__.py b/gramps/gen/plug/report/__init__.py index 56304337b..77ae44e70 100644 --- a/gramps/gen/plug/report/__init__.py +++ b/gramps/gen/plug/report/__init__.py @@ -32,6 +32,6 @@ from ._reportbase import Report from ._bibliography import Bibliography, Citation -from ._options import MenuReportOptions, ReportOptions +from ._options import MenuReportOptions, ReportOptions, DocOptions from ._book import BookList, Book, BookItem, create_style_sheet diff --git a/gramps/gen/plug/report/_options.py b/gramps/gen/plug/report/_options.py index 53748cc82..be084cb40 100644 --- a/gramps/gen/plug/report/_options.py +++ b/gramps/gen/plug/report/_options.py @@ -62,6 +62,7 @@ from ...config import config from ..docgen import PAPER_PORTRAIT from .. import _options from .. import MenuOptions +from gramps.gen.utils.cast import get_type_converter #------------------------------------------------------------------------- # @@ -507,6 +508,10 @@ class OptionParser(_options.OptionParser): # First we try report-specific tags if tag == "last-common": self.common = True + elif tag == 'docgen-option': + if not self.common: + self.oname = attrs['name'] + self.an_o = [attrs['docgen'], attrs['value']] elif tag == "style": self.option_list.set_style_name(attrs['name']) elif tag == "paper": @@ -561,6 +566,8 @@ class OptionParser(_options.OptionParser): # First we try report-specific tags if tag == "last-common": self.common = False + elif tag == 'docgen-option': + self.o[self.oname] = self.an_o else: # Tag is not report-specific, so we let the base class handle it. _options.OptionParser.endElement(self, tag) @@ -870,3 +877,130 @@ class MenuReportOptions(MenuOptions, ReportOptions): menu_option = self.menu.get_option_by_name(optname) if menu_option: menu_option.set_value(self.options_dict[optname]) + +#------------------------------------------------------------------------- +# +# DocOptionHandler class +# +#------------------------------------------------------------------------- +class DocOptionHandler(_options.OptionHandler): + """ + Implements handling of the docgen options for the plugins. + """ + + def __init__(self, module_name, options_dict): + _options.OptionHandler.__init__(self, module_name, options_dict) + + def init_subclass(self): + self.collection_class = DocOptionListCollection + self.list_class = OptionList + self.filename = REPORT_OPTIONS + + def set_options(self): + """ + Set options to be used in this plugin according to the passed + options dictionary. + + Dictionary values are all strings, since they were read from XML. + Here we need to convert them to the needed types. We use default + values to determine the type. + """ + # First we set options_dict values based on the saved options + options = self.saved_option_list.get_options() + docgen_names = self.option_list_collection.docgen_names + for option_name, option_data in options.iteritems(): + if ( option_name in self.options_dict and + isinstance(option_data, list) and + option_data and + option_data[0] in docgen_names ): + try: + converter = get_type_converter( + self.options_dict[option_name]) + self.options_dict[option_name] = converter(option_data[1]) + except (TypeError, ValueError): + pass + +#------------------------------------------------------------------------ +# +# DocOptions class +# +#------------------------------------------------------------------------ +class DocOptions(MenuOptions): + """ + Defines options and provides handling interface. + """ + + def __init__(self, name): + """ + Initialize the class, performing usual house-keeping tasks. + Subclasses MUST call this in their __init__() method. + """ + self.name = name + MenuOptions.__init__(self) + + def load_previous_values(self): + self.handler = DocOptionHandler(self.name, self.options_dict) + +#------------------------------------------------------------------------- +# +# DocOptionListCollection class +# +#------------------------------------------------------------------------- +class DocOptionListCollection(_options.OptionListCollection): + """ + Implements a collection of option lists. + """ + + def __init__(self, filename): + _options.OptionListCollection.__init__(self, filename) + + def init_common(self): + pass + + def parse(self): + """ + Loads the OptionList from the associated file, if it exists. + """ + try: + if os.path.isfile(self.filename): + p = make_parser() + p.setContentHandler(DocOptionParser(self)) + the_file = open(self.filename) + p.parse(the_file) + the_file.close() + except (IOError, OSError, SAXParseException): + pass + +#------------------------------------------------------------------------ +# +# DocOptionParser class +# +#------------------------------------------------------------------------ +class DocOptionParser(_options.OptionParser): + """ + SAX parsing class for the DocOptionListCollection XML file. + """ + + def __init__(self, collection): + """ + Create a DocOptionParser class that populates the passed collection. + + collection: DocOptionListCollection to be loaded from the file. + """ + _options.OptionParser.__init__(self, collection) + self.list_class = OptionList + + def startElement(self, tag, attrs): + "Overridden class that handles the start of a XML element" + if tag == 'docgen-option': + self.oname = attrs['name'] + self.an_o = [attrs['docgen'], attrs['value']] + else: + _options.OptionParser.startElement(self, tag, attrs) + + def endElement(self, tag): + "Overridden class that handles the end of a XML element" + if tag == 'docgen-option': + self.o[self.oname] = self.an_o + else: + _options.OptionParser.endElement(self, tag) diff --git a/gramps/gui/plug/report/_docreportdialog.py b/gramps/gui/plug/report/_docreportdialog.py index 7bab74d54..65bda2f63 100644 --- a/gramps/gui/plug/report/_docreportdialog.py +++ b/gramps/gui/plug/report/_docreportdialog.py @@ -94,7 +94,11 @@ class DocReportDialog(ReportDialog): """ pstyle = self.paper_frame.get_paper_style() - self.doc = self.format(self.selected_style, pstyle) + if self.doc_options: + self.doc = self.format(self.selected_style, pstyle, + self.doc_options) + else: + self.doc = self.format(self.selected_style, pstyle) if not self.format_menu.get_active_plugin().get_paper_used(): #set css filename self.doc.set_css_filename(self.css_filename) @@ -148,6 +152,11 @@ class DocReportDialog(ReportDialog): self.style_button.set_sensitive(docgen_plugin.get_style_support()) self.style_menu.set_sensitive(docgen_plugin.get_style_support()) + self.basedocname = docgen_plugin.get_basedocname() + self.doc_option_class = docgen_plugin.get_doc_option_class() + self.setup_doc_options_frame() + self.show() + 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 @@ -267,6 +276,8 @@ class DocReportDialog(ReportDialog): # Create the output document. self.make_document() + self.parse_doc_options() + # Save options self.options.handler.save_options() config.set('interface.open-with-default-viewer', diff --git a/gramps/gui/plug/report/_reportdialog.py b/gramps/gui/plug/report/_reportdialog.py index fbb1560da..1ec448aa0 100644 --- a/gramps/gui/plug/report/_reportdialog.py +++ b/gramps/gui/plug/report/_reportdialog.py @@ -51,7 +51,7 @@ from gramps.gen.ggettext import gettext as _ from gramps.gen.config import config from gramps.gen.errors import DatabaseError, FilterError, ReportError, WindowActiveError from ...utils import open_file_with_default_application -from .. import add_gui_options +from .. import add_gui_options, make_gui_option from ...user import User from ...dialog import ErrorDialog, OptionDialog from gramps.gen.plug.report import (CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK, @@ -144,6 +144,7 @@ class ReportDialog(ManagedWindow): def init_interface(self): self.widgets = [] + self.doc_widgets = [] self.frame_names = [] self.frames = {} self.format_menu = None @@ -572,6 +573,65 @@ class ReportDialog(ManagedWindow): StyleListDisplay(self.style_sheet_list, self.build_style_menu, self.window) + #---------------------------------------------------------------------- + # + # Functions related to any docgen options for a dialog. + # + #---------------------------------------------------------------------- + def setup_doc_options_frame(self): + if self.doc_widgets: + for option_widget in self.doc_widgets: + self.tbl.remove(option_widget) + self.doc_widgets = [] + self.doc_options = None + + if not self.doc_option_class: + return # this docgen type has no options + + self.init_doc_options(self.doc_option_class) + menu = self.doc_options.menu + for name in menu.get_option_names('Document Options'): + option = menu.get_option('Document Options', name) + # override option default with xml-saved value: + if name in self.doc_options.options_dict: + option.set_value(self.doc_options.options_dict[name]) + widget, has_label = make_gui_option(option, self.dbstate, + self.uistate, self.track) + if has_label: + widget_text = Gtk.Label('%s:' % option.get_label()) + widget_text.set_alignment(0.0, 0.0) + self.tbl.attach(widget_text, 1, 2, self.row, self.row+1, + Gtk.AttachOptions.SHRINK|Gtk.AttachOptions.FILL, Gtk.AttachOptions.SHRINK) + self.doc_widgets.append(widget_text) + self.tbl.attach(widget, 2, 4, self.row, self.row+1, + yoptions=Gtk.AttachOptions.SHRINK) + self.doc_widgets.append(widget) + self.row += 1 + + def init_doc_options(self, option_class): + try: + if (issubclass(option_class, object) or # New-style class + isinstance(option_class, ClassType)): # Old-style class + self.doc_options = option_class(self.raw_name, self.db) + except TypeError: + self.doc_options = option_class + self.doc_options.load_previous_values() + + def parse_doc_options(self): + """ + Called to allow parsing of added docgen widgets. + It is called when OK is pressed in a dialog. + """ + if not self.doc_options: + return + try: + self.doc_options.parse_user_options() + for opt in self.doc_options.options_dict: + self.options.options_dict[opt] = \ + [self.basedocname, self.doc_options.options_dict[opt]] + except: + logging.warning("Failed to parse doc options") + #------------------------------------------------------------------------ # # Generic task function a standalone GUI report diff --git a/gramps/plugins/docgen/asciidoc.py b/gramps/plugins/docgen/asciidoc.py index f3d4ee6ca..99ef89b27 100644 --- a/gramps/plugins/docgen/asciidoc.py +++ b/gramps/plugins/docgen/asciidoc.py @@ -6,6 +6,7 @@ # Copyright (C) 2009-2010 Benny Malengier # Copyright (C) 2010 Peter Landgren # Copyright (C) 2011 Adam Stein +# Copyright (C) 2012 Paul Franklin # # 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 @@ -39,6 +40,8 @@ from gramps.gen.ggettext import gettext as _ from gramps.gen.plug.docgen import (BaseDoc, TextDoc, PARA_ALIGN_RIGHT, PARA_ALIGN_CENTER) from gramps.gen.errors import ReportError +from gramps.gen.plug.menu import NumberOption +from gramps.gen.plug.report import DocOptions #------------------------------------------------------------------------ # @@ -46,7 +49,6 @@ from gramps.gen.errors import ReportError # #------------------------------------------------------------------------ LEFT,RIGHT,CENTER = 'LEFT','RIGHT','CENTER' -_WIDTH_IN_CHARS = 72 #------------------------------------------------------------------------ # @@ -82,11 +84,13 @@ def reformat_para(para='',left=0,right=72,just=LEFT,right_pad=0,first=0): end_words = 1 else: # Compose line of words while len(line)+len(words[word]) <= right-real_left: - line += words[word]+' ' + line += words[word] word += 1 if word >= len(words): end_words = 1 break + elif len(line) < right-real_left: + line += ' ' # add a space since there is still room lines.append(line) #first line finished, discard first real_left = left @@ -130,10 +134,15 @@ def reformat_para(para='',left=0,right=72,just=LEFT,right_pad=0,first=0): #------------------------------------------------------------------------ class AsciiDoc(BaseDoc,TextDoc): - def __init__(self, styles, type): + def __init__(self, styles, type, options=None): BaseDoc.__init__(self, styles, type) self.__note_format = False + self._cpl = 72 # characters per line, in case the options are ignored + if options: + menu = options.menu + self._cpl = menu.get_option_by_name('linechars').get_value() + #-------------------------------------------------------------------- # # Opens the file, resets the text buffer. @@ -165,7 +174,7 @@ class AsciiDoc(BaseDoc,TextDoc): self.f.close() def get_usable_width(self): - return _WIDTH_IN_CHARS + return self._cpl #-------------------------------------------------------------------- # @@ -410,3 +419,26 @@ class AsciiDoc(BaseDoc,TextDoc): #-------------------------------------------------------------------- def write_text(self,text,mark=None,links=False): self.text = self.text + text + +#------------------------------------------------------------------------ +# +# AsciiDocOptions class +# +#------------------------------------------------------------------------ +class AsciiDocOptions(DocOptions): + """ + Defines options and provides handling interface. + """ + + def __init__(self, name, dbase): + DocOptions.__init__(self, name) + + def add_menu_options(self, menu): + """ + Add options to the document menu for the AsciiDoc docgen. + """ + category_name = 'Document Options' # internal name: don't translate + + linechars = NumberOption(_('Characters per line'), 72, 20, 9999) + linechars.set_help(_("The number of characters per line")) + menu.add_option(category_name, 'linechars', linechars) diff --git a/gramps/plugins/docgen/docgen.gpr.py b/gramps/plugins/docgen/docgen.gpr.py index 82b623e1b..df9a4dd8d 100644 --- a/gramps/plugins/docgen/docgen.gpr.py +++ b/gramps/plugins/docgen/docgen.gpr.py @@ -39,6 +39,7 @@ plg.basedocclass = 'AsciiDoc' plg.paper = True plg.style = True plg.extension = "txt" +plg.options = True #------------------------------------------------------------------------ # @@ -59,6 +60,7 @@ plg.basedocclass = 'GtkPrint' plg.paper = True plg.style = True plg.extension = "" +plg.options = False #------------------------------------------------------------------------ # @@ -79,6 +81,7 @@ plg.basedocclass = 'HtmlDoc' plg.paper = False plg.style = True plg.extension = "html" +plg.options = False #------------------------------------------------------------------------ # @@ -99,6 +102,7 @@ plg.basedocclass = 'LaTeXDoc' plg.paper = True plg.style = False plg.extension = "tex" +plg.options = False #------------------------------------------------------------------------ # @@ -120,6 +124,7 @@ plg.basedocclass = 'ODFDoc' plg.paper = True plg.style = True plg.extension = "odt" +plg.options = False #------------------------------------------------------------------------ # @@ -140,6 +145,7 @@ plg.basedocclass = 'PdfDoc' plg.paper = True plg.style = True plg.extension = "pdf" +plg.options = False #------------------------------------------------------------------------ # @@ -160,6 +166,7 @@ plg.basedocclass = 'PSDrawDoc' plg.paper = True plg.style = True plg.extension = "ps" +plg.options = False #------------------------------------------------------------------------ # @@ -180,6 +187,7 @@ plg.basedocclass = 'RTFDoc' plg.paper = True plg.style = True plg.extension = "rtf" +plg.options = False #------------------------------------------------------------------------ # @@ -201,3 +209,4 @@ plg.basedocclass = 'SvgDrawDoc' plg.paper = True plg.style = True plg.extension = "svg" +plg.options = False