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