diff --git a/src/cli/plug/__init__.py b/src/cli/plug/__init__.py
index df43f2be7..dfc57e3f9 100644
--- a/src/cli/plug/__init__.py
+++ b/src/cli/plug/__init__.py
@@ -487,981 +487,3 @@ def run_report(db, name, **options_str_dict):
options_str_dict)
return clr
return clr
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2007 Donald N. Allingham
-# Copyright (C) 2008 Lukasz Rymarczyk
-# Copyright (C) 2008 Raphael Ackermann
-# Copyright (C) 2008 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-#
-# cli.plug.__init__
-#
-# $Id$
-
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-from gen.ggettext import gettext as _
-import traceback
-import os
-import sys
-
-import logging
-log = logging.getLogger(".")
-
-#-------------------------------------------------------------------------
-#
-# Gramps modules
-#
-#-------------------------------------------------------------------------
-import Utils
-from gen.plug import BasePluginManager
-from gen.plug.docgen import (StyleSheet, StyleSheetList, PaperStyle,
- PAPER_PORTRAIT, PAPER_LANDSCAPE)
-from gen.plug.menu import (FamilyOption, PersonOption, NoteOption,
- MediaOption, PersonListOption, NumberOption,
- BooleanOption, DestinationOption, StringOption,
- TextOption, EnumeratedListOption)
-from gen.display.name import displayer as name_displayer
-from Errors import ReportError
-from gen.plug.report import (CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK,
- CATEGORY_GRAPHVIZ, CATEGORY_CODE)
-from gen.plug.report._paper import paper_sizes
-import const
-import DbState
-from cli.grampscli import CLIManager
-
-#------------------------------------------------------------------------
-#
-# Private Functions
-#
-#------------------------------------------------------------------------
-def _validate_options(options, dbase):
- """
- Validate all options by making sure that their values are consistent with
- the database.
-
- menu: The Menu class
- dbase: the database the options will be applied to
- """
- if not hasattr(options, "menu"):
- print 'no menu'
- return
- menu = options.menu
-
- for name in menu.get_all_option_names():
- option = menu.get_option_by_name(name)
-
- if isinstance(option, PersonOption):
- pid = option.get_value()
- person = dbase.get_person_from_gramps_id(pid)
- if not person:
- person = dbase.get_default_person()
- if not person:
- phandle = dbase.iter_person_handles().next()
- person = dbase.get_person_from_handle(phandle)
- if not person:
- print "ERROR: Please specify a person"
- if person:
- option.set_value(person.get_gramps_id())
-
- elif isinstance(option, FamilyOption):
- fid = option.get_value()
- family = dbase.get_family_from_gramps_id(fid)
- if not family:
- person = dbase.get_default_person()
- family_list = []
- family_handle = None
- if person:
- family_list = person.get_family_handle_list()
- if family_list:
- family_handle = family_list[0]
- else:
- family_handle = dbase.iter_family_handles().next()
- if family_handle:
- family = dbase.get_family_from_handle(family_handle)
- option.set_value(family.get_gramps_id())
- else:
- print "ERROR: Please specify a family"
-
-#------------------------------------------------------------------------
-#
-# Command-line report
-#
-#------------------------------------------------------------------------
-class CommandLineReport(object):
- """
- Provide a way to generate report from the command line.
- """
-
- def __init__(self, database, name, category, option_class, options_str_dict,
- noopt=False):
-
- pmgr = BasePluginManager.get_instance()
- self.__textdoc_plugins = []
- self.__drawdoc_plugins = []
- self.__bookdoc_plugins = []
- for plugin in pmgr.get_docgen_plugins():
- if plugin.get_text_support() and plugin.get_extension():
- self.__textdoc_plugins.append(plugin)
- if plugin.get_draw_support() and plugin.get_extension():
- self.__drawdoc_plugins.append(plugin)
- if plugin.get_text_support() and \
- plugin.get_draw_support() and \
- plugin.get_extension():
- self.__bookdoc_plugins.append(plugin)
-
- self.database = database
- self.category = category
- self.format = None
- self.option_class = option_class(name, database)
- self.option_class.load_previous_values()
- _validate_options(self.option_class, database)
- self.show = options_str_dict.pop('show', None)
- self.options_str_dict = options_str_dict
- self.init_standard_options(noopt)
- self.init_report_options()
- self.parse_options()
- self.show_options()
-
- def init_standard_options(self, noopt):
- """
- Initialize the options that are hard-coded into the report system.
- """
- self.options_dict = {
- 'of' : self.option_class.handler.module_name,
- 'off' : self.option_class.handler.get_format_name(),
- 'style' : \
- self.option_class.handler.get_default_stylesheet_name(),
- 'papers' : self.option_class.handler.get_paper_name(),
- 'papero' : self.option_class.handler.get_orientation(),
- 'css' : self.option_class.handler.get_css_filename(),
- }
-
- self.options_help = {
- 'of' : ["=filename", "Output file name. MANDATORY", ""],
- 'off' : ["=format", "Output file format.", []],
- 'style' : ["=name", "Style name.", ""],
- 'papers' : ["=name", "Paper size name.", ""],
- 'papero' : ["=num", "Paper orientation number.", ""],
- 'css' : ["=css filename", "CSS filename to use, html format"
- " only", ""],
- }
-
- if noopt:
- return
-
- self.options_help['of'][2] = os.path.join(const.USER_HOME,
- "whatever_name")
-
- if self.category == CATEGORY_TEXT:
- for plugin in self.__textdoc_plugins:
- self.options_help['off'][2].append(
- plugin.get_extension() + "\t" + plugin.get_description() )
- elif self.category == CATEGORY_DRAW:
- for plugin in self.__drawdoc_plugins:
- self.options_help['off'][2].append(
- plugin.get_extension() + "\t" + plugin.get_description() )
- elif self.category == CATEGORY_BOOK:
- for plugin in self.__bookdoc_plugins:
- self.options_help['off'][2].append(
- plugin.get_extension() + "\t" + plugin.get_description() )
- else:
- self.options_help['off'][2] = "NA"
-
- self.options_help['papers'][2] = \
- [ paper.get_name() for paper in paper_sizes
- if paper.get_name() != _("Custom Size") ]
-
- self.options_help['papero'][2] = [
- "%d\tPortrait" % PAPER_PORTRAIT,
- "%d\tLandscape" % PAPER_LANDSCAPE ]
-
- self.options_help['css'][2] = os.path.join(const.USER_HOME,
- "whatever_name.css")
-
- if self.category in (CATEGORY_TEXT, CATEGORY_DRAW):
- default_style = StyleSheet()
- self.option_class.make_default_style(default_style)
-
- # Read all style sheets available for this item
- style_file = self.option_class.handler.get_stylesheet_savefile()
- self.style_list = StyleSheetList(style_file, default_style)
-
- self.options_help['style'][2] = self.style_list.get_style_names()
-
- def init_report_options(self):
- """
- Initialize the options that are defined by each report.
- """
- 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_dict[name] = option.get_value()
- self.options_help[name] = [ "", option.get_help() ]
-
- if isinstance(option, PersonOption):
- id_list = []
- for person_handle in self.database.get_person_handles():
- person = self.database.get_person_from_handle(person_handle)
- id_list.append("%s\t%s" % (
- person.get_gramps_id(),
- name_displayer.display(person)))
- self.options_help[name].append(id_list)
- elif isinstance(option, FamilyOption):
- id_list = []
- for family in self.database.iter_families():
- mname = ""
- fname = ""
- mhandle = family.get_mother_handle()
- if mhandle:
- mother = self.database.get_person_from_handle(mhandle)
- if mother:
- mname = name_displayer.display(mother)
- fhandle = family.get_father_handle()
- if fhandle:
- father = self.database.get_person_from_handle(fhandle)
- if father:
- fname = name_displayer.display(father)
- text = "%s:\t%s, %s" % \
- (family.get_gramps_id(), fname, mname)
- id_list.append(text)
- self.options_help[name].append(id_list)
- elif isinstance(option, NoteOption):
- id_list = []
- for nhandle in self.database.get_note_handles():
- note = self.database.get_note_from_handle(nhandle)
- id_list.append(note.get_gramps_id())
- self.options_help[name].append(id_list)
- elif isinstance(option, MediaOption):
- id_list = []
- for mhandle in self.database.get_media_object_handles():
- mobject = self.database.get_object_from_handle(mhandle)
- id_list.append(mobject.get_gramps_id())
- self.options_help[name].append(id_list)
- elif isinstance(option, PersonListOption):
- self.options_help[name].append("")
- elif isinstance(option, NumberOption):
- self.options_help[name].append("A number")
- elif isinstance(option, BooleanOption):
- self.options_help[name].append(["0\tno", "1\tyes"])
- elif isinstance(option, DestinationOption):
- self.options_help[name].append("A file system path")
- elif isinstance(option, StringOption):
- self.options_help[name].append("Any text")
- elif isinstance(option, TextOption):
- self.options_help[name].append("Any text")
- elif isinstance(option, EnumeratedListOption):
- ilist = []
- for (value, description) in option.get_items():
- ilist.append("%s\t%s" % (value, description))
- self.options_help[name].append(ilist)
- else:
- print "Unknown option: ", option
-
- def parse_options(self):
- """
- Load the options that the user has entered.
- """
- if not hasattr(self.option_class, "menu"):
- return
- 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:
- converter = Utils.get_type_converter(self.options_dict[opt])
- self.options_dict[opt] = converter(self.options_str_dict[opt])
- self.option_class.handler.options_dict[opt] = \
- self.options_dict[opt]
-
- if 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
-
- self.option_class.handler.output = self.options_dict['of']
-
- self.css_filename = 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']
- if self.format is None:
- # Pick the first one as the default.
- self.format = self.__textdoc_plugins[0].get_basedoc()
- 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()
- 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()
- else:
- self.format = None
-
- for paper in paper_sizes:
- if paper.get_name() == self.options_dict['papers']:
- self.paper = paper
- self.option_class.handler.set_paper(self.paper)
-
- self.orien = self.options_dict['papero']
-
- if self.category in (CATEGORY_TEXT, CATEGORY_DRAW):
- default_style = StyleSheet()
- self.option_class.make_default_style(default_style)
-
- # Read all style sheets available for this item
- style_file = self.option_class.handler.get_stylesheet_savefile()
- self.style_list = StyleSheetList(style_file, default_style)
-
- # Get the selected stylesheet
- style_name = self.option_class.handler.get_default_stylesheet_name()
- self.selected_style = self.style_list.get_style_sheet(style_name)
-
- def show_options(self):
- """
- Print available options on the CLI.
- """
- if not self.show:
- return
- elif self.show == 'all':
- print " Available options:"
- for key in self.options_dict:
- if key in self.options_help:
- opt = self.options_help[key]
- # Make the output nicer to read, assume that tab has 8 spaces
- tabs = '\t' if len(key) < 10 else '\t'*2
- print " %s%s%s (%s)" % (key, tabs, opt[1], opt[0])
- else:
- print " %s" % key
- print " Use 'show=option' to see description and acceptable values"
- elif self.show in self.options_help:
- opt = self.options_help[self.show]
- tabs = '\t' if len(self.show) < 10 else '\t'*2
- print ' %s%s%s%s' % (self.show, tabs, opt[0], opt[1])
- print " Available values are:"
- vals = opt[2]
- if isinstance(vals, (list, tuple)):
- for val in vals:
- print " %s" % val
- else:
- print " %s" % opt[2]
-
- else:
- #there was a show option given, but the option is invalid
- print ("option %s not valid. Use 'show=all' to see all valid "
- "options." % self.show)
-
-#------------------------------------------------------------------------
-#
-# Command-line report generic task
-#
-#------------------------------------------------------------------------
-def cl_report(database, name, category, report_class, options_class,
- options_str_dict):
-
- err_msg = _("Failed to write report. ")
- clr = CommandLineReport(database, name, category, options_class,
- options_str_dict)
-
- # Exit here if show option was given
- if clr.show:
- return
-
- # write report
- try:
- if category in [CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK, \
- CATEGORY_GRAPHVIZ]:
- clr.option_class.handler.doc = clr.format(
- clr.selected_style,
- PaperStyle(clr.paper,clr.orien))
- if clr.css_filename is not None and hasattr(clr.option_class.handler.doc, 'set_css_filename'):
- clr.option_class.handler.doc.set_css_filename(clr.css_filename)
- MyReport = report_class(database, clr.option_class)
- MyReport.doc.init()
- MyReport.begin_report()
- MyReport.write_report()
- MyReport.end_report()
- return clr
- except ReportError, msg:
- (m1, m2) = msg.messages()
- print err_msg
- print m1
- except:
- if len(log.handlers) > 0:
- log.error(err_msg, exc_info=True)
- else:
- print >> sys.stderr, err_msg
- ## Something seems to eat the exception above.
- ## Hack to re-get the exception:
- try:
- raise
- except:
- traceback.print_exc()
-
-def run_report(db, name, **options_str_dict):
- """
- Given a database, run a given report.
-
- db is a Db database
-
- name is the name of a report
-
- options_str_dict is the same kind of options
- given at the command line. For example:
-
- >>> run_report(db, "ancestor_report", off="txt",
- of="ancestor-007.txt", pid="I37")
-
- returns CommandLineReport (clr) if successfully runs the report,
- None otherwise.
-
- You can see:
- options and values used in clr.option_class.options_dict
- filename in clr.option_class.get_output()
- """
- dbstate = DbState.DbState()
- climanager = CLIManager(dbstate, False) # don't load db
- climanager.do_reg_plugins()
- pmgr = BasePluginManager.get_instance()
- cl_list = pmgr.get_reg_reports()
- clr = None
- for pdata in cl_list:
- if name == pdata.id:
- mod = pmgr.load_plugin(pdata)
- if not mod:
- #import of plugin failed
- return clr
- category = pdata.category
- report_class = getattr(mod, pdata.reportclass)
- options_class = getattr(mod, pdata.optionclass)
- if category in (CATEGORY_BOOK, CATEGORY_CODE):
- options_class(db, name, category,
- options_str_dict)
- else:
- clr = cl_report(db, name, category,
- report_class, options_class,
- options_str_dict)
- return clr
- return clr
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2007 Donald N. Allingham
-# Copyright (C) 2008 Lukasz Rymarczyk
-# Copyright (C) 2008 Raphael Ackermann
-# Copyright (C) 2008 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-#
-# cli.plug.__init__
-#
-# $Id$
-
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-from gen.ggettext import gettext as _
-import traceback
-import os
-import sys
-
-import logging
-log = logging.getLogger(".")
-
-#-------------------------------------------------------------------------
-#
-# Gramps modules
-#
-#-------------------------------------------------------------------------
-import Utils
-from gen.plug import BasePluginManager
-from gen.plug.docgen import (StyleSheet, StyleSheetList, PaperStyle,
- PAPER_PORTRAIT, PAPER_LANDSCAPE)
-from gen.plug.menu import (FamilyOption, PersonOption, NoteOption,
- MediaOption, PersonListOption, NumberOption,
- BooleanOption, DestinationOption, StringOption,
- TextOption, EnumeratedListOption)
-from gen.display.name import displayer as name_displayer
-from Errors import ReportError
-from gen.plug.report import (CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK,
- CATEGORY_GRAPHVIZ, CATEGORY_CODE)
-from gen.plug.report._paper import paper_sizes
-import const
-import DbState
-from cli.grampscli import CLIManager
-
-#------------------------------------------------------------------------
-#
-# Private Functions
-#
-#------------------------------------------------------------------------
-def _validate_options(options, dbase):
- """
- Validate all options by making sure that their values are consistent with
- the database.
-
- menu: The Menu class
- dbase: the database the options will be applied to
- """
- if not hasattr(options, "menu"):
- print 'no menu'
- return
- menu = options.menu
-
- for name in menu.get_all_option_names():
- option = menu.get_option_by_name(name)
-
- if isinstance(option, PersonOption):
- pid = option.get_value()
- person = dbase.get_person_from_gramps_id(pid)
- if not person:
- person = dbase.get_default_person()
- if not person:
- phandle = dbase.iter_person_handles().next()
- person = dbase.get_person_from_handle(phandle)
- if not person:
- print "ERROR: Please specify a person"
- if person:
- option.set_value(person.get_gramps_id())
-
- elif isinstance(option, FamilyOption):
- fid = option.get_value()
- family = dbase.get_family_from_gramps_id(fid)
- if not family:
- person = dbase.get_default_person()
- family_list = []
- family_handle = None
- if person:
- family_list = person.get_family_handle_list()
- if family_list:
- family_handle = family_list[0]
- else:
- family_handle = dbase.iter_family_handles().next()
- if family_handle:
- family = dbase.get_family_from_handle(family_handle)
- option.set_value(family.get_gramps_id())
- else:
- print "ERROR: Please specify a family"
-
-#------------------------------------------------------------------------
-#
-# Command-line report
-#
-#------------------------------------------------------------------------
-class CommandLineReport(object):
- """
- Provide a way to generate report from the command line.
- """
-
- def __init__(self, database, name, category, option_class, options_str_dict,
- noopt=False):
-
- pmgr = BasePluginManager.get_instance()
- self.__textdoc_plugins = []
- self.__drawdoc_plugins = []
- self.__bookdoc_plugins = []
- for plugin in pmgr.get_docgen_plugins():
- if plugin.get_text_support() and plugin.get_extension():
- self.__textdoc_plugins.append(plugin)
- if plugin.get_draw_support() and plugin.get_extension():
- self.__drawdoc_plugins.append(plugin)
- if plugin.get_text_support() and \
- plugin.get_draw_support() and \
- plugin.get_extension():
- self.__bookdoc_plugins.append(plugin)
-
- self.database = database
- self.category = category
- self.format = None
- self.option_class = option_class(name, database)
- self.option_class.load_previous_values()
- _validate_options(self.option_class, database)
- self.show = options_str_dict.pop('show', None)
- self.options_str_dict = options_str_dict
- self.init_standard_options(noopt)
- self.init_report_options()
- self.parse_options()
- self.show_options()
-
- def init_standard_options(self, noopt):
- """
- Initialize the options that are hard-coded into the report system.
- """
- self.options_dict = {
- 'of' : self.option_class.handler.module_name,
- 'off' : self.option_class.handler.get_format_name(),
- 'style' : \
- self.option_class.handler.get_default_stylesheet_name(),
- 'papers' : self.option_class.handler.get_paper_name(),
- 'papero' : self.option_class.handler.get_orientation(),
- 'css' : self.option_class.handler.get_css_filename(),
- }
-
- self.options_help = {
- 'of' : ["=filename", "Output file name. MANDATORY", ""],
- 'off' : ["=format", "Output file format.", []],
- 'style' : ["=name", "Style name.", ""],
- 'papers' : ["=name", "Paper size name.", ""],
- 'papero' : ["=num", "Paper orientation number.", ""],
- 'css' : ["=css filename", "CSS filename to use, html format"
- " only", ""],
- }
-
- if noopt:
- return
-
- self.options_help['of'][2] = os.path.join(const.USER_HOME,
- "whatever_name")
-
- if self.category == CATEGORY_TEXT:
- for plugin in self.__textdoc_plugins:
- self.options_help['off'][2].append(
- plugin.get_extension() + "\t" + plugin.get_description() )
- elif self.category == CATEGORY_DRAW:
- for plugin in self.__drawdoc_plugins:
- self.options_help['off'][2].append(
- plugin.get_extension() + "\t" + plugin.get_description() )
- elif self.category == CATEGORY_BOOK:
- for plugin in self.__bookdoc_plugins:
- self.options_help['off'][2].append(
- plugin.get_extension() + "\t" + plugin.get_description() )
- else:
- self.options_help['off'][2] = "NA"
-
- self.options_help['papers'][2] = \
- [ paper.get_name() for paper in paper_sizes
- if paper.get_name() != _("Custom Size") ]
-
- self.options_help['papero'][2] = [
- "%d\tPortrait" % PAPER_PORTRAIT,
- "%d\tLandscape" % PAPER_LANDSCAPE ]
-
- self.options_help['css'][2] = os.path.join(const.USER_HOME,
- "whatever_name.css")
-
- if self.category in (CATEGORY_TEXT, CATEGORY_DRAW):
- default_style = StyleSheet()
- self.option_class.make_default_style(default_style)
-
- # Read all style sheets available for this item
- style_file = self.option_class.handler.get_stylesheet_savefile()
- self.style_list = StyleSheetList(style_file, default_style)
-
- self.options_help['style'][2] = self.style_list.get_style_names()
-
- def init_report_options(self):
- """
- Initialize the options that are defined by each report.
- """
- 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_dict[name] = option.get_value()
- self.options_help[name] = [ "", option.get_help() ]
-
- if isinstance(option, PersonOption):
- id_list = []
- for person_handle in self.database.get_person_handles():
- person = self.database.get_person_from_handle(person_handle)
- id_list.append("%s\t%s" % (
- person.get_gramps_id(),
- name_displayer.display(person)))
- self.options_help[name].append(id_list)
- elif isinstance(option, FamilyOption):
- id_list = []
- for family in self.database.iter_families():
- mname = ""
- fname = ""
- mhandle = family.get_mother_handle()
- if mhandle:
- mother = self.database.get_person_from_handle(mhandle)
- if mother:
- mname = name_displayer.display(mother)
- fhandle = family.get_father_handle()
- if fhandle:
- father = self.database.get_person_from_handle(fhandle)
- if father:
- fname = name_displayer.display(father)
- text = "%s:\t%s, %s" % \
- (family.get_gramps_id(), fname, mname)
- id_list.append(text)
- self.options_help[name].append(id_list)
- elif isinstance(option, NoteOption):
- id_list = []
- for nhandle in self.database.get_note_handles():
- note = self.database.get_note_from_handle(nhandle)
- id_list.append(note.get_gramps_id())
- self.options_help[name].append(id_list)
- elif isinstance(option, MediaOption):
- id_list = []
- for mhandle in self.database.get_media_object_handles():
- mobject = self.database.get_object_from_handle(mhandle)
- id_list.append(mobject.get_gramps_id())
- self.options_help[name].append(id_list)
- elif isinstance(option, PersonListOption):
- self.options_help[name].append("")
- elif isinstance(option, NumberOption):
- self.options_help[name].append("A number")
- elif isinstance(option, BooleanOption):
- self.options_help[name].append(["0\tno", "1\tyes"])
- elif isinstance(option, DestinationOption):
- self.options_help[name].append("A file system path")
- elif isinstance(option, StringOption):
- self.options_help[name].append("Any text")
- elif isinstance(option, TextOption):
- self.options_help[name].append("Any text")
- elif isinstance(option, EnumeratedListOption):
- ilist = []
- for (value, description) in option.get_items():
- ilist.append("%s\t%s" % (value, description))
- self.options_help[name].append(ilist)
- else:
- print "Unknown option: ", option
-
- def parse_options(self):
- """
- Load the options that the user has entered.
- """
- if not hasattr(self.option_class, "menu"):
- return
- 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:
- converter = Utils.get_type_converter(self.options_dict[opt])
- self.options_dict[opt] = converter(self.options_str_dict[opt])
- self.option_class.handler.options_dict[opt] = \
- self.options_dict[opt]
-
- if 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
-
- self.option_class.handler.output = self.options_dict['of']
-
- self.css_filename = 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']
- if self.format is None:
- # Pick the first one as the default.
- self.format = self.__textdoc_plugins[0].get_basedoc()
- 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()
- 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()
- else:
- self.format = None
-
- for paper in paper_sizes:
- if paper.get_name() == self.options_dict['papers']:
- self.paper = paper
- self.option_class.handler.set_paper(self.paper)
-
- self.orien = self.options_dict['papero']
-
- if self.category in (CATEGORY_TEXT, CATEGORY_DRAW):
- default_style = StyleSheet()
- self.option_class.make_default_style(default_style)
-
- # Read all style sheets available for this item
- style_file = self.option_class.handler.get_stylesheet_savefile()
- self.style_list = StyleSheetList(style_file, default_style)
-
- # Get the selected stylesheet
- style_name = self.option_class.handler.get_default_stylesheet_name()
- self.selected_style = self.style_list.get_style_sheet(style_name)
-
- def show_options(self):
- """
- Print available options on the CLI.
- """
- if not self.show:
- return
- elif self.show == 'all':
- print " Available options:"
- for key in self.options_dict:
- if key in self.options_help:
- opt = self.options_help[key]
- # Make the output nicer to read, assume that tab has 8 spaces
- tabs = '\t' if len(key) < 10 else '\t'*2
- print " %s%s%s (%s)" % (key, tabs, opt[1], opt[0])
- else:
- print " %s" % key
- print " Use 'show=option' to see description and acceptable values"
- elif self.show in self.options_help:
- opt = self.options_help[self.show]
- tabs = '\t' if len(self.show) < 10 else '\t'*2
- print ' %s%s%s%s' % (self.show, tabs, opt[0], opt[1])
- print " Available values are:"
- vals = opt[2]
- if isinstance(vals, (list, tuple)):
- for val in vals:
- print " %s" % val
- else:
- print " %s" % opt[2]
-
- else:
- #there was a show option given, but the option is invalid
- print ("option %s not valid. Use 'show=all' to see all valid "
- "options." % self.show)
-
-#------------------------------------------------------------------------
-#
-# Command-line report generic task
-#
-#------------------------------------------------------------------------
-def cl_report(database, name, category, report_class, options_class,
- options_str_dict):
-
- err_msg = _("Failed to write report. ")
- clr = CommandLineReport(database, name, category, options_class,
- options_str_dict)
-
- # Exit here if show option was given
- if clr.show:
- return
-
- # write report
- try:
- if category in [CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK, \
- CATEGORY_GRAPHVIZ]:
- clr.option_class.handler.doc = clr.format(
- clr.selected_style,
- PaperStyle(clr.paper,clr.orien))
- if clr.css_filename is not None and hasattr(clr.option_class.handler.doc, 'set_css_filename'):
- clr.option_class.handler.doc.set_css_filename(clr.css_filename)
- MyReport = report_class(database, clr.option_class)
- MyReport.doc.init()
- MyReport.begin_report()
- MyReport.write_report()
- MyReport.end_report()
- return clr
- except ReportError, msg:
- (m1, m2) = msg.messages()
- print err_msg
- print m1
- except:
- if len(log.handlers) > 0:
- log.error(err_msg, exc_info=True)
- else:
- print >> sys.stderr, err_msg
- ## Something seems to eat the exception above.
- ## Hack to re-get the exception:
- try:
- raise
- except:
- traceback.print_exc()
-
-def run_report(db, name, **options_str_dict):
- """
- Given a database, run a given report.
-
- db is a Db database
-
- name is the name of a report
-
- options_str_dict is the same kind of options
- given at the command line. For example:
-
- >>> run_report(db, "ancestor_report", off="txt",
- of="ancestor-007.txt", pid="I37")
-
- returns CommandLineReport (clr) if successfully runs the report,
- None otherwise.
-
- You can see:
- options and values used in clr.option_class.options_dict
- filename in clr.option_class.get_output()
- """
- dbstate = DbState.DbState()
- climanager = CLIManager(dbstate, False) # don't load db
- climanager.do_reg_plugins()
- pmgr = BasePluginManager.get_instance()
- cl_list = pmgr.get_reg_reports()
- clr = None
- for pdata in cl_list:
- if name == pdata.id:
- mod = pmgr.load_plugin(pdata)
- if not mod:
- #import of plugin failed
- return clr
- category = pdata.category
- report_class = getattr(mod, pdata.reportclass)
- options_class = getattr(mod, pdata.optionclass)
- if category in (CATEGORY_BOOK, CATEGORY_CODE):
- options_class(db, name, category,
- options_str_dict)
- else:
- clr = cl_report(db, name, category,
- report_class, options_class,
- options_str_dict)
- return clr
- return clr
diff --git a/src/gen/plug/_options.py b/src/gen/plug/_options.py
index 495e026a2..eedd9e1de 100644
--- a/src/gen/plug/_options.py
+++ b/src/gen/plug/_options.py
@@ -475,957 +475,3 @@ class Options(object):
in the add_user_options() method above.
"""
pass
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2004-2005 Donald N. Allingham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id:_Options.py 9912 2008-01-22 09:17:46Z acraphae $
-
-# Written by Alex Roitman
-
-"""
-General option handling, including saving and parsing.
-"""
-
-#-------------------------------------------------------------------------
-#
-# Standard Python modules
-#
-#-------------------------------------------------------------------------
-import os
-
-#-------------------------------------------------------------------------
-#
-# SAX interface
-#
-#-------------------------------------------------------------------------
-try:
- from xml.sax import make_parser, handler,SAXParseException
- from xml.sax.saxutils import quoteattr
-except:
- from _xmlplus.sax import make_parser, handler,SAXParseException
- from _xmlplus.sax.saxutils import quoteattr
-
-#-------------------------------------------------------------------------
-#
-# gramps modules
-#
-#-------------------------------------------------------------------------
-import Utils
-
-#-------------------------------------------------------------------------
-#
-# List of options for a single module
-#
-#-------------------------------------------------------------------------
-class OptionList(object):
- """
- Implements a set of options to parse and store for a given module.
- """
-
- def __init__(self):
- self.options = {}
-
- def set_options(self, options):
- """
- Set the whole bunch of options for the OptionList.
- @param options: list of options to set.
- @type options: list
- """
- self.options = options
-
- def get_options(self):
- """
- Return the whole bunch of options for the OptionList.
- @returns: list of options
- @rtype: list
- """
- return self.options
-
- def set_option(self, name,value):
- """
- Set a particular option in the OptionList.
- @param name: name of the option to set.
- @type name: str
- @param value: value of the option to set.
- @type str
- """
- self.options[name] = value
-
- def remove_option(self, name):
- """
- Remove a particular option from the OptionList.
- @param name: name of the option to remove.
- @type name: str
- """
- if name in self.options:
- del self.options[name]
-
- def get_option(self, name):
- """
- Return the value of a particular option in the OptionList.
- @param name: name of the option to retrieve
- @type name: str
- @returns: value associated with the passed option
- @rtype: str
- """
- return self.options.get(name,None)
-
-#-------------------------------------------------------------------------
-#
-# Collection of option lists
-#
-#-------------------------------------------------------------------------
-class OptionListCollection(object):
- """
- Implements a collection of option lists.
- """
-
- def __init__(self,filename):
- """
- Create an OptionListCollection instance from the list defined
- in the specified file.
- @param filename: XML file that contains option definitions
- @type filename: str
- """
-
- self.filename = os.path.expanduser(filename)
- self.option_list_map = {}
- self.init_common()
- self.parse()
-
- def init_common(self):
- pass
-
- def get_option_list_map(self):
- """
- Return the map of module names to option lists.
- @returns: Returns the map of module names to option lists.
- @rtype: dictionary
- """
- return self.option_list_map
-
- def get_option_list(self, name):
- """
- Return the option_list associated with the module name
- @param name: name associated with the desired module.
- @type name: str
- @returns: returns the option list associated with the name,
- or None of no such option exists
- @rtype: str
- """
- return self.option_list_map.get(name,None)
-
- def get_module_names(self):
- """
- Return a list of all the module names in the OptionListCollection
- @returns: returns the list of module names
- @rtype: list
- """
- return self.option_list_map.keys()
-
- def set_option_list(self, name, option_list):
- """
- Add or replaces an option_list in the OptionListCollection.
- @param name: name associated with the module to add or replace.
- @type name: str
- @param option_list: list of options
- @type option_list: str
- """
- self.option_list_map[name] = option_list
-
- def write_common(self,f):
- """
- Stub function for common options. Overridden by reports.
- """
- pass
-
- def write_module_common(self,f, option_list):
- """
- Stub function for common options. Overridden by reports.
- """
- pass
-
- def save(self):
- """
- Saves the current OptionListCollection to the associated file.
- """
- f = open(self.filename,"w")
- f.write("\n")
- f.write('\n')
-
- self.write_common(f)
-
- for module_name in self.get_module_names():
- option_list = self.get_option_list(module_name)
- f.write('\n' % quoteattr(module_name))
- options = option_list.get_options()
- for option_name, option_data in options.iteritems():
- if isinstance(option_data, (list, tuple)):
- f.write(' \n')
- else:
- f.write(' \n')
-
- f.write('\n')
- f.close()
-
- 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(OptionParser(self))
- p.parse(self.filename)
- except (IOError,OSError,SAXParseException):
- pass
-
-#-------------------------------------------------------------------------
-#
-# OptionParser
-#
-#-------------------------------------------------------------------------
-class OptionParser(handler.ContentHandler):
- """
- SAX parsing class for the OptionListCollection XML file.
- """
-
- def __init__(self,collection):
- """
- Create a OptionParser class that populates the passed collection.
-
- collection: OptionListCollection to be loaded from the file.
- """
- handler.ContentHandler.__init__(self)
- self.collection = collection
-
- self.mname = None
- self.option_list = None
- self.oname = None
- self.o = None
- self.an_o = None
- self.list_class = OptionList
-
- def startElement(self,tag,attrs):
- """
- Overridden class that handles the start of a XML element
- """
- if tag in ("report","module"):
- self.mname = attrs['name']
- self.option_list = self.list_class()
- self.o = {}
- elif tag == "option":
- self.oname = attrs['name']
- if attrs.has_key('length'):
- self.an_o = []
- else:
- self.an_o = attrs['value']
- elif tag == "listitem":
- self.an_o.append(attrs['value'])
-
- def endElement(self,tag):
- "Overridden class that handles the end of a XML element"
- if tag == "option":
- self.o[self.oname] = self.an_o
- elif tag in ("report","module"):
- self.option_list.set_options(self.o)
- self.collection.set_option_list(self.mname,self.option_list)
-
-#-------------------------------------------------------------------------
-#
-# Class handling options for plugins
-#
-#-------------------------------------------------------------------------
-class OptionHandler(object):
- """
- Implements handling of the options for the plugins.
- """
-
- def __init__(self,module_name, options_dict,person_id=None):
- self.module_name = module_name
- self.default_options_dict = options_dict.copy()
- self.options_dict = options_dict
-
- # Retrieve our options from whole collection
- self.init_subclass()
- self.option_list_collection = self.collection_class(self.filename)
- self.init_common()
- self.saved_option_list = self.option_list_collection.get_option_list(module_name)
- self.person_id = person_id
-
- # Whatever was found should override the defaults
- if self.saved_option_list:
- self.set_options()
- else:
- # If nothing was found, set up the option list
- self.saved_option_list = self.list_class()
- self.option_list_collection.set_option_list(module_name,
- self.saved_option_list)
-
- def init_subclass(self):
- self.collection_class = OptionListCollection
- self.list_class = OptionList
- self.filename = None
-
- def init_common(self):
- pass
-
- 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()
- bad_opts = []
- for option_name, option_data in options.iteritems():
- if option_name not in self.options_dict:
- print "Option %s is present in the %s but is not known "\
- "to the module." % (option_name,
- self.option_list_collection.filename)
- print "Ignoring..."
- bad_opts.append(option_name)
- continue
- try:
- converter = Utils.get_type_converter(self.options_dict[option_name])
- self.options_dict[option_name] = converter(option_data)
- except ValueError:
- pass
- except TypeError:
- pass
-
- for option_name in bad_opts:
- options.pop(option_name)
-
- # Then we set common options from whatever was found
- self.set_common_options()
-
- def set_common_options(self):
- pass
-
- def save_options(self):
- """
- Saves options to file.
-
- We need to only store non-default options. Therefore, we remove all
- options whose values are the defaults prior to saving.
- """
-
- # First we save options from options_dict
- for option_name, option_data in self.options_dict.iteritems():
- if option_data == self.default_options_dict[option_name]:
- self.saved_option_list.remove_option(option_name)
- else:
- self.saved_option_list.set_option(option_name,self.options_dict[option_name])
-
- # Handle common options
- self.save_common_options()
-
- # Finally, save the whole collection into file
- self.option_list_collection.save()
-
- def save_common_options(self):
- pass
-
- def get_person_id(self):
- return self.person_id
-
- def set_person_id(self,val):
- self.person_id = val
-
-#------------------------------------------------------------------------
-#
-# Base Options class
-#
-#------------------------------------------------------------------------
-class Options(object):
-
- """
- Defines options and provides handling interface.
-
- This is a base Options class for the modules. All modules, options
- classes should derive from it.
- """
-
- def __init__(self, name,person_id=None):
- """
- Initialize the class, performing usual house-keeping tasks.
- Subclasses MUST call this in their __init__() method.
-
- Modules that need custom options need to override this method.
- Two dictionaries allow the addition of custom options:
-
- self.options_dict
- This is a dictionary whose keys are option names
- and values are the default option values.
-
- self.options_help
- This is a dictionary whose keys are option names
- and values are 3- or 4- lists or tuples:
- ('=example','Short description',VALUES,DO_PREPEND)
- The VALUES is either a single string (in that case
- the DO_PREPEND does not matter) or a list/tuple of
- strings to list. In that case, if DO_PREPEND evaluates
- as True then each string will be preneded with the ordinal
- number when help is printed on the command line.
-
- NOTE: Both dictionaries must have identical keys.
- """
- self.name = name
- self.person_id = person_id
- self.options_dict = {}
- self.options_help = {}
- self.handler = None
-
- def load_previous_values(self):
- """
- Modifies all options to have the value they were last used as. Call this
- function after all options have been added.
- """
- self.handler = OptionHandler(self.name,self.options_dict,self.person_id)
-
- def add_user_options(self,dialog):
- """
- Set up UI controls (widgets) for the options specific for this modul.
-
- This method MUST be overridden by modules that define new options.
- The single argument 'dialog' is the Report.ReportDialog instance.
- Any attribute of the dialog is available.
-
- After the widgets are defined, they MUST be added to the dialog
- using the following call:
- dialog.add_options(LABEL,widget)
-
- NOTE: To really have any effect besides looking pretty, each widget
- set up here must be also parsed in the parse_user_options()
- method below.
- """
- pass
-
- def parse_user_options(self,dialog):
- """
- Parses UI controls (widgets) for the options specific for this module.
-
- This method MUST be overridden by modules that define new options.
- The single argument 'dialog' is the Report.ReportDialog instance.
- Any attribute of the dialog is available.
-
- After obtaining values from the widgets, they MUST be used to set the
- appropriate options_dict values. Otherwise the values will not have
- any user-visible effect.
-
- NOTE: Any widget parsed here MUST be defined and added to the dialog
- in the add_user_options() method above.
- """
- pass
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2004-2005 Donald N. Allingham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id:_Options.py 9912 2008-01-22 09:17:46Z acraphae $
-
-# Written by Alex Roitman
-
-"""
-General option handling, including saving and parsing.
-"""
-
-#-------------------------------------------------------------------------
-#
-# Standard Python modules
-#
-#-------------------------------------------------------------------------
-import os
-
-#-------------------------------------------------------------------------
-#
-# SAX interface
-#
-#-------------------------------------------------------------------------
-try:
- from xml.sax import make_parser, handler,SAXParseException
- from xml.sax.saxutils import quoteattr
-except:
- from _xmlplus.sax import make_parser, handler,SAXParseException
- from _xmlplus.sax.saxutils import quoteattr
-
-#-------------------------------------------------------------------------
-#
-# gramps modules
-#
-#-------------------------------------------------------------------------
-import Utils
-
-#-------------------------------------------------------------------------
-#
-# List of options for a single module
-#
-#-------------------------------------------------------------------------
-class OptionList(object):
- """
- Implements a set of options to parse and store for a given module.
- """
-
- def __init__(self):
- self.options = {}
-
- def set_options(self, options):
- """
- Set the whole bunch of options for the OptionList.
- @param options: list of options to set.
- @type options: list
- """
- self.options = options
-
- def get_options(self):
- """
- Return the whole bunch of options for the OptionList.
- @returns: list of options
- @rtype: list
- """
- return self.options
-
- def set_option(self, name,value):
- """
- Set a particular option in the OptionList.
- @param name: name of the option to set.
- @type name: str
- @param value: value of the option to set.
- @type str
- """
- self.options[name] = value
-
- def remove_option(self, name):
- """
- Remove a particular option from the OptionList.
- @param name: name of the option to remove.
- @type name: str
- """
- if name in self.options:
- del self.options[name]
-
- def get_option(self, name):
- """
- Return the value of a particular option in the OptionList.
- @param name: name of the option to retrieve
- @type name: str
- @returns: value associated with the passed option
- @rtype: str
- """
- return self.options.get(name,None)
-
-#-------------------------------------------------------------------------
-#
-# Collection of option lists
-#
-#-------------------------------------------------------------------------
-class OptionListCollection(object):
- """
- Implements a collection of option lists.
- """
-
- def __init__(self,filename):
- """
- Create an OptionListCollection instance from the list defined
- in the specified file.
- @param filename: XML file that contains option definitions
- @type filename: str
- """
-
- self.filename = os.path.expanduser(filename)
- self.option_list_map = {}
- self.init_common()
- self.parse()
-
- def init_common(self):
- pass
-
- def get_option_list_map(self):
- """
- Return the map of module names to option lists.
- @returns: Returns the map of module names to option lists.
- @rtype: dictionary
- """
- return self.option_list_map
-
- def get_option_list(self, name):
- """
- Return the option_list associated with the module name
- @param name: name associated with the desired module.
- @type name: str
- @returns: returns the option list associated with the name,
- or None of no such option exists
- @rtype: str
- """
- return self.option_list_map.get(name,None)
-
- def get_module_names(self):
- """
- Return a list of all the module names in the OptionListCollection
- @returns: returns the list of module names
- @rtype: list
- """
- return self.option_list_map.keys()
-
- def set_option_list(self, name, option_list):
- """
- Add or replaces an option_list in the OptionListCollection.
- @param name: name associated with the module to add or replace.
- @type name: str
- @param option_list: list of options
- @type option_list: str
- """
- self.option_list_map[name] = option_list
-
- def write_common(self,f):
- """
- Stub function for common options. Overridden by reports.
- """
- pass
-
- def write_module_common(self,f, option_list):
- """
- Stub function for common options. Overridden by reports.
- """
- pass
-
- def save(self):
- """
- Saves the current OptionListCollection to the associated file.
- """
- f = open(self.filename,"w")
- f.write("\n")
- f.write('\n')
-
- self.write_common(f)
-
- for module_name in self.get_module_names():
- option_list = self.get_option_list(module_name)
- f.write('\n' % quoteattr(module_name))
- options = option_list.get_options()
- for option_name, option_data in options.iteritems():
- if isinstance(option_data, (list, tuple)):
- f.write(' \n')
- else:
- f.write(' \n')
-
- f.write('\n')
- f.close()
-
- 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(OptionParser(self))
- p.parse(self.filename)
- except (IOError,OSError,SAXParseException):
- pass
-
-#-------------------------------------------------------------------------
-#
-# OptionParser
-#
-#-------------------------------------------------------------------------
-class OptionParser(handler.ContentHandler):
- """
- SAX parsing class for the OptionListCollection XML file.
- """
-
- def __init__(self,collection):
- """
- Create a OptionParser class that populates the passed collection.
-
- collection: OptionListCollection to be loaded from the file.
- """
- handler.ContentHandler.__init__(self)
- self.collection = collection
-
- self.mname = None
- self.option_list = None
- self.oname = None
- self.o = None
- self.an_o = None
- self.list_class = OptionList
-
- def startElement(self,tag,attrs):
- """
- Overridden class that handles the start of a XML element
- """
- if tag in ("report","module"):
- self.mname = attrs['name']
- self.option_list = self.list_class()
- self.o = {}
- elif tag == "option":
- self.oname = attrs['name']
- if attrs.has_key('length'):
- self.an_o = []
- else:
- self.an_o = attrs['value']
- elif tag == "listitem":
- self.an_o.append(attrs['value'])
-
- def endElement(self,tag):
- "Overridden class that handles the end of a XML element"
- if tag == "option":
- self.o[self.oname] = self.an_o
- elif tag in ("report","module"):
- self.option_list.set_options(self.o)
- self.collection.set_option_list(self.mname,self.option_list)
-
-#-------------------------------------------------------------------------
-#
-# Class handling options for plugins
-#
-#-------------------------------------------------------------------------
-class OptionHandler(object):
- """
- Implements handling of the options for the plugins.
- """
-
- def __init__(self,module_name, options_dict,person_id=None):
- self.module_name = module_name
- self.default_options_dict = options_dict.copy()
- self.options_dict = options_dict
-
- # Retrieve our options from whole collection
- self.init_subclass()
- self.option_list_collection = self.collection_class(self.filename)
- self.init_common()
- self.saved_option_list = self.option_list_collection.get_option_list(module_name)
- self.person_id = person_id
-
- # Whatever was found should override the defaults
- if self.saved_option_list:
- self.set_options()
- else:
- # If nothing was found, set up the option list
- self.saved_option_list = self.list_class()
- self.option_list_collection.set_option_list(module_name,
- self.saved_option_list)
-
- def init_subclass(self):
- self.collection_class = OptionListCollection
- self.list_class = OptionList
- self.filename = None
-
- def init_common(self):
- pass
-
- 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()
- bad_opts = []
- for option_name, option_data in options.iteritems():
- if option_name not in self.options_dict:
- print "Option %s is present in the %s but is not known "\
- "to the module." % (option_name,
- self.option_list_collection.filename)
- print "Ignoring..."
- bad_opts.append(option_name)
- continue
- try:
- converter = Utils.get_type_converter(self.options_dict[option_name])
- self.options_dict[option_name] = converter(option_data)
- except ValueError:
- pass
- except TypeError:
- pass
-
- for option_name in bad_opts:
- options.pop(option_name)
-
- # Then we set common options from whatever was found
- self.set_common_options()
-
- def set_common_options(self):
- pass
-
- def save_options(self):
- """
- Saves options to file.
-
- We need to only store non-default options. Therefore, we remove all
- options whose values are the defaults prior to saving.
- """
-
- # First we save options from options_dict
- for option_name, option_data in self.options_dict.iteritems():
- if option_data == self.default_options_dict[option_name]:
- self.saved_option_list.remove_option(option_name)
- else:
- self.saved_option_list.set_option(option_name,self.options_dict[option_name])
-
- # Handle common options
- self.save_common_options()
-
- # Finally, save the whole collection into file
- self.option_list_collection.save()
-
- def save_common_options(self):
- pass
-
- def get_person_id(self):
- return self.person_id
-
- def set_person_id(self,val):
- self.person_id = val
-
-#------------------------------------------------------------------------
-#
-# Base Options class
-#
-#------------------------------------------------------------------------
-class Options(object):
-
- """
- Defines options and provides handling interface.
-
- This is a base Options class for the modules. All modules, options
- classes should derive from it.
- """
-
- def __init__(self, name,person_id=None):
- """
- Initialize the class, performing usual house-keeping tasks.
- Subclasses MUST call this in their __init__() method.
-
- Modules that need custom options need to override this method.
- Two dictionaries allow the addition of custom options:
-
- self.options_dict
- This is a dictionary whose keys are option names
- and values are the default option values.
-
- self.options_help
- This is a dictionary whose keys are option names
- and values are 3- or 4- lists or tuples:
- ('=example','Short description',VALUES,DO_PREPEND)
- The VALUES is either a single string (in that case
- the DO_PREPEND does not matter) or a list/tuple of
- strings to list. In that case, if DO_PREPEND evaluates
- as True then each string will be preneded with the ordinal
- number when help is printed on the command line.
-
- NOTE: Both dictionaries must have identical keys.
- """
- self.name = name
- self.person_id = person_id
- self.options_dict = {}
- self.options_help = {}
- self.handler = None
-
- def load_previous_values(self):
- """
- Modifies all options to have the value they were last used as. Call this
- function after all options have been added.
- """
- self.handler = OptionHandler(self.name,self.options_dict,self.person_id)
-
- def add_user_options(self,dialog):
- """
- Set up UI controls (widgets) for the options specific for this modul.
-
- This method MUST be overridden by modules that define new options.
- The single argument 'dialog' is the Report.ReportDialog instance.
- Any attribute of the dialog is available.
-
- After the widgets are defined, they MUST be added to the dialog
- using the following call:
- dialog.add_options(LABEL,widget)
-
- NOTE: To really have any effect besides looking pretty, each widget
- set up here must be also parsed in the parse_user_options()
- method below.
- """
- pass
-
- def parse_user_options(self,dialog):
- """
- Parses UI controls (widgets) for the options specific for this module.
-
- This method MUST be overridden by modules that define new options.
- The single argument 'dialog' is the Report.ReportDialog instance.
- Any attribute of the dialog is available.
-
- After obtaining values from the widgets, they MUST be used to set the
- appropriate options_dict values. Otherwise the values will not have
- any user-visible effect.
-
- NOTE: Any widget parsed here MUST be defined and added to the dialog
- in the add_user_options() method above.
- """
- pass
diff --git a/src/gen/plug/report/__init__.py b/src/gen/plug/report/__init__.py
index dd05749cc..5404f74df 100644
--- a/src/gen/plug/report/__init__.py
+++ b/src/gen/plug/report/__init__.py
@@ -32,71 +32,3 @@ from _reportbase import Report
from _bibliography import Bibliography, Citation
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001 David R. Hampton
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2007 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# gen.plug.report.__init__
-#
-# $Id: __init__.py 12360 2009-03-19 02:32:16Z pez4brian $
-
-"Report Generation Framework"
-
-from _constants import *
-from _reportbase import Report
-
-from _bibliography import Bibliography, Citation
-
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001 David R. Hampton
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2007 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# gen.plug.report.__init__
-#
-# $Id: __init__.py 12360 2009-03-19 02:32:16Z pez4brian $
-
-"Report Generation Framework"
-
-from _constants import *
-from _reportbase import Report
-
-from _bibliography import Bibliography, Citation
-
diff --git a/src/gen/plug/report/_bibliography.py b/src/gen/plug/report/_bibliography.py
index 6bf37aecb..121cc2b72 100644
--- a/src/gen/plug/report/_bibliography.py
+++ b/src/gen/plug/report/_bibliography.py
@@ -241,489 +241,3 @@ class Bibliography(object):
return False
# Can't find anything different. They must be equal.
return True
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2007 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id: _Bibliography.py 13191 2009-09-10 18:49:48Z gbritton $
-
-"""
-Contain and organize bibliographic information.
-"""
-import string
-import math
-from gen.lib import SourceRef
-
-class Citation(object):
- """
- Store information about a citation and all of its references.
- """
- def __init__(self):
- """
- Initialize members.
- """
- self.__src_handle = None
- self.__ref_list = []
-
- def get_source_handle(self):
- """
- Provide the handle to the source that this citation is for.
-
- @return: Source Handle
- @rtype: handle
- """
- return self.__src_handle
-
- def set_source_handle(self, handle):
- """
- Set the handle for the source that this citation is for.
-
- @param handle: Source Handle
- @type handle: handle
- """
- self.__src_handle = handle
-
- def get_ref_list(self):
- """
- List all the references to this citation.
-
- @return: a list of references
- @rtype: list of L{gen.lib.srcref} objects
- """
- return self.__ref_list
-
- def add_reference(self, source_ref):
- """
- Add a reference to this citation. If a similar reference exists, don't
- add another one.
-
- @param source_ref: Source Reference
- @type source_ref: L{gen.lib.srcref}
- @return: The key of the added reference among all the references.
- @rtype: char
- """
- letter_count = len(string.ascii_lowercase)
- ref_count = len(self.__ref_list)
- x_ref_count = ref_count
- # Return "a" for ref_count = 0, otherwise log(0) does not work
- if ref_count == 0:
- self.__ref_list.append(("a", source_ref))
- return "a"
- last_letter = string.ascii_lowercase[ ref_count % letter_count ]
- key = ""
- # Calculate prek number of digits.
- number_of_letters = int(math.log(float(ref_count), float(letter_count)))+1
- # Exclude index for number_of_letters-1
- for n in range(1, number_of_letters-1):
- ref_count -= pow(letter_count, n)
- # Adjust number_of_letters for new index
- number_of_letters = int(math.log(float(ref_count), float(letter_count))) +1
- for n in range(1, number_of_letters):
- x_ref_count -= pow(letter_count, n)
- for letter in range(1, number_of_letters):
- index = x_ref_count / pow(letter_count, letter) % letter_count
- key += string.ascii_lowercase[ index ]
- key = key + last_letter
- self.__ref_list.append((key, source_ref))
- return key
-
-class Bibliography(object):
- """
- Store and organize multiple citations into a bibliography.
- """
- MODE_DATE = 2**0
- MODE_PAGE = 2**1
- MODE_CONF = 2**2
- MODE_NOTE = 2**3
- MODE_ALL = MODE_DATE | MODE_PAGE | MODE_CONF | MODE_NOTE
-
- def __init__(self, mode=MODE_ALL):
- """
- A bibliography will store citations (sources) and references to those
- citations (source refs). Duplicate entries will not be added. To change
- what is considered duplicate, you can tell the bibliography what source
- ref information you are interested in by passing in the mode.
-
- Possible modes include:
- MODE_DATE
- MODE_PAGE
- MODE_CONF
- MODE_NOTE
- MODE_ALL
-
- If you only care about pages, set "mode=MODE_PAGE".
- If you only care about dates and pages, set "mode=MODE_DATE|MODE_PAGE".
- If you care about everything, set "mode=MODE_ALL".
- """
- self.__citation_list = []
- self.mode = mode
-
- def add_reference(self, source_ref):
- """
- Add a reference to a source to this bibliography. If the source already
- exists, don't add it again. If a similar reference exists, don't
- add another one.
-
- @param source_ref: Source Reference
- @type source_ref: L{gen.lib.srcref}
- @return: A tuple containing the index of the source among all the
- sources and the key of the reference among all the references. If
- there is no reference information, the second element will be None.
- @rtype: (int,char) or (int,None)
- """
- source_handle = source_ref.get_reference_handle()
- cindex = 0
- rkey = ""
- citation = None
- citation_found = False
- for citation in self.__citation_list:
- if citation.get_source_handle() == source_handle:
- citation_found = True
- break
- cindex += 1
-
- if not citation_found:
- citation = Citation()
- citation.set_source_handle(source_handle)
- cindex = len(self.__citation_list)
- self.__citation_list.append(citation)
-
- if self.__sref_has_info(source_ref):
- for key, ref in citation.get_ref_list():
- if self.__srefs_are_equal(ref, source_ref):
- # if a reference like this already exists, don't add
- # another one
- return (cindex, key)
- rkey = citation.add_reference(source_ref)
-
- return (cindex, rkey)
-
- def get_citation_count(self):
- """
- Report the number of citations in this bibliography.
-
- @return: number of citations
- @rtype: int
- """
- return len(self.__citation_list)
-
- def get_citation_list(self):
- """
- Return a list containing all the citations in this bibliography.
-
- @return: citation list
- @rtype: list of L{Citation} objects
- """
- return self.__citation_list
-
- def __sref_has_info(self, source_ref):
- """
- Determine if this source_ref has any useful information based on the
- current mode.
- """
- if ( self.mode & self.MODE_PAGE ) == self.MODE_PAGE:
- if source_ref.get_page() != "":
- return True
- if ( self.mode & self.MODE_DATE ) == self.MODE_DATE:
- date = source_ref.get_date_object()
- if date is not None and not date.is_empty():
- return True
- if ( self.mode & self.MODE_CONF ) == self.MODE_CONF:
- confidence = source_ref.get_confidence_level()
- if confidence is not None and confidence != SourceRef.CONF_NORMAL:
- return True
- if ( self.mode & self.MODE_NOTE ) == self.MODE_NOTE:
- if len(source_ref.get_note_list()) != 0:
- return True
- # Can't find anything interesting.
- return False
-
- def __srefs_are_equal(self, source_ref1, source_ref2):
- """
- Determine if two source references are equal based on the
- current mode.
- """
- if self.mode == self.MODE_ALL:
- return source_ref1.is_equal(source_ref2)
- if ( self.mode & self.MODE_PAGE ) == self.MODE_PAGE:
- if source_ref1.get_page() != source_ref2.get_page():
- return False
- if ( self.mode & self.MODE_DATE ) == self.MODE_DATE:
- date1 = source_ref1.get_date_object()
- date2 = source_ref2.get_date_object()
- if date1.is_equal(date2):
- return False
- if ( self.mode & self.MODE_CONF ) == self.MODE_CONF:
- conf1 = source_ref1.get_confidence_level()
- conf2 = source_ref2.get_confidence_level()
- if conf1 != conf2:
- return False
- if ( self.mode & self.MODE_NOTE ) == self.MODE_NOTE:
- nl1 = source_ref1.get_note_list()
- nl2 = source_ref2.get_note_list()
- if len(nl1) != len(nl2):
- return False
- for notehandle in nl1:
- if notehandle not in nl2:
- return False
- # Can't find anything different. They must be equal.
- return True
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2007 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id: _Bibliography.py 13191 2009-09-10 18:49:48Z gbritton $
-
-"""
-Contain and organize bibliographic information.
-"""
-import string
-import math
-from gen.lib import SourceRef
-
-class Citation(object):
- """
- Store information about a citation and all of its references.
- """
- def __init__(self):
- """
- Initialize members.
- """
- self.__src_handle = None
- self.__ref_list = []
-
- def get_source_handle(self):
- """
- Provide the handle to the source that this citation is for.
-
- @return: Source Handle
- @rtype: handle
- """
- return self.__src_handle
-
- def set_source_handle(self, handle):
- """
- Set the handle for the source that this citation is for.
-
- @param handle: Source Handle
- @type handle: handle
- """
- self.__src_handle = handle
-
- def get_ref_list(self):
- """
- List all the references to this citation.
-
- @return: a list of references
- @rtype: list of L{gen.lib.srcref} objects
- """
- return self.__ref_list
-
- def add_reference(self, source_ref):
- """
- Add a reference to this citation. If a similar reference exists, don't
- add another one.
-
- @param source_ref: Source Reference
- @type source_ref: L{gen.lib.srcref}
- @return: The key of the added reference among all the references.
- @rtype: char
- """
- letter_count = len(string.ascii_lowercase)
- ref_count = len(self.__ref_list)
- x_ref_count = ref_count
- # Return "a" for ref_count = 0, otherwise log(0) does not work
- if ref_count == 0:
- self.__ref_list.append(("a", source_ref))
- return "a"
- last_letter = string.ascii_lowercase[ ref_count % letter_count ]
- key = ""
- # Calculate prek number of digits.
- number_of_letters = int(math.log(float(ref_count), float(letter_count)))+1
- # Exclude index for number_of_letters-1
- for n in range(1, number_of_letters-1):
- ref_count -= pow(letter_count, n)
- # Adjust number_of_letters for new index
- number_of_letters = int(math.log(float(ref_count), float(letter_count))) +1
- for n in range(1, number_of_letters):
- x_ref_count -= pow(letter_count, n)
- for letter in range(1, number_of_letters):
- index = x_ref_count / pow(letter_count, letter) % letter_count
- key += string.ascii_lowercase[ index ]
- key = key + last_letter
- self.__ref_list.append((key, source_ref))
- return key
-
-class Bibliography(object):
- """
- Store and organize multiple citations into a bibliography.
- """
- MODE_DATE = 2**0
- MODE_PAGE = 2**1
- MODE_CONF = 2**2
- MODE_NOTE = 2**3
- MODE_ALL = MODE_DATE | MODE_PAGE | MODE_CONF | MODE_NOTE
-
- def __init__(self, mode=MODE_ALL):
- """
- A bibliography will store citations (sources) and references to those
- citations (source refs). Duplicate entries will not be added. To change
- what is considered duplicate, you can tell the bibliography what source
- ref information you are interested in by passing in the mode.
-
- Possible modes include:
- MODE_DATE
- MODE_PAGE
- MODE_CONF
- MODE_NOTE
- MODE_ALL
-
- If you only care about pages, set "mode=MODE_PAGE".
- If you only care about dates and pages, set "mode=MODE_DATE|MODE_PAGE".
- If you care about everything, set "mode=MODE_ALL".
- """
- self.__citation_list = []
- self.mode = mode
-
- def add_reference(self, source_ref):
- """
- Add a reference to a source to this bibliography. If the source already
- exists, don't add it again. If a similar reference exists, don't
- add another one.
-
- @param source_ref: Source Reference
- @type source_ref: L{gen.lib.srcref}
- @return: A tuple containing the index of the source among all the
- sources and the key of the reference among all the references. If
- there is no reference information, the second element will be None.
- @rtype: (int,char) or (int,None)
- """
- source_handle = source_ref.get_reference_handle()
- cindex = 0
- rkey = ""
- citation = None
- citation_found = False
- for citation in self.__citation_list:
- if citation.get_source_handle() == source_handle:
- citation_found = True
- break
- cindex += 1
-
- if not citation_found:
- citation = Citation()
- citation.set_source_handle(source_handle)
- cindex = len(self.__citation_list)
- self.__citation_list.append(citation)
-
- if self.__sref_has_info(source_ref):
- for key, ref in citation.get_ref_list():
- if self.__srefs_are_equal(ref, source_ref):
- # if a reference like this already exists, don't add
- # another one
- return (cindex, key)
- rkey = citation.add_reference(source_ref)
-
- return (cindex, rkey)
-
- def get_citation_count(self):
- """
- Report the number of citations in this bibliography.
-
- @return: number of citations
- @rtype: int
- """
- return len(self.__citation_list)
-
- def get_citation_list(self):
- """
- Return a list containing all the citations in this bibliography.
-
- @return: citation list
- @rtype: list of L{Citation} objects
- """
- return self.__citation_list
-
- def __sref_has_info(self, source_ref):
- """
- Determine if this source_ref has any useful information based on the
- current mode.
- """
- if ( self.mode & self.MODE_PAGE ) == self.MODE_PAGE:
- if source_ref.get_page() != "":
- return True
- if ( self.mode & self.MODE_DATE ) == self.MODE_DATE:
- date = source_ref.get_date_object()
- if date is not None and not date.is_empty():
- return True
- if ( self.mode & self.MODE_CONF ) == self.MODE_CONF:
- confidence = source_ref.get_confidence_level()
- if confidence is not None and confidence != SourceRef.CONF_NORMAL:
- return True
- if ( self.mode & self.MODE_NOTE ) == self.MODE_NOTE:
- if len(source_ref.get_note_list()) != 0:
- return True
- # Can't find anything interesting.
- return False
-
- def __srefs_are_equal(self, source_ref1, source_ref2):
- """
- Determine if two source references are equal based on the
- current mode.
- """
- if self.mode == self.MODE_ALL:
- return source_ref1.is_equal(source_ref2)
- if ( self.mode & self.MODE_PAGE ) == self.MODE_PAGE:
- if source_ref1.get_page() != source_ref2.get_page():
- return False
- if ( self.mode & self.MODE_DATE ) == self.MODE_DATE:
- date1 = source_ref1.get_date_object()
- date2 = source_ref2.get_date_object()
- if date1.is_equal(date2):
- return False
- if ( self.mode & self.MODE_CONF ) == self.MODE_CONF:
- conf1 = source_ref1.get_confidence_level()
- conf2 = source_ref2.get_confidence_level()
- if conf1 != conf2:
- return False
- if ( self.mode & self.MODE_NOTE ) == self.MODE_NOTE:
- nl1 = source_ref1.get_note_list()
- nl2 = source_ref2.get_note_list()
- if len(nl1) != len(nl2):
- return False
- for notehandle in nl1:
- if notehandle not in nl2:
- return False
- # Can't find anything different. They must be equal.
- return True
diff --git a/src/gen/plug/report/_constants.py b/src/gen/plug/report/_constants.py
index 40e041777..3fd29d664 100644
--- a/src/gen/plug/report/_constants.py
+++ b/src/gen/plug/report/_constants.py
@@ -61,158 +61,6 @@ book_categories = {
# options dialog as well as the location of the corresponding
# stylesheets in src/data.
-CSS_FILES = [
- # First is used as default selection.
- [_("Basic-Ash"), 'Web_Basic-Ash.css'],
- [_("Basic-Blue"), 'Web_Basic-Blue.css'],
- [_("Basic-Cypress"), 'Web_Basic-Cypress.css'],
- [_("Basic-Lilac"), 'Web_Basic-Lilac.css'],
- [_("Basic-Peach"), 'Web_Basic-Peach.css'],
- [_("Basic-Spruce"), 'Web_Basic-Spruce.css'],
- [_("Mainz"), 'Web_Mainz.css'],
- [_("Nebraska"), 'Web_Nebraska.css'],
- [_("Visually Impaired"), 'Web_Visually.css'],
- [_("No style sheet"), ''],
- ]
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2010 Rob G. Healey
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id: _Constants.py 15146 2010-04-15 14:37:18Z robhealey1 $
-
-"Report Generation Framework"
-
-#-------------------------------------------------------------------------
-#
-# standard python modules
-#
-#-------------------------------------------------------------------------
-from gen.ggettext import gettext as _
-
-#-------------------------------------------------------------------------
-#
-# Constants
-#
-#-------------------------------------------------------------------------
-
-# Report categories
-from gen.plug import CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_CODE, CATEGORY_WEB,\
- CATEGORY_BOOK, CATEGORY_GRAPHVIZ
-
-standalone_categories = {
- CATEGORY_TEXT : _("Text Reports"),
- CATEGORY_DRAW : _("Graphical Reports"),
- CATEGORY_CODE : _("Code Generators"),
- CATEGORY_WEB : _("Web Pages"),
- CATEGORY_BOOK : _("Books"),
- CATEGORY_GRAPHVIZ : _("Graphs"),
-}
-
-book_categories = {
- CATEGORY_TEXT : _("Text"),
- CATEGORY_DRAW : _("Graphics"),
-}
-
-#Common data for html reports
-## TODO: move to a system where css files are registered
-# This information defines the list of styles in the Web reports
-# options dialog as well as the location of the corresponding
-# stylesheets in src/data.
-
-CSS_FILES = [
- # First is used as default selection.
- [_("Basic-Ash"), 'Web_Basic-Ash.css'],
- [_("Basic-Blue"), 'Web_Basic-Blue.css'],
- [_("Basic-Cypress"), 'Web_Basic-Cypress.css'],
- [_("Basic-Lilac"), 'Web_Basic-Lilac.css'],
- [_("Basic-Peach"), 'Web_Basic-Peach.css'],
- [_("Basic-Spruce"), 'Web_Basic-Spruce.css'],
- [_("Mainz"), 'Web_Mainz.css'],
- [_("Nebraska"), 'Web_Nebraska.css'],
- [_("Visually Impaired"), 'Web_Visually.css'],
- [_("No style sheet"), ''],
- ]
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2010 Rob G. Healey
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id: _Constants.py 15146 2010-04-15 14:37:18Z robhealey1 $
-
-"Report Generation Framework"
-
-#-------------------------------------------------------------------------
-#
-# standard python modules
-#
-#-------------------------------------------------------------------------
-from gen.ggettext import gettext as _
-
-#-------------------------------------------------------------------------
-#
-# Constants
-#
-#-------------------------------------------------------------------------
-
-# Report categories
-from gen.plug import CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_CODE, CATEGORY_WEB,\
- CATEGORY_BOOK, CATEGORY_GRAPHVIZ
-
-standalone_categories = {
- CATEGORY_TEXT : _("Text Reports"),
- CATEGORY_DRAW : _("Graphical Reports"),
- CATEGORY_CODE : _("Code Generators"),
- CATEGORY_WEB : _("Web Pages"),
- CATEGORY_BOOK : _("Books"),
- CATEGORY_GRAPHVIZ : _("Graphs"),
-}
-
-book_categories = {
- CATEGORY_TEXT : _("Text"),
- CATEGORY_DRAW : _("Graphics"),
-}
-
-#Common data for html reports
-## TODO: move to a system where css files are registered
-# This information defines the list of styles in the Web reports
-# options dialog as well as the location of the corresponding
-# stylesheets in src/data.
-
CSS_FILES = [
# First is used as default selection.
[_("Basic-Ash"), 'Web_Basic-Ash.css'],
diff --git a/src/gen/plug/report/_options.py b/src/gen/plug/report/_options.py
index 80c8ea4bd..c9da00ad8 100644
--- a/src/gen/plug/report/_options.py
+++ b/src/gen/plug/report/_options.py
@@ -818,1646 +818,3 @@ class MenuReportOptions(GuiMenuOptions, ReportOptions):
menu_option = self.menu.get_option_by_name(optname)
if menu_option:
menu_option.set_value(self.options_dict[optname])
-
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2004-2007 Donald N. Allingham
-# Copyright (C) 2008 Gary Burton
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id: _ReportOptions.py 13346 2009-10-08 01:12:51Z dsblank $
-
-# Written by Alex Roitman
-
-"""
-Report option handling, including saving and parsing.
-"""
-
-#-------------------------------------------------------------------------
-#
-# Standard Python modules
-#
-#-------------------------------------------------------------------------
-import os
-import copy
-from xml.sax.saxutils import escape
-
-def escxml(d):
- return escape(d, { '"' : '"' } )
-
-#-------------------------------------------------------------------------
-#
-# SAX interface
-#
-#-------------------------------------------------------------------------
-try:
- from xml.sax import make_parser, SAXParseException
-except:
- from _xmlplus.sax import make_parser, SAXParseException
-
-#-------------------------------------------------------------------------
-#
-# gramps modules
-#
-#-------------------------------------------------------------------------
-import const
-import config
-from gen.plug.docgen import PAPER_PORTRAIT
-from gen.plug import _options
-from gui.plug import GuiMenuOptions
-
-#-------------------------------------------------------------------------
-#
-# List of options for a single report
-#
-#-------------------------------------------------------------------------
-class OptionList(_options.OptionList):
- """
- Implements a set of options to parse and store for a given report.
- """
-
- def __init__(self):
- _options.OptionList.__init__(self)
- self.style_name = None
- self.paper_metric = None
- self.paper_name = None
- self.orientation = None
- self.custom_paper_size = [29.7, 21.0]
- self.margins = [2.54, 2.54, 2.54, 2.54]
- self.format_name = None
- self.css_filename = None
-
- def set_style_name(self, style_name):
- """
- Set the style name for the OptionList.
- @param style_name: name of the style to set.
- @type style_name: str
- """
- self.style_name = style_name
-
- def get_style_name(self):
- """
- Return the style name of the OptionList.
- @returns: string representing the style name
- @rtype: str
- """
- return self.style_name
-
- def set_paper_metric(self, paper_metric):
- """
- Set the paper metric for the OptionList.
- @param paper_metric: whether to use metric.
- @type paper_name: boolean
- """
- self.paper_metric = paper_metric
-
- def get_paper_metric(self):
- """
- Return the paper metric of the OptionList.
- @returns: returns whether to use metric
- @rtype: boolean
- """
- return self.paper_metric
-
- def set_paper_name(self, paper_name):
- """
- Set the paper name for the OptionList.
- @param paper_name: name of the paper to set.
- @type paper_name: str
- """
- self.paper_name = paper_name
-
- def get_paper_name(self):
- """
- Return the paper name of the OptionList.
- @returns: returns the paper name
- @rtype: str
- """
- return self.paper_name
-
- def set_orientation(self, orientation):
- """
- Set the orientation for the OptionList.
- @param orientation: orientation to set. Possible values are
- PAPER_LANDSCAPE or PAPER_PORTRAIT
- @type orientation: int
- """
- self.orientation = orientation
-
- def get_orientation(self):
- """
- Return the orientation for the OptionList.
- @returns: returns the selected orientation. Valid values are
- PAPER_LANDSCAPE or PAPER_PORTRAIT
- @rtype: int
- """
- return self.orientation
-
- def set_custom_paper_size(self, paper_size):
- """
- Set the custom paper size for the OptionList.
- @param paper_size: paper size to set in cm.
- @type paper_size: [float, float]
- """
- self.custom_paper_size = paper_size
-
- def get_custom_paper_size(self):
- """
- Return the custom paper size for the OptionList.
- @returns: returns the custom paper size in cm
- @rtype: [float, float]
- """
- return self.custom_paper_size
-
- def set_margins(self, margins):
- """
- Set the margins for the OptionList.
- @param margins: margins to set. Possible values are floats in cm
- @type margins: [float, float, float, float]
- """
- self.margins = copy.copy(margins)
-
- def get_margins(self):
- """
- Return the margins for the OptionList.
- @returns margins: returns the margins, floats in cm
- @rtype margins: [float, float, float, float]
- """
- return copy.copy(self.margins)
-
- def set_margin(self, pos, value):
- """
- Set a margin for the OptionList.
- @param pos: Position of margin [left, right, top, bottom]
- @param value: floating point in cm
- @type pos: int
- @type value: float
- """
- self.margins[pos] = value
-
- def get_margin(self, pos):
- """
- Return a margin for the OptionList.
- @param pos: Position of margin [left, right, top, bottom]
- @type pos: int
- @returns: float cm of margin
- @rtype: float
- """
- return self.margins[pos]
-
- def set_css_filename(self, css_filename):
- """
- Set the template name for the OptionList.
- @param template_name: name of the template to set.
- @type template_name: str
- """
- self.css_filename = css_filename
-
- def get_css_filename(self):
- """
- Return the template name of the OptionList.
- @returns: template name
- @rtype: str
- """
- return self.css_filename
-
- def set_format_name(self, format_name):
- """
- Set the format name for the OptionList.
- @param format_name: name of the format to set.
- @type format_name: str
- """
- self.format_name = format_name
-
- def get_format_name(self):
- """
- Return the format name of the OptionList.
- @returns: returns the format name
- @rtype: str
- """
- return self.format_name
-
-#-------------------------------------------------------------------------
-#
-# Collection of option lists
-#
-#-------------------------------------------------------------------------
-class OptionListCollection(_options.OptionListCollection):
- """
- Implements a collection of option lists.
- """
- def __init__(self, filename):
- _options.OptionListCollection.__init__(self, filename)
-
- def init_common(self):
- # Default values for common options
- self.default_style_name = "default"
- self.default_paper_metric = config.get('preferences.paper-metric')
- self.default_paper_name = config.get('preferences.paper-preference')
- self.default_orientation = PAPER_PORTRAIT
- self.default_css_filename = ""
- self.default_custom_paper_size = [29.7, 21.0]
- self.default_margins = [2.54, 2.54, 2.54, 2.54]
- self.default_format_name = 'print'
-
- self.last_paper_metric = self.default_paper_metric
- self.last_paper_name = self.default_paper_name
- self.last_orientation = self.default_orientation
- self.last_custom_paper_size = copy.copy(self.default_custom_paper_size)
- self.last_margins = copy.copy(self.default_margins)
- self.last_css_filename = self.default_css_filename
- self.last_format_name = self.default_format_name
- self.option_list_map = {}
-
- def set_last_paper_metric(self, paper_metric):
- """
- Set the last paper metric used for the any report in this collection.
- @param paper_metric: whether to use metric.
- @type paper_name: boolean
- """
- self.last_paper_metric = paper_metric
-
- def get_last_paper_metric(self):
- """
- Return the last paper metric used for the any report in this collection.
- @returns: returns whether or not to use metric
- @rtype: boolean
- """
- return self.last_paper_metric
-
- def set_last_paper_name(self, paper_name):
- """
- Set the last paper name used for the any report in this collection.
- @param paper_name: name of the paper to set.
- @type paper_name: str
- """
- self.last_paper_name = paper_name
-
- def get_last_paper_name(self):
- """
- Return the last paper name used for the any report in this collection.
- @returns: returns the name of the paper
- @rtype: str
- """
- return self.last_paper_name
-
- def set_last_orientation(self, orientation):
- """
- Set the last orientation used for the any report in this collection.
- @param orientation: orientation to set.
- @type orientation: int
- """
- self.last_orientation = orientation
-
- def get_last_orientation(self):
- """
- Return the last orientation used for the any report in this
- collection.
- @returns: last orientation used
- @rtype: int
- """
- return self.last_orientation
-
- def set_last_custom_paper_size(self, custom_paper_size):
- """
- Set the last custom paper size used for the any report in this collection.
- @param custom_paper_size: size to set in cm (width, height)
- @type margins: [float, float]
- """
- self.last_custom_paper_size = copy.copy(custom_paper_size)
-
- def get_last_custom_paper_size(self):
- """
- Return the last custom paper size used for the any report in this
- collection.
- @returns: list of last custom paper size used in cm (width, height)
- @rtype: [float, float]
- """
- return copy.copy(self.last_custom_paper_size)
-
- def set_last_margins(self, margins):
- """
- Set the last margins used for the any report in this collection.
- @param margins: margins to set in cm (left, right, top, bottom)
- @type margins: [float, float, float, float]
- """
- self.last_margins = copy.copy(margins)
-
- def get_last_margins(self):
- """
- Return the last margins used for the any report in this
- collection.
- @returns: list of last margins used in cm (left, right, top, bottom)
- @rtype: [float, float, float, float]
- """
- return copy.copy(self.last_margins)
-
- def set_last_margin(self, pos, value):
- """
- Set the last margin used for the any report in this collection.
- @param pos: pos to set (0-4) (left, right, top, bottom)
- @type pos: int
- @param value: value to set the margin to in cm
- @type value: float
- """
- self.last_margins[pos] = value
-
- def get_last_margin(self, pos):
- """
- Return the last margins used for the any report in this
- collection.
- @param pos: position in margins list
- @type pos: int
- @returns: last margin used in pos
- @rtype: float
- """
- return self.last_margins[pos]
-
- def set_last_css_filename(self, css_filename):
- """
- Set the last css used for the any report in this collection.
-
- css_filename: name of the style to set.
- """
- self.last_css_name = css_filename
-
- def get_last_css_filename(self):
- """
- Return the last template used for the any report in this collection.
- """
- return self.last_css_filename
-
- def set_last_format_name(self, format_name):
- """
- Set the last format used for the any report in this collection.
-
- format_name: name of the format to set.
- """
- self.last_format_name = format_name
-
- def get_last_format_name(self):
- """
- Return the last format used for the any report in this collection.
- """
- return self.last_format_name
-
- def write_common(self, f):
- f.write('\n')
- if self.get_last_paper_metric() != self.default_paper_metric:
- f.write(' \n' % self.get_last_paper_metric() )
- if self.get_last_custom_paper_size() != self.default_custom_paper_size:
- size = self.get_last_custom_paper_size()
- f.write(' \n' % (size[0], size[1]) )
- if self.get_last_paper_name() != self.default_paper_name:
- f.write(' \n' % escxml(self.get_last_paper_name()) )
- if self.get_last_css_filename() != self.default_css_filename:
- f.write(' \n' % escxml(self.get_last_css_filename()) )
- if self.get_last_format_name() != self.default_format_name:
- f.write(' \n' % escxml(self.get_last_format_name()) )
- if self.get_last_orientation() != self.default_orientation:
- f.write(' \n' % self.get_last_orientation() )
- f.write('\n')
-
- def write_module_common(self, f, option_list):
- if option_list.get_style_name() \
- and option_list.get_style_name() != self.default_style_name:
- f.write(' \n' % escxml(option_list.get_style_name()) )
- if option_list.get_paper_metric() \
- and option_list.get_paper_metric() != self.default_paper_metric:
- f.write(' \n' % option_list.get_paper_metric() )
- if option_list.get_custom_paper_size() \
- and option_list.get_custom_paper_size() != self.default_custom_paper_size:
- size = self.get_last_custom_paper_size()
- f.write(' \n' % (size[0], size[1]) )
- if option_list.get_paper_name() \
- and option_list.get_paper_name() != self.default_paper_name:
- f.write(' \n' % escxml(option_list.get_paper_name()) )
- if option_list.get_css_filename() \
- and option_list.get_css_filename() != self.default_css_filename:
- f.write(' \n' % escxml(option_list.get_css_filename()))
- if option_list.get_format_name() \
- and option_list.get_format_name() != self.default_format_name:
- f.write(' \n' % escxml(option_list.get_format_name()) )
- if option_list.get_orientation() \
- and option_list.get_orientation() != self.default_orientation:
- f.write(' \n' % option_list.get_orientation() )
- if option_list.get_margins() \
- and option_list.get_margins() != self.default_margins:
- margins = option_list.get_margins()
- for pos in range(len(margins)):
- f.write(' \n' % (pos, margins[pos]))
-
- 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(OptionParser(self))
- the_file = open(self.filename)
- p.parse(the_file)
- the_file.close()
- except (IOError, OSError, SAXParseException):
- pass
-
-#-------------------------------------------------------------------------
-#
-# OptionParser
-#
-#-------------------------------------------------------------------------
-class OptionParser(_options.OptionParser):
- """
- SAX parsing class for the OptionListCollection XML file.
- """
-
- def __init__(self, collection):
- """
- Create a OptionParser class that populates the passed collection.
-
- collection: BookList to be loaded from the file.
- """
- _options.OptionParser.__init__(self, collection)
- self.common = False
- self.list_class = OptionList
-
- def startElement(self, tag, attrs):
- """
- Overridden class that handles the start of a XML element
- """
- # First we try report-specific tags
- if tag == "last-common":
- self.common = True
- elif tag == "style":
- self.option_list.set_style_name(attrs['name'])
- elif tag == "paper":
- if self.common:
- self.collection.set_last_paper_name(attrs['name'])
- else:
- self.option_list.set_paper_name(attrs['name'])
- elif tag == "css":
- if self.common:
- self.collection.set_last_css_filename(attrs['name'])
- else:
- self.option_list.set_css_filename(attrs['name'])
- elif tag == "format":
- if self.common:
- self.collection.set_last_format_name(attrs['name'])
- else:
- self.option_list.set_format_name(attrs['name'])
- elif tag == "orientation":
- if self.common:
- self.collection.set_last_orientation(int(attrs['value']))
- else:
- self.option_list.set_orientation(int(attrs['value']))
- elif tag == "metric":
- if self.common:
- self.collection.set_last_paper_metric(int(attrs['value']))
- else:
- self.option_list.set_paper_metric(int(attrs['value']))
- elif tag == "size":
- width, height = attrs['value'].split()
- width = float(width)
- height = float(height)
- if self.common:
- self.collection.set_last_custom_paper_size([width, height])
- else:
- self.option_list.set_custom_paper_size([width, height])
-
- elif tag == "margin":
- pos, value = int(attrs['number']), float(attrs['value'])
- if self.common:
- self.collection.set_last_margin(pos, value)
- else:
- self.option_list.set_margin(pos, value)
- else:
- # Tag is not report-specific, so we let the base class handle it.
- _options.OptionParser.startElement(self, tag, attrs)
-
- def endElement(self, tag):
- "Overridden class that handles the end of a XML element"
- # First we try report-specific tags
- if tag == "last-common":
- self.common = False
- else:
- # Tag is not report-specific, so we let the base class handle it.
- _options.OptionParser.endElement(self, tag)
-
-#------------------------------------------------------------------------
-#
-# Empty class to keep the BaseDoc-targeted format happy
-# Yes, this is a hack. Find some other way to pass around documents so that
-# we don't have to handle them for reports that don't use documents (web)
-#
-#------------------------------------------------------------------------
-class EmptyDoc(object):
- def init(self):
- pass
-
- def set_creator(self, creator):
- pass
-
- def open(self, filename):
- pass
-
- def close(self):
- pass
-
-#-------------------------------------------------------------------------
-#
-# Class handling options for plugins
-#
-#-------------------------------------------------------------------------
-class OptionHandler(_options.OptionHandler):
- """
- Implements handling of the options for the plugins.
- """
- def __init__(self, module_name, options_dict):
- _options.OptionHandler.__init__(self, module_name, options_dict, None)
-
- def init_subclass(self):
- self.collection_class = OptionListCollection
- self.list_class = OptionList
- self.filename = const.REPORT_OPTIONS
-
- def init_common(self):
- """
- Specific initialization for reports.
- """
- # These are needed for running reports.
- # We will not need to save/retrieve them, just keep around.
- self.doc = EmptyDoc() # Nasty hack. Text reports replace this
- self.output = None
-
- # Retrieve our options from whole collection
- self.style_name = self.option_list_collection.default_style_name
- self.paper_metric = self.option_list_collection.get_last_paper_metric()
- self.paper_name = self.option_list_collection.get_last_paper_name()
- self.orientation = self.option_list_collection.get_last_orientation()
- self.custom_paper_size = self.option_list_collection.get_last_custom_paper_size()
- self.css_filename = self.option_list_collection.get_last_css_filename()
- self.margins = self.option_list_collection.get_last_margins()
- self.format_name = self.option_list_collection.get_last_format_name()
-
- def set_common_options(self):
- if self.saved_option_list.get_style_name():
- self.style_name = self.saved_option_list.get_style_name()
- if self.saved_option_list.get_orientation():
- self.orientation = self.saved_option_list.get_orientation()
- if self.saved_option_list.get_custom_paper_size():
- self.custom_paper_size = self.saved_option_list.get_custom_paper_size()
- if self.saved_option_list.get_margins():
- self.margins = self.saved_option_list.get_margins()
- if self.saved_option_list.get_css_filename():
- self.css_filename = self.saved_option_list.get_css_filename()
- if self.saved_option_list.get_paper_metric():
- self.paper_metric = self.saved_option_list.get_paper_metric()
- if self.saved_option_list.get_paper_name():
- self.paper_name = self.saved_option_list.get_paper_name()
- if self.saved_option_list.get_format_name():
- self.format_name = self.saved_option_list.get_format_name()
-
- def save_common_options(self):
- # First we save common options
- self.saved_option_list.set_style_name(self.style_name)
- self.saved_option_list.set_orientation(self.orientation)
- self.saved_option_list.set_custom_paper_size(self.custom_paper_size)
- self.saved_option_list.set_margins(self.margins)
- self.saved_option_list.set_paper_metric(self.paper_metric)
- self.saved_option_list.set_paper_name(self.paper_name)
- self.saved_option_list.set_css_filename(self.css_filename)
- self.saved_option_list.set_format_name(self.format_name)
- self.option_list_collection.set_option_list(self.module_name,
- self.saved_option_list)
-
- # Then save last-common options from the current selection
- self.option_list_collection.set_last_orientation(self.orientation)
- self.option_list_collection.set_last_custom_paper_size(self.custom_paper_size)
- self.option_list_collection.set_last_margins(self.margins)
- self.option_list_collection.set_last_paper_metric(self.paper_metric)
- self.option_list_collection.set_last_paper_name(self.paper_name)
- self.option_list_collection.set_last_css_filename(self.css_filename)
- self.option_list_collection.set_last_format_name(self.format_name)
-
- def get_stylesheet_savefile(self):
- """Where to save user defined styles for this report."""
- filename = "%s.xml" % self.module_name
- return os.path.join(const.HOME_DIR, filename)
-
- def get_default_stylesheet_name(self):
- return self.style_name
-
- def set_default_stylesheet_name(self, style_name):
- self.style_name = style_name
-
- def get_format_name(self):
- return self.format_name
-
- def set_format_name(self, format_name):
- self.format_name = format_name
-
- def get_paper_metric(self):
- return self.paper_metric
-
- def set_paper_metric(self, paper_metric):
- self.paper_metric = paper_metric
-
- def get_paper_name(self):
- return self.paper_name
-
- def set_paper_name(self, paper_name):
- self.paper_name = paper_name
-
- def get_paper(self):
- """
- This method is for temporary storage, not for saving/restoring.
- """
- return self.paper
-
- def set_paper(self, paper):
- """
- This method is for temporary storage, not for saving/restoring.
- """
- self.paper = paper
-
- def get_css_filename(self):
- return self.css_filename
-
- def set_css_filename(self, css_filename):
- self.css_filename = css_filename
-
- def get_orientation(self):
- return self.orientation
-
- def set_orientation(self, orientation):
- self.orientation = orientation
-
- def get_custom_paper_size(self):
- return copy.copy(self.custom_paper_size)
-
- def set_custom_paper_size(self, custom_paper_size):
- self.custom_paper_size = copy.copy(custom_paper_size)
-
- def get_margins(self):
- return copy.copy(self.margins)
-
- def set_margins(self,margins):
- self.margins = copy.copy(margins)
-
-#------------------------------------------------------------------------
-#
-# Base Options class
-#
-#------------------------------------------------------------------------
-class ReportOptions(_options.Options):
-
- """
- Defines options and provides handling interface.
-
- This is a base Options class for the reports. All reports, options
- classes should derive from it.
- """
- def __init__(self, name, dbase):
- """
- Initialize the class, performing usual house-keeping tasks.
- Subclasses MUST call this in their __init__() method.
- """
- self.name = name
- self.options_dict = {}
- self.options_help = {}
- self.handler = None
-
- def load_previous_values(self):
- self.handler = OptionHandler(self.name, self.options_dict)
-
- def make_default_style(self, default_style):
- """
- Defines default style for this report.
-
- This method MUST be overridden by reports that use the
- user-adjustable paragraph styles.
-
- NOTE: Unique names MUST be used for all style names, otherwise the
- styles will collide when making a book with duplicate style
- names. A rule of safety is to prepend style name with the
- acronym based on report name. The following acronyms are
- already taken:
- AC- Ancestor Chart
- AC2- Ancestor Chart 2 (Wall Chart)
- AHN- Ahnentafel Report
- AR- Comprehensive Ancestors report
- CBT- Custom Book Text
- DG- Descendant Graph
- DR- Descendant Report
- DAR- Detailed Ancestral Report
- DDR- Detailed Descendant Report
- FGR- Family Group Report
- FC- Fan Chart
- FTA- FTM Style Ancestral report
- FTD- FTM Style Descendant report
- IDS- Individual Complete Report
- IVS- Individual Summary Report
- PLC- Place Report
- SBT- Simple Boot Title
- TLG- Timeline Graph
- """
- pass
-
- def get_document(self):
- """
- Return document instance.
-
- This method MUST NOT be overridden by subclasses.
- """
- return self.handler.doc
-
- def set_document(self, val):
- """
- Set document to a given instance.
-
- This method MUST NOT be overridden by subclasses.
- """
- self.handler.doc = val
-
- def get_output(self):
- """
- Return document output destination.
-
- This method MUST NOT be overridden by subclasses.
- """
- return self.handler.output
-
- def set_output(self, val):
- """
- Set output destination to a given string.
-
- This method MUST NOT be overridden by subclasses.
- """
- self.handler.output = val
-
-#-------------------------------------------------------------------------
-#
-# MenuReportOptions
-#
-#-------------------------------------------------------------------------
-class MenuReportOptions(GuiMenuOptions, ReportOptions):
- """
-
- The MenuReportOptions class implements the ReportOptions
- functionality in a generic way so that the user does not need to
- be concerned with the graphical representation of the options.
-
- The user should inherit the MenuReportOptions class and override the
- add_menu_options function. The user can add options to the menu and the
- MenuReportOptions class will worry about setting up the GUI.
-
- """
- def __init__(self, name, dbase):
- ReportOptions.__init__(self, name, dbase)
- GuiMenuOptions.__init__(self)
-
- def load_previous_values(self):
- ReportOptions.load_previous_values(self)
- # Pass the loaded values to the menu options so they will be displayed
- # properly.
- for optname in self.options_dict:
- menu_option = self.menu.get_option_by_name(optname)
- if menu_option:
- menu_option.set_value(self.options_dict[optname])
-
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2004-2007 Donald N. Allingham
-# Copyright (C) 2008 Gary Burton
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id: _ReportOptions.py 13346 2009-10-08 01:12:51Z dsblank $
-
-# Written by Alex Roitman
-
-"""
-Report option handling, including saving and parsing.
-"""
-
-#-------------------------------------------------------------------------
-#
-# Standard Python modules
-#
-#-------------------------------------------------------------------------
-import os
-import copy
-from xml.sax.saxutils import escape
-
-def escxml(d):
- return escape(d, { '"' : '"' } )
-
-#-------------------------------------------------------------------------
-#
-# SAX interface
-#
-#-------------------------------------------------------------------------
-try:
- from xml.sax import make_parser, SAXParseException
-except:
- from _xmlplus.sax import make_parser, SAXParseException
-
-#-------------------------------------------------------------------------
-#
-# gramps modules
-#
-#-------------------------------------------------------------------------
-import const
-import config
-from gen.plug.docgen import PAPER_PORTRAIT
-from gen.plug import _options
-from gui.plug import GuiMenuOptions
-
-#-------------------------------------------------------------------------
-#
-# List of options for a single report
-#
-#-------------------------------------------------------------------------
-class OptionList(_options.OptionList):
- """
- Implements a set of options to parse and store for a given report.
- """
-
- def __init__(self):
- _options.OptionList.__init__(self)
- self.style_name = None
- self.paper_metric = None
- self.paper_name = None
- self.orientation = None
- self.custom_paper_size = [29.7, 21.0]
- self.margins = [2.54, 2.54, 2.54, 2.54]
- self.format_name = None
- self.css_filename = None
-
- def set_style_name(self, style_name):
- """
- Set the style name for the OptionList.
- @param style_name: name of the style to set.
- @type style_name: str
- """
- self.style_name = style_name
-
- def get_style_name(self):
- """
- Return the style name of the OptionList.
- @returns: string representing the style name
- @rtype: str
- """
- return self.style_name
-
- def set_paper_metric(self, paper_metric):
- """
- Set the paper metric for the OptionList.
- @param paper_metric: whether to use metric.
- @type paper_name: boolean
- """
- self.paper_metric = paper_metric
-
- def get_paper_metric(self):
- """
- Return the paper metric of the OptionList.
- @returns: returns whether to use metric
- @rtype: boolean
- """
- return self.paper_metric
-
- def set_paper_name(self, paper_name):
- """
- Set the paper name for the OptionList.
- @param paper_name: name of the paper to set.
- @type paper_name: str
- """
- self.paper_name = paper_name
-
- def get_paper_name(self):
- """
- Return the paper name of the OptionList.
- @returns: returns the paper name
- @rtype: str
- """
- return self.paper_name
-
- def set_orientation(self, orientation):
- """
- Set the orientation for the OptionList.
- @param orientation: orientation to set. Possible values are
- PAPER_LANDSCAPE or PAPER_PORTRAIT
- @type orientation: int
- """
- self.orientation = orientation
-
- def get_orientation(self):
- """
- Return the orientation for the OptionList.
- @returns: returns the selected orientation. Valid values are
- PAPER_LANDSCAPE or PAPER_PORTRAIT
- @rtype: int
- """
- return self.orientation
-
- def set_custom_paper_size(self, paper_size):
- """
- Set the custom paper size for the OptionList.
- @param paper_size: paper size to set in cm.
- @type paper_size: [float, float]
- """
- self.custom_paper_size = paper_size
-
- def get_custom_paper_size(self):
- """
- Return the custom paper size for the OptionList.
- @returns: returns the custom paper size in cm
- @rtype: [float, float]
- """
- return self.custom_paper_size
-
- def set_margins(self, margins):
- """
- Set the margins for the OptionList.
- @param margins: margins to set. Possible values are floats in cm
- @type margins: [float, float, float, float]
- """
- self.margins = copy.copy(margins)
-
- def get_margins(self):
- """
- Return the margins for the OptionList.
- @returns margins: returns the margins, floats in cm
- @rtype margins: [float, float, float, float]
- """
- return copy.copy(self.margins)
-
- def set_margin(self, pos, value):
- """
- Set a margin for the OptionList.
- @param pos: Position of margin [left, right, top, bottom]
- @param value: floating point in cm
- @type pos: int
- @type value: float
- """
- self.margins[pos] = value
-
- def get_margin(self, pos):
- """
- Return a margin for the OptionList.
- @param pos: Position of margin [left, right, top, bottom]
- @type pos: int
- @returns: float cm of margin
- @rtype: float
- """
- return self.margins[pos]
-
- def set_css_filename(self, css_filename):
- """
- Set the template name for the OptionList.
- @param template_name: name of the template to set.
- @type template_name: str
- """
- self.css_filename = css_filename
-
- def get_css_filename(self):
- """
- Return the template name of the OptionList.
- @returns: template name
- @rtype: str
- """
- return self.css_filename
-
- def set_format_name(self, format_name):
- """
- Set the format name for the OptionList.
- @param format_name: name of the format to set.
- @type format_name: str
- """
- self.format_name = format_name
-
- def get_format_name(self):
- """
- Return the format name of the OptionList.
- @returns: returns the format name
- @rtype: str
- """
- return self.format_name
-
-#-------------------------------------------------------------------------
-#
-# Collection of option lists
-#
-#-------------------------------------------------------------------------
-class OptionListCollection(_options.OptionListCollection):
- """
- Implements a collection of option lists.
- """
- def __init__(self, filename):
- _options.OptionListCollection.__init__(self, filename)
-
- def init_common(self):
- # Default values for common options
- self.default_style_name = "default"
- self.default_paper_metric = config.get('preferences.paper-metric')
- self.default_paper_name = config.get('preferences.paper-preference')
- self.default_orientation = PAPER_PORTRAIT
- self.default_css_filename = ""
- self.default_custom_paper_size = [29.7, 21.0]
- self.default_margins = [2.54, 2.54, 2.54, 2.54]
- self.default_format_name = 'print'
-
- self.last_paper_metric = self.default_paper_metric
- self.last_paper_name = self.default_paper_name
- self.last_orientation = self.default_orientation
- self.last_custom_paper_size = copy.copy(self.default_custom_paper_size)
- self.last_margins = copy.copy(self.default_margins)
- self.last_css_filename = self.default_css_filename
- self.last_format_name = self.default_format_name
- self.option_list_map = {}
-
- def set_last_paper_metric(self, paper_metric):
- """
- Set the last paper metric used for the any report in this collection.
- @param paper_metric: whether to use metric.
- @type paper_name: boolean
- """
- self.last_paper_metric = paper_metric
-
- def get_last_paper_metric(self):
- """
- Return the last paper metric used for the any report in this collection.
- @returns: returns whether or not to use metric
- @rtype: boolean
- """
- return self.last_paper_metric
-
- def set_last_paper_name(self, paper_name):
- """
- Set the last paper name used for the any report in this collection.
- @param paper_name: name of the paper to set.
- @type paper_name: str
- """
- self.last_paper_name = paper_name
-
- def get_last_paper_name(self):
- """
- Return the last paper name used for the any report in this collection.
- @returns: returns the name of the paper
- @rtype: str
- """
- return self.last_paper_name
-
- def set_last_orientation(self, orientation):
- """
- Set the last orientation used for the any report in this collection.
- @param orientation: orientation to set.
- @type orientation: int
- """
- self.last_orientation = orientation
-
- def get_last_orientation(self):
- """
- Return the last orientation used for the any report in this
- collection.
- @returns: last orientation used
- @rtype: int
- """
- return self.last_orientation
-
- def set_last_custom_paper_size(self, custom_paper_size):
- """
- Set the last custom paper size used for the any report in this collection.
- @param custom_paper_size: size to set in cm (width, height)
- @type margins: [float, float]
- """
- self.last_custom_paper_size = copy.copy(custom_paper_size)
-
- def get_last_custom_paper_size(self):
- """
- Return the last custom paper size used for the any report in this
- collection.
- @returns: list of last custom paper size used in cm (width, height)
- @rtype: [float, float]
- """
- return copy.copy(self.last_custom_paper_size)
-
- def set_last_margins(self, margins):
- """
- Set the last margins used for the any report in this collection.
- @param margins: margins to set in cm (left, right, top, bottom)
- @type margins: [float, float, float, float]
- """
- self.last_margins = copy.copy(margins)
-
- def get_last_margins(self):
- """
- Return the last margins used for the any report in this
- collection.
- @returns: list of last margins used in cm (left, right, top, bottom)
- @rtype: [float, float, float, float]
- """
- return copy.copy(self.last_margins)
-
- def set_last_margin(self, pos, value):
- """
- Set the last margin used for the any report in this collection.
- @param pos: pos to set (0-4) (left, right, top, bottom)
- @type pos: int
- @param value: value to set the margin to in cm
- @type value: float
- """
- self.last_margins[pos] = value
-
- def get_last_margin(self, pos):
- """
- Return the last margins used for the any report in this
- collection.
- @param pos: position in margins list
- @type pos: int
- @returns: last margin used in pos
- @rtype: float
- """
- return self.last_margins[pos]
-
- def set_last_css_filename(self, css_filename):
- """
- Set the last css used for the any report in this collection.
-
- css_filename: name of the style to set.
- """
- self.last_css_name = css_filename
-
- def get_last_css_filename(self):
- """
- Return the last template used for the any report in this collection.
- """
- return self.last_css_filename
-
- def set_last_format_name(self, format_name):
- """
- Set the last format used for the any report in this collection.
-
- format_name: name of the format to set.
- """
- self.last_format_name = format_name
-
- def get_last_format_name(self):
- """
- Return the last format used for the any report in this collection.
- """
- return self.last_format_name
-
- def write_common(self, f):
- f.write('\n')
- if self.get_last_paper_metric() != self.default_paper_metric:
- f.write(' \n' % self.get_last_paper_metric() )
- if self.get_last_custom_paper_size() != self.default_custom_paper_size:
- size = self.get_last_custom_paper_size()
- f.write(' \n' % (size[0], size[1]) )
- if self.get_last_paper_name() != self.default_paper_name:
- f.write(' \n' % escxml(self.get_last_paper_name()) )
- if self.get_last_css_filename() != self.default_css_filename:
- f.write(' \n' % escxml(self.get_last_css_filename()) )
- if self.get_last_format_name() != self.default_format_name:
- f.write(' \n' % escxml(self.get_last_format_name()) )
- if self.get_last_orientation() != self.default_orientation:
- f.write(' \n' % self.get_last_orientation() )
- f.write('\n')
-
- def write_module_common(self, f, option_list):
- if option_list.get_style_name() \
- and option_list.get_style_name() != self.default_style_name:
- f.write(' \n' % escxml(option_list.get_style_name()) )
- if option_list.get_paper_metric() \
- and option_list.get_paper_metric() != self.default_paper_metric:
- f.write(' \n' % option_list.get_paper_metric() )
- if option_list.get_custom_paper_size() \
- and option_list.get_custom_paper_size() != self.default_custom_paper_size:
- size = self.get_last_custom_paper_size()
- f.write(' \n' % (size[0], size[1]) )
- if option_list.get_paper_name() \
- and option_list.get_paper_name() != self.default_paper_name:
- f.write(' \n' % escxml(option_list.get_paper_name()) )
- if option_list.get_css_filename() \
- and option_list.get_css_filename() != self.default_css_filename:
- f.write(' \n' % escxml(option_list.get_css_filename()))
- if option_list.get_format_name() \
- and option_list.get_format_name() != self.default_format_name:
- f.write(' \n' % escxml(option_list.get_format_name()) )
- if option_list.get_orientation() \
- and option_list.get_orientation() != self.default_orientation:
- f.write(' \n' % option_list.get_orientation() )
- if option_list.get_margins() \
- and option_list.get_margins() != self.default_margins:
- margins = option_list.get_margins()
- for pos in range(len(margins)):
- f.write(' \n' % (pos, margins[pos]))
-
- 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(OptionParser(self))
- the_file = open(self.filename)
- p.parse(the_file)
- the_file.close()
- except (IOError, OSError, SAXParseException):
- pass
-
-#-------------------------------------------------------------------------
-#
-# OptionParser
-#
-#-------------------------------------------------------------------------
-class OptionParser(_options.OptionParser):
- """
- SAX parsing class for the OptionListCollection XML file.
- """
-
- def __init__(self, collection):
- """
- Create a OptionParser class that populates the passed collection.
-
- collection: BookList to be loaded from the file.
- """
- _options.OptionParser.__init__(self, collection)
- self.common = False
- self.list_class = OptionList
-
- def startElement(self, tag, attrs):
- """
- Overridden class that handles the start of a XML element
- """
- # First we try report-specific tags
- if tag == "last-common":
- self.common = True
- elif tag == "style":
- self.option_list.set_style_name(attrs['name'])
- elif tag == "paper":
- if self.common:
- self.collection.set_last_paper_name(attrs['name'])
- else:
- self.option_list.set_paper_name(attrs['name'])
- elif tag == "css":
- if self.common:
- self.collection.set_last_css_filename(attrs['name'])
- else:
- self.option_list.set_css_filename(attrs['name'])
- elif tag == "format":
- if self.common:
- self.collection.set_last_format_name(attrs['name'])
- else:
- self.option_list.set_format_name(attrs['name'])
- elif tag == "orientation":
- if self.common:
- self.collection.set_last_orientation(int(attrs['value']))
- else:
- self.option_list.set_orientation(int(attrs['value']))
- elif tag == "metric":
- if self.common:
- self.collection.set_last_paper_metric(int(attrs['value']))
- else:
- self.option_list.set_paper_metric(int(attrs['value']))
- elif tag == "size":
- width, height = attrs['value'].split()
- width = float(width)
- height = float(height)
- if self.common:
- self.collection.set_last_custom_paper_size([width, height])
- else:
- self.option_list.set_custom_paper_size([width, height])
-
- elif tag == "margin":
- pos, value = int(attrs['number']), float(attrs['value'])
- if self.common:
- self.collection.set_last_margin(pos, value)
- else:
- self.option_list.set_margin(pos, value)
- else:
- # Tag is not report-specific, so we let the base class handle it.
- _options.OptionParser.startElement(self, tag, attrs)
-
- def endElement(self, tag):
- "Overridden class that handles the end of a XML element"
- # First we try report-specific tags
- if tag == "last-common":
- self.common = False
- else:
- # Tag is not report-specific, so we let the base class handle it.
- _options.OptionParser.endElement(self, tag)
-
-#------------------------------------------------------------------------
-#
-# Empty class to keep the BaseDoc-targeted format happy
-# Yes, this is a hack. Find some other way to pass around documents so that
-# we don't have to handle them for reports that don't use documents (web)
-#
-#------------------------------------------------------------------------
-class EmptyDoc(object):
- def init(self):
- pass
-
- def set_creator(self, creator):
- pass
-
- def open(self, filename):
- pass
-
- def close(self):
- pass
-
-#-------------------------------------------------------------------------
-#
-# Class handling options for plugins
-#
-#-------------------------------------------------------------------------
-class OptionHandler(_options.OptionHandler):
- """
- Implements handling of the options for the plugins.
- """
- def __init__(self, module_name, options_dict):
- _options.OptionHandler.__init__(self, module_name, options_dict, None)
-
- def init_subclass(self):
- self.collection_class = OptionListCollection
- self.list_class = OptionList
- self.filename = const.REPORT_OPTIONS
-
- def init_common(self):
- """
- Specific initialization for reports.
- """
- # These are needed for running reports.
- # We will not need to save/retrieve them, just keep around.
- self.doc = EmptyDoc() # Nasty hack. Text reports replace this
- self.output = None
-
- # Retrieve our options from whole collection
- self.style_name = self.option_list_collection.default_style_name
- self.paper_metric = self.option_list_collection.get_last_paper_metric()
- self.paper_name = self.option_list_collection.get_last_paper_name()
- self.orientation = self.option_list_collection.get_last_orientation()
- self.custom_paper_size = self.option_list_collection.get_last_custom_paper_size()
- self.css_filename = self.option_list_collection.get_last_css_filename()
- self.margins = self.option_list_collection.get_last_margins()
- self.format_name = self.option_list_collection.get_last_format_name()
-
- def set_common_options(self):
- if self.saved_option_list.get_style_name():
- self.style_name = self.saved_option_list.get_style_name()
- if self.saved_option_list.get_orientation():
- self.orientation = self.saved_option_list.get_orientation()
- if self.saved_option_list.get_custom_paper_size():
- self.custom_paper_size = self.saved_option_list.get_custom_paper_size()
- if self.saved_option_list.get_margins():
- self.margins = self.saved_option_list.get_margins()
- if self.saved_option_list.get_css_filename():
- self.css_filename = self.saved_option_list.get_css_filename()
- if self.saved_option_list.get_paper_metric():
- self.paper_metric = self.saved_option_list.get_paper_metric()
- if self.saved_option_list.get_paper_name():
- self.paper_name = self.saved_option_list.get_paper_name()
- if self.saved_option_list.get_format_name():
- self.format_name = self.saved_option_list.get_format_name()
-
- def save_common_options(self):
- # First we save common options
- self.saved_option_list.set_style_name(self.style_name)
- self.saved_option_list.set_orientation(self.orientation)
- self.saved_option_list.set_custom_paper_size(self.custom_paper_size)
- self.saved_option_list.set_margins(self.margins)
- self.saved_option_list.set_paper_metric(self.paper_metric)
- self.saved_option_list.set_paper_name(self.paper_name)
- self.saved_option_list.set_css_filename(self.css_filename)
- self.saved_option_list.set_format_name(self.format_name)
- self.option_list_collection.set_option_list(self.module_name,
- self.saved_option_list)
-
- # Then save last-common options from the current selection
- self.option_list_collection.set_last_orientation(self.orientation)
- self.option_list_collection.set_last_custom_paper_size(self.custom_paper_size)
- self.option_list_collection.set_last_margins(self.margins)
- self.option_list_collection.set_last_paper_metric(self.paper_metric)
- self.option_list_collection.set_last_paper_name(self.paper_name)
- self.option_list_collection.set_last_css_filename(self.css_filename)
- self.option_list_collection.set_last_format_name(self.format_name)
-
- def get_stylesheet_savefile(self):
- """Where to save user defined styles for this report."""
- filename = "%s.xml" % self.module_name
- return os.path.join(const.HOME_DIR, filename)
-
- def get_default_stylesheet_name(self):
- return self.style_name
-
- def set_default_stylesheet_name(self, style_name):
- self.style_name = style_name
-
- def get_format_name(self):
- return self.format_name
-
- def set_format_name(self, format_name):
- self.format_name = format_name
-
- def get_paper_metric(self):
- return self.paper_metric
-
- def set_paper_metric(self, paper_metric):
- self.paper_metric = paper_metric
-
- def get_paper_name(self):
- return self.paper_name
-
- def set_paper_name(self, paper_name):
- self.paper_name = paper_name
-
- def get_paper(self):
- """
- This method is for temporary storage, not for saving/restoring.
- """
- return self.paper
-
- def set_paper(self, paper):
- """
- This method is for temporary storage, not for saving/restoring.
- """
- self.paper = paper
-
- def get_css_filename(self):
- return self.css_filename
-
- def set_css_filename(self, css_filename):
- self.css_filename = css_filename
-
- def get_orientation(self):
- return self.orientation
-
- def set_orientation(self, orientation):
- self.orientation = orientation
-
- def get_custom_paper_size(self):
- return copy.copy(self.custom_paper_size)
-
- def set_custom_paper_size(self, custom_paper_size):
- self.custom_paper_size = copy.copy(custom_paper_size)
-
- def get_margins(self):
- return copy.copy(self.margins)
-
- def set_margins(self,margins):
- self.margins = copy.copy(margins)
-
-#------------------------------------------------------------------------
-#
-# Base Options class
-#
-#------------------------------------------------------------------------
-class ReportOptions(_options.Options):
-
- """
- Defines options and provides handling interface.
-
- This is a base Options class for the reports. All reports, options
- classes should derive from it.
- """
- def __init__(self, name, dbase):
- """
- Initialize the class, performing usual house-keeping tasks.
- Subclasses MUST call this in their __init__() method.
- """
- self.name = name
- self.options_dict = {}
- self.options_help = {}
- self.handler = None
-
- def load_previous_values(self):
- self.handler = OptionHandler(self.name, self.options_dict)
-
- def make_default_style(self, default_style):
- """
- Defines default style for this report.
-
- This method MUST be overridden by reports that use the
- user-adjustable paragraph styles.
-
- NOTE: Unique names MUST be used for all style names, otherwise the
- styles will collide when making a book with duplicate style
- names. A rule of safety is to prepend style name with the
- acronym based on report name. The following acronyms are
- already taken:
- AC- Ancestor Chart
- AC2- Ancestor Chart 2 (Wall Chart)
- AHN- Ahnentafel Report
- AR- Comprehensive Ancestors report
- CBT- Custom Book Text
- DG- Descendant Graph
- DR- Descendant Report
- DAR- Detailed Ancestral Report
- DDR- Detailed Descendant Report
- FGR- Family Group Report
- FC- Fan Chart
- FTA- FTM Style Ancestral report
- FTD- FTM Style Descendant report
- IDS- Individual Complete Report
- IVS- Individual Summary Report
- PLC- Place Report
- SBT- Simple Boot Title
- TLG- Timeline Graph
- """
- pass
-
- def get_document(self):
- """
- Return document instance.
-
- This method MUST NOT be overridden by subclasses.
- """
- return self.handler.doc
-
- def set_document(self, val):
- """
- Set document to a given instance.
-
- This method MUST NOT be overridden by subclasses.
- """
- self.handler.doc = val
-
- def get_output(self):
- """
- Return document output destination.
-
- This method MUST NOT be overridden by subclasses.
- """
- return self.handler.output
-
- def set_output(self, val):
- """
- Set output destination to a given string.
-
- This method MUST NOT be overridden by subclasses.
- """
- self.handler.output = val
-
-#-------------------------------------------------------------------------
-#
-# MenuReportOptions
-#
-#-------------------------------------------------------------------------
-class MenuReportOptions(GuiMenuOptions, ReportOptions):
- """
-
- The MenuReportOptions class implements the ReportOptions
- functionality in a generic way so that the user does not need to
- be concerned with the graphical representation of the options.
-
- The user should inherit the MenuReportOptions class and override the
- add_menu_options function. The user can add options to the menu and the
- MenuReportOptions class will worry about setting up the GUI.
-
- """
- def __init__(self, name, dbase):
- ReportOptions.__init__(self, name, dbase)
- GuiMenuOptions.__init__(self)
-
- def load_previous_values(self):
- ReportOptions.load_previous_values(self)
- # Pass the loaded values to the menu options so they will be displayed
- # properly.
- for optname in self.options_dict:
- menu_option = self.menu.get_option_by_name(optname)
- if menu_option:
- menu_option.set_value(self.options_dict[optname])
-
diff --git a/src/gen/plug/report/_paper.py b/src/gen/plug/report/_paper.py
index bb36e63b7..78eeff74c 100644
--- a/src/gen/plug/report/_paper.py
+++ b/src/gen/plug/report/_paper.py
@@ -54,234 +54,6 @@ except:
#-------------------------------------------------------------------------
paper_sizes = []
-#-------------------------------------------------------------------------
-#
-# PageSizeParser
-#
-#-------------------------------------------------------------------------
-class PageSizeParser(handler.ContentHandler):
- """Parses the XML file and builds the list of page sizes"""
-
- def __init__(self, paper_list):
- handler.ContentHandler.__init__(self)
- self.paper_list = paper_list
- self.locator = None
-
- def setDocumentLocator(self, locator):
- self.locator = locator
-
- def startElement(self, tag, attrs):
- if tag == "page":
- name = attrs['name']
- height = gfloat(attrs['height'])
- width = gfloat(attrs['width'])
- self.paper_list.append(PaperSize(name, height, width))
-
-#-------------------------------------------------------------------------
-#
-# Parse XML file. If failed, used default
-#
-#-------------------------------------------------------------------------
-try:
- parser = make_parser()
- parser.setContentHandler(PageSizeParser(paper_sizes))
- the_file = open(const.PAPERSIZE)
- parser.parse(the_file)
- the_file.close()
- paper_sizes.append(PaperSize(_("Custom Size"), -1, -1))
-except (IOError, OSError, SAXParseException):
- paper_sizes = [
- PaperSize("Letter",27.94,21.59),
- PaperSize("Legal",35.56,21.59),
- PaperSize("A0",118.9,84.1),
- PaperSize("A1",84.1,59.4),
- PaperSize("A2",59.4,42.0),
- PaperSize("A3",42.0,29.7),
- PaperSize("A4",29.7,21.0),
- PaperSize("A5",21.0,14.8),
- PaperSize("B0",141.4,100.0),
- PaperSize("B1",100.0,70.7),
- PaperSize("B2",70.7,50.0),
- PaperSize("B3",50.0,35.3),
- PaperSize("B4",35.3,25.0),
- PaperSize("B5",25.0,17.6),
- PaperSize("B6",17.6,12.5),
- PaperSize("B",43.18,27.94),
- PaperSize("C",55.88,43.18),
- PaperSize("D",86.36, 55.88),
- PaperSize("E",111.76,86.36),
- PaperSize(_("Custom Size"),-1,-1)
- ]
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2000-2007 Donald N. Allingham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id: _PaperMenu.py 14293 2010-02-09 10:48:11Z ldnp $
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-from gen.ggettext import sgettext as _
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-from gen.plug.utils import gfloat
-from gen.plug.docgen import PaperSize
-import const
-
-#-------------------------------------------------------------------------
-#
-# Try to abstract SAX1 from SAX2
-#
-#-------------------------------------------------------------------------
-try:
- from xml.sax import make_parser, handler, SAXParseException
-except:
- from _xmlplus.sax import make_parser, handler, SAXParseException
-
-#-------------------------------------------------------------------------
-#
-# Constants
-#
-#-------------------------------------------------------------------------
-paper_sizes = []
-
-#-------------------------------------------------------------------------
-#
-# PageSizeParser
-#
-#-------------------------------------------------------------------------
-class PageSizeParser(handler.ContentHandler):
- """Parses the XML file and builds the list of page sizes"""
-
- def __init__(self, paper_list):
- handler.ContentHandler.__init__(self)
- self.paper_list = paper_list
- self.locator = None
-
- def setDocumentLocator(self, locator):
- self.locator = locator
-
- def startElement(self, tag, attrs):
- if tag == "page":
- name = attrs['name']
- height = gfloat(attrs['height'])
- width = gfloat(attrs['width'])
- self.paper_list.append(PaperSize(name, height, width))
-
-#-------------------------------------------------------------------------
-#
-# Parse XML file. If failed, used default
-#
-#-------------------------------------------------------------------------
-try:
- parser = make_parser()
- parser.setContentHandler(PageSizeParser(paper_sizes))
- the_file = open(const.PAPERSIZE)
- parser.parse(the_file)
- the_file.close()
- paper_sizes.append(PaperSize(_("Custom Size"), -1, -1))
-except (IOError, OSError, SAXParseException):
- paper_sizes = [
- PaperSize("Letter",27.94,21.59),
- PaperSize("Legal",35.56,21.59),
- PaperSize("A0",118.9,84.1),
- PaperSize("A1",84.1,59.4),
- PaperSize("A2",59.4,42.0),
- PaperSize("A3",42.0,29.7),
- PaperSize("A4",29.7,21.0),
- PaperSize("A5",21.0,14.8),
- PaperSize("B0",141.4,100.0),
- PaperSize("B1",100.0,70.7),
- PaperSize("B2",70.7,50.0),
- PaperSize("B3",50.0,35.3),
- PaperSize("B4",35.3,25.0),
- PaperSize("B5",25.0,17.6),
- PaperSize("B6",17.6,12.5),
- PaperSize("B",43.18,27.94),
- PaperSize("C",55.88,43.18),
- PaperSize("D",86.36, 55.88),
- PaperSize("E",111.76,86.36),
- PaperSize(_("Custom Size"),-1,-1)
- ]
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2000-2007 Donald N. Allingham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id: _PaperMenu.py 14293 2010-02-09 10:48:11Z ldnp $
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-from gen.ggettext import sgettext as _
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-from gen.plug.utils import gfloat
-from gen.plug.docgen import PaperSize
-import const
-
-#-------------------------------------------------------------------------
-#
-# Try to abstract SAX1 from SAX2
-#
-#-------------------------------------------------------------------------
-try:
- from xml.sax import make_parser, handler, SAXParseException
-except:
- from _xmlplus.sax import make_parser, handler, SAXParseException
-
-#-------------------------------------------------------------------------
-#
-# Constants
-#
-#-------------------------------------------------------------------------
-paper_sizes = []
-
#-------------------------------------------------------------------------
#
# PageSizeParser
diff --git a/src/gen/plug/report/_reportbase.py b/src/gen/plug/report/_reportbase.py
index 8491747fe..8560a972c 100644
--- a/src/gen/plug/report/_reportbase.py
+++ b/src/gen/plug/report/_reportbase.py
@@ -61,129 +61,3 @@ class Report(object):
if self.standalone:
self.doc.close()
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001 David R. Hampton
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2007 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id: _Report.py 12559 2009-05-21 17:19:50Z gbritton $
-
-#-------------------------------------------------------------------------
-#
-# Report
-#
-#-------------------------------------------------------------------------
-class Report(object):
- """
- The Report base class. This is a base class for generating
- customized reports. It cannot be used as is, but it can be easily
- sub-classed to create a functional report generator.
- """
-
- def __init__(self, database, options_class):
- self.database = database
- self.options_class = options_class
-
- self.doc = options_class.get_document()
-
- creator = database.get_researcher().get_name()
- self.doc.set_creator(creator)
-
- output = options_class.get_output()
- if output:
- self.standalone = True
- self.doc.open(options_class.get_output())
- else:
- self.standalone = False
-
- def begin_report(self):
- pass
-
- def write_report(self):
- pass
-
- def end_report(self):
- if self.standalone:
- self.doc.close()
-
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001 David R. Hampton
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2007 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id: _Report.py 12559 2009-05-21 17:19:50Z gbritton $
-
-#-------------------------------------------------------------------------
-#
-# Report
-#
-#-------------------------------------------------------------------------
-class Report(object):
- """
- The Report base class. This is a base class for generating
- customized reports. It cannot be used as is, but it can be easily
- sub-classed to create a functional report generator.
- """
-
- def __init__(self, database, options_class):
- self.database = database
- self.options_class = options_class
-
- self.doc = options_class.get_document()
-
- creator = database.get_researcher().get_name()
- self.doc.set_creator(creator)
-
- output = options_class.get_output()
- if output:
- self.standalone = True
- self.doc.open(options_class.get_output())
- else:
- self.standalone = False
-
- def begin_report(self):
- pass
-
- def write_report(self):
- pass
-
- def end_report(self):
- if self.standalone:
- self.doc.close()
-
diff --git a/src/gen/plug/report/endnotes.py b/src/gen/plug/report/endnotes.py
index 05cd815e4..2da931133 100644
--- a/src/gen/plug/report/endnotes.py
+++ b/src/gen/plug/report/endnotes.py
@@ -178,363 +178,3 @@ def _format_source_text(source):
src_txt += "(%s)" % source.get_abbreviation()
return src_txt
-##
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2007 Brian G. Matherly
-# Copyright (C) 2010 Peter Landgren
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id: _Endnotes.py 15169 2010-04-16 20:59:10Z bmcage $
-
-"""
-Provide utilities for printing endnotes in text reports.
-"""
-from gen.plug.docgen import FontStyle, ParagraphStyle, FONT_SANS_SERIF
-from gen.lib import NoteType
-from gen.ggettext import gettext as _
-
-def add_endnote_styles(style_sheet):
- """
- Add paragraph styles to a style sheet to be used for displaying endnotes.
-
- @param style_sheet: Style sheet
- @type style_sheet: L{docgen.StyleSheet}
- """
- font = FontStyle()
- font.set(face=FONT_SANS_SERIF, size=14, italic=1)
- para = ParagraphStyle()
- para.set_font(font)
- para.set_header_level(2)
- para.set_top_margin(0.25)
- para.set_bottom_margin(0.25)
- para.set_description(_('The style used for the generation header.'))
- style_sheet.add_paragraph_style("Endnotes-Header", para)
-
- para = ParagraphStyle()
- para.set(first_indent=-0.75, lmargin=.75)
- para.set_top_margin(0.25)
- para.set_bottom_margin(0.25)
- para.set_description(_('The basic style used for the endnotes source display.'))
- style_sheet.add_paragraph_style("Endnotes-Source", para)
-
- para = ParagraphStyle()
- para.set(first_indent=-0.9, lmargin=1.9)
-# para.set(lmargin=1.5)
- para.set_top_margin(0.25)
- para.set_bottom_margin(0.25)
- para.set_description(_('The basic style used for the endnotes reference display.'))
- style_sheet.add_paragraph_style("Endnotes-Ref", para)
-
- para = ParagraphStyle()
- para.set(lmargin=1.5)
- para.set_top_margin(0.25)
- para.set_bottom_margin(0.25)
- para.set_description(_('The basic style used for the endnotes notes display.'))
- style_sheet.add_paragraph_style("Endnotes-Notes", para)
-
-def cite_source(bibliography, obj):
- """
- Cite any sources for the object and add them to the bibliography.
-
- @param bibliography: The bibliography to contain the citations.
- @type bibliography: L{Bibliography}
- @param obj: An object with source references.
- @type obj: L{gen.lib.srcbase}
- """
- txt = ""
- slist = obj.get_source_references()
- if slist:
- first = 1
- for ref in slist:
- if not first:
- txt += ', '
- first = 0
- (cindex, key) = bibliography.add_reference(ref)
- txt += "%d" % (cindex + 1)
- if key is not None:
- txt += key
- return txt
-
-def write_endnotes(bibliography, database, doc, printnotes=False):
- """
- Write all the entries in the bibliography as endnotes.
-
- @param bibliography: The bibliography that contains the citations.
- @type bibliography: L{Bibliography}
- @param database: The database that the sources come from.
- @type database: DbBase
- @param doc: The document to write the endnotes into.
- @type doc: L{docgen.TextDoc}
- @param printnotes: Indicate if the notes attached to a source must be
- written too.
- @type printnotes: bool
- """
- if bibliography.get_citation_count() == 0:
- return
-
- doc.start_paragraph('Endnotes-Header')
- doc.write_text(_('Endnotes'))
- doc.end_paragraph()
-
- cindex = 0
- for citation in bibliography.get_citation_list():
- cindex += 1
- source = database.get_source_from_handle(citation.get_source_handle())
- first = True
-
- doc.start_paragraph('Endnotes-Source', "%d." % cindex)
-
- src_txt = _format_source_text(source)
-
- doc.write_text(src_txt)
- doc.end_paragraph()
-
- ref_list = citation.get_ref_list()
-
- if ref_list:
- first = True
- reflines = ""
- for key, ref in ref_list:
- txt = "%s: %s" % (key, ref.get_page())
- if first:
- reflines += txt
- first = False
- else:
- reflines += ('\n%s' % txt)
- doc.write_endnotes_ref(reflines,'Endnotes-Ref')
-
- if printnotes:
- note_list = source.get_note_list()
- ind = 1
- for notehandle in note_list:
- note = database.get_note_from_handle(notehandle)
- doc.start_paragraph('Endnotes-Notes')
- doc.write_text(_('Note %(ind)d - Type: %(type)s') % {
- 'ind': ind,
- 'type': str(note.get_type())})
- doc.end_paragraph()
- doc.write_styled_note(note.get_styledtext(),
- note.get_format(),'Endnotes-Notes',
- contains_html= note.get_type() \
- == NoteType.HTML_CODE)
- ind += 1
-
-def _format_source_text(source):
- if not source: return ""
-
- src_txt = ""
-
- if source.get_author():
- src_txt += source.get_author()
-
- if source.get_title():
- if src_txt:
- src_txt += ", "
- src_txt += '"%s"' % source.get_title()
-
- if source.get_publication_info():
- if src_txt:
- src_txt += ", "
- src_txt += source.get_publication_info()
-
- if source.get_abbreviation():
- if src_txt:
- src_txt += ", "
- src_txt += "(%s)" % source.get_abbreviation()
-
- return src_txt
-##
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2007 Brian G. Matherly
-# Copyright (C) 2010 Peter Landgren
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id: _Endnotes.py 15169 2010-04-16 20:59:10Z bmcage $
-
-"""
-Provide utilities for printing endnotes in text reports.
-"""
-from gen.plug.docgen import FontStyle, ParagraphStyle, FONT_SANS_SERIF
-from gen.lib import NoteType
-from gen.ggettext import gettext as _
-
-def add_endnote_styles(style_sheet):
- """
- Add paragraph styles to a style sheet to be used for displaying endnotes.
-
- @param style_sheet: Style sheet
- @type style_sheet: L{docgen.StyleSheet}
- """
- font = FontStyle()
- font.set(face=FONT_SANS_SERIF, size=14, italic=1)
- para = ParagraphStyle()
- para.set_font(font)
- para.set_header_level(2)
- para.set_top_margin(0.25)
- para.set_bottom_margin(0.25)
- para.set_description(_('The style used for the generation header.'))
- style_sheet.add_paragraph_style("Endnotes-Header", para)
-
- para = ParagraphStyle()
- para.set(first_indent=-0.75, lmargin=.75)
- para.set_top_margin(0.25)
- para.set_bottom_margin(0.25)
- para.set_description(_('The basic style used for the endnotes source display.'))
- style_sheet.add_paragraph_style("Endnotes-Source", para)
-
- para = ParagraphStyle()
- para.set(first_indent=-0.9, lmargin=1.9)
-# para.set(lmargin=1.5)
- para.set_top_margin(0.25)
- para.set_bottom_margin(0.25)
- para.set_description(_('The basic style used for the endnotes reference display.'))
- style_sheet.add_paragraph_style("Endnotes-Ref", para)
-
- para = ParagraphStyle()
- para.set(lmargin=1.5)
- para.set_top_margin(0.25)
- para.set_bottom_margin(0.25)
- para.set_description(_('The basic style used for the endnotes notes display.'))
- style_sheet.add_paragraph_style("Endnotes-Notes", para)
-
-def cite_source(bibliography, obj):
- """
- Cite any sources for the object and add them to the bibliography.
-
- @param bibliography: The bibliography to contain the citations.
- @type bibliography: L{Bibliography}
- @param obj: An object with source references.
- @type obj: L{gen.lib.srcbase}
- """
- txt = ""
- slist = obj.get_source_references()
- if slist:
- first = 1
- for ref in slist:
- if not first:
- txt += ', '
- first = 0
- (cindex, key) = bibliography.add_reference(ref)
- txt += "%d" % (cindex + 1)
- if key is not None:
- txt += key
- return txt
-
-def write_endnotes(bibliography, database, doc, printnotes=False):
- """
- Write all the entries in the bibliography as endnotes.
-
- @param bibliography: The bibliography that contains the citations.
- @type bibliography: L{Bibliography}
- @param database: The database that the sources come from.
- @type database: DbBase
- @param doc: The document to write the endnotes into.
- @type doc: L{docgen.TextDoc}
- @param printnotes: Indicate if the notes attached to a source must be
- written too.
- @type printnotes: bool
- """
- if bibliography.get_citation_count() == 0:
- return
-
- doc.start_paragraph('Endnotes-Header')
- doc.write_text(_('Endnotes'))
- doc.end_paragraph()
-
- cindex = 0
- for citation in bibliography.get_citation_list():
- cindex += 1
- source = database.get_source_from_handle(citation.get_source_handle())
- first = True
-
- doc.start_paragraph('Endnotes-Source', "%d." % cindex)
-
- src_txt = _format_source_text(source)
-
- doc.write_text(src_txt)
- doc.end_paragraph()
-
- ref_list = citation.get_ref_list()
-
- if ref_list:
- first = True
- reflines = ""
- for key, ref in ref_list:
- txt = "%s: %s" % (key, ref.get_page())
- if first:
- reflines += txt
- first = False
- else:
- reflines += ('\n%s' % txt)
- doc.write_endnotes_ref(reflines,'Endnotes-Ref')
-
- if printnotes:
- note_list = source.get_note_list()
- ind = 1
- for notehandle in note_list:
- note = database.get_note_from_handle(notehandle)
- doc.start_paragraph('Endnotes-Notes')
- doc.write_text(_('Note %(ind)d - Type: %(type)s') % {
- 'ind': ind,
- 'type': str(note.get_type())})
- doc.end_paragraph()
- doc.write_styled_note(note.get_styledtext(),
- note.get_format(),'Endnotes-Notes',
- contains_html= note.get_type() \
- == NoteType.HTML_CODE)
- ind += 1
-
-def _format_source_text(source):
- if not source: return ""
-
- src_txt = ""
-
- if source.get_author():
- src_txt += source.get_author()
-
- if source.get_title():
- if src_txt:
- src_txt += ", "
- src_txt += '"%s"' % source.get_title()
-
- if source.get_publication_info():
- if src_txt:
- src_txt += ", "
- src_txt += source.get_publication_info()
-
- if source.get_abbreviation():
- if src_txt:
- src_txt += ", "
- src_txt += "(%s)" % source.get_abbreviation()
-
- return src_txt
diff --git a/src/gen/plug/report/utils.py b/src/gen/plug/report/utils.py
index 041036bd7..add0eb91e 100644
--- a/src/gen/plug/report/utils.py
+++ b/src/gen/plug/report/utils.py
@@ -289,585 +289,3 @@ def get_person_filters(person, include_single=True):
the_filters = [all, des, df, ans, com]
the_filters.extend(CustomFilters.get_filters('Person'))
return the_filters
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2000-2007 Donald N. Allingham
-# Copyright (C) 2007-2009 Brian G. Matherly
-# Copyright (C) 2008 James Friedmann
-# Copyright (C) 2010 Jakim Friant
-#
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id:_ReportUtils.py 9912 2008-01-22 09:17:46Z acraphae $
-
-"""
-A collection of utilities to aid in the generation of reports.
-"""
-
-#-------------------------------------------------------------------------
-#
-# Standard Python modules
-#
-#-------------------------------------------------------------------------
-import os
-from gen.ggettext import gettext as _
-
-#------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#------------------------------------------------------------------------
-import DateHandler
-from Utils import media_path_full
-from gen.plug.docgen import IndexMark, INDEX_TYPE_ALP
-
-#-------------------------------------------------------------------------
-#
-# Convert points to cm and back
-#
-#-------------------------------------------------------------------------
-def pt2cm(pt):
- """
- Convert points to centimeters. Fonts are typically specified in points,
- but the BaseDoc classes use centimeters.
-
- @param pt: points
- @type pt: float or int
- @returns: equivalent units in centimeters
- @rtype: float
- """
- return pt/28.3465
-
-def cm2pt(cm):
- """
- Convert centimeters to points. Fonts are typically specified in points,
- but the BaseDoc classes use centimeters.
-
- @param cm: centimeters
- @type cm: float or int
- @returns: equivalent units in points
- @rtype: float
- """
- return cm*28.3465
-
-def rgb_color(color):
- """
- Convert color value from 0-255 integer range into 0-1 float range.
-
- @param color: list or tuple of integer values for red, green, and blue
- @type color: int
- @returns: (r, g, b) tuple of floating point color values
- @rtype: 3-tuple
- """
- r = float(color[0])/255.0
- g = float(color[1])/255.0
- b = float(color[2])/255.0
- return (r, g, b)
-
-#-------------------------------------------------------------------------
-#
-# Roman numbers
-#
-#-------------------------------------------------------------------------
-def roman(num):
- """ Integer to Roman numeral converter for 0 < num < 4000 """
- if not isinstance(num, int):
- return "?"
- if not 0 < num < 4000:
- return "?"
- vals = (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1)
- nums = ( 'M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I')
- retval = ""
- for i in range(len(vals)):
- amount = int(num / vals[i])
- retval += nums[i] * amount
- num -= vals[i] * amount
- return retval
-
-#-------------------------------------------------------------------------
-#
-#
-#
-#-------------------------------------------------------------------------
-def place_name(db, place_handle):
- if place_handle:
- place = db.get_place_from_handle(place_handle).get_title()
- else:
- place = ""
- return unicode(place)
-
-#-------------------------------------------------------------------------
-#
-# Functions commonly used in reports
-#
-#-------------------------------------------------------------------------
-def insert_image(database, doc, photo, w_cm=4.0, h_cm=4.0):
- """
- Insert pictures of a person into the document.
- """
-
- object_handle = photo.get_reference_handle()
- media_object = database.get_object_from_handle(object_handle)
- mime_type = media_object.get_mime_type()
- if mime_type and mime_type.startswith("image"):
- filename = media_path_full(database, media_object.get_path())
- if os.path.exists(filename):
- doc.add_media_object(filename, "right", w_cm, h_cm)
- else:
- # TODO: Replace this with a callback
- from QuestionDialog import WarningDialog
- WarningDialog(_("Could not add photo to page"),
- "%s: %s" % (filename, _('File does not exist')))
-
-#-------------------------------------------------------------------------
-#
-# find_spouse
-#
-#-------------------------------------------------------------------------
-def find_spouse(person, family):
- if person.get_handle() == family.get_father_handle():
- spouse_handle = family.get_mother_handle()
- else:
- spouse_handle = family.get_father_handle()
- return spouse_handle
-
-#-------------------------------------------------------------------------
-#
-# find_marriage
-#
-#-------------------------------------------------------------------------
-def find_marriage(database, family):
- for event_ref in family.get_event_ref_list():
- event = database.get_event_from_handle(event_ref.ref)
- if (event and event.type.is_marriage() and
- event_ref.role.is_family()):
- return event
- return None
-
-#-------------------------------------------------------------------------
-#
-# Indexing function
-#
-#-------------------------------------------------------------------------
-def get_person_mark(db, person):
- """
- Return a IndexMark that can be used to index a person in a report
-
- @param db: the GRAMPS database instance
- @param person: the the key is for
- """
- if not person:
- return None
-
- name = person.get_primary_name().get_name()
- birth = " "
- death = " "
- key = ""
-
- birth_ref = person.get_birth_ref()
- if birth_ref:
- birthEvt = db.get_event_from_handle(birth_ref.ref)
- birth = DateHandler.get_date(birthEvt)
-
- death_ref = person.get_death_ref()
- if death_ref:
- deathEvt = db.get_event_from_handle(death_ref.ref)
- death = DateHandler.get_date(deathEvt)
-
- if birth == death == " ":
- key = name
- else:
- key = "%s (%s - %s)" % (name, birth, death)
-
- return IndexMark( key, INDEX_TYPE_ALP )
-
-#-------------------------------------------------------------------------
-#
-# Address String
-#
-#-------------------------------------------------------------------------
-def get_address_str(addr):
- """
- Return a string that combines the elements of an addres
-
- @param addr: the GRAMPS address instance
- """
- str = ""
- elems = [ addr.get_street(),
- addr.get_city(),
- addr.get_county(),
- addr.get_state(),
- addr.get_country(),
- addr.get_postal_code(),
- addr.get_phone() ]
-
- for info in elems:
- if info:
- if str == "":
- str = info
- else:
- str = "%s, %s" % (str, info)
- return str
-
-#-------------------------------------------------------------------------
-#
-# People Filters
-#
-#-------------------------------------------------------------------------
-def get_person_filters(person, include_single=True):
- """
- Return a list of filters that are relevant for the given person
-
- @param person: the person the filters should apply to.
- @type person: L{Person}
- @param include_single: include a filter to include the single person
- @type person: boolean
- """
- from Filters import GenericFilter, Rules, CustomFilters
- from gen.display.name import displayer as name_displayer
-
- if person:
- name = name_displayer.display(person)
- gramps_id = person.get_gramps_id()
- else:
- # Do this in case of command line options query (show=filter)
- name = 'PERSON'
- gramps_id = ''
-
- if include_single:
- filt_id = GenericFilter()
- filt_id.set_name(name)
- filt_id.add_rule(Rules.Person.HasIdOf([gramps_id]))
-
- all = GenericFilter()
- all.set_name(_("Entire Database"))
- all.add_rule(Rules.Person.Everyone([]))
-
- des = GenericFilter()
- des.set_name(_("Descendants of %s") % name)
- des.add_rule(Rules.Person.IsDescendantOf([gramps_id, 1]))
-
- df = GenericFilter()
- df.set_name(_("Descendant Families of %s") % name)
- df.add_rule(Rules.Person.IsDescendantFamilyOf([gramps_id, 1]))
-
- ans = GenericFilter()
- ans.set_name(_("Ancestors of %s") % name)
- ans.add_rule(Rules.Person.IsAncestorOf([gramps_id, 1]))
-
- com = GenericFilter()
- com.set_name(_("People with common ancestor with %s") % name)
- com.add_rule(Rules.Person.HasCommonAncestorWith([gramps_id]))
-
- if include_single:
- the_filters = [filt_id, all, des, df, ans, com]
- else:
- the_filters = [all, des, df, ans, com]
- the_filters.extend(CustomFilters.get_filters('Person'))
- return the_filters
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2000-2007 Donald N. Allingham
-# Copyright (C) 2007-2009 Brian G. Matherly
-# Copyright (C) 2008 James Friedmann
-# Copyright (C) 2010 Jakim Friant
-#
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id:_ReportUtils.py 9912 2008-01-22 09:17:46Z acraphae $
-
-"""
-A collection of utilities to aid in the generation of reports.
-"""
-
-#-------------------------------------------------------------------------
-#
-# Standard Python modules
-#
-#-------------------------------------------------------------------------
-import os
-from gen.ggettext import gettext as _
-
-#------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#------------------------------------------------------------------------
-import DateHandler
-from Utils import media_path_full
-from gen.plug.docgen import IndexMark, INDEX_TYPE_ALP
-
-#-------------------------------------------------------------------------
-#
-# Convert points to cm and back
-#
-#-------------------------------------------------------------------------
-def pt2cm(pt):
- """
- Convert points to centimeters. Fonts are typically specified in points,
- but the BaseDoc classes use centimeters.
-
- @param pt: points
- @type pt: float or int
- @returns: equivalent units in centimeters
- @rtype: float
- """
- return pt/28.3465
-
-def cm2pt(cm):
- """
- Convert centimeters to points. Fonts are typically specified in points,
- but the BaseDoc classes use centimeters.
-
- @param cm: centimeters
- @type cm: float or int
- @returns: equivalent units in points
- @rtype: float
- """
- return cm*28.3465
-
-def rgb_color(color):
- """
- Convert color value from 0-255 integer range into 0-1 float range.
-
- @param color: list or tuple of integer values for red, green, and blue
- @type color: int
- @returns: (r, g, b) tuple of floating point color values
- @rtype: 3-tuple
- """
- r = float(color[0])/255.0
- g = float(color[1])/255.0
- b = float(color[2])/255.0
- return (r, g, b)
-
-#-------------------------------------------------------------------------
-#
-# Roman numbers
-#
-#-------------------------------------------------------------------------
-def roman(num):
- """ Integer to Roman numeral converter for 0 < num < 4000 """
- if not isinstance(num, int):
- return "?"
- if not 0 < num < 4000:
- return "?"
- vals = (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1)
- nums = ( 'M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I')
- retval = ""
- for i in range(len(vals)):
- amount = int(num / vals[i])
- retval += nums[i] * amount
- num -= vals[i] * amount
- return retval
-
-#-------------------------------------------------------------------------
-#
-#
-#
-#-------------------------------------------------------------------------
-def place_name(db, place_handle):
- if place_handle:
- place = db.get_place_from_handle(place_handle).get_title()
- else:
- place = ""
- return unicode(place)
-
-#-------------------------------------------------------------------------
-#
-# Functions commonly used in reports
-#
-#-------------------------------------------------------------------------
-def insert_image(database, doc, photo, w_cm=4.0, h_cm=4.0):
- """
- Insert pictures of a person into the document.
- """
-
- object_handle = photo.get_reference_handle()
- media_object = database.get_object_from_handle(object_handle)
- mime_type = media_object.get_mime_type()
- if mime_type and mime_type.startswith("image"):
- filename = media_path_full(database, media_object.get_path())
- if os.path.exists(filename):
- doc.add_media_object(filename, "right", w_cm, h_cm)
- else:
- # TODO: Replace this with a callback
- from QuestionDialog import WarningDialog
- WarningDialog(_("Could not add photo to page"),
- "%s: %s" % (filename, _('File does not exist')))
-
-#-------------------------------------------------------------------------
-#
-# find_spouse
-#
-#-------------------------------------------------------------------------
-def find_spouse(person, family):
- if person.get_handle() == family.get_father_handle():
- spouse_handle = family.get_mother_handle()
- else:
- spouse_handle = family.get_father_handle()
- return spouse_handle
-
-#-------------------------------------------------------------------------
-#
-# find_marriage
-#
-#-------------------------------------------------------------------------
-def find_marriage(database, family):
- for event_ref in family.get_event_ref_list():
- event = database.get_event_from_handle(event_ref.ref)
- if (event and event.type.is_marriage() and
- event_ref.role.is_family()):
- return event
- return None
-
-#-------------------------------------------------------------------------
-#
-# Indexing function
-#
-#-------------------------------------------------------------------------
-def get_person_mark(db, person):
- """
- Return a IndexMark that can be used to index a person in a report
-
- @param db: the GRAMPS database instance
- @param person: the the key is for
- """
- if not person:
- return None
-
- name = person.get_primary_name().get_name()
- birth = " "
- death = " "
- key = ""
-
- birth_ref = person.get_birth_ref()
- if birth_ref:
- birthEvt = db.get_event_from_handle(birth_ref.ref)
- birth = DateHandler.get_date(birthEvt)
-
- death_ref = person.get_death_ref()
- if death_ref:
- deathEvt = db.get_event_from_handle(death_ref.ref)
- death = DateHandler.get_date(deathEvt)
-
- if birth == death == " ":
- key = name
- else:
- key = "%s (%s - %s)" % (name, birth, death)
-
- return IndexMark( key, INDEX_TYPE_ALP )
-
-#-------------------------------------------------------------------------
-#
-# Address String
-#
-#-------------------------------------------------------------------------
-def get_address_str(addr):
- """
- Return a string that combines the elements of an addres
-
- @param addr: the GRAMPS address instance
- """
- str = ""
- elems = [ addr.get_street(),
- addr.get_city(),
- addr.get_county(),
- addr.get_state(),
- addr.get_country(),
- addr.get_postal_code(),
- addr.get_phone() ]
-
- for info in elems:
- if info:
- if str == "":
- str = info
- else:
- str = "%s, %s" % (str, info)
- return str
-
-#-------------------------------------------------------------------------
-#
-# People Filters
-#
-#-------------------------------------------------------------------------
-def get_person_filters(person, include_single=True):
- """
- Return a list of filters that are relevant for the given person
-
- @param person: the person the filters should apply to.
- @type person: L{Person}
- @param include_single: include a filter to include the single person
- @type person: boolean
- """
- from Filters import GenericFilter, Rules, CustomFilters
- from gen.display.name import displayer as name_displayer
-
- if person:
- name = name_displayer.display(person)
- gramps_id = person.get_gramps_id()
- else:
- # Do this in case of command line options query (show=filter)
- name = 'PERSON'
- gramps_id = ''
-
- if include_single:
- filt_id = GenericFilter()
- filt_id.set_name(name)
- filt_id.add_rule(Rules.Person.HasIdOf([gramps_id]))
-
- all = GenericFilter()
- all.set_name(_("Entire Database"))
- all.add_rule(Rules.Person.Everyone([]))
-
- des = GenericFilter()
- des.set_name(_("Descendants of %s") % name)
- des.add_rule(Rules.Person.IsDescendantOf([gramps_id, 1]))
-
- df = GenericFilter()
- df.set_name(_("Descendant Families of %s") % name)
- df.add_rule(Rules.Person.IsDescendantFamilyOf([gramps_id, 1]))
-
- ans = GenericFilter()
- ans.set_name(_("Ancestors of %s") % name)
- ans.add_rule(Rules.Person.IsAncestorOf([gramps_id, 1]))
-
- com = GenericFilter()
- com.set_name(_("People with common ancestor with %s") % name)
- com.add_rule(Rules.Person.HasCommonAncestorWith([gramps_id]))
-
- if include_single:
- the_filters = [filt_id, all, des, df, ans, com]
- else:
- the_filters = [all, des, df, ans, com]
- the_filters.extend(CustomFilters.get_filters('Person'))
- return the_filters
diff --git a/src/gui/plug/__init__.py b/src/gui/plug/__init__.py
index b45ff82fd..252ec729e 100644
--- a/src/gui/plug/__init__.py
+++ b/src/gui/plug/__init__.py
@@ -34,106 +34,6 @@ from _guioptions import GuiMenuOptions, make_gui_option
from _dialogs import ReportPluginDialog, ToolPluginDialog
import _windows as PluginWindows
-# This needs to go above Tool and MenuOption as it needs both
-class MenuToolOptions(GuiMenuOptions, tool.ToolOptions):
- """
- The MenuToolOptions class implements the ToolOptions
- functionality in a generic way so that the user does not need to
- be concerned with the graphical representation of the options.
-
- The user should inherit the MenuToolOptions class and override the
- add_menu_options function. The user can add options to the menu
- and the MenuToolOptions class will worry about setting up the GUI.
- """
- def __init__(self, name, person_id=None, dbstate=None):
- tool.ToolOptions.__init__(self, name, person_id)
- GuiMenuOptions.__init__(self)
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2008 Brian Matherly
-# Copyright (C) 2008 Gary Burton
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# gui.plug.__init__.py
-#
-# $Id$
-#
-__author__="jfriant"
-__date__ ="$Apr 20, 2010 3:13:24 PM$"
-
-from gui.plug import tool
-
-from _guioptions import GuiMenuOptions, make_gui_option
-
-from _dialogs import ReportPluginDialog, ToolPluginDialog
-import _windows as PluginWindows
-
-# This needs to go above Tool and MenuOption as it needs both
-class MenuToolOptions(GuiMenuOptions, tool.ToolOptions):
- """
- The MenuToolOptions class implements the ToolOptions
- functionality in a generic way so that the user does not need to
- be concerned with the graphical representation of the options.
-
- The user should inherit the MenuToolOptions class and override the
- add_menu_options function. The user can add options to the menu
- and the MenuToolOptions class will worry about setting up the GUI.
- """
- def __init__(self, name, person_id=None, dbstate=None):
- tool.ToolOptions.__init__(self, name, person_id)
- GuiMenuOptions.__init__(self)
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2008 Brian Matherly
-# Copyright (C) 2008 Gary Burton
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# gui.plug.__init__.py
-#
-# $Id$
-#
-__author__="jfriant"
-__date__ ="$Apr 20, 2010 3:13:24 PM$"
-
-from gui.plug import tool
-
-from _guioptions import GuiMenuOptions, make_gui_option
-
-from _dialogs import ReportPluginDialog, ToolPluginDialog
-import _windows as PluginWindows
-
# This needs to go above Tool and MenuOption as it needs both
class MenuToolOptions(GuiMenuOptions, tool.ToolOptions):
"""
diff --git a/src/gui/plug/_dialogs.py b/src/gui/plug/_dialogs.py
index 57cf4510f..f7864104a 100644
--- a/src/gui/plug/_dialogs.py
+++ b/src/gui/plug/_dialogs.py
@@ -316,639 +316,3 @@ class ToolPluginDialog(PluginDialog):
def rebuild(self):
tool_list = self._pmgr.get_reg_tools()
self.build_plugin_tree(tool_list, tool.tool_categories)
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2000-2006 Donald N. Allingham
-# Copyright (C) 2008 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# GTK libraries
-#
-#-------------------------------------------------------------------------
-import gtk
-
-#-------------------------------------------------------------------------
-#
-# Standard Python modules
-#
-#-------------------------------------------------------------------------
-from gen.ggettext import gettext as _
-from collections import defaultdict
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-import const
-from gen.plug.report._constants import standalone_categories
-from gui.plug import tool
-from gen.plug import REPORT
-from gui.plug.report import report
-from gui.pluginmanager import GuiPluginManager
-import ManagedWindow
-
-#-------------------------------------------------------------------------
-#
-# Constants
-#
-#-------------------------------------------------------------------------
-_REPORTS = 0
-_TOOLS = 1
-_UNSUPPORTED = _("Unsupported")
-
-#-------------------------------------------------------------------------
-#
-# PluginDialog interface class
-#
-#-------------------------------------------------------------------------
-class PluginDialog(ManagedWindow.ManagedWindow):
- """
- Displays the dialog box that allows the user to select the
- plugin that is desired.
- """
- def __init__(self, state, uistate, track, categories, msg,
- label=None, button_label=None, tool_tip=None,
- content=_REPORTS):
- """
- Display the dialog box, and build up the list of available
- reports. This is used to build the selection tree on the left
- hand side of the dialog box.
- """
- self.active = uistate.get_active('Person')
- self.imap = {}
- self.msg = msg
- self.content = content
- self._pmgr = GuiPluginManager.get_instance()
-
- ManagedWindow.ManagedWindow.__init__(self, uistate, track,
- self.__class__)
-
- self.state = state
- self.uistate = uistate
-
- self.dialog = gtk.Builder()
- self.dialog.add_from_file(const.PLUGINS_GLADE)
- self.dialog.connect_signals({
- "on_report_apply_clicked" : self.on_apply_clicked,
- "destroy_passed_object" : self.close,
- "on_delete_event": self.close,
- })
-
- self.tree = self.dialog.get_object("tree")
- window = self.dialog.get_object("report")
- self.title = self.dialog.get_object("title")
-
- self.set_window(window, self.title, msg )
-
- self.store = gtk.TreeStore(str)
- self.selection = self.tree.get_selection()
- self.selection.connect('changed', self.on_node_selected)
- col = gtk.TreeViewColumn('', gtk.CellRendererText(), text=0)
- self.tree.append_column(col)
- self.tree.set_model(self.store)
-
- self.description = self.dialog.get_object("description")
- if label:
- self.description.set_text(label)
- self.status = self.dialog.get_object("report_status")
-
- self.author_name = self.dialog.get_object("author_name")
- self.author_email = self.dialog.get_object("author_email")
-
- self.apply_button = self.dialog.get_object("apply")
- if button_label:
- self.apply_button.set_label(button_label)
- else:
- self.apply_button.set_label(_("_Apply"))
- self.apply_button.set_use_underline(True)
- if tool_tip:
- self.apply_button.set_tooltip_text(tool_tip)
-
- self.item = None
-
- if content == _REPORTS:
- reg_list = self._pmgr.get_reg_reports()
- elif content == _TOOLS:
- reg_list = self._pmgr.get_reg_tools()
- else:
- reg_list = []
- self.build_plugin_tree(reg_list, categories)
- self.show()
-
- def rebuild(self):
- # This method needs to be overridden in the subclass
- assert False, "This method needs to be overridden in the subclass."
-
- def build_menu_names(self, obj):
- return (self.msg, None)
-
- def on_apply_clicked(self, obj):
- """Execute the selected report"""
- if not self.item:
- return
- self.run_plugin(self.item)
-
- def on_node_selected(self, obj):
- """Updates the informational display on the right hand side of
- the dialog box with the description of the selected report"""
-
- store, node = self.selection.get_selected()
- if node:
- path = store.get_path(node)
- if not node or path not in self.imap:
- return
- pdata = self.imap[path]
-
- #(report_class, options_class, title, category, name,
- # doc,status,author,email,unsupported,require_active) = data
- self.description.set_text(pdata.description)
- if not pdata.supported:
- status = _UNSUPPORTED
- self.status.set_text(pdata.statustext())
- self.title.set_text('%s' \
- % pdata.name)
- self.title.set_use_markup(1)
- self.author_name.set_text(', '.join(pdata.authors))
- self.author_email.set_text(', '.join(pdata.authors_email))
- self.item = pdata
-
- def build_plugin_tree(self, reg_list, categories):
- """Populates a GtkTree with each menu item associated with a entry
- in the lists. The list consists of PluginData objects for reports or
- tools.
-
- old data was (item_class, options_class,title,category, name,
- doc,status,author,email)
-
- Items in the same category are grouped under the same submenu.
- The categories must be dicts from integer to string.
- """
- ilist = []
- self.store.clear()
-
- # build the tree items and group together based on the category name
- item_hash = defaultdict(list)
- for plugin in reg_list:
- if not plugin.supported:
- category = _UNSUPPORTED
- else:
- category = categories[plugin.category]
- item_hash[category].append(plugin)
-
- # add a submenu for each category, and populate it with the
- # GtkTreeItems that are associated with it.
- key_list = [item for item in item_hash if item != _UNSUPPORTED]
- key_list.sort(reverse=True)
-
- prev = None
- if _UNSUPPORTED in item_hash:
- key = _UNSUPPORTED
- data = item_hash[key]
- node = self.store.insert_after(None, prev)
- self.store.set(node, 0, key)
- next = None
- data.sort(lambda x, y: cmp(x.name, y.name))
- for item in data:
- next = self.store.insert_after(node, next)
- ilist.append((next, item))
- self.store.set(next, 0, item.name)
- for key in key_list:
- data = item_hash[key]
- node = self.store.insert_after(None, prev)
- self.store.set(node, 0, key)
- next = None
- data.sort(key=lambda k:k.name)
- for item in data:
- next = self.store.insert_after(node, next)
- ilist.append((next, item))
- self.store.set(next, 0, item.name)
- for next, tab in ilist:
- path = self.store.get_path(next)
- self.imap[path] = tab
-
- def run_plugin(self, pdata):
- """
- run a plugin based on it's PluginData:
- 1/ load plugin.
- 2/ the report is run
- """
- mod = self._pmgr.load_plugin(pdata)
- if not mod:
- #import of plugin failed
- return
-
- if pdata.ptype == REPORT:
- active_handle = self.uistate.get_active('Person')
- report(self.state, self.uistate,
- self.state.db.get_person_from_handle(active_handle),
- eval('mod.' + pdata.reportclass),
- eval('mod.' + pdata.optionclass),
- pdata.name, pdata.id,
- pdata.category, pdata.require_active)
- else:
- tool.gui_tool(self.state, self.uistate,
- eval('mod.' + pdata.toolclass),
- eval('mod.' + pdata.optionclass),
- pdata.name, pdata.id, pdata.category,
- self.state.db.request_rebuild)
-
-#-------------------------------------------------------------------------
-#
-# ReportPluginDialog
-#
-#-------------------------------------------------------------------------
-class ReportPluginDialog(PluginDialog):
- """
- Displays the dialog box that allows the user to select the
- report that is desired.
- """
-
- def __init__(self, dbstate, uistate, track):
- """Display the dialog box, and build up the list of available
- reports. This is used to build the selection tree on the left
- hand side of the dailog box."""
-
- PluginDialog.__init__(
- self,
- dbstate,
- uistate,
- track,
- standalone_categories,
- _("Report Selection"),
- _("Select a report from those available on the left."),
- _("_Generate"), _("Generate selected report"),
- _REPORTS)
-
- self._pmgr.connect('plugins-reloaded', self.rebuild)
-
- def rebuild(self):
- report_list = self._pmgr.get_reg_reports()
- self.build_plugin_tree(report_list, standalone_categories)
-
-#-------------------------------------------------------------------------
-#
-# ToolPluginDialog
-#
-#-------------------------------------------------------------------------
-class ToolPluginDialog(PluginDialog):
- """Displays the dialog box that allows the user to select the tool
- that is desired."""
-
- def __init__(self, dbstate, uistate, track):
- """Display the dialog box, and build up the list of available
- reports. This is used to build the selection tree on the left
- hand side of the dailog box."""
-
- PluginDialog.__init__(
- self,
- dbstate,
- uistate,
- track,
- tool.tool_categories,
- _("Tool Selection"),
- _("Select a tool from those available on the left."),
- _("_Run"),
- _("Run selected tool"),
- _TOOLS)
-
- def rebuild(self):
- tool_list = self._pmgr.get_reg_tools()
- self.build_plugin_tree(tool_list, tool.tool_categories)
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2000-2006 Donald N. Allingham
-# Copyright (C) 2008 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# GTK libraries
-#
-#-------------------------------------------------------------------------
-import gtk
-
-#-------------------------------------------------------------------------
-#
-# Standard Python modules
-#
-#-------------------------------------------------------------------------
-from gen.ggettext import gettext as _
-from collections import defaultdict
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-import const
-from gen.plug.report._constants import standalone_categories
-from gui.plug import tool
-from gen.plug import REPORT
-from gui.plug.report import report
-from gui.pluginmanager import GuiPluginManager
-import ManagedWindow
-
-#-------------------------------------------------------------------------
-#
-# Constants
-#
-#-------------------------------------------------------------------------
-_REPORTS = 0
-_TOOLS = 1
-_UNSUPPORTED = _("Unsupported")
-
-#-------------------------------------------------------------------------
-#
-# PluginDialog interface class
-#
-#-------------------------------------------------------------------------
-class PluginDialog(ManagedWindow.ManagedWindow):
- """
- Displays the dialog box that allows the user to select the
- plugin that is desired.
- """
- def __init__(self, state, uistate, track, categories, msg,
- label=None, button_label=None, tool_tip=None,
- content=_REPORTS):
- """
- Display the dialog box, and build up the list of available
- reports. This is used to build the selection tree on the left
- hand side of the dialog box.
- """
- self.active = uistate.get_active('Person')
- self.imap = {}
- self.msg = msg
- self.content = content
- self._pmgr = GuiPluginManager.get_instance()
-
- ManagedWindow.ManagedWindow.__init__(self, uistate, track,
- self.__class__)
-
- self.state = state
- self.uistate = uistate
-
- self.dialog = gtk.Builder()
- self.dialog.add_from_file(const.PLUGINS_GLADE)
- self.dialog.connect_signals({
- "on_report_apply_clicked" : self.on_apply_clicked,
- "destroy_passed_object" : self.close,
- "on_delete_event": self.close,
- })
-
- self.tree = self.dialog.get_object("tree")
- window = self.dialog.get_object("report")
- self.title = self.dialog.get_object("title")
-
- self.set_window(window, self.title, msg )
-
- self.store = gtk.TreeStore(str)
- self.selection = self.tree.get_selection()
- self.selection.connect('changed', self.on_node_selected)
- col = gtk.TreeViewColumn('', gtk.CellRendererText(), text=0)
- self.tree.append_column(col)
- self.tree.set_model(self.store)
-
- self.description = self.dialog.get_object("description")
- if label:
- self.description.set_text(label)
- self.status = self.dialog.get_object("report_status")
-
- self.author_name = self.dialog.get_object("author_name")
- self.author_email = self.dialog.get_object("author_email")
-
- self.apply_button = self.dialog.get_object("apply")
- if button_label:
- self.apply_button.set_label(button_label)
- else:
- self.apply_button.set_label(_("_Apply"))
- self.apply_button.set_use_underline(True)
- if tool_tip:
- self.apply_button.set_tooltip_text(tool_tip)
-
- self.item = None
-
- if content == _REPORTS:
- reg_list = self._pmgr.get_reg_reports()
- elif content == _TOOLS:
- reg_list = self._pmgr.get_reg_tools()
- else:
- reg_list = []
- self.build_plugin_tree(reg_list, categories)
- self.show()
-
- def rebuild(self):
- # This method needs to be overridden in the subclass
- assert False, "This method needs to be overridden in the subclass."
-
- def build_menu_names(self, obj):
- return (self.msg, None)
-
- def on_apply_clicked(self, obj):
- """Execute the selected report"""
- if not self.item:
- return
- self.run_plugin(self.item)
-
- def on_node_selected(self, obj):
- """Updates the informational display on the right hand side of
- the dialog box with the description of the selected report"""
-
- store, node = self.selection.get_selected()
- if node:
- path = store.get_path(node)
- if not node or path not in self.imap:
- return
- pdata = self.imap[path]
-
- #(report_class, options_class, title, category, name,
- # doc,status,author,email,unsupported,require_active) = data
- self.description.set_text(pdata.description)
- if not pdata.supported:
- status = _UNSUPPORTED
- self.status.set_text(pdata.statustext())
- self.title.set_text('%s' \
- % pdata.name)
- self.title.set_use_markup(1)
- self.author_name.set_text(', '.join(pdata.authors))
- self.author_email.set_text(', '.join(pdata.authors_email))
- self.item = pdata
-
- def build_plugin_tree(self, reg_list, categories):
- """Populates a GtkTree with each menu item associated with a entry
- in the lists. The list consists of PluginData objects for reports or
- tools.
-
- old data was (item_class, options_class,title,category, name,
- doc,status,author,email)
-
- Items in the same category are grouped under the same submenu.
- The categories must be dicts from integer to string.
- """
- ilist = []
- self.store.clear()
-
- # build the tree items and group together based on the category name
- item_hash = defaultdict(list)
- for plugin in reg_list:
- if not plugin.supported:
- category = _UNSUPPORTED
- else:
- category = categories[plugin.category]
- item_hash[category].append(plugin)
-
- # add a submenu for each category, and populate it with the
- # GtkTreeItems that are associated with it.
- key_list = [item for item in item_hash if item != _UNSUPPORTED]
- key_list.sort(reverse=True)
-
- prev = None
- if _UNSUPPORTED in item_hash:
- key = _UNSUPPORTED
- data = item_hash[key]
- node = self.store.insert_after(None, prev)
- self.store.set(node, 0, key)
- next = None
- data.sort(lambda x, y: cmp(x.name, y.name))
- for item in data:
- next = self.store.insert_after(node, next)
- ilist.append((next, item))
- self.store.set(next, 0, item.name)
- for key in key_list:
- data = item_hash[key]
- node = self.store.insert_after(None, prev)
- self.store.set(node, 0, key)
- next = None
- data.sort(key=lambda k:k.name)
- for item in data:
- next = self.store.insert_after(node, next)
- ilist.append((next, item))
- self.store.set(next, 0, item.name)
- for next, tab in ilist:
- path = self.store.get_path(next)
- self.imap[path] = tab
-
- def run_plugin(self, pdata):
- """
- run a plugin based on it's PluginData:
- 1/ load plugin.
- 2/ the report is run
- """
- mod = self._pmgr.load_plugin(pdata)
- if not mod:
- #import of plugin failed
- return
-
- if pdata.ptype == REPORT:
- active_handle = self.uistate.get_active('Person')
- report(self.state, self.uistate,
- self.state.db.get_person_from_handle(active_handle),
- eval('mod.' + pdata.reportclass),
- eval('mod.' + pdata.optionclass),
- pdata.name, pdata.id,
- pdata.category, pdata.require_active)
- else:
- tool.gui_tool(self.state, self.uistate,
- eval('mod.' + pdata.toolclass),
- eval('mod.' + pdata.optionclass),
- pdata.name, pdata.id, pdata.category,
- self.state.db.request_rebuild)
-
-#-------------------------------------------------------------------------
-#
-# ReportPluginDialog
-#
-#-------------------------------------------------------------------------
-class ReportPluginDialog(PluginDialog):
- """
- Displays the dialog box that allows the user to select the
- report that is desired.
- """
-
- def __init__(self, dbstate, uistate, track):
- """Display the dialog box, and build up the list of available
- reports. This is used to build the selection tree on the left
- hand side of the dailog box."""
-
- PluginDialog.__init__(
- self,
- dbstate,
- uistate,
- track,
- standalone_categories,
- _("Report Selection"),
- _("Select a report from those available on the left."),
- _("_Generate"), _("Generate selected report"),
- _REPORTS)
-
- self._pmgr.connect('plugins-reloaded', self.rebuild)
-
- def rebuild(self):
- report_list = self._pmgr.get_reg_reports()
- self.build_plugin_tree(report_list, standalone_categories)
-
-#-------------------------------------------------------------------------
-#
-# ToolPluginDialog
-#
-#-------------------------------------------------------------------------
-class ToolPluginDialog(PluginDialog):
- """Displays the dialog box that allows the user to select the tool
- that is desired."""
-
- def __init__(self, dbstate, uistate, track):
- """Display the dialog box, and build up the list of available
- reports. This is used to build the selection tree on the left
- hand side of the dailog box."""
-
- PluginDialog.__init__(
- self,
- dbstate,
- uistate,
- track,
- tool.tool_categories,
- _("Tool Selection"),
- _("Select a tool from those available on the left."),
- _("_Run"),
- _("Run selected tool"),
- _TOOLS)
-
- def rebuild(self):
- tool_list = self._pmgr.get_reg_tools()
- self.build_plugin_tree(tool_list, tool.tool_categories)
diff --git a/src/gui/plug/_guioptions.py b/src/gui/plug/_guioptions.py
index a24a0bfe6..8a200e117 100644
--- a/src/gui/plug/_guioptions.py
+++ b/src/gui/plug/_guioptions.py
@@ -1537,3081 +1537,3 @@ def make_gui_option(option, dbstate, uistate, track):
raise AttributeError(
"can't make GuiOption: unknown option type: '%s'" % option)
return widget, label
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2007-2008 Brian G. Matherly
-# Copyright (C) 2008,2010 Gary Burton
-# Copyright (C) 2008 Craig J. Anderson
-# Copyright (C) 2009 Nick Hall
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id$
-
-"""
-Specific option handling for a GUI.
-"""
-#------------------------------------------------------------------------
-#
-# python modules
-#
-#------------------------------------------------------------------------
-from gen.ggettext import gettext as _
-import os
-import sys
-
-#-------------------------------------------------------------------------
-#
-# gtk modules
-#
-#-------------------------------------------------------------------------
-import gtk
-import gobject
-
-#-------------------------------------------------------------------------
-#
-# gramps modules
-#
-#-------------------------------------------------------------------------
-import Utils
-from gui.utils import ProgressMeter
-from gui.pluginmanager import GuiPluginManager
-from gui import widgets
-import ManagedWindow
-from QuestionDialog import OptionDialog
-from gui.selectors import SelectorFactory
-from gen.display.name import displayer as _nd
-from Filters import GenericFilterFactory, GenericFilter, Rules
-import gen
-
-#------------------------------------------------------------------------
-#
-# Dialog window used to select a surname
-#
-#------------------------------------------------------------------------
-class LastNameDialog(ManagedWindow.ManagedWindow):
- """
- A dialog that allows the selection of a surname from the database.
- """
- def __init__(self, database, uistate, track, surnames, skip_list=set()):
-
- ManagedWindow.ManagedWindow.__init__(self, uistate, track, self)
- flags = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT | \
- gtk.DIALOG_NO_SEPARATOR
- buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK,
- gtk.RESPONSE_ACCEPT)
- self.__dlg = gtk.Dialog(None, uistate.window, flags, buttons)
- self.__dlg.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.set_window(self.__dlg, None, _('Select surname'))
- self.window.set_default_size(400, 400)
-
- # build up a container to display all of the people of interest
- self.__model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT)
- self.__tree_view = gtk.TreeView(self.__model)
- col1 = gtk.TreeViewColumn(_('Surname'), gtk.CellRendererText(), text=0)
- col2 = gtk.TreeViewColumn(_('Count'), gtk.CellRendererText(), text=1)
- col1.set_resizable(True)
- col2.set_resizable(True)
- col1.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col2.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col1.set_sort_column_id(0)
- col2.set_sort_column_id(1)
- self.__tree_view.append_column(col1)
- self.__tree_view.append_column(col2)
- scrolled_window = gtk.ScrolledWindow()
- scrolled_window.add(self.__tree_view)
- scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- scrolled_window.set_shadow_type(gtk.SHADOW_OUT)
- self.__dlg.vbox.pack_start(scrolled_window, expand=True, fill=True)
- scrolled_window.show_all()
-
- if len(surnames) == 0:
- # we could use database.get_surname_list(), but if we do that
- # all we get is a list of names without a count...therefore
- # we'll traverse the entire database ourself and build up a
- # list that we can use
-# for name in database.get_surname_list():
-# self.__model.append([name, 0])
-
- # build up the list of surnames, keeping track of the count for each
- # name (this can be a lengthy process, so by passing in the
- # dictionary we can be certain we only do this once)
- progress = ProgressMeter(_('Finding Surnames'))
- progress.set_pass(_('Finding surnames'),
- database.get_number_of_people())
- for person in database.iter_people():
- progress.step()
- key = person.get_primary_name().get_surname()
- count = 0
- if key in surnames:
- count = surnames[key]
- surnames[key] = count + 1
- progress.close()
-
- # insert the names and count into the model
- for key in surnames:
- if key.encode('iso-8859-1','xmlcharrefreplace') not in skip_list:
- self.__model.append([key, surnames[key]])
-
- # keep the list sorted starting with the most popular last name
- self.__model.set_sort_column_id(1, gtk.SORT_DESCENDING)
-
- # the "OK" button should be enabled/disabled based on the selection of
- # a row
- self.__tree_selection = self.__tree_view.get_selection()
- self.__tree_selection.set_mode(gtk.SELECTION_MULTIPLE)
- self.__tree_selection.select_path(0)
-
- def run(self):
- """
- Display the dialog and return the selected surnames when done.
- """
- response = self.__dlg.run()
- surname_set = set()
- if response == gtk.RESPONSE_ACCEPT:
- (mode, paths) = self.__tree_selection.get_selected_rows()
- for path in paths:
- i = self.__model.get_iter(path)
- surname = self.__model.get_value(i, 0)
- surname_set.add(surname)
- self.__dlg.destroy()
- return surname_set
-
-#-------------------------------------------------------------------------
-#
-# GuiStringOption class
-#
-#-------------------------------------------------------------------------
-class GuiStringOption(gtk.Entry):
- """
- This class displays an option that is a simple one-line string.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.StringOption
- @return: nothing
- """
- gtk.Entry.__init__(self)
- self.__option = option
- self.set_text( self.__option.get_value() )
- self.connect('changed', self.__text_changed)
- self.set_tooltip_text(self.__option.get_help())
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __text_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of the value.
- """
- self.__option.set_value( self.get_text() )
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiColorOption class
-#
-#-------------------------------------------------------------------------
-class GuiColorOption(gtk.ColorButton):
- """
- This class displays an option that allows the selection of a colour.
- """
- def __init__(self, option, dbstate, uistate, track):
- self.__option = option
- value = self.__option.get_value()
- gtk.ColorButton.__init__( self, gtk.gdk.color_parse(value) )
- self.connect('color-set', self.__value_changed)
- self.set_tooltip_text(self.__option.get_help())
-
- def __value_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of color.
- """
- colour = self.get_color()
- value = '#%02x%02x%02x' % (
- int(colour.red * 256 / 65536),
- int(colour.green * 256 / 65536),
- int(colour.blue * 256 / 65536))
- self.__option.set_value(value)
-
-#-------------------------------------------------------------------------
-#
-# GuiNumberOption class
-#
-#-------------------------------------------------------------------------
-class GuiNumberOption(gtk.SpinButton):
- """
- This class displays an option that is a simple number with defined maximum
- and minimum values.
- """
- def __init__(self, option, dbstate, uistate, track):
- self.__option = option
-
- decimals = 0
- step = self.__option.get_step()
- adj = gtk.Adjustment(1,
- self.__option.get_min(),
- self.__option.get_max(),
- step)
-
- # Calculate the number of decimal places if necessary
- if step < 1:
- import math
- decimals = int(math.log10(step) * -1)
-
- gtk.SpinButton.__init__(self, adj, digits=decimals)
- gtk.SpinButton.set_numeric(self, True)
-
- self.set_value(self.__option.get_value())
- self.connect('value_changed', self.__value_changed)
- self.set_tooltip_text(self.__option.get_help())
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __value_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of the value.
- """
- vtype = type(self.__option.get_value())
- self.__option.set_value( vtype(self.get_value()) )
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiTextOption class
-#
-#-------------------------------------------------------------------------
-class GuiTextOption(gtk.ScrolledWindow):
- """
- This class displays an option that is a multi-line string.
- """
- def __init__(self, option, dbstate, uistate, track):
- self.__option = option
- gtk.ScrolledWindow.__init__(self)
- self.set_shadow_type(gtk.SHADOW_IN)
- self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-
- # Add a TextView
- value = self.__option.get_value()
- gtext = gtk.TextView()
- gtext.get_buffer().set_text("\n".join(value))
- gtext.set_editable(1)
- self.add(gtext)
-
- # Required for tooltip
- gtext.add_events(gtk.gdk.ENTER_NOTIFY_MASK)
- gtext.add_events(gtk.gdk.LEAVE_NOTIFY_MASK)
- gtext.set_tooltip_text(self.__option.get_help())
-
- self.__buff = gtext.get_buffer()
- self.__buff.connect('changed', self.__value_changed)
-
- def __value_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of the value.
- """
- text_val = unicode( self.__buff.get_text( self.__buff.get_start_iter(),
- self.__buff.get_end_iter(),
- False) )
- self.__option.set_value( text_val.split('\n') )
-
-#-------------------------------------------------------------------------
-#
-# GuiBooleanOption class
-#
-#-------------------------------------------------------------------------
-class GuiBooleanOption(gtk.CheckButton):
- """
- This class displays an option that is a boolean (True or False).
- """
- def __init__(self, option, dbstate, uistate, track):
- self.__option = option
- gtk.CheckButton.__init__(self, self.__option.get_label())
- self.set_active(self.__option.get_value())
- self.connect('toggled', self.__value_changed)
- self.set_tooltip_text(self.__option.get_help())
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __value_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of the value.
- """
- self.__option.set_value( self.get_active() )
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiEnumeratedListOption class
-#
-#-------------------------------------------------------------------------
-class GuiEnumeratedListOption(gtk.HBox):
- """
- This class displays an option that provides a finite number of values.
- Each possible value is assigned a value and a description.
- """
- def __init__(self, option, dbstate, uistate, track):
- gtk.HBox.__init__(self)
- evtBox = gtk.EventBox()
- self.__option = option
- self.__combo = gtk.combo_box_new_text()
- evtBox.add(self.__combo)
- self.pack_start(evtBox, True, True)
-
- self.__update_options()
-
- self.set_tooltip_text(self.__option.get_help())
-
- self.__combo.connect('changed', self.__value_changed)
- self.__option.connect('options-changed', self.__update_options)
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __value_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of the value.
- """
- index = self.__combo.get_active()
- if index < 0:
- return
- items = self.__option.get_items()
- value, description = items[index] # IGNORE:W0612 - description is unused
- self.__option.set_value( value )
- self.value_changed()
-
- def value_changed(self):
- pass
-
- def __update_options(self):
- """
- Handle the change of the available options.
- """
- self.__combo.get_model().clear()
- cur_val = self.__option.get_value()
- active_index = 0
- current_index = 0
- for (value, description) in self.__option.get_items():
- self.__combo.append_text(description)
- if value == cur_val:
- active_index = current_index
- current_index += 1
- self.__combo.set_active( active_index )
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiPersonOption class
-#
-#-------------------------------------------------------------------------
-class GuiPersonOption(gtk.HBox):
- """
- This class displays an option that allows a person from the
- database to be selected.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.PersonOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
- self.__person_label = gtk.Label()
- self.__person_label.set_alignment(0.0, 0.5)
-
- pevt = gtk.EventBox()
- pevt.add(self.__person_label)
- person_button = widgets.SimpleButton(gtk.STOCK_INDEX,
- self.__get_person_clicked)
- person_button.set_relief(gtk.RELIEF_NORMAL)
-
- self.pack_start(pevt, False)
- self.pack_end(person_button, False)
-
- person_handle = self.__uistate.get_active('Person')
- person = self.__dbstate.db.get_person_from_handle(person_handle)
- if not person:
- person = self.__db.get_default_person()
- self.__update_person(person)
-
- pevt.set_tooltip_text(self.__option.get_help())
- person_button.set_tooltip_text(_('Select a different person'))
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __get_person_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the button to choose a different person.
- """
- # Create a filter for the person selector.
- rfilter = GenericFilter()
- rfilter.set_logical_op('or')
- rfilter.add_rule(Rules.Person.IsBookmarked([]))
- rfilter.add_rule(Rules.Person.HasIdOf([self.__option.get_value()]))
-
- # Add the database home person if one exists.
- default_person = self.__db.get_default_person()
- if default_person:
- gid = default_person.get_gramps_id()
- rfilter.add_rule(Rules.Person.HasIdOf([gid]))
-
- # Add the selected person if one exists.
- person_handle = self.__uistate.get_active('Person')
- active_person = self.__dbstate.db.get_person_from_handle(person_handle)
- if active_person:
- gid = active_person.get_gramps_id()
- rfilter.add_rule(Rules.Person.HasIdOf([gid]))
-
- select_class = SelectorFactory('Person')
- sel = select_class(self.__dbstate, self.__uistate, self.__track,
- title=_('Select a person for the report'),
- filter=rfilter )
- person = sel.run()
- self.__update_person(person)
-
- def __update_person(self, person):
- """
- Update the currently selected person.
- """
- if person:
- name = _nd.display(person)
- gid = person.get_gramps_id()
- self.__person_label.set_text( "%s (%s)" % (name, gid) )
- self.__option.set_value(gid)
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiFamilyOption class
-#
-#-------------------------------------------------------------------------
-class GuiFamilyOption(gtk.HBox):
- """
- This class displays an option that allows a family from the
- database to be selected.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.FamilyOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
- self.__family_label = gtk.Label()
- self.__family_label.set_alignment(0.0, 0.5)
-
- pevt = gtk.EventBox()
- pevt.add(self.__family_label)
- family_button = widgets.SimpleButton(gtk.STOCK_INDEX,
- self.__get_family_clicked)
- family_button.set_relief(gtk.RELIEF_NORMAL)
-
- self.pack_start(pevt, False)
- self.pack_end(family_button, False)
-
- self.__initialize_family()
-
- pevt.set_tooltip_text(self.__option.get_help())
- family_button.set_tooltip_text(_('Select a different family'))
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __initialize_family(self):
- """
- Find a family to initialize the option with. Any family will do, but
- try to find a family that the user is likely interested in.
- """
- family_list = []
-
- # Use the active family if one is selected
- family = self.__uistate.get_active('Family')
- if family:
- family_list = [family]
-
- if not family_list:
- # Next try the family of the active person
- person_handle = self.__uistate.get_active('Person')
- person = self.__dbstate.db.get_person_from_handle(person_handle)
- if person:
- family_list = person.get_family_handle_list()
-
- if not family_list:
- # Next try the family of the default person in the database.
- person = self.__db.get_default_person()
- if person:
- family_list = person.get_family_handle_list()
-
- if not family_list:
- # Finally, take any family you can find.
- for family in self.__db.iter_family_handles():
- self.__update_family(family)
- break
- else:
- self.__update_family(family_list[0])
-
- def __get_family_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the button to choose a different family.
- """
- # Create a filter for the person selector.
- rfilter = GenericFilterFactory('Family')()
- rfilter.set_logical_op('or')
-
- # Add the current family
- rfilter.add_rule(Rules.Family.HasIdOf([self.__option.get_value()]))
-
- # Add all bookmarked families
- rfilter.add_rule(Rules.Family.IsBookmarked([]))
-
- # Add the families of the database home person if one exists.
- default_person = self.__db.get_default_person()
- if default_person:
- family_list = default_person.get_family_handle_list()
- for family_handle in family_list:
- family = self.__db.get_family_from_handle(family_handle)
- gid = family.get_gramps_id()
- rfilter.add_rule(Rules.Family.HasIdOf([gid]))
-
- # Add the families of the selected person if one exists.
- active_person = self.__db.get_default_person()
- if active_person:
- family_list = active_person.get_family_handle_list()
- for family_handle in family_list:
- family = self.__db.get_family_from_handle(family_handle)
- gid = family.get_gramps_id()
- rfilter.add_rule(Rules.Family.HasIdOf([gid]))
-
- select_class = SelectorFactory('Family')
- sel = select_class(self.__dbstate, self.__uistate, self.__track,
- filter=rfilter )
- family = sel.run()
- if family:
- self.__update_family(family.get_handle())
-
- def __update_family(self, handle):
- """
- Update the currently selected family.
- """
- if handle:
- family = self.__dbstate.db.get_family_from_handle(handle)
- family_id = family.get_gramps_id()
- fhandle = family.get_father_handle()
- mhandle = family.get_mother_handle()
-
- if fhandle:
- father = self.__db.get_person_from_handle(fhandle)
- father_name = _nd.display(father)
- else:
- father_name = _("unknown father")
-
- if mhandle:
- mother = self.__db.get_person_from_handle(mhandle)
- mother_name = _nd.display(mother)
- else:
- mother_name = _("unknown mother")
-
- name = _("%s and %s (%s)") % (father_name, mother_name, family_id)
-
- self.__family_label.set_text( name )
- self.__option.set_value(family_id)
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiNoteOption class
-#
-#-------------------------------------------------------------------------
-class GuiNoteOption(gtk.HBox):
- """
- This class displays an option that allows a note from the
- database to be selected.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.NoteOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
- self.__note_label = gtk.Label()
- self.__note_label.set_alignment(0.0, 0.5)
-
- pevt = gtk.EventBox()
- pevt.add(self.__note_label)
- note_button = widgets.SimpleButton(gtk.STOCK_INDEX,
- self.__get_note_clicked)
- note_button.set_relief(gtk.RELIEF_NORMAL)
-
- self.pack_start(pevt, False)
- self.pack_end(note_button, False)
-
- # Initialize to the current value
- nid = self.__option.get_value()
- note = self.__db.get_note_from_gramps_id(nid)
- self.__update_note(note)
-
- pevt.set_tooltip_text(self.__option.get_help())
- note_button.set_tooltip_text(_('Select an existing note'))
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __get_note_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the button to choose a different note.
- """
- select_class = SelectorFactory('Note')
- sel = select_class(self.__dbstate, self.__uistate, self.__track)
- note = sel.run()
- self.__update_note(note)
-
- def __update_note(self, note):
- """
- Update the currently selected note.
- """
- if note:
- note_id = note.get_gramps_id()
- txt = " ".join(note.get().split())
- #String must be unicode for truncation to work for non ascii characters
- txt = unicode(txt)
- if len(txt) > 35:
- txt = txt[:35] + "..."
- txt = "%s [%s]" % (txt, note_id)
-
- self.__note_label.set_text( txt )
- self.__option.set_value(note_id)
- else:
- txt = "%s" % _('No note given, click button to select one')
- self.__note_label.set_text( txt )
- self.__note_label.set_use_markup(True)
- self.__option.set_value("")
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiMediaOption class
-#
-#-------------------------------------------------------------------------
-class GuiMediaOption(gtk.HBox):
- """
- This class displays an option that allows a media object from the
- database to be selected.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.MediaOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
- self.__media_label = gtk.Label()
- self.__media_label.set_alignment(0.0, 0.5)
-
- pevt = gtk.EventBox()
- pevt.add(self.__media_label)
- media_button = widgets.SimpleButton(gtk.STOCK_INDEX,
- self.__get_media_clicked)
- media_button.set_relief(gtk.RELIEF_NORMAL)
-
- self.pack_start(pevt, False)
- self.pack_end(media_button, False)
-
- # Initialize to the current value
- mid = self.__option.get_value()
- media = self.__db.get_object_from_gramps_id(mid)
- self.__update_media(media)
-
- pevt.set_tooltip_text(self.__option.get_help())
- media_button.set_tooltip_text(_('Select an existing media object'))
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __get_media_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the button to choose a different note.
- """
- select_class = SelectorFactory('MediaObject')
- sel = select_class(self.__dbstate, self.__uistate, self.__track)
- media = sel.run()
- self.__update_media(media)
-
- def __update_media(self, media):
- """
- Update the currently selected media.
- """
- if media:
- media_id = media.get_gramps_id()
- txt = "%s [%s]" % (media.get_description(), media_id)
-
- self.__media_label.set_text( txt )
- self.__option.set_value(media_id)
- else:
- txt = "%s" % _('No image given, click button to select one')
- self.__media_label.set_text( txt )
- self.__media_label.set_use_markup(True)
- self.__option.set_value("")
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiPersonListOption class
-#
-#-------------------------------------------------------------------------
-class GuiPersonListOption(gtk.HBox):
- """
- This class displays a widget that allows multiple people from the
- database to be selected.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.PersonListOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
-
- self.__model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
- self.__tree_view = gtk.TreeView(self.__model)
- self.__tree_view.set_size_request(150, 150)
- col1 = gtk.TreeViewColumn(_('Name' ), gtk.CellRendererText(), text=0)
- col2 = gtk.TreeViewColumn(_('ID' ), gtk.CellRendererText(), text=1)
- col1.set_resizable(True)
- col2.set_resizable(True)
- col1.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col2.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col1.set_sort_column_id(0)
- col2.set_sort_column_id(1)
- self.__tree_view.append_column(col1)
- self.__tree_view.append_column(col2)
- self.__scrolled_window = gtk.ScrolledWindow()
- self.__scrolled_window.add(self.__tree_view)
- self.__scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
- gtk.POLICY_AUTOMATIC)
- self.__scrolled_window.set_shadow_type(gtk.SHADOW_OUT)
-
- self.pack_start(self.__scrolled_window, expand=True, fill=True)
-
- value = self.__option.get_value()
- for gid in value.split():
- person = self.__db.get_person_from_gramps_id(gid)
- if person:
- name = _nd.display(person)
- self.__model.append([name, gid])
-
- # now setup the '+' and '-' pushbutton for adding/removing people from
- # the container
- self.__add_person = widgets.SimpleButton(gtk.STOCK_ADD,
- self.__add_person_clicked)
- self.__del_person = widgets.SimpleButton(gtk.STOCK_REMOVE,
- self.__del_person_clicked)
- self.__vbbox = gtk.VButtonBox()
- self.__vbbox.add(self.__add_person)
- self.__vbbox.add(self.__del_person)
- self.__vbbox.set_layout(gtk.BUTTONBOX_SPREAD)
- self.pack_end(self.__vbbox, expand=False)
-
- self.__tree_view.set_tooltip_text(self.__option.get_help())
-
- def __update_value(self):
- """
- Parse the object and return.
- """
- gidlist = ''
- i = self.__model.get_iter_first()
- while (i):
- gid = self.__model.get_value(i, 1)
- gidlist = gidlist + gid + ' '
- i = self.__model.iter_next(i)
- self.__option.set_value(gidlist)
-
- def __add_person_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the add person button.
- """
- # people we already have must be excluded
- # so we don't list them multiple times
- skip_list = set()
- i = self.__model.get_iter_first()
- while (i):
- gid = self.__model.get_value(i, 1) # get the GID stored in column #1
- person = self.__db.get_person_from_gramps_id(gid)
- skip_list.add(person.get_handle())
- i = self.__model.iter_next(i)
-
- select_class = SelectorFactory('Person')
- sel = select_class(self.__dbstate, self.__uistate,
- self.__track, skip=skip_list)
- person = sel.run()
- if person:
- name = _nd.display(person)
- gid = person.get_gramps_id()
- self.__model.append([name, gid])
-
- # if this person has a spouse, ask if we should include the spouse
- # in the list of "people of interest"
- #
- # NOTE: we may want to make this an optional thing, determined
- # by the use of a parameter at the time this class is instatiated
- family_list = person.get_family_handle_list()
- for family_handle in family_list:
- family = self.__db.get_family_from_handle(family_handle)
-
- if person.get_handle() == family.get_father_handle():
- spouse_handle = family.get_mother_handle()
- else:
- spouse_handle = family.get_father_handle()
-
- if spouse_handle and (spouse_handle not in skip_list):
- spouse = self.__db.get_person_from_handle(
- spouse_handle)
- spouse_name = _nd.display(spouse)
- text = _('Also include %s?') % spouse_name
-
- prompt = OptionDialog(_('Select Person'),
- text,
- _('No'), None,
- _('Yes'), None)
- if prompt.get_response() == gtk.RESPONSE_YES:
- gid = spouse.get_gramps_id()
- self.__model.append([spouse_name, gid])
-
- self.__update_value()
-
- def __del_person_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the delete person button.
- """
- (path, column) = self.__tree_view.get_cursor()
- if (path):
- i = self.__model.get_iter(path)
- self.__model.remove(i)
- self.__update_value()
-
-#-------------------------------------------------------------------------
-#
-# GuiPlaceListOption class
-#
-#-------------------------------------------------------------------------
-class GuiPlaceListOption(gtk.HBox):
- """
- This class displays a widget that allows multiple places from the
- database to be selected.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.PlaceListOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
-
- self.__model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
- self.__tree_view = gtk.TreeView(self.__model)
- self.__tree_view.set_size_request(150, 150)
- col1 = gtk.TreeViewColumn(_('Place' ), gtk.CellRendererText(), text=0)
- col2 = gtk.TreeViewColumn(_('ID' ), gtk.CellRendererText(), text=1)
- col1.set_resizable(True)
- col2.set_resizable(True)
- col1.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col2.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col1.set_sort_column_id(0)
- col2.set_sort_column_id(1)
- self.__tree_view.append_column(col1)
- self.__tree_view.append_column(col2)
- self.__scrolled_window = gtk.ScrolledWindow()
- self.__scrolled_window.add(self.__tree_view)
- self.__scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
- gtk.POLICY_AUTOMATIC)
- self.__scrolled_window.set_shadow_type(gtk.SHADOW_OUT)
-
- self.pack_start(self.__scrolled_window, expand=True, fill=True)
-
- value = self.__option.get_value()
- for gid in value.split():
- place = self.__db.get_place_from_gramps_id(gid)
- if place:
- place_name = place.get_title()
- self.__model.append([place_name, gid])
-
- # now setup the '+' and '-' pushbutton for adding/removing places from
- # the container
- self.__add_place = widgets.SimpleButton(gtk.STOCK_ADD,
- self.__add_place_clicked)
- self.__del_place = widgets.SimpleButton(gtk.STOCK_REMOVE,
- self.__del_place_clicked)
- self.__vbbox = gtk.VButtonBox()
- self.__vbbox.add(self.__add_place)
- self.__vbbox.add(self.__del_place)
- self.__vbbox.set_layout(gtk.BUTTONBOX_SPREAD)
- self.pack_end(self.__vbbox, expand=False)
-
- self.__tree_view.set_tooltip_text(self.__option.get_help())
-
- def __update_value(self):
- """
- Parse the object and return.
- """
- gidlist = ''
- i = self.__model.get_iter_first()
- while (i):
- gid = self.__model.get_value(i, 1)
- gidlist = gidlist + gid + ' '
- i = self.__model.iter_next(i)
- self.__option.set_value(gidlist)
-
- def __add_place_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the add place button.
- """
- # places we already have must be excluded
- # so we don't list them multiple times
- skip_list = set()
- i = self.__model.get_iter_first()
- while (i):
- gid = self.__model.get_value(i, 1) # get the GID stored in column #1
- place = self.__db.get_place_from_gramps_id(gid)
- skip_list.add(place.get_handle())
- i = self.__model.iter_next(i)
-
- select_class = SelectorFactory('Place')
- sel = select_class(self.__dbstate, self.__uistate,
- self.__track, skip=skip_list)
- place = sel.run()
- if place:
- place_name = place.get_title()
- gid = place.get_gramps_id()
- self.__model.append([place_name, gid])
- self.__update_value()
-
- def __del_place_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the delete place button.
- """
- (path, column) = self.__tree_view.get_cursor()
- if (path):
- i = self.__model.get_iter(path)
- self.__model.remove(i)
- self.__update_value()
-
-#-------------------------------------------------------------------------
-#
-# GuiSurnameColorOption class
-#
-#-------------------------------------------------------------------------
-class GuiSurnameColorOption(gtk.HBox):
- """
- This class displays a widget that allows multiple surnames to be
- selected from the database, and to assign a colour (not necessarily
- unique) to each one.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.SurnameColorOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
-
- # This will get populated the first time the dialog is run,
- # and used each time after.
- self.__surnames = {} # list of surnames and count
-
- self.__model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
- self.__tree_view = gtk.TreeView(self.__model)
- self.__tree_view.set_size_request(150, 150)
- self.__tree_view.connect('row-activated', self.__row_clicked)
- col1 = gtk.TreeViewColumn(_('Surname'), gtk.CellRendererText(), text=0)
- col2 = gtk.TreeViewColumn(_('Colour'), gtk.CellRendererText(), text=1)
- col1.set_resizable(True)
- col2.set_resizable(True)
- col1.set_sort_column_id(0)
- col1.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col2.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- self.__tree_view.append_column(col1)
- self.__tree_view.append_column(col2)
- self.scrolled_window = gtk.ScrolledWindow()
- self.scrolled_window.add(self.__tree_view)
- self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
- gtk.POLICY_AUTOMATIC)
- self.scrolled_window.set_shadow_type(gtk.SHADOW_OUT)
- self.pack_start(self.scrolled_window, expand=True, fill=True)
-
- self.add_surname = widgets.SimpleButton(gtk.STOCK_ADD,
- self.__add_clicked)
- self.del_surname = widgets.SimpleButton(gtk.STOCK_REMOVE,
- self.__del_clicked)
- self.vbbox = gtk.VButtonBox()
- self.vbbox.add(self.add_surname)
- self.vbbox.add(self.del_surname)
- self.vbbox.set_layout(gtk.BUTTONBOX_SPREAD)
- self.pack_end(self.vbbox, expand=False)
-
- # populate the surname/colour treeview
- #
- # For versions prior to 3.0.2, the fields were delimited with
- # whitespace. However, this causes problems when the surname
- # also has a space within it. When populating the control,
- # support both the new and old format -- look for the \xb0
- # delimiter, and if it isn't there, assume this is the old-
- # style space-delimited format. (Bug #2162.)
- if (self.__option.get_value().find(u'\xb0') >= 0):
- tmp = self.__option.get_value().split(u'\xb0')
- else:
- tmp = self.__option.get_value().split(' ')
- while len(tmp) > 1:
- surname = tmp.pop(0)
- colour = tmp.pop(0)
- self.__model.append([surname, colour])
-
- self.__tree_view.set_tooltip_text(self.__option.get_help())
-
- def __value_changed(self):
- """
- Parse the object and return.
- """
- surname_colours = ''
- i = self.__model.get_iter_first()
- while (i):
- surname = self.__model.get_value(i, 0)
- #surname = surname.encode('iso-8859-1','xmlcharrefreplace')
- colour = self.__model.get_value(i, 1)
- # Tried to use a dictionary, and tried to save it as a tuple,
- # but coulnd't get this to work right -- this is lame, but now
- # the surnames and colours are saved as a plain text string
- #
- # Hmmm...putting whitespace between the fields causes
- # problems when the surname has whitespace -- for example,
- # with surnames like "Del Monte". So now we insert a non-
- # whitespace character which is unlikely to appear in
- # a surname. (See bug report #2162.)
- surname_colours += surname + u'\xb0' + colour + u'\xb0'
- i = self.__model.iter_next(i)
- self.__option.set_value( surname_colours )
-
- def __row_clicked(self, treeview, path, column):
- """
- Handle the case of a row being clicked on.
- """
- # get the surname and colour value for this family
- i = self.__model.get_iter(path)
- surname = self.__model.get_value(i, 0)
- colour = gtk.gdk.color_parse(self.__model.get_value(i, 1))
-
- title = 'Select colour for %s' % surname
- colour_dialog = gtk.ColorSelectionDialog(title)
- colorsel = colour_dialog.colorsel
- colorsel.set_current_color(colour)
- response = colour_dialog.run()
-
- if response == gtk.RESPONSE_OK:
- colour = colorsel.get_current_color()
- colour_name = '#%02x%02x%02x' % (
- int(colour.red *256/65536),
- int(colour.green*256/65536),
- int(colour.blue *256/65536))
- self.__model.set_value(i, 1, colour_name)
-
- colour_dialog.destroy()
- self.__value_changed()
-
- def __add_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the the add surname button.
- """
- skip_list = set()
- i = self.__model.get_iter_first()
- while (i):
- surname = self.__model.get_value(i, 0)
- skip_list.add(surname.encode('iso-8859-1','xmlcharrefreplace'))
- i = self.__model.iter_next(i)
-
- ln_dialog = LastNameDialog(self.__db, self.__uistate,
- self.__track, self.__surnames, skip_list)
- surname_set = ln_dialog.run()
- for surname in surname_set:
- self.__model.append([surname, '#ffffff'])
- self.__value_changed()
-
- def __del_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the the delete surname button.
- """
- (path, column) = self.__tree_view.get_cursor()
- if (path):
- i = self.__model.get_iter(path)
- self.__model.remove(i)
- self.__value_changed()
-
-#-------------------------------------------------------------------------
-#
-# GuiDestinationOption class
-#
-#-------------------------------------------------------------------------
-class GuiDestinationOption(gtk.HBox):
- """
- This class displays an option that allows the user to select a
- DestinationOption.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.DestinationOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__entry = gtk.Entry()
- self.__entry.set_text( self.__option.get_value() )
- self.__entry.connect('changed', self.__text_changed)
-
- self.__button = gtk.Button()
- img = gtk.Image()
- img.set_from_stock(gtk.STOCK_OPEN, gtk.ICON_SIZE_BUTTON)
- self.__button.add(img)
- self.__button.connect('clicked', self.__select_file)
-
- self.pack_start(self.__entry, True, True)
- self.pack_end(self.__button, False, False)
-
- self.set_tooltip_text(self.__option.get_help())
-
- self.__option.connect('options-changed', self.__option_changed)
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __text_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of the value.
- """
- self.__option.set_value( self.__entry.get_text() )
-
- def __select_file(self, obj):
- """
- Handle the user's request to select a file (or directory).
- """
- if self.__option.get_directory_entry():
- my_action = gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER
- else:
- my_action = gtk.FILE_CHOOSER_ACTION_SAVE
-
- fcd = gtk.FileChooserDialog(_("Save As"), action=my_action,
- buttons=(gtk.STOCK_CANCEL,
- gtk.RESPONSE_CANCEL,
- gtk.STOCK_OPEN,
- gtk.RESPONSE_OK))
-
- name = os.path.abspath(self.__option.get_value())
- if self.__option.get_directory_entry():
- while not os.path.isdir(name):
- # Keep looking up levels to find a valid drive.
- name, tail = os.path.split(name)
- if not name:
- # Avoid infinite loops
- name = os.getcwd()
- fcd.set_current_folder(name)
- else:
- fcd.set_current_name(name)
-
- status = fcd.run()
- if status == gtk.RESPONSE_OK:
- path = Utils.get_unicode_path(fcd.get_filename())
- if path:
- if not self.__option.get_directory_entry() and \
- not path.endswith(self.__option.get_extension()):
- path = path + self.__option.get_extension()
- self.__entry.set_text(path)
- self.__option.set_value(path)
- fcd.destroy()
-
- def __option_changed(self):
- """
- Handle a change of the option.
- """
- extension = self.__option.get_extension()
- directory = self.__option.get_directory_entry()
- value = self.__option.get_value()
-
- if not directory and not value.endswith(extension):
- value = value + extension
- self.__option.set_value(value)
- elif directory and value.endswith(extension):
- value = value[:-len(extension)]
- self.__option.set_value(value)
-
- self.__entry.set_text( self.__option.get_value() )
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiStyleOption class
-#
-#-------------------------------------------------------------------------
-class GuiStyleOption(GuiEnumeratedListOption):
- """
- This class displays a StyleOption.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.StyleOption
- @return: nothing
- """
- GuiEnumeratedListOption.__init__(self, option, dbstate,
- uistate, track)
- self.__option = option
-
- self.__button = gtk.Button("%s..." % _("Style Editor"))
- self.__button.connect('clicked', self.__on_style_edit_clicked)
-
- self.pack_end(self.__button, False, False)
-
- def __on_style_edit_clicked(self, *obj):
- """The user has clicked on the 'Edit Styles' button. Create a
- style sheet editor object and let them play. When they are
- done, update the displayed styles."""
- from gen.plug.docgen import StyleSheetList
- from gui.plug.report._styleeditor import StyleListDisplay
- style_list = StyleSheetList(self.__option.get_style_file(),
- self.__option.get_default_style())
- StyleListDisplay(style_list, None, None)
-
- new_items = []
- for style_name in style_list.get_style_names():
- new_items.append( (style_name, style_name) )
- self.__option.set_items(new_items)
-
-#-------------------------------------------------------------------------
-#
-# GuiBooleanListOption class
-#
-#-------------------------------------------------------------------------
-class GuiBooleanListOption(gtk.HBox):
- """
- This class displays an option that provides a list of check boxes.
- Each possible value is assigned a value and a description.
- """
- def __init__(self, option, dbstate, uistate, track):
- gtk.HBox.__init__(self)
- self.__option = option
- self.__cbutton = []
-
- COLUMNS = 2 # Number of checkbox columns
- column = []
- for i in range(COLUMNS):
- vbox = gtk.VBox()
- self.pack_start(vbox, True, True)
- column.append(vbox)
- vbox.show()
-
- counter = 0
- default = option.get_value().split(',')
- for description in option.get_descriptions():
- button = gtk.CheckButton(description)
- self.__cbutton.append(button)
- if default[counter] == 'True':
- button.set_active(True)
- button.connect("toggled", self.__value_changed)
- column[counter % COLUMNS].pack_start(button, True, True)
- button.show()
- counter += 1
-
- self.set_tooltip_text(self.__option.get_help())
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __value_changed(self, button):
- """
- Handle the change of the value.
- """
- value = ''
- for button in self.__cbutton:
- value = value + str(button.get_active()) + ','
- value = value[:len(value)-1]
- self.__option.set_value(value)
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#------------------------------------------------------------------------
-#
-# GuiMenuOptions class
-#
-#------------------------------------------------------------------------
-class GuiMenuOptions(object):
- """
- Introduction
- ============
- A GuiMenuOptions is used to implement the necessary funtions for adding
- options to a GTK dialog.
- """
- def __init__(self):
- self.menu = gen.plug.menu.Menu()
-
- # Fill options_dict with report/tool defaults:
- self.options_dict = {}
- self.options_help = {}
- self.add_menu_options(self.menu)
- for name in self.menu.get_all_option_names():
- option = self.menu.get_option_by_name(name)
- self.options_dict[name] = option.get_value()
- self.options_help[name] = [ "", option.get_help() ]
-
- def make_default_style(self, default_style):
- """
- This function is currently required by some reports.
- """
- pass
-
- def add_menu_options(self, menu):
- """
- Add the user defined options to the menu.
-
- @param menu: A menu class for the options to belong to.
- @type menu: Menu
- @return: nothing
- """
- raise NotImplementedError
-
- def add_menu_option(self, category, name, option):
- """
- Add a single option to the menu.
- """
- self.menu.add_option(category, name, option)
- self.options_dict[name] = option.get_value()
- self.options_help[name] = [ "", option.get_help() ]
-
- def add_user_options(self, dialog):
- """
- Generic method to add user options to the gui.
- """
- for category in self.menu.get_categories():
- for name in self.menu.get_option_names(category):
- option = self.menu.get_option(category, name)
-
- # override option default with xml-saved value:
- if name in self.options_dict:
- option.set_value(self.options_dict[name])
-
- widget, label = make_gui_option(option, dialog.dbstate,
- dialog.uistate, dialog.track)
-
- if widget is None:
- print "UNKNOWN OPTION: ", option
- else:
- if label:
- dialog.add_frame_option(category,
- option.get_label(),
- widget)
- else:
- dialog.add_frame_option(category, "", widget)
-
- def parse_user_options(self, dialog): # IGNORE:W0613 - dialog is unused
- """
- Load the changed values into the saved options.
- """
- for name in self.menu.get_all_option_names():
- option = self.menu.get_option_by_name(name)
- self.options_dict[name] = option.get_value()
-
-def make_gui_option(option, dbstate, uistate, track):
- """
- Stand-alone function so that Options can be used in other
- ways, too. Takes an Option and returns a GuiOption.
- """
- widget = None
- label = True
- pmgr = GuiPluginManager.get_instance()
- external_options = pmgr.get_external_opt_dict()
- if isinstance(option, gen.plug.menu.PersonOption):
- widget = GuiPersonOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.FamilyOption):
- widget = GuiFamilyOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.NoteOption):
- widget = GuiNoteOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.MediaOption):
- widget = GuiMediaOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.PersonListOption):
- widget = GuiPersonListOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.NumberOption):
- widget = GuiNumberOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.BooleanOption):
- widget = GuiBooleanOption(option, dbstate, uistate, track)
- label = False
- elif isinstance(option, gen.plug.menu.DestinationOption):
- widget = GuiDestinationOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.StringOption):
- widget = GuiStringOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.StyleOption):
- widget = GuiStyleOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.EnumeratedListOption):
- widget = GuiEnumeratedListOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.TextOption):
- widget = GuiTextOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.ColorOption):
- widget = GuiColorOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.SurnameColorOption):
- widget = GuiSurnameColorOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.PlaceListOption):
- widget = GuiPlaceListOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.BooleanListOption):
- widget = GuiBooleanListOption(option, dbstate, uistate, track)
- elif option.__class__ in external_options:
- widget = external_options[option.__class__](option, dbstate, uistate,
- track)
- else:
- raise AttributeError(
- "can't make GuiOption: unknown option type: '%s'" % option)
- return widget, label
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2007-2008 Brian G. Matherly
-# Copyright (C) 2008,2010 Gary Burton
-# Copyright (C) 2008 Craig J. Anderson
-# Copyright (C) 2009 Nick Hall
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id$
-
-"""
-Specific option handling for a GUI.
-"""
-#------------------------------------------------------------------------
-#
-# python modules
-#
-#------------------------------------------------------------------------
-from gen.ggettext import gettext as _
-import os
-import sys
-
-#-------------------------------------------------------------------------
-#
-# gtk modules
-#
-#-------------------------------------------------------------------------
-import gtk
-import gobject
-
-#-------------------------------------------------------------------------
-#
-# gramps modules
-#
-#-------------------------------------------------------------------------
-import Utils
-from gui.utils import ProgressMeter
-from gui.pluginmanager import GuiPluginManager
-from gui import widgets
-import ManagedWindow
-from QuestionDialog import OptionDialog
-from gui.selectors import SelectorFactory
-from gen.display.name import displayer as _nd
-from Filters import GenericFilterFactory, GenericFilter, Rules
-import gen
-
-#------------------------------------------------------------------------
-#
-# Dialog window used to select a surname
-#
-#------------------------------------------------------------------------
-class LastNameDialog(ManagedWindow.ManagedWindow):
- """
- A dialog that allows the selection of a surname from the database.
- """
- def __init__(self, database, uistate, track, surnames, skip_list=set()):
-
- ManagedWindow.ManagedWindow.__init__(self, uistate, track, self)
- flags = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT | \
- gtk.DIALOG_NO_SEPARATOR
- buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK,
- gtk.RESPONSE_ACCEPT)
- self.__dlg = gtk.Dialog(None, uistate.window, flags, buttons)
- self.__dlg.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.set_window(self.__dlg, None, _('Select surname'))
- self.window.set_default_size(400, 400)
-
- # build up a container to display all of the people of interest
- self.__model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT)
- self.__tree_view = gtk.TreeView(self.__model)
- col1 = gtk.TreeViewColumn(_('Surname'), gtk.CellRendererText(), text=0)
- col2 = gtk.TreeViewColumn(_('Count'), gtk.CellRendererText(), text=1)
- col1.set_resizable(True)
- col2.set_resizable(True)
- col1.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col2.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col1.set_sort_column_id(0)
- col2.set_sort_column_id(1)
- self.__tree_view.append_column(col1)
- self.__tree_view.append_column(col2)
- scrolled_window = gtk.ScrolledWindow()
- scrolled_window.add(self.__tree_view)
- scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- scrolled_window.set_shadow_type(gtk.SHADOW_OUT)
- self.__dlg.vbox.pack_start(scrolled_window, expand=True, fill=True)
- scrolled_window.show_all()
-
- if len(surnames) == 0:
- # we could use database.get_surname_list(), but if we do that
- # all we get is a list of names without a count...therefore
- # we'll traverse the entire database ourself and build up a
- # list that we can use
-# for name in database.get_surname_list():
-# self.__model.append([name, 0])
-
- # build up the list of surnames, keeping track of the count for each
- # name (this can be a lengthy process, so by passing in the
- # dictionary we can be certain we only do this once)
- progress = ProgressMeter(_('Finding Surnames'))
- progress.set_pass(_('Finding surnames'),
- database.get_number_of_people())
- for person in database.iter_people():
- progress.step()
- key = person.get_primary_name().get_surname()
- count = 0
- if key in surnames:
- count = surnames[key]
- surnames[key] = count + 1
- progress.close()
-
- # insert the names and count into the model
- for key in surnames:
- if key.encode('iso-8859-1','xmlcharrefreplace') not in skip_list:
- self.__model.append([key, surnames[key]])
-
- # keep the list sorted starting with the most popular last name
- self.__model.set_sort_column_id(1, gtk.SORT_DESCENDING)
-
- # the "OK" button should be enabled/disabled based on the selection of
- # a row
- self.__tree_selection = self.__tree_view.get_selection()
- self.__tree_selection.set_mode(gtk.SELECTION_MULTIPLE)
- self.__tree_selection.select_path(0)
-
- def run(self):
- """
- Display the dialog and return the selected surnames when done.
- """
- response = self.__dlg.run()
- surname_set = set()
- if response == gtk.RESPONSE_ACCEPT:
- (mode, paths) = self.__tree_selection.get_selected_rows()
- for path in paths:
- i = self.__model.get_iter(path)
- surname = self.__model.get_value(i, 0)
- surname_set.add(surname)
- self.__dlg.destroy()
- return surname_set
-
-#-------------------------------------------------------------------------
-#
-# GuiStringOption class
-#
-#-------------------------------------------------------------------------
-class GuiStringOption(gtk.Entry):
- """
- This class displays an option that is a simple one-line string.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.StringOption
- @return: nothing
- """
- gtk.Entry.__init__(self)
- self.__option = option
- self.set_text( self.__option.get_value() )
- self.connect('changed', self.__text_changed)
- self.set_tooltip_text(self.__option.get_help())
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __text_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of the value.
- """
- self.__option.set_value( self.get_text() )
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiColorOption class
-#
-#-------------------------------------------------------------------------
-class GuiColorOption(gtk.ColorButton):
- """
- This class displays an option that allows the selection of a colour.
- """
- def __init__(self, option, dbstate, uistate, track):
- self.__option = option
- value = self.__option.get_value()
- gtk.ColorButton.__init__( self, gtk.gdk.color_parse(value) )
- self.connect('color-set', self.__value_changed)
- self.set_tooltip_text(self.__option.get_help())
-
- def __value_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of color.
- """
- colour = self.get_color()
- value = '#%02x%02x%02x' % (
- int(colour.red * 256 / 65536),
- int(colour.green * 256 / 65536),
- int(colour.blue * 256 / 65536))
- self.__option.set_value(value)
-
-#-------------------------------------------------------------------------
-#
-# GuiNumberOption class
-#
-#-------------------------------------------------------------------------
-class GuiNumberOption(gtk.SpinButton):
- """
- This class displays an option that is a simple number with defined maximum
- and minimum values.
- """
- def __init__(self, option, dbstate, uistate, track):
- self.__option = option
-
- decimals = 0
- step = self.__option.get_step()
- adj = gtk.Adjustment(1,
- self.__option.get_min(),
- self.__option.get_max(),
- step)
-
- # Calculate the number of decimal places if necessary
- if step < 1:
- import math
- decimals = int(math.log10(step) * -1)
-
- gtk.SpinButton.__init__(self, adj, digits=decimals)
- gtk.SpinButton.set_numeric(self, True)
-
- self.set_value(self.__option.get_value())
- self.connect('value_changed', self.__value_changed)
- self.set_tooltip_text(self.__option.get_help())
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __value_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of the value.
- """
- vtype = type(self.__option.get_value())
- self.__option.set_value( vtype(self.get_value()) )
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiTextOption class
-#
-#-------------------------------------------------------------------------
-class GuiTextOption(gtk.ScrolledWindow):
- """
- This class displays an option that is a multi-line string.
- """
- def __init__(self, option, dbstate, uistate, track):
- self.__option = option
- gtk.ScrolledWindow.__init__(self)
- self.set_shadow_type(gtk.SHADOW_IN)
- self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-
- # Add a TextView
- value = self.__option.get_value()
- gtext = gtk.TextView()
- gtext.get_buffer().set_text("\n".join(value))
- gtext.set_editable(1)
- self.add(gtext)
-
- # Required for tooltip
- gtext.add_events(gtk.gdk.ENTER_NOTIFY_MASK)
- gtext.add_events(gtk.gdk.LEAVE_NOTIFY_MASK)
- gtext.set_tooltip_text(self.__option.get_help())
-
- self.__buff = gtext.get_buffer()
- self.__buff.connect('changed', self.__value_changed)
-
- def __value_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of the value.
- """
- text_val = unicode( self.__buff.get_text( self.__buff.get_start_iter(),
- self.__buff.get_end_iter(),
- False) )
- self.__option.set_value( text_val.split('\n') )
-
-#-------------------------------------------------------------------------
-#
-# GuiBooleanOption class
-#
-#-------------------------------------------------------------------------
-class GuiBooleanOption(gtk.CheckButton):
- """
- This class displays an option that is a boolean (True or False).
- """
- def __init__(self, option, dbstate, uistate, track):
- self.__option = option
- gtk.CheckButton.__init__(self, self.__option.get_label())
- self.set_active(self.__option.get_value())
- self.connect('toggled', self.__value_changed)
- self.set_tooltip_text(self.__option.get_help())
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __value_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of the value.
- """
- self.__option.set_value( self.get_active() )
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiEnumeratedListOption class
-#
-#-------------------------------------------------------------------------
-class GuiEnumeratedListOption(gtk.HBox):
- """
- This class displays an option that provides a finite number of values.
- Each possible value is assigned a value and a description.
- """
- def __init__(self, option, dbstate, uistate, track):
- gtk.HBox.__init__(self)
- evtBox = gtk.EventBox()
- self.__option = option
- self.__combo = gtk.combo_box_new_text()
- evtBox.add(self.__combo)
- self.pack_start(evtBox, True, True)
-
- self.__update_options()
-
- self.set_tooltip_text(self.__option.get_help())
-
- self.__combo.connect('changed', self.__value_changed)
- self.__option.connect('options-changed', self.__update_options)
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __value_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of the value.
- """
- index = self.__combo.get_active()
- if index < 0:
- return
- items = self.__option.get_items()
- value, description = items[index] # IGNORE:W0612 - description is unused
- self.__option.set_value( value )
- self.value_changed()
-
- def value_changed(self):
- pass
-
- def __update_options(self):
- """
- Handle the change of the available options.
- """
- self.__combo.get_model().clear()
- cur_val = self.__option.get_value()
- active_index = 0
- current_index = 0
- for (value, description) in self.__option.get_items():
- self.__combo.append_text(description)
- if value == cur_val:
- active_index = current_index
- current_index += 1
- self.__combo.set_active( active_index )
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiPersonOption class
-#
-#-------------------------------------------------------------------------
-class GuiPersonOption(gtk.HBox):
- """
- This class displays an option that allows a person from the
- database to be selected.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.PersonOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
- self.__person_label = gtk.Label()
- self.__person_label.set_alignment(0.0, 0.5)
-
- pevt = gtk.EventBox()
- pevt.add(self.__person_label)
- person_button = widgets.SimpleButton(gtk.STOCK_INDEX,
- self.__get_person_clicked)
- person_button.set_relief(gtk.RELIEF_NORMAL)
-
- self.pack_start(pevt, False)
- self.pack_end(person_button, False)
-
- person_handle = self.__uistate.get_active('Person')
- person = self.__dbstate.db.get_person_from_handle(person_handle)
- if not person:
- person = self.__db.get_default_person()
- self.__update_person(person)
-
- pevt.set_tooltip_text(self.__option.get_help())
- person_button.set_tooltip_text(_('Select a different person'))
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __get_person_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the button to choose a different person.
- """
- # Create a filter for the person selector.
- rfilter = GenericFilter()
- rfilter.set_logical_op('or')
- rfilter.add_rule(Rules.Person.IsBookmarked([]))
- rfilter.add_rule(Rules.Person.HasIdOf([self.__option.get_value()]))
-
- # Add the database home person if one exists.
- default_person = self.__db.get_default_person()
- if default_person:
- gid = default_person.get_gramps_id()
- rfilter.add_rule(Rules.Person.HasIdOf([gid]))
-
- # Add the selected person if one exists.
- person_handle = self.__uistate.get_active('Person')
- active_person = self.__dbstate.db.get_person_from_handle(person_handle)
- if active_person:
- gid = active_person.get_gramps_id()
- rfilter.add_rule(Rules.Person.HasIdOf([gid]))
-
- select_class = SelectorFactory('Person')
- sel = select_class(self.__dbstate, self.__uistate, self.__track,
- title=_('Select a person for the report'),
- filter=rfilter )
- person = sel.run()
- self.__update_person(person)
-
- def __update_person(self, person):
- """
- Update the currently selected person.
- """
- if person:
- name = _nd.display(person)
- gid = person.get_gramps_id()
- self.__person_label.set_text( "%s (%s)" % (name, gid) )
- self.__option.set_value(gid)
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiFamilyOption class
-#
-#-------------------------------------------------------------------------
-class GuiFamilyOption(gtk.HBox):
- """
- This class displays an option that allows a family from the
- database to be selected.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.FamilyOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
- self.__family_label = gtk.Label()
- self.__family_label.set_alignment(0.0, 0.5)
-
- pevt = gtk.EventBox()
- pevt.add(self.__family_label)
- family_button = widgets.SimpleButton(gtk.STOCK_INDEX,
- self.__get_family_clicked)
- family_button.set_relief(gtk.RELIEF_NORMAL)
-
- self.pack_start(pevt, False)
- self.pack_end(family_button, False)
-
- self.__initialize_family()
-
- pevt.set_tooltip_text(self.__option.get_help())
- family_button.set_tooltip_text(_('Select a different family'))
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __initialize_family(self):
- """
- Find a family to initialize the option with. Any family will do, but
- try to find a family that the user is likely interested in.
- """
- family_list = []
-
- # Use the active family if one is selected
- family = self.__uistate.get_active('Family')
- if family:
- family_list = [family]
-
- if not family_list:
- # Next try the family of the active person
- person_handle = self.__uistate.get_active('Person')
- person = self.__dbstate.db.get_person_from_handle(person_handle)
- if person:
- family_list = person.get_family_handle_list()
-
- if not family_list:
- # Next try the family of the default person in the database.
- person = self.__db.get_default_person()
- if person:
- family_list = person.get_family_handle_list()
-
- if not family_list:
- # Finally, take any family you can find.
- for family in self.__db.iter_family_handles():
- self.__update_family(family)
- break
- else:
- self.__update_family(family_list[0])
-
- def __get_family_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the button to choose a different family.
- """
- # Create a filter for the person selector.
- rfilter = GenericFilterFactory('Family')()
- rfilter.set_logical_op('or')
-
- # Add the current family
- rfilter.add_rule(Rules.Family.HasIdOf([self.__option.get_value()]))
-
- # Add all bookmarked families
- rfilter.add_rule(Rules.Family.IsBookmarked([]))
-
- # Add the families of the database home person if one exists.
- default_person = self.__db.get_default_person()
- if default_person:
- family_list = default_person.get_family_handle_list()
- for family_handle in family_list:
- family = self.__db.get_family_from_handle(family_handle)
- gid = family.get_gramps_id()
- rfilter.add_rule(Rules.Family.HasIdOf([gid]))
-
- # Add the families of the selected person if one exists.
- active_person = self.__db.get_default_person()
- if active_person:
- family_list = active_person.get_family_handle_list()
- for family_handle in family_list:
- family = self.__db.get_family_from_handle(family_handle)
- gid = family.get_gramps_id()
- rfilter.add_rule(Rules.Family.HasIdOf([gid]))
-
- select_class = SelectorFactory('Family')
- sel = select_class(self.__dbstate, self.__uistate, self.__track,
- filter=rfilter )
- family = sel.run()
- if family:
- self.__update_family(family.get_handle())
-
- def __update_family(self, handle):
- """
- Update the currently selected family.
- """
- if handle:
- family = self.__dbstate.db.get_family_from_handle(handle)
- family_id = family.get_gramps_id()
- fhandle = family.get_father_handle()
- mhandle = family.get_mother_handle()
-
- if fhandle:
- father = self.__db.get_person_from_handle(fhandle)
- father_name = _nd.display(father)
- else:
- father_name = _("unknown father")
-
- if mhandle:
- mother = self.__db.get_person_from_handle(mhandle)
- mother_name = _nd.display(mother)
- else:
- mother_name = _("unknown mother")
-
- name = _("%s and %s (%s)") % (father_name, mother_name, family_id)
-
- self.__family_label.set_text( name )
- self.__option.set_value(family_id)
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiNoteOption class
-#
-#-------------------------------------------------------------------------
-class GuiNoteOption(gtk.HBox):
- """
- This class displays an option that allows a note from the
- database to be selected.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.NoteOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
- self.__note_label = gtk.Label()
- self.__note_label.set_alignment(0.0, 0.5)
-
- pevt = gtk.EventBox()
- pevt.add(self.__note_label)
- note_button = widgets.SimpleButton(gtk.STOCK_INDEX,
- self.__get_note_clicked)
- note_button.set_relief(gtk.RELIEF_NORMAL)
-
- self.pack_start(pevt, False)
- self.pack_end(note_button, False)
-
- # Initialize to the current value
- nid = self.__option.get_value()
- note = self.__db.get_note_from_gramps_id(nid)
- self.__update_note(note)
-
- pevt.set_tooltip_text(self.__option.get_help())
- note_button.set_tooltip_text(_('Select an existing note'))
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __get_note_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the button to choose a different note.
- """
- select_class = SelectorFactory('Note')
- sel = select_class(self.__dbstate, self.__uistate, self.__track)
- note = sel.run()
- self.__update_note(note)
-
- def __update_note(self, note):
- """
- Update the currently selected note.
- """
- if note:
- note_id = note.get_gramps_id()
- txt = " ".join(note.get().split())
- #String must be unicode for truncation to work for non ascii characters
- txt = unicode(txt)
- if len(txt) > 35:
- txt = txt[:35] + "..."
- txt = "%s [%s]" % (txt, note_id)
-
- self.__note_label.set_text( txt )
- self.__option.set_value(note_id)
- else:
- txt = "%s" % _('No note given, click button to select one')
- self.__note_label.set_text( txt )
- self.__note_label.set_use_markup(True)
- self.__option.set_value("")
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiMediaOption class
-#
-#-------------------------------------------------------------------------
-class GuiMediaOption(gtk.HBox):
- """
- This class displays an option that allows a media object from the
- database to be selected.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.MediaOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
- self.__media_label = gtk.Label()
- self.__media_label.set_alignment(0.0, 0.5)
-
- pevt = gtk.EventBox()
- pevt.add(self.__media_label)
- media_button = widgets.SimpleButton(gtk.STOCK_INDEX,
- self.__get_media_clicked)
- media_button.set_relief(gtk.RELIEF_NORMAL)
-
- self.pack_start(pevt, False)
- self.pack_end(media_button, False)
-
- # Initialize to the current value
- mid = self.__option.get_value()
- media = self.__db.get_object_from_gramps_id(mid)
- self.__update_media(media)
-
- pevt.set_tooltip_text(self.__option.get_help())
- media_button.set_tooltip_text(_('Select an existing media object'))
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __get_media_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the button to choose a different note.
- """
- select_class = SelectorFactory('MediaObject')
- sel = select_class(self.__dbstate, self.__uistate, self.__track)
- media = sel.run()
- self.__update_media(media)
-
- def __update_media(self, media):
- """
- Update the currently selected media.
- """
- if media:
- media_id = media.get_gramps_id()
- txt = "%s [%s]" % (media.get_description(), media_id)
-
- self.__media_label.set_text( txt )
- self.__option.set_value(media_id)
- else:
- txt = "%s" % _('No image given, click button to select one')
- self.__media_label.set_text( txt )
- self.__media_label.set_use_markup(True)
- self.__option.set_value("")
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiPersonListOption class
-#
-#-------------------------------------------------------------------------
-class GuiPersonListOption(gtk.HBox):
- """
- This class displays a widget that allows multiple people from the
- database to be selected.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.PersonListOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
-
- self.__model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
- self.__tree_view = gtk.TreeView(self.__model)
- self.__tree_view.set_size_request(150, 150)
- col1 = gtk.TreeViewColumn(_('Name' ), gtk.CellRendererText(), text=0)
- col2 = gtk.TreeViewColumn(_('ID' ), gtk.CellRendererText(), text=1)
- col1.set_resizable(True)
- col2.set_resizable(True)
- col1.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col2.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col1.set_sort_column_id(0)
- col2.set_sort_column_id(1)
- self.__tree_view.append_column(col1)
- self.__tree_view.append_column(col2)
- self.__scrolled_window = gtk.ScrolledWindow()
- self.__scrolled_window.add(self.__tree_view)
- self.__scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
- gtk.POLICY_AUTOMATIC)
- self.__scrolled_window.set_shadow_type(gtk.SHADOW_OUT)
-
- self.pack_start(self.__scrolled_window, expand=True, fill=True)
-
- value = self.__option.get_value()
- for gid in value.split():
- person = self.__db.get_person_from_gramps_id(gid)
- if person:
- name = _nd.display(person)
- self.__model.append([name, gid])
-
- # now setup the '+' and '-' pushbutton for adding/removing people from
- # the container
- self.__add_person = widgets.SimpleButton(gtk.STOCK_ADD,
- self.__add_person_clicked)
- self.__del_person = widgets.SimpleButton(gtk.STOCK_REMOVE,
- self.__del_person_clicked)
- self.__vbbox = gtk.VButtonBox()
- self.__vbbox.add(self.__add_person)
- self.__vbbox.add(self.__del_person)
- self.__vbbox.set_layout(gtk.BUTTONBOX_SPREAD)
- self.pack_end(self.__vbbox, expand=False)
-
- self.__tree_view.set_tooltip_text(self.__option.get_help())
-
- def __update_value(self):
- """
- Parse the object and return.
- """
- gidlist = ''
- i = self.__model.get_iter_first()
- while (i):
- gid = self.__model.get_value(i, 1)
- gidlist = gidlist + gid + ' '
- i = self.__model.iter_next(i)
- self.__option.set_value(gidlist)
-
- def __add_person_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the add person button.
- """
- # people we already have must be excluded
- # so we don't list them multiple times
- skip_list = set()
- i = self.__model.get_iter_first()
- while (i):
- gid = self.__model.get_value(i, 1) # get the GID stored in column #1
- person = self.__db.get_person_from_gramps_id(gid)
- skip_list.add(person.get_handle())
- i = self.__model.iter_next(i)
-
- select_class = SelectorFactory('Person')
- sel = select_class(self.__dbstate, self.__uistate,
- self.__track, skip=skip_list)
- person = sel.run()
- if person:
- name = _nd.display(person)
- gid = person.get_gramps_id()
- self.__model.append([name, gid])
-
- # if this person has a spouse, ask if we should include the spouse
- # in the list of "people of interest"
- #
- # NOTE: we may want to make this an optional thing, determined
- # by the use of a parameter at the time this class is instatiated
- family_list = person.get_family_handle_list()
- for family_handle in family_list:
- family = self.__db.get_family_from_handle(family_handle)
-
- if person.get_handle() == family.get_father_handle():
- spouse_handle = family.get_mother_handle()
- else:
- spouse_handle = family.get_father_handle()
-
- if spouse_handle and (spouse_handle not in skip_list):
- spouse = self.__db.get_person_from_handle(
- spouse_handle)
- spouse_name = _nd.display(spouse)
- text = _('Also include %s?') % spouse_name
-
- prompt = OptionDialog(_('Select Person'),
- text,
- _('No'), None,
- _('Yes'), None)
- if prompt.get_response() == gtk.RESPONSE_YES:
- gid = spouse.get_gramps_id()
- self.__model.append([spouse_name, gid])
-
- self.__update_value()
-
- def __del_person_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the delete person button.
- """
- (path, column) = self.__tree_view.get_cursor()
- if (path):
- i = self.__model.get_iter(path)
- self.__model.remove(i)
- self.__update_value()
-
-#-------------------------------------------------------------------------
-#
-# GuiPlaceListOption class
-#
-#-------------------------------------------------------------------------
-class GuiPlaceListOption(gtk.HBox):
- """
- This class displays a widget that allows multiple places from the
- database to be selected.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.PlaceListOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
-
- self.__model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
- self.__tree_view = gtk.TreeView(self.__model)
- self.__tree_view.set_size_request(150, 150)
- col1 = gtk.TreeViewColumn(_('Place' ), gtk.CellRendererText(), text=0)
- col2 = gtk.TreeViewColumn(_('ID' ), gtk.CellRendererText(), text=1)
- col1.set_resizable(True)
- col2.set_resizable(True)
- col1.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col2.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col1.set_sort_column_id(0)
- col2.set_sort_column_id(1)
- self.__tree_view.append_column(col1)
- self.__tree_view.append_column(col2)
- self.__scrolled_window = gtk.ScrolledWindow()
- self.__scrolled_window.add(self.__tree_view)
- self.__scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
- gtk.POLICY_AUTOMATIC)
- self.__scrolled_window.set_shadow_type(gtk.SHADOW_OUT)
-
- self.pack_start(self.__scrolled_window, expand=True, fill=True)
-
- value = self.__option.get_value()
- for gid in value.split():
- place = self.__db.get_place_from_gramps_id(gid)
- if place:
- place_name = place.get_title()
- self.__model.append([place_name, gid])
-
- # now setup the '+' and '-' pushbutton for adding/removing places from
- # the container
- self.__add_place = widgets.SimpleButton(gtk.STOCK_ADD,
- self.__add_place_clicked)
- self.__del_place = widgets.SimpleButton(gtk.STOCK_REMOVE,
- self.__del_place_clicked)
- self.__vbbox = gtk.VButtonBox()
- self.__vbbox.add(self.__add_place)
- self.__vbbox.add(self.__del_place)
- self.__vbbox.set_layout(gtk.BUTTONBOX_SPREAD)
- self.pack_end(self.__vbbox, expand=False)
-
- self.__tree_view.set_tooltip_text(self.__option.get_help())
-
- def __update_value(self):
- """
- Parse the object and return.
- """
- gidlist = ''
- i = self.__model.get_iter_first()
- while (i):
- gid = self.__model.get_value(i, 1)
- gidlist = gidlist + gid + ' '
- i = self.__model.iter_next(i)
- self.__option.set_value(gidlist)
-
- def __add_place_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the add place button.
- """
- # places we already have must be excluded
- # so we don't list them multiple times
- skip_list = set()
- i = self.__model.get_iter_first()
- while (i):
- gid = self.__model.get_value(i, 1) # get the GID stored in column #1
- place = self.__db.get_place_from_gramps_id(gid)
- skip_list.add(place.get_handle())
- i = self.__model.iter_next(i)
-
- select_class = SelectorFactory('Place')
- sel = select_class(self.__dbstate, self.__uistate,
- self.__track, skip=skip_list)
- place = sel.run()
- if place:
- place_name = place.get_title()
- gid = place.get_gramps_id()
- self.__model.append([place_name, gid])
- self.__update_value()
-
- def __del_place_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the delete place button.
- """
- (path, column) = self.__tree_view.get_cursor()
- if (path):
- i = self.__model.get_iter(path)
- self.__model.remove(i)
- self.__update_value()
-
-#-------------------------------------------------------------------------
-#
-# GuiSurnameColorOption class
-#
-#-------------------------------------------------------------------------
-class GuiSurnameColorOption(gtk.HBox):
- """
- This class displays a widget that allows multiple surnames to be
- selected from the database, and to assign a colour (not necessarily
- unique) to each one.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.SurnameColorOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__dbstate = dbstate
- self.__db = dbstate.get_database()
- self.__uistate = uistate
- self.__track = track
-
- # This will get populated the first time the dialog is run,
- # and used each time after.
- self.__surnames = {} # list of surnames and count
-
- self.__model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
- self.__tree_view = gtk.TreeView(self.__model)
- self.__tree_view.set_size_request(150, 150)
- self.__tree_view.connect('row-activated', self.__row_clicked)
- col1 = gtk.TreeViewColumn(_('Surname'), gtk.CellRendererText(), text=0)
- col2 = gtk.TreeViewColumn(_('Colour'), gtk.CellRendererText(), text=1)
- col1.set_resizable(True)
- col2.set_resizable(True)
- col1.set_sort_column_id(0)
- col1.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- col2.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
- self.__tree_view.append_column(col1)
- self.__tree_view.append_column(col2)
- self.scrolled_window = gtk.ScrolledWindow()
- self.scrolled_window.add(self.__tree_view)
- self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
- gtk.POLICY_AUTOMATIC)
- self.scrolled_window.set_shadow_type(gtk.SHADOW_OUT)
- self.pack_start(self.scrolled_window, expand=True, fill=True)
-
- self.add_surname = widgets.SimpleButton(gtk.STOCK_ADD,
- self.__add_clicked)
- self.del_surname = widgets.SimpleButton(gtk.STOCK_REMOVE,
- self.__del_clicked)
- self.vbbox = gtk.VButtonBox()
- self.vbbox.add(self.add_surname)
- self.vbbox.add(self.del_surname)
- self.vbbox.set_layout(gtk.BUTTONBOX_SPREAD)
- self.pack_end(self.vbbox, expand=False)
-
- # populate the surname/colour treeview
- #
- # For versions prior to 3.0.2, the fields were delimited with
- # whitespace. However, this causes problems when the surname
- # also has a space within it. When populating the control,
- # support both the new and old format -- look for the \xb0
- # delimiter, and if it isn't there, assume this is the old-
- # style space-delimited format. (Bug #2162.)
- if (self.__option.get_value().find(u'\xb0') >= 0):
- tmp = self.__option.get_value().split(u'\xb0')
- else:
- tmp = self.__option.get_value().split(' ')
- while len(tmp) > 1:
- surname = tmp.pop(0)
- colour = tmp.pop(0)
- self.__model.append([surname, colour])
-
- self.__tree_view.set_tooltip_text(self.__option.get_help())
-
- def __value_changed(self):
- """
- Parse the object and return.
- """
- surname_colours = ''
- i = self.__model.get_iter_first()
- while (i):
- surname = self.__model.get_value(i, 0)
- #surname = surname.encode('iso-8859-1','xmlcharrefreplace')
- colour = self.__model.get_value(i, 1)
- # Tried to use a dictionary, and tried to save it as a tuple,
- # but coulnd't get this to work right -- this is lame, but now
- # the surnames and colours are saved as a plain text string
- #
- # Hmmm...putting whitespace between the fields causes
- # problems when the surname has whitespace -- for example,
- # with surnames like "Del Monte". So now we insert a non-
- # whitespace character which is unlikely to appear in
- # a surname. (See bug report #2162.)
- surname_colours += surname + u'\xb0' + colour + u'\xb0'
- i = self.__model.iter_next(i)
- self.__option.set_value( surname_colours )
-
- def __row_clicked(self, treeview, path, column):
- """
- Handle the case of a row being clicked on.
- """
- # get the surname and colour value for this family
- i = self.__model.get_iter(path)
- surname = self.__model.get_value(i, 0)
- colour = gtk.gdk.color_parse(self.__model.get_value(i, 1))
-
- title = 'Select colour for %s' % surname
- colour_dialog = gtk.ColorSelectionDialog(title)
- colorsel = colour_dialog.colorsel
- colorsel.set_current_color(colour)
- response = colour_dialog.run()
-
- if response == gtk.RESPONSE_OK:
- colour = colorsel.get_current_color()
- colour_name = '#%02x%02x%02x' % (
- int(colour.red *256/65536),
- int(colour.green*256/65536),
- int(colour.blue *256/65536))
- self.__model.set_value(i, 1, colour_name)
-
- colour_dialog.destroy()
- self.__value_changed()
-
- def __add_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the the add surname button.
- """
- skip_list = set()
- i = self.__model.get_iter_first()
- while (i):
- surname = self.__model.get_value(i, 0)
- skip_list.add(surname.encode('iso-8859-1','xmlcharrefreplace'))
- i = self.__model.iter_next(i)
-
- ln_dialog = LastNameDialog(self.__db, self.__uistate,
- self.__track, self.__surnames, skip_list)
- surname_set = ln_dialog.run()
- for surname in surname_set:
- self.__model.append([surname, '#ffffff'])
- self.__value_changed()
-
- def __del_clicked(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the the delete surname button.
- """
- (path, column) = self.__tree_view.get_cursor()
- if (path):
- i = self.__model.get_iter(path)
- self.__model.remove(i)
- self.__value_changed()
-
-#-------------------------------------------------------------------------
-#
-# GuiDestinationOption class
-#
-#-------------------------------------------------------------------------
-class GuiDestinationOption(gtk.HBox):
- """
- This class displays an option that allows the user to select a
- DestinationOption.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.DestinationOption
- @return: nothing
- """
- gtk.HBox.__init__(self)
- self.__option = option
- self.__entry = gtk.Entry()
- self.__entry.set_text( self.__option.get_value() )
- self.__entry.connect('changed', self.__text_changed)
-
- self.__button = gtk.Button()
- img = gtk.Image()
- img.set_from_stock(gtk.STOCK_OPEN, gtk.ICON_SIZE_BUTTON)
- self.__button.add(img)
- self.__button.connect('clicked', self.__select_file)
-
- self.pack_start(self.__entry, True, True)
- self.pack_end(self.__button, False, False)
-
- self.set_tooltip_text(self.__option.get_help())
-
- self.__option.connect('options-changed', self.__option_changed)
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __text_changed(self, obj): # IGNORE:W0613 - obj is unused
- """
- Handle the change of the value.
- """
- self.__option.set_value( self.__entry.get_text() )
-
- def __select_file(self, obj):
- """
- Handle the user's request to select a file (or directory).
- """
- if self.__option.get_directory_entry():
- my_action = gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER
- else:
- my_action = gtk.FILE_CHOOSER_ACTION_SAVE
-
- fcd = gtk.FileChooserDialog(_("Save As"), action=my_action,
- buttons=(gtk.STOCK_CANCEL,
- gtk.RESPONSE_CANCEL,
- gtk.STOCK_OPEN,
- gtk.RESPONSE_OK))
-
- name = os.path.abspath(self.__option.get_value())
- if self.__option.get_directory_entry():
- while not os.path.isdir(name):
- # Keep looking up levels to find a valid drive.
- name, tail = os.path.split(name)
- if not name:
- # Avoid infinite loops
- name = os.getcwd()
- fcd.set_current_folder(name)
- else:
- fcd.set_current_name(name)
-
- status = fcd.run()
- if status == gtk.RESPONSE_OK:
- path = Utils.get_unicode_path(fcd.get_filename())
- if path:
- if not self.__option.get_directory_entry() and \
- not path.endswith(self.__option.get_extension()):
- path = path + self.__option.get_extension()
- self.__entry.set_text(path)
- self.__option.set_value(path)
- fcd.destroy()
-
- def __option_changed(self):
- """
- Handle a change of the option.
- """
- extension = self.__option.get_extension()
- directory = self.__option.get_directory_entry()
- value = self.__option.get_value()
-
- if not directory and not value.endswith(extension):
- value = value + extension
- self.__option.set_value(value)
- elif directory and value.endswith(extension):
- value = value[:-len(extension)]
- self.__option.set_value(value)
-
- self.__entry.set_text( self.__option.get_value() )
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#-------------------------------------------------------------------------
-#
-# GuiStyleOption class
-#
-#-------------------------------------------------------------------------
-class GuiStyleOption(GuiEnumeratedListOption):
- """
- This class displays a StyleOption.
- """
- def __init__(self, option, dbstate, uistate, track):
- """
- @param option: The option to display.
- @type option: gen.plug.menu.StyleOption
- @return: nothing
- """
- GuiEnumeratedListOption.__init__(self, option, dbstate,
- uistate, track)
- self.__option = option
-
- self.__button = gtk.Button("%s..." % _("Style Editor"))
- self.__button.connect('clicked', self.__on_style_edit_clicked)
-
- self.pack_end(self.__button, False, False)
-
- def __on_style_edit_clicked(self, *obj):
- """The user has clicked on the 'Edit Styles' button. Create a
- style sheet editor object and let them play. When they are
- done, update the displayed styles."""
- from gen.plug.docgen import StyleSheetList
- from gui.plug.report._styleeditor import StyleListDisplay
- style_list = StyleSheetList(self.__option.get_style_file(),
- self.__option.get_default_style())
- StyleListDisplay(style_list, None, None)
-
- new_items = []
- for style_name in style_list.get_style_names():
- new_items.append( (style_name, style_name) )
- self.__option.set_items(new_items)
-
-#-------------------------------------------------------------------------
-#
-# GuiBooleanListOption class
-#
-#-------------------------------------------------------------------------
-class GuiBooleanListOption(gtk.HBox):
- """
- This class displays an option that provides a list of check boxes.
- Each possible value is assigned a value and a description.
- """
- def __init__(self, option, dbstate, uistate, track):
- gtk.HBox.__init__(self)
- self.__option = option
- self.__cbutton = []
-
- COLUMNS = 2 # Number of checkbox columns
- column = []
- for i in range(COLUMNS):
- vbox = gtk.VBox()
- self.pack_start(vbox, True, True)
- column.append(vbox)
- vbox.show()
-
- counter = 0
- default = option.get_value().split(',')
- for description in option.get_descriptions():
- button = gtk.CheckButton(description)
- self.__cbutton.append(button)
- if default[counter] == 'True':
- button.set_active(True)
- button.connect("toggled", self.__value_changed)
- column[counter % COLUMNS].pack_start(button, True, True)
- button.show()
- counter += 1
-
- self.set_tooltip_text(self.__option.get_help())
-
- self.__option.connect('avail-changed', self.__update_avail)
- self.__update_avail()
-
- def __value_changed(self, button):
- """
- Handle the change of the value.
- """
- value = ''
- for button in self.__cbutton:
- value = value + str(button.get_active()) + ','
- value = value[:len(value)-1]
- self.__option.set_value(value)
-
- def __update_avail(self):
- """
- Update the availability (sensitivity) of this widget.
- """
- avail = self.__option.get_available()
- self.set_sensitive(avail)
-
-#------------------------------------------------------------------------
-#
-# GuiMenuOptions class
-#
-#------------------------------------------------------------------------
-class GuiMenuOptions(object):
- """
- Introduction
- ============
- A GuiMenuOptions is used to implement the necessary funtions for adding
- options to a GTK dialog.
- """
- def __init__(self):
- self.menu = gen.plug.menu.Menu()
-
- # Fill options_dict with report/tool defaults:
- self.options_dict = {}
- self.options_help = {}
- self.add_menu_options(self.menu)
- for name in self.menu.get_all_option_names():
- option = self.menu.get_option_by_name(name)
- self.options_dict[name] = option.get_value()
- self.options_help[name] = [ "", option.get_help() ]
-
- def make_default_style(self, default_style):
- """
- This function is currently required by some reports.
- """
- pass
-
- def add_menu_options(self, menu):
- """
- Add the user defined options to the menu.
-
- @param menu: A menu class for the options to belong to.
- @type menu: Menu
- @return: nothing
- """
- raise NotImplementedError
-
- def add_menu_option(self, category, name, option):
- """
- Add a single option to the menu.
- """
- self.menu.add_option(category, name, option)
- self.options_dict[name] = option.get_value()
- self.options_help[name] = [ "", option.get_help() ]
-
- def add_user_options(self, dialog):
- """
- Generic method to add user options to the gui.
- """
- for category in self.menu.get_categories():
- for name in self.menu.get_option_names(category):
- option = self.menu.get_option(category, name)
-
- # override option default with xml-saved value:
- if name in self.options_dict:
- option.set_value(self.options_dict[name])
-
- widget, label = make_gui_option(option, dialog.dbstate,
- dialog.uistate, dialog.track)
-
- if widget is None:
- print "UNKNOWN OPTION: ", option
- else:
- if label:
- dialog.add_frame_option(category,
- option.get_label(),
- widget)
- else:
- dialog.add_frame_option(category, "", widget)
-
- def parse_user_options(self, dialog): # IGNORE:W0613 - dialog is unused
- """
- Load the changed values into the saved options.
- """
- for name in self.menu.get_all_option_names():
- option = self.menu.get_option_by_name(name)
- self.options_dict[name] = option.get_value()
-
-def make_gui_option(option, dbstate, uistate, track):
- """
- Stand-alone function so that Options can be used in other
- ways, too. Takes an Option and returns a GuiOption.
- """
- widget = None
- label = True
- pmgr = GuiPluginManager.get_instance()
- external_options = pmgr.get_external_opt_dict()
- if isinstance(option, gen.plug.menu.PersonOption):
- widget = GuiPersonOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.FamilyOption):
- widget = GuiFamilyOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.NoteOption):
- widget = GuiNoteOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.MediaOption):
- widget = GuiMediaOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.PersonListOption):
- widget = GuiPersonListOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.NumberOption):
- widget = GuiNumberOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.BooleanOption):
- widget = GuiBooleanOption(option, dbstate, uistate, track)
- label = False
- elif isinstance(option, gen.plug.menu.DestinationOption):
- widget = GuiDestinationOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.StringOption):
- widget = GuiStringOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.StyleOption):
- widget = GuiStyleOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.EnumeratedListOption):
- widget = GuiEnumeratedListOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.TextOption):
- widget = GuiTextOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.ColorOption):
- widget = GuiColorOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.SurnameColorOption):
- widget = GuiSurnameColorOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.PlaceListOption):
- widget = GuiPlaceListOption(option, dbstate, uistate, track)
- elif isinstance(option, gen.plug.menu.BooleanListOption):
- widget = GuiBooleanListOption(option, dbstate, uistate, track)
- elif option.__class__ in external_options:
- widget = external_options[option.__class__](option, dbstate, uistate,
- track)
- else:
- raise AttributeError(
- "can't make GuiOption: unknown option type: '%s'" % option)
- return widget, label
diff --git a/src/gui/plug/report/__init__.py b/src/gui/plug/report/__init__.py
index 4b92fb09a..20494c2b2 100644
--- a/src/gui/plug/report/__init__.py
+++ b/src/gui/plug/report/__init__.py
@@ -33,73 +33,3 @@ from _textreportdialog import TextReportDialog
from _options import ReportOptions, MenuReportOptions
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001 David R. Hampton
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2007 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# gui.plug.report.__init__
-#
-# $Id$
-
-"Report Generation Framework"
-
-from _reportdialog import report
-from _drawreportdialog import DrawReportDialog
-from _textreportdialog import TextReportDialog
-
-from _options import ReportOptions, MenuReportOptions
-
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001 David R. Hampton
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2007 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# gui.plug.report.__init__
-#
-# $Id$
-
-"Report Generation Framework"
-
-from _reportdialog import report
-from _drawreportdialog import DrawReportDialog
-from _textreportdialog import TextReportDialog
-
-from _options import ReportOptions, MenuReportOptions
-
diff --git a/src/gui/plug/report/_docreportdialog.py b/src/gui/plug/report/_docreportdialog.py
index 6e21a0236..85ea0e216 100644
--- a/src/gui/plug/report/_docreportdialog.py
+++ b/src/gui/plug/report/_docreportdialog.py
@@ -260,527 +260,3 @@ class DocReportDialog(ReportDialog):
# Save options
self.options.handler.save_options()
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2007 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-import os
-from gen.ggettext import gettext as _
-
-#-------------------------------------------------------------------------
-#
-# GTK+ modules
-#
-#-------------------------------------------------------------------------
-import gtk
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-import const
-from _reportdialog import ReportDialog
-from gen.plug.report._constants import CSS_FILES
-from _papermenu import PaperFrame
-
-#-------------------------------------------------------------------------
-#
-# ReportDialog class
-#
-#-------------------------------------------------------------------------
-class DocReportDialog(ReportDialog):
- """
- The DocReportDialog base class. This is a base class for generating
- dialogs for docgen derived reports.
- """
-
- def __init__(self, dbstate, uistate, option_class, name, trans_name):
- """Initialize a dialog to request that the user select options
- for a basic *stand-alone* report."""
-
- self.style_name = "default"
- self.firstpage_added = False
- ReportDialog.__init__(self, dbstate, uistate, option_class,
- name, trans_name)
-
- # Allow for post processing of the format frame, since the
- # show_all task calls events that may reset values
-
- def init_interface(self):
- ReportDialog.init_interface(self)
- self.doc_type_changed(self.format_menu)
-
- #------------------------------------------------------------------------
- #
- # Functions related to selecting/changing the current file format.
- #
- #------------------------------------------------------------------------
- def make_doc_menu(self, active=None):
- """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."""
- raise NotImplementedError
-
- def make_document(self):
- """Create a document of the type requested by the user.
- """
- pstyle = self.paper_frame.get_paper_style()
-
- 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(const.DATA_DIR + os.sep +
- self.css_filename)
-
- self.options.set_document(self.doc)
-
- if self.open_with_app.get_active():
- self.doc.open_requested()
-
- 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 css
- file. Those chances are made here."""
- docgen_plugin = obj.get_active_plugin()
- if docgen_plugin.get_extension():
- self.open_with_app.set_sensitive (True)
- else:
- self.open_with_app.set_sensitive (False)
-
- # Is this to be a printed report or an electronic report
- # (i.e. a set of web pages)
-
- if self.firstpage_added:
- self.notebook.remove_page(0)
- if docgen_plugin.get_paper_used():
- self.paper_label = gtk.Label('%s'%_("Paper Options"))
- self.paper_label.set_use_markup(True)
- self.notebook.insert_page(self.paper_frame, self.paper_label, 0)
- self.paper_frame.show_all()
- else:
- self.html_label = gtk.Label('%s' % _("HTML Options"))
- self.html_label.set_use_markup(True)
- self.notebook.insert_page(self.html_table, self.html_label, 0)
- self.html_table.show_all()
- self.firstpage_added = True
-
- ext_val = docgen_plugin.get_extension()
- if ext_val:
- fname = self.target_fileentry.get_full_path(0)
- (spath, ext) = os.path.splitext(fname)
-
- fname = spath + "." + ext_val
- self.target_fileentry.set_filename(fname)
- self.target_fileentry.set_sensitive(True)
- else:
- self.target_fileentry.set_filename("")
- self.target_fileentry.set_sensitive(False)
-
- # Does this report format use styles?
- if self.style_button:
- self.style_button.set_sensitive(docgen_plugin.get_style_support())
- self.style_menu.set_sensitive(docgen_plugin.get_style_support())
-
- 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.make_doc_menu(self.options.handler.get_format_name())
- self.format_menu.connect('changed', self.doc_type_changed)
- label = gtk.Label("%s:" % _("Output Format"))
- label.set_alignment(0.0, 0.5)
- self.tbl.attach(label, 1, 2, self.row, self.row+1, gtk.SHRINK|gtk.FILL)
- self.tbl.attach(self.format_menu, 2, 4, self.row, self.row+1,
- yoptions=gtk.SHRINK)
- self.row += 1
-
- self.open_with_app = gtk.CheckButton(_("Open with default viewer"))
- self.tbl.attach(self.open_with_app, 2, 4, self.row, self.row+1,
- yoptions=gtk.SHRINK)
- self.row += 1
-
- ext = self.format_menu.get_active_plugin().get_extension()
- if ext is None:
- ext = ""
- else:
- spath = self.get_default_directory()
- base = "%s.%s" % (self.raw_name, ext)
- spath = os.path.normpath(os.path.join(spath, base))
- self.target_fileentry.set_filename(spath)
-
- def setup_report_options_frame(self):
- self.paper_frame = PaperFrame(self.options.handler.get_paper_metric(),
- self.options.handler.get_paper_name(),
- self.options.handler.get_orientation(),
- self.options.handler.get_margins(),
- self.options.handler.get_custom_paper_size()
- )
- self.setup_html_frame()
- ReportDialog.setup_report_options_frame(self)
-
- 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)
-
- label = gtk.Label("%s:" % _("CSS file"))
- label.set_alignment(0.0,0.5)
- self.html_table.attach(label, 1, 2, 1, 2, gtk.SHRINK|gtk.FILL,
- yoptions=gtk.SHRINK)
-
- self.css_combo = gtk.combo_box_new_text()
-
- css_filename = self.options.handler.get_css_filename()
- active_index = 0
- index = 0
- for style in CSS_FILES:
- self.css_combo.append_text(style[0])
- if css_filename == style[1]:
- active_index = index
- index += 1
-
- self.html_table.attach(self.css_combo,2,3,1,2, yoptions=gtk.SHRINK)
- self.css_combo.set_active(active_index)
-
- def parse_format_frame(self):
- """Parse the format frame of the dialog. Save the user
- selected output format for later use."""
- docgen_plugin = self.format_menu.get_active_plugin()
- self.format = docgen_plugin.get_basedoc()
- format_name = docgen_plugin.get_extension()
- self.options.handler.set_format_name(format_name)
-
- def parse_html_frame(self):
- """Parse the html frame of the dialog. Save the user selected
- html template name for later use. Note that this routine
- retrieves a value whether or not the file entry box is
- displayed on the screen. The subclass will know whether this
- entry was enabled. This is for simplicity of programming."""
-
- self.css_filename = CSS_FILES[self.css_combo.get_active()][1]
- self.options.handler.set_css_filename(self.css_filename)
-
- 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():
- self.window.run()
-
- # Preparation
- self.parse_format_frame()
- self.parse_style_frame()
- self.parse_html_frame()
-
- self.options.handler.set_paper_metric(self.paper_frame.get_paper_metric())
- self.options.handler.set_paper_name(self.paper_frame.get_paper_name())
- self.options.handler.set_orientation(self.paper_frame.get_orientation())
- self.options.handler.set_margins(self.paper_frame.get_paper_margins())
- self.options.handler.set_custom_paper_size(self.paper_frame.get_custom_paper_size())
-
- self.parse_user_options()
-
- # Create the output document.
- self.make_document()
-
- # Save options
- self.options.handler.save_options()
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2007 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-import os
-from gen.ggettext import gettext as _
-
-#-------------------------------------------------------------------------
-#
-# GTK+ modules
-#
-#-------------------------------------------------------------------------
-import gtk
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-import const
-from _reportdialog import ReportDialog
-from gen.plug.report._constants import CSS_FILES
-from _papermenu import PaperFrame
-
-#-------------------------------------------------------------------------
-#
-# ReportDialog class
-#
-#-------------------------------------------------------------------------
-class DocReportDialog(ReportDialog):
- """
- The DocReportDialog base class. This is a base class for generating
- dialogs for docgen derived reports.
- """
-
- def __init__(self, dbstate, uistate, option_class, name, trans_name):
- """Initialize a dialog to request that the user select options
- for a basic *stand-alone* report."""
-
- self.style_name = "default"
- self.firstpage_added = False
- ReportDialog.__init__(self, dbstate, uistate, option_class,
- name, trans_name)
-
- # Allow for post processing of the format frame, since the
- # show_all task calls events that may reset values
-
- def init_interface(self):
- ReportDialog.init_interface(self)
- self.doc_type_changed(self.format_menu)
-
- #------------------------------------------------------------------------
- #
- # Functions related to selecting/changing the current file format.
- #
- #------------------------------------------------------------------------
- def make_doc_menu(self, active=None):
- """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."""
- raise NotImplementedError
-
- def make_document(self):
- """Create a document of the type requested by the user.
- """
- pstyle = self.paper_frame.get_paper_style()
-
- 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(const.DATA_DIR + os.sep +
- self.css_filename)
-
- self.options.set_document(self.doc)
-
- if self.open_with_app.get_active():
- self.doc.open_requested()
-
- 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 css
- file. Those chances are made here."""
- docgen_plugin = obj.get_active_plugin()
- if docgen_plugin.get_extension():
- self.open_with_app.set_sensitive (True)
- else:
- self.open_with_app.set_sensitive (False)
-
- # Is this to be a printed report or an electronic report
- # (i.e. a set of web pages)
-
- if self.firstpage_added:
- self.notebook.remove_page(0)
- if docgen_plugin.get_paper_used():
- self.paper_label = gtk.Label('%s'%_("Paper Options"))
- self.paper_label.set_use_markup(True)
- self.notebook.insert_page(self.paper_frame, self.paper_label, 0)
- self.paper_frame.show_all()
- else:
- self.html_label = gtk.Label('%s' % _("HTML Options"))
- self.html_label.set_use_markup(True)
- self.notebook.insert_page(self.html_table, self.html_label, 0)
- self.html_table.show_all()
- self.firstpage_added = True
-
- ext_val = docgen_plugin.get_extension()
- if ext_val:
- fname = self.target_fileentry.get_full_path(0)
- (spath, ext) = os.path.splitext(fname)
-
- fname = spath + "." + ext_val
- self.target_fileentry.set_filename(fname)
- self.target_fileentry.set_sensitive(True)
- else:
- self.target_fileentry.set_filename("")
- self.target_fileentry.set_sensitive(False)
-
- # Does this report format use styles?
- if self.style_button:
- self.style_button.set_sensitive(docgen_plugin.get_style_support())
- self.style_menu.set_sensitive(docgen_plugin.get_style_support())
-
- 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.make_doc_menu(self.options.handler.get_format_name())
- self.format_menu.connect('changed', self.doc_type_changed)
- label = gtk.Label("%s:" % _("Output Format"))
- label.set_alignment(0.0, 0.5)
- self.tbl.attach(label, 1, 2, self.row, self.row+1, gtk.SHRINK|gtk.FILL)
- self.tbl.attach(self.format_menu, 2, 4, self.row, self.row+1,
- yoptions=gtk.SHRINK)
- self.row += 1
-
- self.open_with_app = gtk.CheckButton(_("Open with default viewer"))
- self.tbl.attach(self.open_with_app, 2, 4, self.row, self.row+1,
- yoptions=gtk.SHRINK)
- self.row += 1
-
- ext = self.format_menu.get_active_plugin().get_extension()
- if ext is None:
- ext = ""
- else:
- spath = self.get_default_directory()
- base = "%s.%s" % (self.raw_name, ext)
- spath = os.path.normpath(os.path.join(spath, base))
- self.target_fileentry.set_filename(spath)
-
- def setup_report_options_frame(self):
- self.paper_frame = PaperFrame(self.options.handler.get_paper_metric(),
- self.options.handler.get_paper_name(),
- self.options.handler.get_orientation(),
- self.options.handler.get_margins(),
- self.options.handler.get_custom_paper_size()
- )
- self.setup_html_frame()
- ReportDialog.setup_report_options_frame(self)
-
- 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)
-
- label = gtk.Label("%s:" % _("CSS file"))
- label.set_alignment(0.0,0.5)
- self.html_table.attach(label, 1, 2, 1, 2, gtk.SHRINK|gtk.FILL,
- yoptions=gtk.SHRINK)
-
- self.css_combo = gtk.combo_box_new_text()
-
- css_filename = self.options.handler.get_css_filename()
- active_index = 0
- index = 0
- for style in CSS_FILES:
- self.css_combo.append_text(style[0])
- if css_filename == style[1]:
- active_index = index
- index += 1
-
- self.html_table.attach(self.css_combo,2,3,1,2, yoptions=gtk.SHRINK)
- self.css_combo.set_active(active_index)
-
- def parse_format_frame(self):
- """Parse the format frame of the dialog. Save the user
- selected output format for later use."""
- docgen_plugin = self.format_menu.get_active_plugin()
- self.format = docgen_plugin.get_basedoc()
- format_name = docgen_plugin.get_extension()
- self.options.handler.set_format_name(format_name)
-
- def parse_html_frame(self):
- """Parse the html frame of the dialog. Save the user selected
- html template name for later use. Note that this routine
- retrieves a value whether or not the file entry box is
- displayed on the screen. The subclass will know whether this
- entry was enabled. This is for simplicity of programming."""
-
- self.css_filename = CSS_FILES[self.css_combo.get_active()][1]
- self.options.handler.set_css_filename(self.css_filename)
-
- 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():
- self.window.run()
-
- # Preparation
- self.parse_format_frame()
- self.parse_style_frame()
- self.parse_html_frame()
-
- self.options.handler.set_paper_metric(self.paper_frame.get_paper_metric())
- self.options.handler.set_paper_name(self.paper_frame.get_paper_name())
- self.options.handler.set_orientation(self.paper_frame.get_orientation())
- self.options.handler.set_margins(self.paper_frame.get_paper_margins())
- self.options.handler.set_custom_paper_size(self.paper_frame.get_custom_paper_size())
-
- self.parse_user_options()
-
- # Create the output document.
- self.make_document()
-
- # Save options
- self.options.handler.save_options()
diff --git a/src/gui/plug/report/_drawreportdialog.py b/src/gui/plug/report/_drawreportdialog.py
index b8d4d5da2..cc9214c09 100644
--- a/src/gui/plug/report/_drawreportdialog.py
+++ b/src/gui/plug/report/_drawreportdialog.py
@@ -38,222 +38,6 @@ from gen.plug.report._constants import CATEGORY_DRAW
from _docreportdialog import DocReportDialog
from gui.pluginmanager import GuiPluginManager
-#-------------------------------------------------------------------------
-#
-# _DrawFormatComboBox
-#
-#-------------------------------------------------------------------------
-class _DrawFormatComboBox(gtk.ComboBox):
- """
- This class is a combo box that allows the selection of a docgen plugin
- from all drawdoc plugins.
- """
- def __init__(self, active):
-
- gtk.ComboBox.__init__(self)
-
- pmgr = GuiPluginManager.get_instance()
- self.__drawdoc_plugins = []
- for plugin in pmgr.get_docgen_plugins():
- if plugin.get_draw_support():
- self.__drawdoc_plugins.append(plugin)
-
- self.store = gtk.ListStore(gobject.TYPE_STRING)
- self.set_model(self.store)
- cell = gtk.CellRendererText()
- self.pack_start(cell, True)
- self.add_attribute(cell, 'text', 0)
-
- index = 0
- active_index = 0
- for plugin in self.__drawdoc_plugins:
- name = plugin.get_name()
- self.store.append(row=[name])
- if plugin.get_extension() == active:
- active_index = index
- index += 1
- self.set_active(active_index)
-
- def get_active_plugin(self):
- """
- Get the plugin represented by the currently active selection.
- """
- return self.__drawdoc_plugins[self.get_active()]
-
-#-----------------------------------------------------------------------
-#
-# DrawReportDialog
-#
-#-----------------------------------------------------------------------
-class DrawReportDialog(DocReportDialog):
- """
- A class of ReportDialog customized for drawing based reports.
- """
- def __init__(self, dbstate, uistate, opt, name, translated_name):
- """
- Initialize a dialog to request that the user select options
- for a basic drawing report. See the ReportDialog class for
- more information.
- """
- self.format_menu = None
- self.category = CATEGORY_DRAW
- DocReportDialog.__init__(self, dbstate, uistate, opt,
- name, translated_name)
-
- def make_doc_menu(self,active=None):
- """
- Build a menu of document types that are appropriate for
- this drawing report.
- """
- self.format_menu = _DrawFormatComboBox( active )
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# GTK modules
-#
-#-------------------------------------------------------------------------
-import gtk
-import gobject
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-from gen.plug.report._constants import CATEGORY_DRAW
-from _docreportdialog import DocReportDialog
-from gui.pluginmanager import GuiPluginManager
-
-#-------------------------------------------------------------------------
-#
-# _DrawFormatComboBox
-#
-#-------------------------------------------------------------------------
-class _DrawFormatComboBox(gtk.ComboBox):
- """
- This class is a combo box that allows the selection of a docgen plugin
- from all drawdoc plugins.
- """
- def __init__(self, active):
-
- gtk.ComboBox.__init__(self)
-
- pmgr = GuiPluginManager.get_instance()
- self.__drawdoc_plugins = []
- for plugin in pmgr.get_docgen_plugins():
- if plugin.get_draw_support():
- self.__drawdoc_plugins.append(plugin)
-
- self.store = gtk.ListStore(gobject.TYPE_STRING)
- self.set_model(self.store)
- cell = gtk.CellRendererText()
- self.pack_start(cell, True)
- self.add_attribute(cell, 'text', 0)
-
- index = 0
- active_index = 0
- for plugin in self.__drawdoc_plugins:
- name = plugin.get_name()
- self.store.append(row=[name])
- if plugin.get_extension() == active:
- active_index = index
- index += 1
- self.set_active(active_index)
-
- def get_active_plugin(self):
- """
- Get the plugin represented by the currently active selection.
- """
- return self.__drawdoc_plugins[self.get_active()]
-
-#-----------------------------------------------------------------------
-#
-# DrawReportDialog
-#
-#-----------------------------------------------------------------------
-class DrawReportDialog(DocReportDialog):
- """
- A class of ReportDialog customized for drawing based reports.
- """
- def __init__(self, dbstate, uistate, opt, name, translated_name):
- """
- Initialize a dialog to request that the user select options
- for a basic drawing report. See the ReportDialog class for
- more information.
- """
- self.format_menu = None
- self.category = CATEGORY_DRAW
- DocReportDialog.__init__(self, dbstate, uistate, opt,
- name, translated_name)
-
- def make_doc_menu(self,active=None):
- """
- Build a menu of document types that are appropriate for
- this drawing report.
- """
- self.format_menu = _DrawFormatComboBox( active )
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# GTK modules
-#
-#-------------------------------------------------------------------------
-import gtk
-import gobject
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-from gen.plug.report._constants import CATEGORY_DRAW
-from _docreportdialog import DocReportDialog
-from gui.pluginmanager import GuiPluginManager
-
#-------------------------------------------------------------------------
#
# _DrawFormatComboBox
diff --git a/src/gui/plug/report/_fileentry.py b/src/gui/plug/report/_fileentry.py
index c909e521f..80a8e99f0 100644
--- a/src/gui/plug/report/_fileentry.py
+++ b/src/gui/plug/report/_fileentry.py
@@ -26,210 +26,6 @@ import os
import gtk
import Utils
-class FileEntry(gtk.HBox):
- """ A widget that allows the user to select a file from the file system """
- def __init__(self, defname, title):
- gtk.HBox.__init__(self)
-
- self.title = title
- self.dir = False
- self.__base_path = ""
- self.__file_name = ""
- self.entry = gtk.Entry()
- self.entry.set_text(defname)
- self.set_filename(defname)
- self.set_spacing(6)
- self.set_homogeneous(False)
- self.button = gtk.Button()
- image = gtk.Image()
- image.set_from_stock(gtk.STOCK_OPEN, gtk.ICON_SIZE_BUTTON)
- self.button.add(image)
- self.button.connect('clicked', self.__select_file)
- self.pack_start(self.entry, True, True)
- self.pack_end(self.button, False, False)
-
- def __select_file(self, obj):
- """ Call back function to handle the open button press """
- if self.dir:
- my_action = gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER
- else:
- my_action = gtk.FILE_CHOOSER_ACTION_SAVE
-
- dialog = gtk.FileChooserDialog(self.title,
- action=my_action,
- buttons=(gtk.STOCK_CANCEL,
- gtk.RESPONSE_CANCEL,
- gtk.STOCK_OPEN,
- gtk.RESPONSE_OK))
-
- name = os.path.basename(self.entry.get_text())
- if self.dir:
- if os.path.isdir(name):
- dialog.set_current_name(name)
- elif os.path.isdir(os.path.basename(name)):
- dialog.set_current_name(os.path.basename(name))
- else:
- dialog.set_current_name(name)
- dialog.set_current_folder(self.__base_path)
- dialog.present()
- status = dialog.run()
- if status == gtk.RESPONSE_OK:
- self.set_filename(Utils.get_unicode_path(dialog.get_filename()))
- dialog.destroy()
-
- def set_filename(self, path):
- """ Set the currently selected dialog. """
- if not path:
- return
- if os.path.dirname(path):
- self.__base_path = os.path.dirname(path)
- self.__file_name = os.path.basename(path)
- else:
- self.__base_path = os.getcwd()
- self.__file_name = path
- self.entry.set_text(os.path.join(self.__base_path, self.__file_name))
-
- def get_full_path(self, val):
- """ Get the full path of the currently selected file. """
- return self.entry.get_text()
-
- def set_directory_entry(self, opt):
- """
- Configure the FileEntry to either select a directory or a file.
- Set it to True to select a directory.
- Set it to False to select a file.
- """
- self.dir = opt
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2009 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id:_FileEntry.py 9912 2008-01-22 09:17:46Z acraphae $
-
-import os
-import gtk
-import Utils
-
-class FileEntry(gtk.HBox):
- """ A widget that allows the user to select a file from the file system """
- def __init__(self, defname, title):
- gtk.HBox.__init__(self)
-
- self.title = title
- self.dir = False
- self.__base_path = ""
- self.__file_name = ""
- self.entry = gtk.Entry()
- self.entry.set_text(defname)
- self.set_filename(defname)
- self.set_spacing(6)
- self.set_homogeneous(False)
- self.button = gtk.Button()
- image = gtk.Image()
- image.set_from_stock(gtk.STOCK_OPEN, gtk.ICON_SIZE_BUTTON)
- self.button.add(image)
- self.button.connect('clicked', self.__select_file)
- self.pack_start(self.entry, True, True)
- self.pack_end(self.button, False, False)
-
- def __select_file(self, obj):
- """ Call back function to handle the open button press """
- if self.dir:
- my_action = gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER
- else:
- my_action = gtk.FILE_CHOOSER_ACTION_SAVE
-
- dialog = gtk.FileChooserDialog(self.title,
- action=my_action,
- buttons=(gtk.STOCK_CANCEL,
- gtk.RESPONSE_CANCEL,
- gtk.STOCK_OPEN,
- gtk.RESPONSE_OK))
-
- name = os.path.basename(self.entry.get_text())
- if self.dir:
- if os.path.isdir(name):
- dialog.set_current_name(name)
- elif os.path.isdir(os.path.basename(name)):
- dialog.set_current_name(os.path.basename(name))
- else:
- dialog.set_current_name(name)
- dialog.set_current_folder(self.__base_path)
- dialog.present()
- status = dialog.run()
- if status == gtk.RESPONSE_OK:
- self.set_filename(Utils.get_unicode_path(dialog.get_filename()))
- dialog.destroy()
-
- def set_filename(self, path):
- """ Set the currently selected dialog. """
- if not path:
- return
- if os.path.dirname(path):
- self.__base_path = os.path.dirname(path)
- self.__file_name = os.path.basename(path)
- else:
- self.__base_path = os.getcwd()
- self.__file_name = path
- self.entry.set_text(os.path.join(self.__base_path, self.__file_name))
-
- def get_full_path(self, val):
- """ Get the full path of the currently selected file. """
- return self.entry.get_text()
-
- def set_directory_entry(self, opt):
- """
- Configure the FileEntry to either select a directory or a file.
- Set it to True to select a directory.
- Set it to False to select a file.
- """
- self.dir = opt
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2009 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id:_FileEntry.py 9912 2008-01-22 09:17:46Z acraphae $
-
-import os
-import gtk
-import Utils
-
class FileEntry(gtk.HBox):
""" A widget that allows the user to select a file from the file system """
def __init__(self, defname, title):
diff --git a/src/gui/plug/report/_graphvizreportdialog.py b/src/gui/plug/report/_graphvizreportdialog.py
index 1a9196049..06e67af38 100644
--- a/src/gui/plug/report/_graphvizreportdialog.py
+++ b/src/gui/plug/report/_graphvizreportdialog.py
@@ -1192,2391 +1192,3 @@ class GraphvizReportDialog(ReportDialog):
def setup_style_frame(self):
"""Required by ReportDialog"""
pass
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2007-2008 Brian G. Matherly
-# Copyright (C) 2007-2009 Stephane Charette
-# Copyright (C) 2009 Gary Burton
-# Contribution 2009 by Bob Ham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id$
-
-#------------------------------------------------------------------------
-#
-# python modules
-#
-#------------------------------------------------------------------------
-import os
-from cStringIO import StringIO
-import tempfile
-import threading
-import time
-from types import ClassType, InstanceType
-from gen.ggettext import gettext as _
-
-#-------------------------------------------------------------------------------
-#
-# GTK+ modules
-#
-#-------------------------------------------------------------------------------
-import gtk
-import gobject
-
-#-------------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------------
-import Utils
-from gui.utils import ProgressMeter, open_file_with_default_application
-from gen.plug.docgen import BaseDoc, GVDoc
-import config
-from gen.plug.report import CATEGORY_GRAPHVIZ
-from _reportdialog import ReportDialog
-from _papermenu import PaperFrame
-from gen.plug.menu import NumberOption, TextOption, EnumeratedListOption, \
- BooleanOption
-import constfunc
-
-#-------------------------------------------------------------------------------
-#
-# Private Constants
-#
-#-------------------------------------------------------------------------------
-_FONTS = [ { 'name' : _("Default"), 'value' : "" },
- { 'name' : _("PostScript / Helvetica"), 'value' : "Helvetica" },
- { 'name' : _("TrueType / FreeSans"), 'value' : "FreeSans" } ]
-
-_RANKDIR = [ { 'name' : _("Vertical (top to bottom)"), 'value' : "TB" },
- { 'name' : _("Vertical (bottom to top)"), 'value' : "BT" },
- { 'name' : _("Horizontal (left to right)"), 'value' : "LR" },
- { 'name' : _("Horizontal (right to left)"), 'value' : "RL" } ]
-
-_PAGEDIR = [ { 'name' : _("Bottom, left"), 'value' :"BL" },
- { 'name' : _("Bottom, right"), 'value' :"BR" },
- { 'name' : _("Top, left"), 'value' :"TL" },
- { 'name' : _("Top, Right"), 'value' :"TR" },
- { 'name' : _("Right, bottom"), 'value' :"RB" },
- { 'name' : _("Right, top"), 'value' :"RT" },
- { 'name' : _("Left, bottom"), 'value' :"LB" },
- { 'name' : _("Left, top"), 'value' :"LT" } ]
-
-_RATIO = [ { 'name' : _("Minimal size"), 'value': "compress" },
- { 'name' : _("Fill the given area"), 'value': "fill" },
- { 'name' : _("Use optimal number of pages"), 'value': "expand" } ]
-
-_NOTELOC = [ { 'name' : _("Top"), 'value' : "t" },
- { 'name' : _("Bottom"), 'value' : "b" }]
-
-if constfunc.win():
- _DOT_FOUND = Utils.search_for("dot.exe")
-
- if Utils.search_for("gswin32c.exe") == 1:
- _GS_CMD = "gswin32c.exe"
- elif Utils.search_for("gswin32.exe") == 1:
- _GS_CMD = "gswin32.exe"
- else:
- _GS_CMD = ""
-else:
- _DOT_FOUND = Utils.search_for("dot")
-
- if Utils.search_for("gs") == 1:
- _GS_CMD = "gs"
- else:
- _GS_CMD = ""
-
-#-------------------------------------------------------------------------------
-#
-# Private Functions
-#
-#-------------------------------------------------------------------------------
-def _run_long_process_in_thread(func, header):
- """
- This function will spawn a new thread to execute the provided function.
- While the function is running, a progress bar will be created.
- The progress bar will show activity while the function executes.
-
- @param func: A function that will take an unknown amount of time to
- complete.
- @type category: callable
- @param header: A header for the progress bar.
- Example: "Updating Data"
- @type name: string
- @return: nothing
-
- """
- pbar = ProgressMeter(_('Processing File'))
- pbar.set_pass(total=40,
- mode=ProgressMeter.MODE_ACTIVITY,
- header=header)
-
- sys_thread = threading.Thread(target=func)
- sys_thread.start()
-
- while sys_thread.isAlive():
- # The loop runs 20 times per second until the thread completes.
- # With the progress pass total set at 40, it should move across the bar
- # every two seconds.
- time.sleep(0.05)
- pbar.step()
-
- pbar.close()
-
-#-------------------------------------------------------------------------------
-#
-# GVDocBase
-#
-#-------------------------------------------------------------------------------
-class GVDocBase(BaseDoc, GVDoc):
- """
- Base document generator for all Graphviz document generators. Classes that
- inherit from this class will only need to implement the close function.
- The close function will generate the actual file of the appropriate type.
- """
- def __init__(self, options, paper_style):
- BaseDoc.__init__(self, None, paper_style)
-
- self._filename = None
- self._dot = StringIO()
- self._paper = paper_style
-
- menu = options.menu
-
- self.dpi = menu.get_option_by_name('dpi').get_value()
- self.fontfamily = menu.get_option_by_name('font_family').get_value()
- self.fontsize = menu.get_option_by_name('font_size').get_value()
- self.hpages = menu.get_option_by_name('h_pages').get_value()
- self.nodesep = menu.get_option_by_name('nodesep').get_value()
- self.noteloc = menu.get_option_by_name('noteloc').get_value()
- self.notesize = menu.get_option_by_name('notesize').get_value()
- self.note = menu.get_option_by_name('note').get_value()
- self.pagedir = menu.get_option_by_name('page_dir').get_value()
- self.rankdir = menu.get_option_by_name('rank_dir').get_value()
- self.ranksep = menu.get_option_by_name('ranksep').get_value()
- self.ratio = menu.get_option_by_name('ratio').get_value()
- self.vpages = menu.get_option_by_name('v_pages').get_value()
- self.usesubgraphs = menu.get_option_by_name('usesubgraphs').get_value()
-
- paper_size = paper_style.get_size()
-
- # Subtract 0.01" from the drawing area to make some room between
- # this area and the margin in order to compensate for different
- # rounding errors internally in dot
- sizew = ( paper_size.get_width() -
- self._paper.get_left_margin() -
- self._paper.get_right_margin() ) / 2.54 - 0.01
- sizeh = ( paper_size.get_height() -
- self._paper.get_top_margin() -
- self._paper.get_bottom_margin() ) / 2.54 - 0.01
-
- pheight = paper_size.get_height_inches()
- pwidth = paper_size.get_width_inches()
-
- xmargin = self._paper.get_left_margin() / 2.54
- ymargin = self._paper.get_top_margin() / 2.54
-
- sizew *= self.hpages
- sizeh *= self.vpages
-
- self.write( 'digraph GRAMPS_graph\n' )
- self.write( '{\n' )
- self.write( ' bgcolor=white;\n' )
- self.write( ' center="true"; \n' )
- self.write( ' charset="utf8";\n' )
- self.write( ' concentrate="false";\n' )
- self.write( ' dpi="%d";\n' % self.dpi )
- self.write( ' graph [fontsize=%d];\n' % self.fontsize )
- self.write( ' margin="%3.2f,%3.2f"; \n' % (xmargin, ymargin))
- self.write( ' mclimit="99";\n' )
- self.write( ' nodesep="%.2f";\n' % self.nodesep )
- self.write( ' outputorder="edgesfirst";\n' )
- if self.hpages == 1 and self.vpages == 1:
- self.write( '#' ) # comment out "page=" if the graph is on 1 page (bug #2121)
- self.write( ' page="%3.2f,%3.2f";\n' % (pwidth, pheight) )
- self.write( ' pagedir="%s";\n' % self.pagedir )
- self.write( ' rankdir="%s";\n' % self.rankdir )
- self.write( ' ranksep="%.2f";\n' % self.ranksep )
- self.write( ' ratio="%s";\n' % self.ratio )
- self.write( ' searchsize="100";\n' )
- self.write( ' size="%3.2f,%3.2f"; \n' % (sizew, sizeh) )
- self.write( ' splines="true";\n' )
- self.write( '\n' )
- self.write( ' edge [len=0.5 style=solid fontsize=%d];\n' % self.fontsize )
- if self.fontfamily:
- self.write( ' node [style=filled fontname="%s" fontsize=%d];\n'
- % ( self.fontfamily, self.fontsize ) )
- else:
- self.write( ' node [style=filled fontsize=%d];\n'
- % self.fontsize )
- self.write( '\n' )
-
- def write(self, text):
- """ Write text to the dot file """
- self._dot.write(text.encode('utf8', 'xmlcharrefreplace'))
-
- def open(self, filename):
- """ Implement BaseDoc.open() """
- self._filename = os.path.normpath(os.path.abspath(filename))
-
- def close(self):
- """
- This isn't useful by itself. Other classes need to override this and
- actually generate a file.
- """
- if self.note:
- # build up the label
- label = u''
- for line in self.note: # for every line in the note...
- line = line.strip() # ...strip whitespace from this line...
- if line != '': # ...and if we still have a line...
- if label != '': # ...see if we need to insert a newline...
- label += '\\n'
- label += line.replace('"', '\\\"')
-
- # after all that, see if we have a label to display
- if label != '':
- self.write( '\n')
- self.write( ' label="%s";\n' % label )
- self.write( ' labelloc="%s";\n' % self.noteloc )
- self.write( ' fontsize="%d";\n' % self.notesize )
-
- self.write( '}\n\n' )
-
- def add_node(self, node_id, label, shape="", color="",
- style="", fillcolor="", url="", htmloutput=False):
- """
- Add a node to this graph. Nodes can be different shapes like boxes and
- circles.
-
- Implements GVDoc.add_node().
- """
- text = '['
-
- if shape:
- text += ' shape="%s"' % shape
-
- if color:
- text += ' color="%s"' % color
-
- if fillcolor:
- text += ' fillcolor="%s"' % fillcolor
-
- if style:
- text += ' style="%s"' % style
-
- # note that we always output a label -- even if an empty string --
- # otherwise GraphViz uses the node ID as the label which is unlikely
- # to be what the user wants to see in the graph
- if label.startswith("<") or htmloutput:
- text += ' label=<%s>' % label
- else:
- text += ' label="%s"' % label
-
- if url:
- text += ' URL="%s"' % url
-
- text += " ]"
- self.write(' %s %s;\n' % (node_id, text))
-
- def add_link(self, id1, id2, style="", head="", tail="", comment=""):
- """
- Add a link between two nodes.
-
- Implements GVDoc.add_link().
- """
- self.write(' %s -> %s' % (id1, id2))
-
- if style or head or tail:
- self.write(' [')
-
- if style:
- self.write(' style=%s' % style)
- if head:
- self.write(' arrowhead=%s' % head)
- if tail:
- self.write(' arrowtail=%s' % tail)
- if head:
- if tail:
- self.write(' dir=both')
- else:
- self.write(' dir=forward')
- else:
- if tail:
- self.write(' dir=back')
- else:
- self.write(' dir=none')
- self.write(' ]')
-
- self.write(';')
-
- if comment:
- self.write(' // %s' % comment)
-
- self.write('\n')
-
- def add_comment(self, comment):
- """
- Add a comment.
-
- Implements GVDoc.add_comment().
- """
- tmp = comment.split('\n')
- for line in tmp:
- text = line.strip()
- if text == "":
- self.write('\n')
- elif text.startswith('#'):
- self.write('%s\n' % text)
- else:
- self.write('# %s\n' % text)
-
- def start_subgraph(self, graph_id):
- """ Implement GVDoc.start_subgraph() """
- self.write(' subgraph cluster_%s\n' % graph_id)
- self.write(' {\n')
- self.write(' style="invis";\n') # no border around subgraph (#0002176)
-
- def end_subgraph(self):
- """ Implement GVDoc.end_subgraph() """
- self.write(' }\n')
-
-#-------------------------------------------------------------------------------
-#
-# GVDotDoc
-#
-#-------------------------------------------------------------------------------
-class GVDotDoc(GVDocBase):
- """ GVDoc implementation that generates a .gv text file. """
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-3:] != ".gv":
- self._filename += ".gv"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- dotfile = open(self._filename, "w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVPsDoc
-#
-#-------------------------------------------------------------------------------
-class GVPsDoc(GVDocBase):
- """ GVDoc implementation that generates a .ps file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # DPI must always be 72 for PDF.
- # GV documentation says dpi is only for image formats.
- options.menu.get_option_by_name('dpi').set_value(72)
- GVDocBase.__init__(self, options, paper_style)
- # GV documentation allow multiple pages only for ps format,
- # But it does not work with -Tps:cairo in order to
- # show Non Latin-1 letters. Force to only 1 page.
- # See bug tracker issue 2815
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-3:] != ".ps":
- self._filename += ".ps"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the PS file.
- # Reason for using -Tps:cairo. Needed for Non Latin-1 letters
- # Some testing with Tps:cairo. Non Latin-1 letters are OK i all cases:
- # Output format: ps PDF-GostScript PDF-GraphViz
- # Single page OK OK OK
- # Multip page 1 page, OK 1 page,
- # corrupted set by gramps
- # If I take a correct multip page PDF and convert it with pdf2ps I get multip pages,
- # but the output is clipped, some margins have disappeared. I used 1 inch margins always.
- # See bug tracker issue 2815
-
- os.system( 'dot -Tps:cairo -o"%s" "%s"' % (self._filename, tmp_dot) )
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVSvgDoc
-#
-#-------------------------------------------------------------------------------
-class GVSvgDoc(GVDocBase):
- """ GVDoc implementation that generates a .svg file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # GV documentation allow multiple pages only for ps format,
- # which also includes pdf via ghostscript.
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-4:] != ".svg":
- self._filename += ".svg"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the SVG file.
- os.system( 'dot -Tsvg -o"%s" "%s"' % (self._filename, tmp_dot) )
-
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVSvgzDoc
-#
-#-------------------------------------------------------------------------------
-class GVSvgzDoc(GVDocBase):
- """ GVDoc implementation that generates a .svg file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # GV documentation allow multiple pages only for ps format,
- # which also includes pdf via ghostscript.
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-5:] != ".svgz":
- self._filename += ".svgz"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the SVGZ file.
- os.system( 'dot -Tsvgz -o"%s" "%s"' % (self._filename, tmp_dot) )
-
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVPngDoc
-#
-#-------------------------------------------------------------------------------
-class GVPngDoc(GVDocBase):
- """ GVDoc implementation that generates a .png file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # GV documentation allow multiple pages only for ps format,
- # which also includes pdf via ghostscript.
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-4:] != ".png":
- self._filename += ".png"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the PNG file.
- os.system( 'dot -Tpng -o"%s" "%s"' % (self._filename, tmp_dot) )
-
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVJpegDoc
-#
-#-------------------------------------------------------------------------------
-class GVJpegDoc(GVDocBase):
- """ GVDoc implementation that generates a .jpg file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # GV documentation allow multiple pages only for ps format,
- # which also includes pdf via ghostscript.
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-4:] != ".jpg":
- self._filename += ".jpg"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the JPEG file.
- os.system( 'dot -Tjpg -o"%s" "%s"' % (self._filename, tmp_dot) )
-
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVGifDoc
-#
-#-------------------------------------------------------------------------------
-class GVGifDoc(GVDocBase):
- """ GVDoc implementation that generates a .gif file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # GV documentation allow multiple pages only for ps format,
- # which also includes pdf via ghostscript.
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-4:] != ".gif":
- self._filename += ".gif"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the GIF file.
- os.system( 'dot -Tgif -o"%s" "%s"' % (self._filename, tmp_dot) )
-
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVPdfGvDoc
-#
-#-------------------------------------------------------------------------------
-class GVPdfGvDoc(GVDocBase):
- """ GVDoc implementation that generates a .pdf file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # DPI must always be 72 for PDF.
- # GV documentation says dpi is only for image formats.
- options.menu.get_option_by_name('dpi').set_value(72)
- # GV documentation allow multiple pages only for ps format,
- # which also includes pdf via ghostscript.
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-4:] != ".pdf":
- self._filename += ".pdf"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the PDF file.
- os.system( 'dot -Tpdf -o"%s" "%s"' % (self._filename, tmp_dot) )
-
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVPdfGsDoc
-#
-#-------------------------------------------------------------------------------
-class GVPdfGsDoc(GVDocBase):
- """ GVDoc implementation that generates a .pdf file using Ghostscript. """
- def __init__(self, options, paper_style):
- # DPI must always be 72 for PDF.
- # GV documentation says dpi is only for image formats.
- options.menu.get_option_by_name('dpi').set_value(72)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-4:] != ".pdf":
- self._filename += ".pdf"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Create a temporary PostScript file
- (handle, tmp_ps) = tempfile.mkstemp(".ps" )
- os.close( handle )
-
- # Generate PostScript using dot
- # Reason for using -Tps:cairo. Needed for Non Latin-1 letters
- # See bug tracker issue 2815
- command = 'dot -Tps:cairo -o"%s" "%s"' % ( tmp_ps, tmp_dot )
- os.system(command)
-
- # Add .5 to remove rounding errors.
- paper_size = self._paper.get_size()
- width_pt = int( (paper_size.get_width_inches() * 72) + 0.5 )
- height_pt = int( (paper_size.get_height_inches() * 72) + 0.5 )
-
- # Convert to PDF using ghostscript
- command = '%s -q -sDEVICE=pdfwrite -dNOPAUSE -dDEVICEWIDTHPOINTS=%d' \
- ' -dDEVICEHEIGHTPOINTS=%d -sOutputFile="%s" "%s" -c quit' \
- % ( _GS_CMD, width_pt, height_pt, self._filename, tmp_ps )
- os.system(command)
-
- os.remove(tmp_ps)
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# Various Graphviz formats.
-#
-#-------------------------------------------------------------------------------
-_FORMATS = []
-
-if _DOT_FOUND:
-
- if _GS_CMD != "":
- _FORMATS += [{ 'type' : "gspdf",
- 'ext' : "pdf",
- 'descr': _("PDF (Ghostscript)"),
- 'mime' : "application/pdf",
- 'class': GVPdfGsDoc }]
-
- _FORMATS += [{ 'type' : "gvpdf",
- 'ext' : "pdf",
- 'descr': _("PDF (Graphviz)"),
- 'mime' : "application/pdf",
- 'class': GVPdfGvDoc }]
-
- _FORMATS += [{ 'type' : "ps",
- 'ext' : "ps",
- 'descr': _("PostScript"),
- 'mime' : "application/postscript",
- 'class': GVPsDoc }]
-
- _FORMATS += [{ 'type' : "svg",
- 'ext' : "svg",
- 'descr': _("Structured Vector Graphics (SVG)"),
- 'mime' : "image/svg",
- 'class': GVSvgDoc }]
-
- _FORMATS += [{ 'type' : "svgz",
- 'ext' : "svgz",
- 'descr': _("Compressed Structured Vector Graphs (SVGZ)"),
- 'mime' : "image/svgz",
- 'class': GVSvgzDoc }]
-
- _FORMATS += [{ 'type' : "jpg",
- 'ext' : "jpg",
- 'descr': _("JPEG image"),
- 'mime' : "image/jpeg",
- 'class': GVJpegDoc }]
-
- _FORMATS += [{ 'type' : "gif",
- 'ext' : "gif",
- 'descr': _("GIF image"),
- 'mime' : "image/gif",
- 'class': GVGifDoc }]
-
- _FORMATS += [{ 'type' : "png",
- 'ext' : "png",
- 'descr': _("PNG image"),
- 'mime' : "image/png",
- 'class': GVPngDoc }]
-
-_FORMATS += [{ 'type' : "dot",
- 'ext' : "gv",
- 'descr': _("Graphviz File"),
- 'mime' : "text/x-graphviz",
- 'class': GVDotDoc }]
-
-#-------------------------------------------------------------------------------
-#
-# GraphvizFormatComboBox
-#
-#-------------------------------------------------------------------------------
-class GraphvizFormatComboBox(gtk.ComboBox):
- """
- Format combo box class for Graphviz report.
- """
- def set(self, active=None):
- self.store = gtk.ListStore(gobject.TYPE_STRING)
- self.set_model(self.store)
- cell = gtk.CellRendererText()
- self.pack_start(cell, True)
- self.add_attribute(cell, 'text', 0)
-
- index = 0
- active_index = 0
- for item in _FORMATS:
- name = item["descr"]
- self.store.append(row=[name])
- if item['type'] == active:
- active_index = index
- index += 1
- self.set_active(active_index)
-
- def get_label(self):
- return _FORMATS[self.get_active()]["descr"]
-
- def get_reference(self):
- return _FORMATS[self.get_active()]["class"]
-
- def get_paper(self):
- return 1
-
- def get_styles(self):
- return 0
-
- def get_ext(self):
- return '.%s' % _FORMATS[self.get_active()]['ext']
-
- def get_format_str(self):
- return _FORMATS[self.get_active()]["type"]
-
- def is_file_output(self):
- return True
-
- def get_clname(self):
- return _FORMATS[self.get_active()]["type"]
-
-#-----------------------------------------------------------------------
-#
-# GraphvizReportDialog
-#
-#-----------------------------------------------------------------------
-class GraphvizReportDialog(ReportDialog):
- """A class of ReportDialog customized for graphviz based reports."""
- def __init__(self, dbstate, uistate, opt, name, translated_name):
- """Initialize a dialog to request that the user select options
- for a graphviz report. See the ReportDialog class for
- more information."""
- self.category = CATEGORY_GRAPHVIZ
- ReportDialog.__init__(self, dbstate, uistate, opt,
- name, translated_name)
-
- def init_options(self, option_class):
- try:
- if (issubclass(option_class, object) or # New-style class
- isinstance(options_class, ClassType)): # Old-style class
- self.options = option_class(self.raw_name,
- self.dbstate.get_database())
- except TypeError:
- self.options = option_class
-
- ################################
- category = _("GraphViz Layout")
- ################################
- font_family = EnumeratedListOption(_("Font family"), "")
- index = 0
- for item in _FONTS:
- font_family.add_item(item["value"], item["name"])
- index += 1
- font_family.set_help(_("Choose the font family. If international "
- "characters don't show, use FreeSans font. "
- "FreeSans is available from: "
- "http://www.nongnu.org/freefont/"))
- self.options.add_menu_option(category, "font_family", font_family)
-
- font_size = NumberOption(_("Font size"), 14, 8, 128)
- font_size.set_help(_("The font size, in points."))
- self.options.add_menu_option(category, "font_size", font_size)
-
- rank_dir = EnumeratedListOption(_("Graph Direction"), "TB")
- index = 0
- for item in _RANKDIR:
- rank_dir.add_item(item["value"], item["name"])
- index += 1
- rank_dir.set_help(_("Whether graph goes from top to bottom "
- "or left to right."))
- self.options.add_menu_option(category, "rank_dir", rank_dir)
-
- h_pages = NumberOption(_("Number of Horizontal Pages"), 1, 1, 25)
- h_pages.set_help(_("GraphViz can create very large graphs by "
- "spreading the graph across a rectangular "
- "array of pages. This controls the number "
- "pages in the array horizontally. "
- "Only valid for dot and pdf via Ghostscript."))
- self.options.add_menu_option(category, "h_pages", h_pages)
-
- v_pages = NumberOption(_("Number of Vertical Pages"), 1, 1, 25)
- v_pages.set_help(_("GraphViz can create very large graphs by "
- "spreading the graph across a rectangular "
- "array of pages. This controls the number "
- "pages in the array vertically. "
- "Only valid for dot and pdf via Ghostscript."))
- self.options.add_menu_option(category, "v_pages", v_pages)
-
- page_dir = EnumeratedListOption(_("Paging Direction"), "BL")
- index = 0
- for item in _PAGEDIR:
- page_dir.add_item(item["value"], item["name"])
- index += 1
- page_dir.set_help(_("The order in which the graph pages are output. "
- "This option only applies if the horizontal pages "
- "or vertical pages are greater than 1."))
- self.options.add_menu_option(category, "page_dir", page_dir)
-
- # the page direction option only makes sense when the
- # number of horizontal and/or vertical pages is > 1,
- # so we need to remember these 3 controls for later
- self.h_pages = h_pages
- self.v_pages = v_pages
- self.page_dir = page_dir
-
- # the page direction option only makes sense when the
- # number of horizontal and/or vertical pages is > 1
- self.h_pages.connect('value-changed', self.pages_changed)
- self.v_pages.connect('value-changed', self.pages_changed)
-
- ################################
- category = _("GraphViz Options")
- ################################
-
- aspect_ratio = EnumeratedListOption(_("Aspect ratio"), "fill")
- index = 0
- for item in _RATIO:
- aspect_ratio.add_item(item["value"], item["name"])
- index += 1
- aspect_ratio.set_help(_("Affects greatly how the graph is layed out "
- "on the page."))
- self.options.add_menu_option(category, "ratio", aspect_ratio)
-
- dpi = NumberOption(_("DPI"), 75, 20, 1200)
- dpi.set_help(_( "Dots per inch. When creating images such as "
- ".gif or .png files for the web, try numbers "
- "such as 100 or 300 DPI. When creating PostScript "
- "or PDF files, use 72 DPI."))
- self.options.add_menu_option(category, "dpi", dpi)
-
- nodesep = NumberOption(_("Node spacing"), 0.20, 0.01, 5.00, 0.01)
- nodesep.set_help(_( "The minimum amount of free space, in inches, "
- "between individual nodes. For vertical graphs, "
- "this corresponds to spacing between columns. "
- "For horizontal graphs, this corresponds to "
- "spacing between rows."))
- self.options.add_menu_option(category, "nodesep", nodesep)
-
- ranksep = NumberOption(_("Rank spacing"), 0.20, 0.01, 5.00, 0.01)
- ranksep.set_help(_( "The minimum amount of free space, in inches, "
- "between ranks. For vertical graphs, this "
- "corresponds to spacing between rows. For "
- "horizontal graphs, this corresponds to spacing "
- "between columns."))
- self.options.add_menu_option(category, "ranksep", ranksep)
-
- use_subgraphs = BooleanOption(_('Use subgraphs'), True)
- use_subgraphs.set_help(_("Subgraphs can help GraphViz position "
- "spouses together, but with non-trivial "
- "graphs will result in longer lines and "
- "larger graphs."))
- self.options.add_menu_option(category, "usesubgraphs", use_subgraphs)
-
- ################################
- category = _("Note")
- ################################
-
- note = TextOption(_("Note to add to the graph"),
- [""] )
- note.set_help(_("This text will be added to the graph."))
- self.options.add_menu_option(category, "note", note)
-
- noteloc = EnumeratedListOption(_("Note location"), 't')
- for i in range( 0, len(_NOTELOC) ):
- noteloc.add_item(_NOTELOC[i]["value"], _NOTELOC[i]["name"])
- noteloc.set_help(_("Whether note will appear on top "
- "or bottom of the page."))
- self.options.add_menu_option(category, "noteloc", noteloc)
-
- notesize = NumberOption(_("Note size"), 32, 8, 128)
- notesize.set_help(_("The size of note text, in points."))
- self.options.add_menu_option(category, "notesize", notesize)
-
- self.options.load_previous_values()
-
- def pages_changed(self):
- """
- This method gets called every time the v_pages or h_pages
- options are changed; when both vertical and horizontal
- pages are set to "1", then the page_dir control needs to
- be unavailable
- """
- if self.v_pages.get_value() > 1 or \
- self.h_pages.get_value() > 1:
- self.page_dir.set_available(True)
- else:
- self.page_dir.set_available(False)
-
- def init_interface(self):
- ReportDialog.init_interface(self)
- self.doc_type_changed(self.format_menu)
-
- def setup_format_frame(self):
- """Set up the format frame of the dialog."""
- self.format_menu = GraphvizFormatComboBox()
- self.format_menu.set(self.options.handler.get_format_name())
- self.format_menu.connect('changed', self.doc_type_changed)
- label = gtk.Label("%s:" % _("Output Format"))
- label.set_alignment(0.0, 0.5)
- self.tbl.attach(label, 1, 2, self.row, self.row+1, gtk.SHRINK|gtk.FILL)
- self.tbl.attach(self.format_menu, 2, 4, self.row, self.row+1,
- yoptions=gtk.SHRINK)
- self.row += 1
-
- self.open_with_app = gtk.CheckButton(_("Open with default viewer"))
- self.tbl.attach(self.open_with_app, 2, 4, self.row, self.row+1,
- yoptions=gtk.SHRINK)
- self.row += 1
-
- ext = self.format_menu.get_ext()
- if ext is None:
- ext = ""
- else:
- spath = self.get_default_directory()
- base = "%s%s" % (self.raw_name, ext)
- spath = os.path.normpath(os.path.join(spath, base))
- self.target_fileentry.set_filename(spath)
-
- def setup_report_options_frame(self):
- self.paper_label = gtk.Label('%s'%_("Paper Options"))
- self.paper_label.set_use_markup(True)
-
- self.paper_frame = PaperFrame(
- self.options.handler.get_paper_metric(),
- self.options.handler.get_paper_name(),
- self.options.handler.get_orientation(),
- self.options.handler.get_margins(),
- self.options.handler.get_custom_paper_size()
- )
- self.notebook.insert_page(self.paper_frame, self.paper_label, 0)
- self.paper_frame.show_all()
-
- ReportDialog.setup_report_options_frame(self)
-
- 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.
- """
- self.open_with_app.set_sensitive(True)
-
- fname = self.target_fileentry.get_full_path(0)
- (spath, ext) = os.path.splitext(fname)
-
- ext_val = obj.get_ext()
- if ext_val:
- fname = spath + ext_val
- else:
- fname = spath
- self.target_fileentry.set_filename(fname)
-
- def make_document(self):
- """Create a document of the type requested by the user.
- """
- pstyle = self.paper_frame.get_paper_style()
-
- self.doc = self.format(self.options, pstyle)
-
- self.options.set_document(self.doc)
-
- if self.open_with_app.get_active():
- self.doc.open_requested()
-
- 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():
- self.window.run()
-
- # Preparation
- self.parse_format_frame()
- self.parse_user_options()
-
- self.options.handler.set_paper_metric(
- self.paper_frame.get_paper_metric())
- self.options.handler.set_paper_name(self.paper_frame.get_paper_name())
- self.options.handler.set_orientation(self.paper_frame.get_orientation())
- self.options.handler.set_margins(self.paper_frame.get_paper_margins())
- self.options.handler.set_custom_paper_size(
- self.paper_frame.get_custom_paper_size())
-
- # Create the output document.
- self.make_document()
-
- # Save options
- self.options.handler.save_options()
-
- def parse_format_frame(self):
- """Parse the format frame of the dialog. Save the user
- selected output format for later use."""
- self.format = self.format_menu.get_reference()
- format_name = self.format_menu.get_clname()
- self.options.handler.set_format_name(format_name)
-
- def setup_style_frame(self):
- """Required by ReportDialog"""
- pass
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2007-2008 Brian G. Matherly
-# Copyright (C) 2007-2009 Stephane Charette
-# Copyright (C) 2009 Gary Burton
-# Contribution 2009 by Bob Ham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id$
-
-#------------------------------------------------------------------------
-#
-# python modules
-#
-#------------------------------------------------------------------------
-import os
-from cStringIO import StringIO
-import tempfile
-import threading
-import time
-from types import ClassType, InstanceType
-from gen.ggettext import gettext as _
-
-#-------------------------------------------------------------------------------
-#
-# GTK+ modules
-#
-#-------------------------------------------------------------------------------
-import gtk
-import gobject
-
-#-------------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------------
-import Utils
-from gui.utils import ProgressMeter, open_file_with_default_application
-from gen.plug.docgen import BaseDoc, GVDoc
-import config
-from gen.plug.report import CATEGORY_GRAPHVIZ
-from _reportdialog import ReportDialog
-from _papermenu import PaperFrame
-from gen.plug.menu import NumberOption, TextOption, EnumeratedListOption, \
- BooleanOption
-import constfunc
-
-#-------------------------------------------------------------------------------
-#
-# Private Constants
-#
-#-------------------------------------------------------------------------------
-_FONTS = [ { 'name' : _("Default"), 'value' : "" },
- { 'name' : _("PostScript / Helvetica"), 'value' : "Helvetica" },
- { 'name' : _("TrueType / FreeSans"), 'value' : "FreeSans" } ]
-
-_RANKDIR = [ { 'name' : _("Vertical (top to bottom)"), 'value' : "TB" },
- { 'name' : _("Vertical (bottom to top)"), 'value' : "BT" },
- { 'name' : _("Horizontal (left to right)"), 'value' : "LR" },
- { 'name' : _("Horizontal (right to left)"), 'value' : "RL" } ]
-
-_PAGEDIR = [ { 'name' : _("Bottom, left"), 'value' :"BL" },
- { 'name' : _("Bottom, right"), 'value' :"BR" },
- { 'name' : _("Top, left"), 'value' :"TL" },
- { 'name' : _("Top, Right"), 'value' :"TR" },
- { 'name' : _("Right, bottom"), 'value' :"RB" },
- { 'name' : _("Right, top"), 'value' :"RT" },
- { 'name' : _("Left, bottom"), 'value' :"LB" },
- { 'name' : _("Left, top"), 'value' :"LT" } ]
-
-_RATIO = [ { 'name' : _("Minimal size"), 'value': "compress" },
- { 'name' : _("Fill the given area"), 'value': "fill" },
- { 'name' : _("Use optimal number of pages"), 'value': "expand" } ]
-
-_NOTELOC = [ { 'name' : _("Top"), 'value' : "t" },
- { 'name' : _("Bottom"), 'value' : "b" }]
-
-if constfunc.win():
- _DOT_FOUND = Utils.search_for("dot.exe")
-
- if Utils.search_for("gswin32c.exe") == 1:
- _GS_CMD = "gswin32c.exe"
- elif Utils.search_for("gswin32.exe") == 1:
- _GS_CMD = "gswin32.exe"
- else:
- _GS_CMD = ""
-else:
- _DOT_FOUND = Utils.search_for("dot")
-
- if Utils.search_for("gs") == 1:
- _GS_CMD = "gs"
- else:
- _GS_CMD = ""
-
-#-------------------------------------------------------------------------------
-#
-# Private Functions
-#
-#-------------------------------------------------------------------------------
-def _run_long_process_in_thread(func, header):
- """
- This function will spawn a new thread to execute the provided function.
- While the function is running, a progress bar will be created.
- The progress bar will show activity while the function executes.
-
- @param func: A function that will take an unknown amount of time to
- complete.
- @type category: callable
- @param header: A header for the progress bar.
- Example: "Updating Data"
- @type name: string
- @return: nothing
-
- """
- pbar = ProgressMeter(_('Processing File'))
- pbar.set_pass(total=40,
- mode=ProgressMeter.MODE_ACTIVITY,
- header=header)
-
- sys_thread = threading.Thread(target=func)
- sys_thread.start()
-
- while sys_thread.isAlive():
- # The loop runs 20 times per second until the thread completes.
- # With the progress pass total set at 40, it should move across the bar
- # every two seconds.
- time.sleep(0.05)
- pbar.step()
-
- pbar.close()
-
-#-------------------------------------------------------------------------------
-#
-# GVDocBase
-#
-#-------------------------------------------------------------------------------
-class GVDocBase(BaseDoc, GVDoc):
- """
- Base document generator for all Graphviz document generators. Classes that
- inherit from this class will only need to implement the close function.
- The close function will generate the actual file of the appropriate type.
- """
- def __init__(self, options, paper_style):
- BaseDoc.__init__(self, None, paper_style)
-
- self._filename = None
- self._dot = StringIO()
- self._paper = paper_style
-
- menu = options.menu
-
- self.dpi = menu.get_option_by_name('dpi').get_value()
- self.fontfamily = menu.get_option_by_name('font_family').get_value()
- self.fontsize = menu.get_option_by_name('font_size').get_value()
- self.hpages = menu.get_option_by_name('h_pages').get_value()
- self.nodesep = menu.get_option_by_name('nodesep').get_value()
- self.noteloc = menu.get_option_by_name('noteloc').get_value()
- self.notesize = menu.get_option_by_name('notesize').get_value()
- self.note = menu.get_option_by_name('note').get_value()
- self.pagedir = menu.get_option_by_name('page_dir').get_value()
- self.rankdir = menu.get_option_by_name('rank_dir').get_value()
- self.ranksep = menu.get_option_by_name('ranksep').get_value()
- self.ratio = menu.get_option_by_name('ratio').get_value()
- self.vpages = menu.get_option_by_name('v_pages').get_value()
- self.usesubgraphs = menu.get_option_by_name('usesubgraphs').get_value()
-
- paper_size = paper_style.get_size()
-
- # Subtract 0.01" from the drawing area to make some room between
- # this area and the margin in order to compensate for different
- # rounding errors internally in dot
- sizew = ( paper_size.get_width() -
- self._paper.get_left_margin() -
- self._paper.get_right_margin() ) / 2.54 - 0.01
- sizeh = ( paper_size.get_height() -
- self._paper.get_top_margin() -
- self._paper.get_bottom_margin() ) / 2.54 - 0.01
-
- pheight = paper_size.get_height_inches()
- pwidth = paper_size.get_width_inches()
-
- xmargin = self._paper.get_left_margin() / 2.54
- ymargin = self._paper.get_top_margin() / 2.54
-
- sizew *= self.hpages
- sizeh *= self.vpages
-
- self.write( 'digraph GRAMPS_graph\n' )
- self.write( '{\n' )
- self.write( ' bgcolor=white;\n' )
- self.write( ' center="true"; \n' )
- self.write( ' charset="utf8";\n' )
- self.write( ' concentrate="false";\n' )
- self.write( ' dpi="%d";\n' % self.dpi )
- self.write( ' graph [fontsize=%d];\n' % self.fontsize )
- self.write( ' margin="%3.2f,%3.2f"; \n' % (xmargin, ymargin))
- self.write( ' mclimit="99";\n' )
- self.write( ' nodesep="%.2f";\n' % self.nodesep )
- self.write( ' outputorder="edgesfirst";\n' )
- if self.hpages == 1 and self.vpages == 1:
- self.write( '#' ) # comment out "page=" if the graph is on 1 page (bug #2121)
- self.write( ' page="%3.2f,%3.2f";\n' % (pwidth, pheight) )
- self.write( ' pagedir="%s";\n' % self.pagedir )
- self.write( ' rankdir="%s";\n' % self.rankdir )
- self.write( ' ranksep="%.2f";\n' % self.ranksep )
- self.write( ' ratio="%s";\n' % self.ratio )
- self.write( ' searchsize="100";\n' )
- self.write( ' size="%3.2f,%3.2f"; \n' % (sizew, sizeh) )
- self.write( ' splines="true";\n' )
- self.write( '\n' )
- self.write( ' edge [len=0.5 style=solid fontsize=%d];\n' % self.fontsize )
- if self.fontfamily:
- self.write( ' node [style=filled fontname="%s" fontsize=%d];\n'
- % ( self.fontfamily, self.fontsize ) )
- else:
- self.write( ' node [style=filled fontsize=%d];\n'
- % self.fontsize )
- self.write( '\n' )
-
- def write(self, text):
- """ Write text to the dot file """
- self._dot.write(text.encode('utf8', 'xmlcharrefreplace'))
-
- def open(self, filename):
- """ Implement BaseDoc.open() """
- self._filename = os.path.normpath(os.path.abspath(filename))
-
- def close(self):
- """
- This isn't useful by itself. Other classes need to override this and
- actually generate a file.
- """
- if self.note:
- # build up the label
- label = u''
- for line in self.note: # for every line in the note...
- line = line.strip() # ...strip whitespace from this line...
- if line != '': # ...and if we still have a line...
- if label != '': # ...see if we need to insert a newline...
- label += '\\n'
- label += line.replace('"', '\\\"')
-
- # after all that, see if we have a label to display
- if label != '':
- self.write( '\n')
- self.write( ' label="%s";\n' % label )
- self.write( ' labelloc="%s";\n' % self.noteloc )
- self.write( ' fontsize="%d";\n' % self.notesize )
-
- self.write( '}\n\n' )
-
- def add_node(self, node_id, label, shape="", color="",
- style="", fillcolor="", url="", htmloutput=False):
- """
- Add a node to this graph. Nodes can be different shapes like boxes and
- circles.
-
- Implements GVDoc.add_node().
- """
- text = '['
-
- if shape:
- text += ' shape="%s"' % shape
-
- if color:
- text += ' color="%s"' % color
-
- if fillcolor:
- text += ' fillcolor="%s"' % fillcolor
-
- if style:
- text += ' style="%s"' % style
-
- # note that we always output a label -- even if an empty string --
- # otherwise GraphViz uses the node ID as the label which is unlikely
- # to be what the user wants to see in the graph
- if label.startswith("<") or htmloutput:
- text += ' label=<%s>' % label
- else:
- text += ' label="%s"' % label
-
- if url:
- text += ' URL="%s"' % url
-
- text += " ]"
- self.write(' %s %s;\n' % (node_id, text))
-
- def add_link(self, id1, id2, style="", head="", tail="", comment=""):
- """
- Add a link between two nodes.
-
- Implements GVDoc.add_link().
- """
- self.write(' %s -> %s' % (id1, id2))
-
- if style or head or tail:
- self.write(' [')
-
- if style:
- self.write(' style=%s' % style)
- if head:
- self.write(' arrowhead=%s' % head)
- if tail:
- self.write(' arrowtail=%s' % tail)
- if head:
- if tail:
- self.write(' dir=both')
- else:
- self.write(' dir=forward')
- else:
- if tail:
- self.write(' dir=back')
- else:
- self.write(' dir=none')
- self.write(' ]')
-
- self.write(';')
-
- if comment:
- self.write(' // %s' % comment)
-
- self.write('\n')
-
- def add_comment(self, comment):
- """
- Add a comment.
-
- Implements GVDoc.add_comment().
- """
- tmp = comment.split('\n')
- for line in tmp:
- text = line.strip()
- if text == "":
- self.write('\n')
- elif text.startswith('#'):
- self.write('%s\n' % text)
- else:
- self.write('# %s\n' % text)
-
- def start_subgraph(self, graph_id):
- """ Implement GVDoc.start_subgraph() """
- self.write(' subgraph cluster_%s\n' % graph_id)
- self.write(' {\n')
- self.write(' style="invis";\n') # no border around subgraph (#0002176)
-
- def end_subgraph(self):
- """ Implement GVDoc.end_subgraph() """
- self.write(' }\n')
-
-#-------------------------------------------------------------------------------
-#
-# GVDotDoc
-#
-#-------------------------------------------------------------------------------
-class GVDotDoc(GVDocBase):
- """ GVDoc implementation that generates a .gv text file. """
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-3:] != ".gv":
- self._filename += ".gv"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- dotfile = open(self._filename, "w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVPsDoc
-#
-#-------------------------------------------------------------------------------
-class GVPsDoc(GVDocBase):
- """ GVDoc implementation that generates a .ps file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # DPI must always be 72 for PDF.
- # GV documentation says dpi is only for image formats.
- options.menu.get_option_by_name('dpi').set_value(72)
- GVDocBase.__init__(self, options, paper_style)
- # GV documentation allow multiple pages only for ps format,
- # But it does not work with -Tps:cairo in order to
- # show Non Latin-1 letters. Force to only 1 page.
- # See bug tracker issue 2815
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-3:] != ".ps":
- self._filename += ".ps"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the PS file.
- # Reason for using -Tps:cairo. Needed for Non Latin-1 letters
- # Some testing with Tps:cairo. Non Latin-1 letters are OK i all cases:
- # Output format: ps PDF-GostScript PDF-GraphViz
- # Single page OK OK OK
- # Multip page 1 page, OK 1 page,
- # corrupted set by gramps
- # If I take a correct multip page PDF and convert it with pdf2ps I get multip pages,
- # but the output is clipped, some margins have disappeared. I used 1 inch margins always.
- # See bug tracker issue 2815
-
- os.system( 'dot -Tps:cairo -o"%s" "%s"' % (self._filename, tmp_dot) )
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVSvgDoc
-#
-#-------------------------------------------------------------------------------
-class GVSvgDoc(GVDocBase):
- """ GVDoc implementation that generates a .svg file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # GV documentation allow multiple pages only for ps format,
- # which also includes pdf via ghostscript.
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-4:] != ".svg":
- self._filename += ".svg"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the SVG file.
- os.system( 'dot -Tsvg -o"%s" "%s"' % (self._filename, tmp_dot) )
-
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVSvgzDoc
-#
-#-------------------------------------------------------------------------------
-class GVSvgzDoc(GVDocBase):
- """ GVDoc implementation that generates a .svg file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # GV documentation allow multiple pages only for ps format,
- # which also includes pdf via ghostscript.
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-5:] != ".svgz":
- self._filename += ".svgz"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the SVGZ file.
- os.system( 'dot -Tsvgz -o"%s" "%s"' % (self._filename, tmp_dot) )
-
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVPngDoc
-#
-#-------------------------------------------------------------------------------
-class GVPngDoc(GVDocBase):
- """ GVDoc implementation that generates a .png file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # GV documentation allow multiple pages only for ps format,
- # which also includes pdf via ghostscript.
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-4:] != ".png":
- self._filename += ".png"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the PNG file.
- os.system( 'dot -Tpng -o"%s" "%s"' % (self._filename, tmp_dot) )
-
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVJpegDoc
-#
-#-------------------------------------------------------------------------------
-class GVJpegDoc(GVDocBase):
- """ GVDoc implementation that generates a .jpg file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # GV documentation allow multiple pages only for ps format,
- # which also includes pdf via ghostscript.
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-4:] != ".jpg":
- self._filename += ".jpg"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the JPEG file.
- os.system( 'dot -Tjpg -o"%s" "%s"' % (self._filename, tmp_dot) )
-
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVGifDoc
-#
-#-------------------------------------------------------------------------------
-class GVGifDoc(GVDocBase):
- """ GVDoc implementation that generates a .gif file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # GV documentation allow multiple pages only for ps format,
- # which also includes pdf via ghostscript.
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-4:] != ".gif":
- self._filename += ".gif"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the GIF file.
- os.system( 'dot -Tgif -o"%s" "%s"' % (self._filename, tmp_dot) )
-
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVPdfGvDoc
-#
-#-------------------------------------------------------------------------------
-class GVPdfGvDoc(GVDocBase):
- """ GVDoc implementation that generates a .pdf file using Graphviz. """
-
- def __init__(self, options, paper_style):
- # DPI must always be 72 for PDF.
- # GV documentation says dpi is only for image formats.
- options.menu.get_option_by_name('dpi').set_value(72)
- # GV documentation allow multiple pages only for ps format,
- # which also includes pdf via ghostscript.
- options.menu.get_option_by_name('v_pages').set_value(1)
- options.menu.get_option_by_name('h_pages').set_value(1)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-4:] != ".pdf":
- self._filename += ".pdf"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Generate the PDF file.
- os.system( 'dot -Tpdf -o"%s" "%s"' % (self._filename, tmp_dot) )
-
- # Delete the temporary dot file
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# GVPdfGsDoc
-#
-#-------------------------------------------------------------------------------
-class GVPdfGsDoc(GVDocBase):
- """ GVDoc implementation that generates a .pdf file using Ghostscript. """
- def __init__(self, options, paper_style):
- # DPI must always be 72 for PDF.
- # GV documentation says dpi is only for image formats.
- options.menu.get_option_by_name('dpi').set_value(72)
- GVDocBase.__init__(self, options, paper_style)
-
- def close(self):
- """ Implements GVDocBase.close() """
- GVDocBase.close(self)
-
- # Make sure the extension is correct
- if self._filename[-4:] != ".pdf":
- self._filename += ".pdf"
-
- _run_long_process_in_thread(self.__generate, self._filename)
-
- def __generate(self):
- """
- This function will generate the actual file.
- It is nice to run this function in the background so that the
- application does not appear to hang.
- """
- # Create a temporary dot file
- (handle, tmp_dot) = tempfile.mkstemp(".gv" )
- dotfile = os.fdopen(handle,"w")
- dotfile.write(self._dot.getvalue())
- dotfile.close()
-
- # Create a temporary PostScript file
- (handle, tmp_ps) = tempfile.mkstemp(".ps" )
- os.close( handle )
-
- # Generate PostScript using dot
- # Reason for using -Tps:cairo. Needed for Non Latin-1 letters
- # See bug tracker issue 2815
- command = 'dot -Tps:cairo -o"%s" "%s"' % ( tmp_ps, tmp_dot )
- os.system(command)
-
- # Add .5 to remove rounding errors.
- paper_size = self._paper.get_size()
- width_pt = int( (paper_size.get_width_inches() * 72) + 0.5 )
- height_pt = int( (paper_size.get_height_inches() * 72) + 0.5 )
-
- # Convert to PDF using ghostscript
- command = '%s -q -sDEVICE=pdfwrite -dNOPAUSE -dDEVICEWIDTHPOINTS=%d' \
- ' -dDEVICEHEIGHTPOINTS=%d -sOutputFile="%s" "%s" -c quit' \
- % ( _GS_CMD, width_pt, height_pt, self._filename, tmp_ps )
- os.system(command)
-
- os.remove(tmp_ps)
- os.remove(tmp_dot)
-
- if self.open_req:
- open_file_with_default_application(self._filename)
-
-#-------------------------------------------------------------------------------
-#
-# Various Graphviz formats.
-#
-#-------------------------------------------------------------------------------
-_FORMATS = []
-
-if _DOT_FOUND:
-
- if _GS_CMD != "":
- _FORMATS += [{ 'type' : "gspdf",
- 'ext' : "pdf",
- 'descr': _("PDF (Ghostscript)"),
- 'mime' : "application/pdf",
- 'class': GVPdfGsDoc }]
-
- _FORMATS += [{ 'type' : "gvpdf",
- 'ext' : "pdf",
- 'descr': _("PDF (Graphviz)"),
- 'mime' : "application/pdf",
- 'class': GVPdfGvDoc }]
-
- _FORMATS += [{ 'type' : "ps",
- 'ext' : "ps",
- 'descr': _("PostScript"),
- 'mime' : "application/postscript",
- 'class': GVPsDoc }]
-
- _FORMATS += [{ 'type' : "svg",
- 'ext' : "svg",
- 'descr': _("Structured Vector Graphics (SVG)"),
- 'mime' : "image/svg",
- 'class': GVSvgDoc }]
-
- _FORMATS += [{ 'type' : "svgz",
- 'ext' : "svgz",
- 'descr': _("Compressed Structured Vector Graphs (SVGZ)"),
- 'mime' : "image/svgz",
- 'class': GVSvgzDoc }]
-
- _FORMATS += [{ 'type' : "jpg",
- 'ext' : "jpg",
- 'descr': _("JPEG image"),
- 'mime' : "image/jpeg",
- 'class': GVJpegDoc }]
-
- _FORMATS += [{ 'type' : "gif",
- 'ext' : "gif",
- 'descr': _("GIF image"),
- 'mime' : "image/gif",
- 'class': GVGifDoc }]
-
- _FORMATS += [{ 'type' : "png",
- 'ext' : "png",
- 'descr': _("PNG image"),
- 'mime' : "image/png",
- 'class': GVPngDoc }]
-
-_FORMATS += [{ 'type' : "dot",
- 'ext' : "gv",
- 'descr': _("Graphviz File"),
- 'mime' : "text/x-graphviz",
- 'class': GVDotDoc }]
-
-#-------------------------------------------------------------------------------
-#
-# GraphvizFormatComboBox
-#
-#-------------------------------------------------------------------------------
-class GraphvizFormatComboBox(gtk.ComboBox):
- """
- Format combo box class for Graphviz report.
- """
- def set(self, active=None):
- self.store = gtk.ListStore(gobject.TYPE_STRING)
- self.set_model(self.store)
- cell = gtk.CellRendererText()
- self.pack_start(cell, True)
- self.add_attribute(cell, 'text', 0)
-
- index = 0
- active_index = 0
- for item in _FORMATS:
- name = item["descr"]
- self.store.append(row=[name])
- if item['type'] == active:
- active_index = index
- index += 1
- self.set_active(active_index)
-
- def get_label(self):
- return _FORMATS[self.get_active()]["descr"]
-
- def get_reference(self):
- return _FORMATS[self.get_active()]["class"]
-
- def get_paper(self):
- return 1
-
- def get_styles(self):
- return 0
-
- def get_ext(self):
- return '.%s' % _FORMATS[self.get_active()]['ext']
-
- def get_format_str(self):
- return _FORMATS[self.get_active()]["type"]
-
- def is_file_output(self):
- return True
-
- def get_clname(self):
- return _FORMATS[self.get_active()]["type"]
-
-#-----------------------------------------------------------------------
-#
-# GraphvizReportDialog
-#
-#-----------------------------------------------------------------------
-class GraphvizReportDialog(ReportDialog):
- """A class of ReportDialog customized for graphviz based reports."""
- def __init__(self, dbstate, uistate, opt, name, translated_name):
- """Initialize a dialog to request that the user select options
- for a graphviz report. See the ReportDialog class for
- more information."""
- self.category = CATEGORY_GRAPHVIZ
- ReportDialog.__init__(self, dbstate, uistate, opt,
- name, translated_name)
-
- def init_options(self, option_class):
- try:
- if (issubclass(option_class, object) or # New-style class
- isinstance(options_class, ClassType)): # Old-style class
- self.options = option_class(self.raw_name,
- self.dbstate.get_database())
- except TypeError:
- self.options = option_class
-
- ################################
- category = _("GraphViz Layout")
- ################################
- font_family = EnumeratedListOption(_("Font family"), "")
- index = 0
- for item in _FONTS:
- font_family.add_item(item["value"], item["name"])
- index += 1
- font_family.set_help(_("Choose the font family. If international "
- "characters don't show, use FreeSans font. "
- "FreeSans is available from: "
- "http://www.nongnu.org/freefont/"))
- self.options.add_menu_option(category, "font_family", font_family)
-
- font_size = NumberOption(_("Font size"), 14, 8, 128)
- font_size.set_help(_("The font size, in points."))
- self.options.add_menu_option(category, "font_size", font_size)
-
- rank_dir = EnumeratedListOption(_("Graph Direction"), "TB")
- index = 0
- for item in _RANKDIR:
- rank_dir.add_item(item["value"], item["name"])
- index += 1
- rank_dir.set_help(_("Whether graph goes from top to bottom "
- "or left to right."))
- self.options.add_menu_option(category, "rank_dir", rank_dir)
-
- h_pages = NumberOption(_("Number of Horizontal Pages"), 1, 1, 25)
- h_pages.set_help(_("GraphViz can create very large graphs by "
- "spreading the graph across a rectangular "
- "array of pages. This controls the number "
- "pages in the array horizontally. "
- "Only valid for dot and pdf via Ghostscript."))
- self.options.add_menu_option(category, "h_pages", h_pages)
-
- v_pages = NumberOption(_("Number of Vertical Pages"), 1, 1, 25)
- v_pages.set_help(_("GraphViz can create very large graphs by "
- "spreading the graph across a rectangular "
- "array of pages. This controls the number "
- "pages in the array vertically. "
- "Only valid for dot and pdf via Ghostscript."))
- self.options.add_menu_option(category, "v_pages", v_pages)
-
- page_dir = EnumeratedListOption(_("Paging Direction"), "BL")
- index = 0
- for item in _PAGEDIR:
- page_dir.add_item(item["value"], item["name"])
- index += 1
- page_dir.set_help(_("The order in which the graph pages are output. "
- "This option only applies if the horizontal pages "
- "or vertical pages are greater than 1."))
- self.options.add_menu_option(category, "page_dir", page_dir)
-
- # the page direction option only makes sense when the
- # number of horizontal and/or vertical pages is > 1,
- # so we need to remember these 3 controls for later
- self.h_pages = h_pages
- self.v_pages = v_pages
- self.page_dir = page_dir
-
- # the page direction option only makes sense when the
- # number of horizontal and/or vertical pages is > 1
- self.h_pages.connect('value-changed', self.pages_changed)
- self.v_pages.connect('value-changed', self.pages_changed)
-
- ################################
- category = _("GraphViz Options")
- ################################
-
- aspect_ratio = EnumeratedListOption(_("Aspect ratio"), "fill")
- index = 0
- for item in _RATIO:
- aspect_ratio.add_item(item["value"], item["name"])
- index += 1
- aspect_ratio.set_help(_("Affects greatly how the graph is layed out "
- "on the page."))
- self.options.add_menu_option(category, "ratio", aspect_ratio)
-
- dpi = NumberOption(_("DPI"), 75, 20, 1200)
- dpi.set_help(_( "Dots per inch. When creating images such as "
- ".gif or .png files for the web, try numbers "
- "such as 100 or 300 DPI. When creating PostScript "
- "or PDF files, use 72 DPI."))
- self.options.add_menu_option(category, "dpi", dpi)
-
- nodesep = NumberOption(_("Node spacing"), 0.20, 0.01, 5.00, 0.01)
- nodesep.set_help(_( "The minimum amount of free space, in inches, "
- "between individual nodes. For vertical graphs, "
- "this corresponds to spacing between columns. "
- "For horizontal graphs, this corresponds to "
- "spacing between rows."))
- self.options.add_menu_option(category, "nodesep", nodesep)
-
- ranksep = NumberOption(_("Rank spacing"), 0.20, 0.01, 5.00, 0.01)
- ranksep.set_help(_( "The minimum amount of free space, in inches, "
- "between ranks. For vertical graphs, this "
- "corresponds to spacing between rows. For "
- "horizontal graphs, this corresponds to spacing "
- "between columns."))
- self.options.add_menu_option(category, "ranksep", ranksep)
-
- use_subgraphs = BooleanOption(_('Use subgraphs'), True)
- use_subgraphs.set_help(_("Subgraphs can help GraphViz position "
- "spouses together, but with non-trivial "
- "graphs will result in longer lines and "
- "larger graphs."))
- self.options.add_menu_option(category, "usesubgraphs", use_subgraphs)
-
- ################################
- category = _("Note")
- ################################
-
- note = TextOption(_("Note to add to the graph"),
- [""] )
- note.set_help(_("This text will be added to the graph."))
- self.options.add_menu_option(category, "note", note)
-
- noteloc = EnumeratedListOption(_("Note location"), 't')
- for i in range( 0, len(_NOTELOC) ):
- noteloc.add_item(_NOTELOC[i]["value"], _NOTELOC[i]["name"])
- noteloc.set_help(_("Whether note will appear on top "
- "or bottom of the page."))
- self.options.add_menu_option(category, "noteloc", noteloc)
-
- notesize = NumberOption(_("Note size"), 32, 8, 128)
- notesize.set_help(_("The size of note text, in points."))
- self.options.add_menu_option(category, "notesize", notesize)
-
- self.options.load_previous_values()
-
- def pages_changed(self):
- """
- This method gets called every time the v_pages or h_pages
- options are changed; when both vertical and horizontal
- pages are set to "1", then the page_dir control needs to
- be unavailable
- """
- if self.v_pages.get_value() > 1 or \
- self.h_pages.get_value() > 1:
- self.page_dir.set_available(True)
- else:
- self.page_dir.set_available(False)
-
- def init_interface(self):
- ReportDialog.init_interface(self)
- self.doc_type_changed(self.format_menu)
-
- def setup_format_frame(self):
- """Set up the format frame of the dialog."""
- self.format_menu = GraphvizFormatComboBox()
- self.format_menu.set(self.options.handler.get_format_name())
- self.format_menu.connect('changed', self.doc_type_changed)
- label = gtk.Label("%s:" % _("Output Format"))
- label.set_alignment(0.0, 0.5)
- self.tbl.attach(label, 1, 2, self.row, self.row+1, gtk.SHRINK|gtk.FILL)
- self.tbl.attach(self.format_menu, 2, 4, self.row, self.row+1,
- yoptions=gtk.SHRINK)
- self.row += 1
-
- self.open_with_app = gtk.CheckButton(_("Open with default viewer"))
- self.tbl.attach(self.open_with_app, 2, 4, self.row, self.row+1,
- yoptions=gtk.SHRINK)
- self.row += 1
-
- ext = self.format_menu.get_ext()
- if ext is None:
- ext = ""
- else:
- spath = self.get_default_directory()
- base = "%s%s" % (self.raw_name, ext)
- spath = os.path.normpath(os.path.join(spath, base))
- self.target_fileentry.set_filename(spath)
-
- def setup_report_options_frame(self):
- self.paper_label = gtk.Label('%s'%_("Paper Options"))
- self.paper_label.set_use_markup(True)
-
- self.paper_frame = PaperFrame(
- self.options.handler.get_paper_metric(),
- self.options.handler.get_paper_name(),
- self.options.handler.get_orientation(),
- self.options.handler.get_margins(),
- self.options.handler.get_custom_paper_size()
- )
- self.notebook.insert_page(self.paper_frame, self.paper_label, 0)
- self.paper_frame.show_all()
-
- ReportDialog.setup_report_options_frame(self)
-
- 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.
- """
- self.open_with_app.set_sensitive(True)
-
- fname = self.target_fileentry.get_full_path(0)
- (spath, ext) = os.path.splitext(fname)
-
- ext_val = obj.get_ext()
- if ext_val:
- fname = spath + ext_val
- else:
- fname = spath
- self.target_fileentry.set_filename(fname)
-
- def make_document(self):
- """Create a document of the type requested by the user.
- """
- pstyle = self.paper_frame.get_paper_style()
-
- self.doc = self.format(self.options, pstyle)
-
- self.options.set_document(self.doc)
-
- if self.open_with_app.get_active():
- self.doc.open_requested()
-
- 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():
- self.window.run()
-
- # Preparation
- self.parse_format_frame()
- self.parse_user_options()
-
- self.options.handler.set_paper_metric(
- self.paper_frame.get_paper_metric())
- self.options.handler.set_paper_name(self.paper_frame.get_paper_name())
- self.options.handler.set_orientation(self.paper_frame.get_orientation())
- self.options.handler.set_margins(self.paper_frame.get_paper_margins())
- self.options.handler.set_custom_paper_size(
- self.paper_frame.get_custom_paper_size())
-
- # Create the output document.
- self.make_document()
-
- # Save options
- self.options.handler.save_options()
-
- def parse_format_frame(self):
- """Parse the format frame of the dialog. Save the user
- selected output format for later use."""
- self.format = self.format_menu.get_reference()
- format_name = self.format_menu.get_clname()
- self.options.handler.set_format_name(format_name)
-
- def setup_style_frame(self):
- """Required by ReportDialog"""
- pass
diff --git a/src/gui/plug/report/_options.py b/src/gui/plug/report/_options.py
index 2395c86aa..402c6feac 100644
--- a/src/gui/plug/report/_options.py
+++ b/src/gui/plug/report/_options.py
@@ -59,125 +59,3 @@ class MenuReportOptions(GuiMenuOptions, ReportOptions):
if menu_option:
menu_option.set_value(self.options_dict[optname])
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2004-2007 Donald N. Allingham
-# Copyright (C) 2008 Gary Burton
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id$
-
-# Written by Alex Roitman
-
-"""
-Report option handling, including saving and parsing.
-"""
-from gen.plug.report._options import ReportOptions
-from gui.plug import GuiMenuOptions
-
-#-------------------------------------------------------------------------
-#
-# MenuReportOptions
-#
-#-------------------------------------------------------------------------
-class MenuReportOptions(GuiMenuOptions, ReportOptions):
- """
-
- The MenuReportOptions class implements the ReportOptions
- functionality in a generic way so that the user does not need to
- be concerned with the graphical representation of the options.
-
- The user should inherit the MenuReportOptions class and override the
- add_menu_options function. The user can add options to the menu and the
- MenuReportOptions class will worry about setting up the GUI.
-
- """
- def __init__(self, name, dbase):
- ReportOptions.__init__(self, name, dbase)
- GuiMenuOptions.__init__(self)
-
- def load_previous_values(self):
- ReportOptions.load_previous_values(self)
- # Pass the loaded values to the menu options so they will be displayed
- # properly.
- for optname in self.options_dict:
- menu_option = self.menu.get_option_by_name(optname)
- if menu_option:
- menu_option.set_value(self.options_dict[optname])
-
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2004-2007 Donald N. Allingham
-# Copyright (C) 2008 Gary Burton
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# $Id$
-
-# Written by Alex Roitman
-
-"""
-Report option handling, including saving and parsing.
-"""
-from gen.plug.report._options import ReportOptions
-from gui.plug import GuiMenuOptions
-
-#-------------------------------------------------------------------------
-#
-# MenuReportOptions
-#
-#-------------------------------------------------------------------------
-class MenuReportOptions(GuiMenuOptions, ReportOptions):
- """
-
- The MenuReportOptions class implements the ReportOptions
- functionality in a generic way so that the user does not need to
- be concerned with the graphical representation of the options.
-
- The user should inherit the MenuReportOptions class and override the
- add_menu_options function. The user can add options to the menu and the
- MenuReportOptions class will worry about setting up the GUI.
-
- """
- def __init__(self, name, dbase):
- ReportOptions.__init__(self, name, dbase)
- GuiMenuOptions.__init__(self)
-
- def load_previous_values(self):
- ReportOptions.load_previous_values(self)
- # Pass the loaded values to the menu options so they will be displayed
- # properly.
- for optname in self.options_dict:
- menu_option = self.menu.get_option_by_name(optname)
- if menu_option:
- menu_option.set_value(self.options_dict[optname])
-
diff --git a/src/gui/plug/report/_papermenu.py b/src/gui/plug/report/_papermenu.py
index 591aeda99..85cc50a2b 100644
--- a/src/gui/plug/report/_papermenu.py
+++ b/src/gui/plug/report/_papermenu.py
@@ -305,617 +305,3 @@ class PaperFrame(gtk.HBox):
def get_orientation(self):
return self.orientation_menu.get_value()
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2000-2007 Donald N. Allingham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-from gen.ggettext import sgettext as _
-
-#-------------------------------------------------------------------------
-#
-# GNOME modules
-#
-#-------------------------------------------------------------------------
-import gtk
-import gobject
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-from gen.plug.docgen import PaperStyle, PAPER_PORTRAIT, PAPER_LANDSCAPE
-from gen.plug.report._paper import paper_sizes
-from glade import Glade
-
-#-------------------------------------------------------------------------
-#
-# PaperComboBox
-#
-#-------------------------------------------------------------------------
-class PaperComboBox(gtk.ComboBox):
-
- def __init__(self,default_name):
- gtk.ComboBox.__init__(self)
-
- self.store = gtk.ListStore(gobject.TYPE_STRING)
- self.set_model(self.store)
- cell = gtk.CellRendererText()
- self.pack_start(cell,True)
- self.add_attribute(cell,'text',0)
- self.mapping = {}
-
- index = 0
- start_index = 0
- for key in paper_sizes:
- self.mapping[key.get_name()] = key
- self.store.append(row=[key.get_name()])
- if key.get_name() == default_name:
- start_index = index
- index += 1
-
- self.set_active(start_index)
-
- def get_value(self):
- active = self.get_active()
- if active < 0:
- return None
- key = unicode(self.store[active][0])
- return (self.mapping[key],key)
-
-#-------------------------------------------------------------------------
-#
-# OrientationComboBox
-#
-#-------------------------------------------------------------------------
-class OrientationComboBox(gtk.ComboBox):
-
- def __init__(self,default=PAPER_PORTRAIT):
- gtk.ComboBox.__init__(self)
-
- self.store = gtk.ListStore(gobject.TYPE_STRING)
- self.set_model(self.store)
- cell = gtk.CellRendererText()
- self.pack_start(cell,True)
- self.add_attribute(cell,'text',0)
- self.mapping = {}
-
- self.store.append(row=[_('Portrait')])
- self.store.append(row=[_('Landscape')])
- if default == PAPER_PORTRAIT:
- self.set_active(0)
- else:
- self.set_active(1)
-
- def set_value(self,value=0):
- if value == PAPER_PORTRAIT:
- self.set_active(0)
- else:
- self.set_active(1)
-
- def get_value(self):
- active = self.get_active()
- if active < 0:
- return None
- if active == 0:
- return PAPER_PORTRAIT
- else:
- return PAPER_LANDSCAPE
-
-#-------------------------------------------------------------------------
-#
-# PaperFrame
-#
-#-------------------------------------------------------------------------
-class PaperFrame(gtk.HBox):
- """PaperFrame provides all the entry necessary to specify a paper style. """
- def __init__(self,default_metric,default_name,default_orientation,
- margins=[2.54,2.54,2.54,2.54], custom=[29.7,21.0]):
- gtk.HBox.__init__(self)
- glade_xml = Glade()
-
- self.paper_table = glade_xml.get_object('paper_table')
-
-
- # get all the widgets
- widgets = ('pwidth', 'pheight', 'lmargin', 'rmargin', 'tmargin',
- 'bmargin', 'lunits1', 'lunits2', 'lunits3', 'lunits4',
- 'lunits5', 'lunits6', 'metric')
-
- for w in widgets:
- setattr(self, w, glade_xml.get_object(w))
-
- # insert custom widgets
- self.papersize_menu = PaperComboBox(default_name)
- self.orientation_menu = OrientationComboBox(default_orientation)
- self.metric.set_active(default_metric)
-
- # connect all widgets
- format_table = glade_xml.get_object('format_table')
- format_table.attach(self.papersize_menu, 1, 3, 0, 1,
- yoptions=gtk.SHRINK)
- format_table.attach(self.orientation_menu, 1, 3, 3, 4,
- yoptions=gtk.SHRINK)
-
- # connect signals
- self.papersize_menu.connect('changed',self.size_changed)
- self.metric.connect('toggled',self.units_changed)
-
- # set initial values
- self.paper_unit = 'cm'
- self.paper_unit_multiplier = 1.0
-
- self.pwidth.set_text("%.2f" % custom[0])
- self.pheight.set_text("%.2f" % custom[1])
- self.lmargin.set_text("%.2f" % margins[0])
- self.rmargin.set_text("%.2f" % margins[1])
- self.tmargin.set_text("%.2f" % margins[2])
- self.bmargin.set_text("%.2f" % margins[3])
-
- self.paper_table.show_all()
- self.paper_table.reparent(self)
-
- self.units_changed(self.metric)
- self.size_changed(None)
-
- def size_changed(self, obj):
- """Paper size combobox 'changed' callback."""
- size, name = self.get_paper_size()
-
- is_custom = name == _("Custom Size")
- self.pwidth.set_sensitive(is_custom)
- self.pheight.set_sensitive(is_custom)
-
- if self.paper_unit == 'cm':
- self.pwidth.set_text("%.2f" % size.get_width())
- self.pheight.set_text("%.2f" % size.get_height())
- elif self.paper_unit == 'in.':
- self.pwidth.set_text("%.2f" % size.get_width_inches())
- self.pheight.set_text("%.2f" % size.get_height_inches())
- else:
- raise ValueError('Paper dimension unit "%s" is not allowed' %
- self.paper_unit)
-
- def units_changed(self, checkbox):
- """Metric checkbox 'toggled' callback."""
- paper_size, paper_name = self.get_paper_size()
- paper_margins = self.get_paper_margins()
-
- if checkbox.get_active():
- self.paper_unit = 'cm'
- self.paper_unit_multiplier = 1.0
- paper_unit_text = _("cm")
- else:
- self.paper_unit = 'in.'
- self.paper_unit_multiplier = 2.54
- paper_unit_text = _("inch|in.")
-
- self.lunits1.set_text(paper_unit_text)
- self.lunits2.set_text(paper_unit_text)
- self.lunits3.set_text(paper_unit_text)
- self.lunits4.set_text(paper_unit_text)
- self.lunits5.set_text(paper_unit_text)
- self.lunits6.set_text(paper_unit_text)
-
- if self.paper_unit == 'cm':
- self.pwidth.set_text("%.2f" % paper_size.get_width())
- self.pheight.set_text("%.2f" % paper_size.get_height())
- else:
- self.pwidth.set_text("%.2f" % paper_size.get_width_inches())
- self.pheight.set_text("%.2f" % paper_size.get_height_inches())
-
- self.lmargin.set_text("%.2f" %
- (paper_margins[0] / self.paper_unit_multiplier))
- self.rmargin.set_text("%.2f" %
- (paper_margins[1] / self.paper_unit_multiplier))
- self.tmargin.set_text("%.2f" %
- (paper_margins[2] / self.paper_unit_multiplier))
- self.bmargin.set_text("%.2f" %
- (paper_margins[3] / self.paper_unit_multiplier))
-
- def get_paper_size(self):
- """Read and validate paper size values.
-
- If needed update the dimensions from the width, height entries,
- and worst case fallback to A4 size.
-
- """
- papersize, papername = self.papersize_menu.get_value()
- # FIXME it is wrong to use translatable text in comparison.
- # How can we distinguish custom size though?
- if papername == _('Custom Size'):
- try:
- h = float(unicode(self.pheight.get_text().replace(",", ".")))
- w = float(unicode(self.pwidth.get_text().replace(",", ".") ))
-
- if h <= 1.0 or w <= 1.0:
- papersize.set_height(29.7)
- papersize.set_width(21.0)
- else:
- papersize.set_height(h * self.paper_unit_multiplier)
- papersize.set_width(w * self.paper_unit_multiplier)
- except:
- papersize.set_height(29.7)
- papersize.set_width(21.0)
-
- return papersize, papername
-
- def get_paper_margins(self):
- """Get and validate margin values from dialog entries.
-
- Values returned in [cm].
-
- """
- paper_margins = [unicode(margin.get_text()) for margin in
- self.lmargin, self.rmargin, self.tmargin, self.bmargin]
-
- for i, margin in enumerate(paper_margins):
- try:
- paper_margins[i] = float(margin.replace(",", "."))
- paper_margins[i] = paper_margins[i] * self.paper_unit_multiplier
- paper_margins[i] = max(paper_margins[i], 0)
- except:
- paper_margins[i] = 2.54
-
- return paper_margins
-
- def get_custom_paper_size(self):
- width = float(self.pwidth.get_text().replace(",", ".")) * \
- self.paper_unit_multiplier
- height = float(self.pheight.get_text().replace(",", ".")) * \
- self.paper_unit_multiplier
-
- paper_size = [max(width, 1.0), max(height, 1.0)]
-
- return paper_size
-
- def get_paper_style(self):
- paper_size, paper_name = self.get_paper_size()
- paper_orientation = self.orientation_menu.get_value()
- paper_margins = self.get_paper_margins()
-
- pstyle = PaperStyle(paper_size,
- paper_orientation,
- *paper_margins)
- return pstyle
-
- def get_paper_metric(self):
- return self.metric.get_active()
-
- def get_paper_name(self):
- paper_size, paper_name = self.get_paper_size()
- return paper_name
-
- def get_orientation(self):
- return self.orientation_menu.get_value()
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2000-2007 Donald N. Allingham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-from gen.ggettext import sgettext as _
-
-#-------------------------------------------------------------------------
-#
-# GNOME modules
-#
-#-------------------------------------------------------------------------
-import gtk
-import gobject
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-from gen.plug.docgen import PaperStyle, PAPER_PORTRAIT, PAPER_LANDSCAPE
-from gen.plug.report._paper import paper_sizes
-from glade import Glade
-
-#-------------------------------------------------------------------------
-#
-# PaperComboBox
-#
-#-------------------------------------------------------------------------
-class PaperComboBox(gtk.ComboBox):
-
- def __init__(self,default_name):
- gtk.ComboBox.__init__(self)
-
- self.store = gtk.ListStore(gobject.TYPE_STRING)
- self.set_model(self.store)
- cell = gtk.CellRendererText()
- self.pack_start(cell,True)
- self.add_attribute(cell,'text',0)
- self.mapping = {}
-
- index = 0
- start_index = 0
- for key in paper_sizes:
- self.mapping[key.get_name()] = key
- self.store.append(row=[key.get_name()])
- if key.get_name() == default_name:
- start_index = index
- index += 1
-
- self.set_active(start_index)
-
- def get_value(self):
- active = self.get_active()
- if active < 0:
- return None
- key = unicode(self.store[active][0])
- return (self.mapping[key],key)
-
-#-------------------------------------------------------------------------
-#
-# OrientationComboBox
-#
-#-------------------------------------------------------------------------
-class OrientationComboBox(gtk.ComboBox):
-
- def __init__(self,default=PAPER_PORTRAIT):
- gtk.ComboBox.__init__(self)
-
- self.store = gtk.ListStore(gobject.TYPE_STRING)
- self.set_model(self.store)
- cell = gtk.CellRendererText()
- self.pack_start(cell,True)
- self.add_attribute(cell,'text',0)
- self.mapping = {}
-
- self.store.append(row=[_('Portrait')])
- self.store.append(row=[_('Landscape')])
- if default == PAPER_PORTRAIT:
- self.set_active(0)
- else:
- self.set_active(1)
-
- def set_value(self,value=0):
- if value == PAPER_PORTRAIT:
- self.set_active(0)
- else:
- self.set_active(1)
-
- def get_value(self):
- active = self.get_active()
- if active < 0:
- return None
- if active == 0:
- return PAPER_PORTRAIT
- else:
- return PAPER_LANDSCAPE
-
-#-------------------------------------------------------------------------
-#
-# PaperFrame
-#
-#-------------------------------------------------------------------------
-class PaperFrame(gtk.HBox):
- """PaperFrame provides all the entry necessary to specify a paper style. """
- def __init__(self,default_metric,default_name,default_orientation,
- margins=[2.54,2.54,2.54,2.54], custom=[29.7,21.0]):
- gtk.HBox.__init__(self)
- glade_xml = Glade()
-
- self.paper_table = glade_xml.get_object('paper_table')
-
-
- # get all the widgets
- widgets = ('pwidth', 'pheight', 'lmargin', 'rmargin', 'tmargin',
- 'bmargin', 'lunits1', 'lunits2', 'lunits3', 'lunits4',
- 'lunits5', 'lunits6', 'metric')
-
- for w in widgets:
- setattr(self, w, glade_xml.get_object(w))
-
- # insert custom widgets
- self.papersize_menu = PaperComboBox(default_name)
- self.orientation_menu = OrientationComboBox(default_orientation)
- self.metric.set_active(default_metric)
-
- # connect all widgets
- format_table = glade_xml.get_object('format_table')
- format_table.attach(self.papersize_menu, 1, 3, 0, 1,
- yoptions=gtk.SHRINK)
- format_table.attach(self.orientation_menu, 1, 3, 3, 4,
- yoptions=gtk.SHRINK)
-
- # connect signals
- self.papersize_menu.connect('changed',self.size_changed)
- self.metric.connect('toggled',self.units_changed)
-
- # set initial values
- self.paper_unit = 'cm'
- self.paper_unit_multiplier = 1.0
-
- self.pwidth.set_text("%.2f" % custom[0])
- self.pheight.set_text("%.2f" % custom[1])
- self.lmargin.set_text("%.2f" % margins[0])
- self.rmargin.set_text("%.2f" % margins[1])
- self.tmargin.set_text("%.2f" % margins[2])
- self.bmargin.set_text("%.2f" % margins[3])
-
- self.paper_table.show_all()
- self.paper_table.reparent(self)
-
- self.units_changed(self.metric)
- self.size_changed(None)
-
- def size_changed(self, obj):
- """Paper size combobox 'changed' callback."""
- size, name = self.get_paper_size()
-
- is_custom = name == _("Custom Size")
- self.pwidth.set_sensitive(is_custom)
- self.pheight.set_sensitive(is_custom)
-
- if self.paper_unit == 'cm':
- self.pwidth.set_text("%.2f" % size.get_width())
- self.pheight.set_text("%.2f" % size.get_height())
- elif self.paper_unit == 'in.':
- self.pwidth.set_text("%.2f" % size.get_width_inches())
- self.pheight.set_text("%.2f" % size.get_height_inches())
- else:
- raise ValueError('Paper dimension unit "%s" is not allowed' %
- self.paper_unit)
-
- def units_changed(self, checkbox):
- """Metric checkbox 'toggled' callback."""
- paper_size, paper_name = self.get_paper_size()
- paper_margins = self.get_paper_margins()
-
- if checkbox.get_active():
- self.paper_unit = 'cm'
- self.paper_unit_multiplier = 1.0
- paper_unit_text = _("cm")
- else:
- self.paper_unit = 'in.'
- self.paper_unit_multiplier = 2.54
- paper_unit_text = _("inch|in.")
-
- self.lunits1.set_text(paper_unit_text)
- self.lunits2.set_text(paper_unit_text)
- self.lunits3.set_text(paper_unit_text)
- self.lunits4.set_text(paper_unit_text)
- self.lunits5.set_text(paper_unit_text)
- self.lunits6.set_text(paper_unit_text)
-
- if self.paper_unit == 'cm':
- self.pwidth.set_text("%.2f" % paper_size.get_width())
- self.pheight.set_text("%.2f" % paper_size.get_height())
- else:
- self.pwidth.set_text("%.2f" % paper_size.get_width_inches())
- self.pheight.set_text("%.2f" % paper_size.get_height_inches())
-
- self.lmargin.set_text("%.2f" %
- (paper_margins[0] / self.paper_unit_multiplier))
- self.rmargin.set_text("%.2f" %
- (paper_margins[1] / self.paper_unit_multiplier))
- self.tmargin.set_text("%.2f" %
- (paper_margins[2] / self.paper_unit_multiplier))
- self.bmargin.set_text("%.2f" %
- (paper_margins[3] / self.paper_unit_multiplier))
-
- def get_paper_size(self):
- """Read and validate paper size values.
-
- If needed update the dimensions from the width, height entries,
- and worst case fallback to A4 size.
-
- """
- papersize, papername = self.papersize_menu.get_value()
- # FIXME it is wrong to use translatable text in comparison.
- # How can we distinguish custom size though?
- if papername == _('Custom Size'):
- try:
- h = float(unicode(self.pheight.get_text().replace(",", ".")))
- w = float(unicode(self.pwidth.get_text().replace(",", ".") ))
-
- if h <= 1.0 or w <= 1.0:
- papersize.set_height(29.7)
- papersize.set_width(21.0)
- else:
- papersize.set_height(h * self.paper_unit_multiplier)
- papersize.set_width(w * self.paper_unit_multiplier)
- except:
- papersize.set_height(29.7)
- papersize.set_width(21.0)
-
- return papersize, papername
-
- def get_paper_margins(self):
- """Get and validate margin values from dialog entries.
-
- Values returned in [cm].
-
- """
- paper_margins = [unicode(margin.get_text()) for margin in
- self.lmargin, self.rmargin, self.tmargin, self.bmargin]
-
- for i, margin in enumerate(paper_margins):
- try:
- paper_margins[i] = float(margin.replace(",", "."))
- paper_margins[i] = paper_margins[i] * self.paper_unit_multiplier
- paper_margins[i] = max(paper_margins[i], 0)
- except:
- paper_margins[i] = 2.54
-
- return paper_margins
-
- def get_custom_paper_size(self):
- width = float(self.pwidth.get_text().replace(",", ".")) * \
- self.paper_unit_multiplier
- height = float(self.pheight.get_text().replace(",", ".")) * \
- self.paper_unit_multiplier
-
- paper_size = [max(width, 1.0), max(height, 1.0)]
-
- return paper_size
-
- def get_paper_style(self):
- paper_size, paper_name = self.get_paper_size()
- paper_orientation = self.orientation_menu.get_value()
- paper_margins = self.get_paper_margins()
-
- pstyle = PaperStyle(paper_size,
- paper_orientation,
- *paper_margins)
- return pstyle
-
- def get_paper_metric(self):
- return self.metric.get_active()
-
- def get_paper_name(self):
- paper_size, paper_name = self.get_paper_size()
- return paper_name
-
- def get_orientation(self):
- return self.orientation_menu.get_value()
diff --git a/src/gui/plug/report/_reportdialog.py b/src/gui/plug/report/_reportdialog.py
index 9754a8bcd..ed05d2e4a 100644
--- a/src/gui/plug/report/_reportdialog.py
+++ b/src/gui/plug/report/_reportdialog.py
@@ -647,1301 +647,3 @@ def report(dbstate, uistate, person, report_class, options_class,
#just stop, in ManagedWindow, delete-event is already coupled to
#correct action.
break
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2008 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-import os
-from types import ClassType
-from gen.ggettext import gettext as _
-
-import logging
-LOG = logging.getLogger(".")
-
-#-------------------------------------------------------------------------
-#
-# GTK+ modules
-#
-#-------------------------------------------------------------------------
-import gtk
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-import config
-import Errors
-from QuestionDialog import ErrorDialog, OptionDialog
-from gen.plug.report import (CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK,
- CATEGORY_CODE, CATEGORY_WEB, CATEGORY_GRAPHVIZ,
- standalone_categories)
-from gen.plug.docgen import StyleSheet, StyleSheetList
-import ManagedWindow
-from _stylecombobox import StyleComboBox
-from _styleeditor import StyleListDisplay
-from _fileentry import FileEntry
-from const import URL_MANUAL_PAGE
-
-#-------------------------------------------------------------------------
-#
-# Private Constants
-#
-#-------------------------------------------------------------------------
-URL_REPORT_PAGE = URL_MANUAL_PAGE + "_-_Reports"
-
-#-------------------------------------------------------------------------
-#
-# ReportDialog class
-#
-#-------------------------------------------------------------------------
-class ReportDialog(ManagedWindow.ManagedWindow):
- """
- 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.
- """
- border_pad = 6
-
- def __init__(self, dbstate, uistate, option_class, name, trans_name,
- track=[]):
- """Initialize a dialog to request that the user select options
- for a basic *stand-alone* report."""
-
- self.style_name = "default"
- self.firstpage_added = False
- self.raw_name = name
- self.dbstate = dbstate
- self.db = dbstate.db
- self.report_name = trans_name
-
- ManagedWindow.ManagedWindow.__init__(self, uistate, track, self)
-
- self.init_options(option_class)
- self.init_interface()
-
- def init_options(self, option_class):
- try:
- if (issubclass(option_class, object) or # New-style class
- isinstance(option_class, ClassType)): # Old-style class
- self.options = option_class(self.raw_name, self.db)
- except TypeError:
- self.options = option_class
-
- self.options.load_previous_values()
-
- def build_window_key(self, obj):
- key = self.raw_name
- return key
-
- def build_menu_names(self, obj):
- return (_("Configuration"), self.report_name)
-
- def init_interface(self):
- self.widgets = []
- self.frame_names = []
- self.frames = {}
- self.format_menu = None
- self.style_button = None
-
- self.style_name = self.options.handler.get_default_stylesheet_name()
-
- window = gtk.Dialog('Gramps')
- self.set_window(window, None, self.get_title())
- self.window.set_has_separator(False)
- self.window.set_modal(True)
-
- self.help = self.window.add_button(gtk.STOCK_HELP, gtk.RESPONSE_HELP)
- self.help.connect('clicked', self.on_help_clicked)
-
- self.cancel = self.window.add_button(gtk.STOCK_CANCEL,
- gtk.RESPONSE_CANCEL)
- self.cancel.connect('clicked', self.on_cancel)
-
- self.ok = self.window.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
- self.ok.connect('clicked', self.on_ok_clicked)
-
- self.window.set_default_size(600, -1)
-
- # Set up and run the dialog. These calls are not in top down
- # order when looking at the dialog box as there is some
- # interaction between the various frames.
-
- self.setup_title()
- self.setup_header()
- self.tbl = gtk.Table(4, 4, False)
- self.tbl.set_col_spacings(12)
- self.tbl.set_row_spacings(6)
- self.tbl.set_border_width(6)
- self.row = 0
-
- # Build the list of widgets that are used to extend the Options
- # frame and to create other frames
- self.add_user_options()
-
- self.setup_main_options()
- self.setup_init()
- self.setup_format_frame()
- self.setup_target_frame()
- self.setup_style_frame()
-
- self.notebook = gtk.Notebook()
- self.notebook.set_scrollable(True)
- self.notebook.set_border_width(6)
- self.window.vbox.add(self.notebook)
-
- self.setup_report_options_frame()
- self.setup_other_frames()
- self.notebook.set_current_page(0)
-
- self.window.vbox.add(self.tbl)
- self.show()
-
- def get_title(self):
- """The window title for this dialog"""
- name = self.report_name
- category = standalone_categories[self.category]
- return "%s - %s - Gramps" % (name, category)
-
- #------------------------------------------------------------------------
- #
- # Functions related to extending the options
- #
- #------------------------------------------------------------------------
- def add_user_options(self):
- """Called to allow subclasses add widgets to the dialog form.
- It is called immediately before the window is displayed. All
- calls to add_option or add_frame_option should be called in
- this task."""
- self.options.add_user_options(self)
-
- def parse_user_options(self):
- """Called to allow parsing of added widgets.
- It is called when OK is pressed in a dialog.
- All custom widgets should provide a parsing code here."""
- try:
- self.options.parse_user_options(self)
- except:
- LOG.error("Failed to parse user options.", exc_info=True)
-
- def add_option(self, label_text, widget):
- """Takes a text string and a Gtk Widget, and stores them to be
- appended to the Options section of the dialog. The text string
- is used to create a label for the passed widget. This allows the
- subclass to extend the Options section with its own widgets. The
- subclass is responsible for all managing of the widgets, including
- extracting the final value before the report executes. This task
- should only be called in the add_user_options task."""
- self.widgets.append((label_text, widget))
-
- def add_frame_option(self, frame_name, label_text, widget):
- """Similar to add_option this method takes a frame_name, a
- text string and a Gtk Widget. When the interface is built,
- all widgets with the same frame_name are grouped into a
- GtkFrame. This allows the subclass to create its own sections,
- filling them with its own widgets. The subclass is responsible for
- all managing of the widgets, including extracting the final value
- before the report executes. This task should only be called in
- the add_user_options task."""
-
- if frame_name in self.frames:
- self.frames[frame_name].append((label_text, widget))
- else:
- self.frames[frame_name] = [(label_text, widget)]
- self.frame_names.append(frame_name)
-
- #------------------------------------------------------------------------
- #
- # Functions to create a default output style.
- #
- #------------------------------------------------------------------------
-
- def build_style_menu(self, default=None):
- """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."""
-
- if default is None:
- default = self.style_name
-
- style_sheet_map = self.style_sheet_list.get_style_sheet_map()
- self.style_menu.set(style_sheet_map, default)
-
- #------------------------------------------------------------------------
- #
- # Functions related to setting up the dialog window.
- #
- #------------------------------------------------------------------------
- def setup_title(self):
- """Set up the title bar of the dialog. This function relies
- on the get_title() customization function for what the title
- should be."""
- self.window.set_title(self.get_title())
-
- def setup_header(self):
- """Set up the header line bar of the dialog."""
- label = gtk.Label('%s' %
- self.report_name)
- label.set_use_markup(True)
- self.window.vbox.pack_start(label, True, True, self.border_pad)
-
- 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."""
- # Build the default style set for this report.
- self.default_style = StyleSheet()
- self.options.make_default_style(self.default_style)
-
- if self.default_style.is_empty():
- # Don't display the option of no styles are used
- return
-
- # Styles Frame
- label = gtk.Label("%s:" % _("Style"))
- label.set_alignment(0.0, 0.5)
-
- self.style_menu = StyleComboBox()
- 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.row, self.row+1, gtk.SHRINK|gtk.FILL)
- self.tbl.attach(self.style_menu, 2, 3, self.row, self.row+1,
- yoptions=gtk.SHRINK)
- self.tbl.attach(self.style_button, 3, 4, self.row, self.row+1,
- xoptions=gtk.SHRINK|gtk.FILL, yoptions=gtk.SHRINK)
- self.row += 1
-
- # 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 = StyleSheetList(
- self.options.handler.get_stylesheet_savefile(),
- self.default_style)
-
- # Now build the actual menu.
- style = self.options.handler.get_default_stylesheet_name()
- self.build_style_menu(style)
-
- def setup_report_options_frame(self):
- """Set up the report options frame of the dialog. This
- function relies on several report_xxx() customization
- functions to determine which of the items should be present in
- this box. *All* of these items are optional, although the
- generations fields is used in most
- (but not all) dialog boxes."""
-
- row = 0
- max_rows = len(self.widgets)
-
- if max_rows == 0:
- return
-
- table = gtk.Table(3, max_rows+1)
- table.set_col_spacings(12)
- table.set_row_spacings(6)
-
- label = gtk.Label("%s" % _("Report Options"))
- label.set_alignment(0.0, 0.5)
- label.set_use_markup(True)
-
- table.set_border_width(6)
- self.notebook.append_page(table, label)
- row += 1
-
- # Setup requested widgets
- for (text, widget) in self.widgets:
- if text:
- text_widget = gtk.Label("%s:" % text)
- text_widget.set_alignment(0.0, 0.0)
- table.attach(text_widget, 1, 2, row, row+1,
- gtk.SHRINK|gtk.FILL, gtk.SHRINK)
- table.attach(widget, 2, 3, row, row+1,
- yoptions=gtk.SHRINK)
- else:
- table.attach(widget, 2, 3, row, row+1,
- yoptions=gtk.SHRINK)
- row += 1
-
- def setup_other_frames(self):
- for key in self.frame_names:
- if key == "":
- continue
- flist = self.frames[key]
- table = gtk.Table(3, len(flist))
- table.set_col_spacings(12)
- table.set_row_spacings(6)
- table.set_border_width(6)
- l = gtk.Label("%s" % _(key))
- l.set_use_markup(True)
- self.notebook.append_page(table, l)
-
- row = 0
- for (text, widget) in flist:
- if text:
- text_widget = gtk.Label('%s:' % text)
- text_widget.set_alignment(0.0, 0.5)
- table.attach(text_widget, 1, 2, row, row+1,
- gtk.SHRINK|gtk.FILL, gtk.SHRINK)
- table.attach(widget, 2, 3, row, row+1,
- yoptions=gtk.SHRINK)
- else:
- table.attach(widget, 2, 3, row, row+1,
- yoptions=gtk.SHRINK)
- row += 1
-
- def setup_main_options(self):
- if "" in self.frames:
- flist = self.frames[""]
- for (text, widget) in flist:
- label = gtk.Label("%s" % text)
- label.set_use_markup(True)
- label.set_alignment(0.0, 0.5)
-
- self.tbl.set_border_width(12)
- self.tbl.attach(label, 0, 4, self.row, self.row+1)
- self.row += 1
-
- self.tbl.attach(widget, 2, 4, self.row, self.row+1)
- self.row += 1
-
- #------------------------------------------------------------------------
- #
- # Customization hooks for stand-alone reports (subclass ReportDialog)
- #
- #------------------------------------------------------------------------
- def setup_format_frame(self):
- """Not used in bare report dialogs. Override in the subclass."""
- pass
-
- #------------------------------------------------------------------------
- #
- # 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 config.get('paths.report-directory')
-
- 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."""
- config.set('paths.report-directory', value)
-
- #------------------------------------------------------------------------
- #
- # Functions related to setting up the dialog window.
- #
- #------------------------------------------------------------------------
- def setup_init(self):
- # add any elements that we are going to need:
- hid = self.style_name
- if hid[-4:] == ".xml":
- hid = hid[0:-4]
- self.target_fileentry = FileEntry(hid, _("Save As"))
- spath = self.get_default_directory()
- self.target_fileentry.set_filename(spath)
- # need any labels at top:
- 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.row, self.row+1, gtk.FILL)
- self.row += 1
-
- 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
- self.doc_label = gtk.Label("%s:" % _("Filename"))
- self.doc_label.set_alignment(0.0, 0.5)
-
- self.tbl.attach(self.doc_label, 1, 2, self.row, self.row+1,
- xoptions=gtk.SHRINK|gtk.FILL,yoptions=gtk.SHRINK)
- self.tbl.attach(self.target_fileentry, 2, 4, self.row, self.row+1,
- xoptions=gtk.EXPAND|gtk.FILL,yoptions=gtk.SHRINK)
- self.row += 1
-
- #------------------------------------------------------------------------
- #
- # Functions related to retrieving data from the dialog window
- #
- #------------------------------------------------------------------------
- def parse_target_frame(self):
- """Parse the target frame of the dialog. If the target
- filename is empty this routine returns a special value of None
- to tell the calling routine to give up. This function also
- saves the current directory so that any future reports will
- default to the most recently used directory."""
- self.target_path = self.target_fileentry.get_full_path(0)
- if not self.target_path:
- return None
-
- # First we check whether the selected path exists
- if os.path.exists(self.target_path):
-
- # selected path is an existing dir and we need a dir
- if os.path.isdir(self.target_path):
-
- # check whether the dir has rwx permissions
- if not os.access(self.target_path, os.R_OK|os.W_OK|os.X_OK):
- ErrorDialog(_('Permission problem'),
- _("You do not have permission to write "
- "under the directory %s\n\n"
- "Please select another directory or correct "
- "the permissions.") % self.target_path
- )
- return None
-
- # selected path is an existing file and we need a file
- if os.path.isfile(self.target_path):
- a = OptionDialog(_('File already exists'),
- _('You can choose to either overwrite the '
- 'file, or change the selected filename.'),
- _('_Overwrite'), None,
- _('_Change filename'), None)
-
- if a.get_response() == gtk.RESPONSE_YES:
- return None
-
- # selected path does not exist yet
- else:
- # we will need to create the file/dir
- # need to make sure we can create in the parent dir
- parent_dir = os.path.dirname(os.path.normpath(self.target_path))
- if not os.access(parent_dir, os.W_OK):
- ErrorDialog(_('Permission problem'),
- _("You do not have permission to create "
- "%s\n\n"
- "Please select another path or correct "
- "the permissions.") % self.target_path
- )
- return None
-
- self.set_default_directory(os.path.dirname(self.target_path) + os.sep)
- self.options.handler.output = self.target_path
- return 1
-
- def parse_style_frame(self):
- """Parse the style frame of the dialog. Save the user
- selected output style for later use. Note that this routine
- retrieves a value whether or not the menu is displayed on the
- screen. The subclass will know whether this menu was enabled.
- This is for simplicity of programming."""
- if not self.default_style.is_empty():
- (style_name, self.selected_style) = self.style_menu.get_value()
- self.options.handler.set_default_stylesheet_name(style_name)
-
- #------------------------------------------------------------------------
- #
- # Callback functions from the dialog
- #
- #------------------------------------------------------------------------
- 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():
- self.window.run()
-
- # Preparation
- self.parse_style_frame()
- self.parse_user_options()
-
- # Save options
- self.options.handler.save_options()
-
- def on_cancel(self, *obj):
- pass
-
- def on_help_clicked(self, *obj):
- import GrampsDisplay
- GrampsDisplay.help(URL_REPORT_PAGE, self.report_name.replace(" ", "_"))
-
- def on_style_edit_clicked(self, *obj):
- """The user has clicked on the 'Edit Styles' button. Create a
- style sheet editor object and let them play. When they are
- done, the previous routine will be called to update the dialog
- menu for selecting a style."""
- StyleListDisplay(self.style_sheet_list, self.build_style_menu,
- self.window)
-
-#------------------------------------------------------------------------
-#
-# Generic task function a standalone GUI report
-#
-#------------------------------------------------------------------------
-def report(dbstate, uistate, person, report_class, options_class,
- trans_name, name, category, require_active):
- """
- report - task starts the report. The plugin system requires that the
- task be in the format of task that takes a database and a person as
- its arguments.
- """
-
- if require_active and not person:
- ErrorDialog(
- _('Active person has not been set'),
- _('You must select an active person for this report to work '
- 'properly.'))
- return
-
- if category == CATEGORY_TEXT:
- from _textreportdialog import TextReportDialog
- dialog_class = TextReportDialog
- elif category == CATEGORY_DRAW:
- from _drawreportdialog import DrawReportDialog
- dialog_class = DrawReportDialog
- elif category == CATEGORY_GRAPHVIZ:
- from _graphvizreportdialog import GraphvizReportDialog
- dialog_class = GraphvizReportDialog
- elif category == CATEGORY_WEB:
- from _webreportdialog import WebReportDialog
- dialog_class = WebReportDialog
- elif category in (CATEGORY_BOOK, CATEGORY_CODE):
- try:
- report_class(dbstate, uistate)
- except Errors.WindowActiveError:
- pass
- return
- else:
- dialog_class = ReportDialog
-
- dialog = dialog_class(dbstate, uistate, options_class, name, trans_name)
-
- while True:
- response = dialog.window.run()
- if response == gtk.RESPONSE_OK:
- dialog.close()
- try:
- MyReport = report_class(dialog.db, dialog.options)
- MyReport.doc.init()
- MyReport.begin_report()
- MyReport.write_report()
- MyReport.end_report()
- except Errors.FilterError, msg:
- (m1, m2) = msg.messages()
- ErrorDialog(m1, m2)
- except IOError, msg:
- ErrorDialog(_("Report could not be created"), str(msg))
- except Errors.ReportError, msg:
- (m1, m2) = msg.messages()
- ErrorDialog(m1, m2)
- except Errors.DatabaseError,msg:
- ErrorDialog(_("Report could not be created"), str(msg))
-# The following except statement will catch all "NoneType" exceptions.
-# This is useful for released code where the exception is most likely
-# a corrupt database. But it is less useful for developing new reports
-# where the exception is most likely a report bug.
-# except AttributeError,msg:
-# if str(msg).startswith("'NoneType' object has no attribute"):
-# # "'NoneType' object has no attribute ..." usually means
-# # database corruption
-# RunDatabaseRepair(str(msg))
-# else:
-# raise
- raise
- except:
- LOG.error("Failed to run report.", exc_info=True)
- break
- elif response == gtk.RESPONSE_CANCEL:
- dialog.close()
- break
- elif response == gtk.RESPONSE_DELETE_EVENT:
- #just stop, in ManagedWindow, delete-event is already coupled to
- #correct action.
- break
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2008 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-import os
-from types import ClassType
-from gen.ggettext import gettext as _
-
-import logging
-LOG = logging.getLogger(".")
-
-#-------------------------------------------------------------------------
-#
-# GTK+ modules
-#
-#-------------------------------------------------------------------------
-import gtk
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-import config
-import Errors
-from QuestionDialog import ErrorDialog, OptionDialog
-from gen.plug.report import (CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK,
- CATEGORY_CODE, CATEGORY_WEB, CATEGORY_GRAPHVIZ,
- standalone_categories)
-from gen.plug.docgen import StyleSheet, StyleSheetList
-import ManagedWindow
-from _stylecombobox import StyleComboBox
-from _styleeditor import StyleListDisplay
-from _fileentry import FileEntry
-from const import URL_MANUAL_PAGE
-
-#-------------------------------------------------------------------------
-#
-# Private Constants
-#
-#-------------------------------------------------------------------------
-URL_REPORT_PAGE = URL_MANUAL_PAGE + "_-_Reports"
-
-#-------------------------------------------------------------------------
-#
-# ReportDialog class
-#
-#-------------------------------------------------------------------------
-class ReportDialog(ManagedWindow.ManagedWindow):
- """
- 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.
- """
- border_pad = 6
-
- def __init__(self, dbstate, uistate, option_class, name, trans_name,
- track=[]):
- """Initialize a dialog to request that the user select options
- for a basic *stand-alone* report."""
-
- self.style_name = "default"
- self.firstpage_added = False
- self.raw_name = name
- self.dbstate = dbstate
- self.db = dbstate.db
- self.report_name = trans_name
-
- ManagedWindow.ManagedWindow.__init__(self, uistate, track, self)
-
- self.init_options(option_class)
- self.init_interface()
-
- def init_options(self, option_class):
- try:
- if (issubclass(option_class, object) or # New-style class
- isinstance(option_class, ClassType)): # Old-style class
- self.options = option_class(self.raw_name, self.db)
- except TypeError:
- self.options = option_class
-
- self.options.load_previous_values()
-
- def build_window_key(self, obj):
- key = self.raw_name
- return key
-
- def build_menu_names(self, obj):
- return (_("Configuration"), self.report_name)
-
- def init_interface(self):
- self.widgets = []
- self.frame_names = []
- self.frames = {}
- self.format_menu = None
- self.style_button = None
-
- self.style_name = self.options.handler.get_default_stylesheet_name()
-
- window = gtk.Dialog('Gramps')
- self.set_window(window, None, self.get_title())
- self.window.set_has_separator(False)
- self.window.set_modal(True)
-
- self.help = self.window.add_button(gtk.STOCK_HELP, gtk.RESPONSE_HELP)
- self.help.connect('clicked', self.on_help_clicked)
-
- self.cancel = self.window.add_button(gtk.STOCK_CANCEL,
- gtk.RESPONSE_CANCEL)
- self.cancel.connect('clicked', self.on_cancel)
-
- self.ok = self.window.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
- self.ok.connect('clicked', self.on_ok_clicked)
-
- self.window.set_default_size(600, -1)
-
- # Set up and run the dialog. These calls are not in top down
- # order when looking at the dialog box as there is some
- # interaction between the various frames.
-
- self.setup_title()
- self.setup_header()
- self.tbl = gtk.Table(4, 4, False)
- self.tbl.set_col_spacings(12)
- self.tbl.set_row_spacings(6)
- self.tbl.set_border_width(6)
- self.row = 0
-
- # Build the list of widgets that are used to extend the Options
- # frame and to create other frames
- self.add_user_options()
-
- self.setup_main_options()
- self.setup_init()
- self.setup_format_frame()
- self.setup_target_frame()
- self.setup_style_frame()
-
- self.notebook = gtk.Notebook()
- self.notebook.set_scrollable(True)
- self.notebook.set_border_width(6)
- self.window.vbox.add(self.notebook)
-
- self.setup_report_options_frame()
- self.setup_other_frames()
- self.notebook.set_current_page(0)
-
- self.window.vbox.add(self.tbl)
- self.show()
-
- def get_title(self):
- """The window title for this dialog"""
- name = self.report_name
- category = standalone_categories[self.category]
- return "%s - %s - Gramps" % (name, category)
-
- #------------------------------------------------------------------------
- #
- # Functions related to extending the options
- #
- #------------------------------------------------------------------------
- def add_user_options(self):
- """Called to allow subclasses add widgets to the dialog form.
- It is called immediately before the window is displayed. All
- calls to add_option or add_frame_option should be called in
- this task."""
- self.options.add_user_options(self)
-
- def parse_user_options(self):
- """Called to allow parsing of added widgets.
- It is called when OK is pressed in a dialog.
- All custom widgets should provide a parsing code here."""
- try:
- self.options.parse_user_options(self)
- except:
- LOG.error("Failed to parse user options.", exc_info=True)
-
- def add_option(self, label_text, widget):
- """Takes a text string and a Gtk Widget, and stores them to be
- appended to the Options section of the dialog. The text string
- is used to create a label for the passed widget. This allows the
- subclass to extend the Options section with its own widgets. The
- subclass is responsible for all managing of the widgets, including
- extracting the final value before the report executes. This task
- should only be called in the add_user_options task."""
- self.widgets.append((label_text, widget))
-
- def add_frame_option(self, frame_name, label_text, widget):
- """Similar to add_option this method takes a frame_name, a
- text string and a Gtk Widget. When the interface is built,
- all widgets with the same frame_name are grouped into a
- GtkFrame. This allows the subclass to create its own sections,
- filling them with its own widgets. The subclass is responsible for
- all managing of the widgets, including extracting the final value
- before the report executes. This task should only be called in
- the add_user_options task."""
-
- if frame_name in self.frames:
- self.frames[frame_name].append((label_text, widget))
- else:
- self.frames[frame_name] = [(label_text, widget)]
- self.frame_names.append(frame_name)
-
- #------------------------------------------------------------------------
- #
- # Functions to create a default output style.
- #
- #------------------------------------------------------------------------
-
- def build_style_menu(self, default=None):
- """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."""
-
- if default is None:
- default = self.style_name
-
- style_sheet_map = self.style_sheet_list.get_style_sheet_map()
- self.style_menu.set(style_sheet_map, default)
-
- #------------------------------------------------------------------------
- #
- # Functions related to setting up the dialog window.
- #
- #------------------------------------------------------------------------
- def setup_title(self):
- """Set up the title bar of the dialog. This function relies
- on the get_title() customization function for what the title
- should be."""
- self.window.set_title(self.get_title())
-
- def setup_header(self):
- """Set up the header line bar of the dialog."""
- label = gtk.Label('%s' %
- self.report_name)
- label.set_use_markup(True)
- self.window.vbox.pack_start(label, True, True, self.border_pad)
-
- 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."""
- # Build the default style set for this report.
- self.default_style = StyleSheet()
- self.options.make_default_style(self.default_style)
-
- if self.default_style.is_empty():
- # Don't display the option of no styles are used
- return
-
- # Styles Frame
- label = gtk.Label("%s:" % _("Style"))
- label.set_alignment(0.0, 0.5)
-
- self.style_menu = StyleComboBox()
- 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.row, self.row+1, gtk.SHRINK|gtk.FILL)
- self.tbl.attach(self.style_menu, 2, 3, self.row, self.row+1,
- yoptions=gtk.SHRINK)
- self.tbl.attach(self.style_button, 3, 4, self.row, self.row+1,
- xoptions=gtk.SHRINK|gtk.FILL, yoptions=gtk.SHRINK)
- self.row += 1
-
- # 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 = StyleSheetList(
- self.options.handler.get_stylesheet_savefile(),
- self.default_style)
-
- # Now build the actual menu.
- style = self.options.handler.get_default_stylesheet_name()
- self.build_style_menu(style)
-
- def setup_report_options_frame(self):
- """Set up the report options frame of the dialog. This
- function relies on several report_xxx() customization
- functions to determine which of the items should be present in
- this box. *All* of these items are optional, although the
- generations fields is used in most
- (but not all) dialog boxes."""
-
- row = 0
- max_rows = len(self.widgets)
-
- if max_rows == 0:
- return
-
- table = gtk.Table(3, max_rows+1)
- table.set_col_spacings(12)
- table.set_row_spacings(6)
-
- label = gtk.Label("%s" % _("Report Options"))
- label.set_alignment(0.0, 0.5)
- label.set_use_markup(True)
-
- table.set_border_width(6)
- self.notebook.append_page(table, label)
- row += 1
-
- # Setup requested widgets
- for (text, widget) in self.widgets:
- if text:
- text_widget = gtk.Label("%s:" % text)
- text_widget.set_alignment(0.0, 0.0)
- table.attach(text_widget, 1, 2, row, row+1,
- gtk.SHRINK|gtk.FILL, gtk.SHRINK)
- table.attach(widget, 2, 3, row, row+1,
- yoptions=gtk.SHRINK)
- else:
- table.attach(widget, 2, 3, row, row+1,
- yoptions=gtk.SHRINK)
- row += 1
-
- def setup_other_frames(self):
- for key in self.frame_names:
- if key == "":
- continue
- flist = self.frames[key]
- table = gtk.Table(3, len(flist))
- table.set_col_spacings(12)
- table.set_row_spacings(6)
- table.set_border_width(6)
- l = gtk.Label("%s" % _(key))
- l.set_use_markup(True)
- self.notebook.append_page(table, l)
-
- row = 0
- for (text, widget) in flist:
- if text:
- text_widget = gtk.Label('%s:' % text)
- text_widget.set_alignment(0.0, 0.5)
- table.attach(text_widget, 1, 2, row, row+1,
- gtk.SHRINK|gtk.FILL, gtk.SHRINK)
- table.attach(widget, 2, 3, row, row+1,
- yoptions=gtk.SHRINK)
- else:
- table.attach(widget, 2, 3, row, row+1,
- yoptions=gtk.SHRINK)
- row += 1
-
- def setup_main_options(self):
- if "" in self.frames:
- flist = self.frames[""]
- for (text, widget) in flist:
- label = gtk.Label("%s" % text)
- label.set_use_markup(True)
- label.set_alignment(0.0, 0.5)
-
- self.tbl.set_border_width(12)
- self.tbl.attach(label, 0, 4, self.row, self.row+1)
- self.row += 1
-
- self.tbl.attach(widget, 2, 4, self.row, self.row+1)
- self.row += 1
-
- #------------------------------------------------------------------------
- #
- # Customization hooks for stand-alone reports (subclass ReportDialog)
- #
- #------------------------------------------------------------------------
- def setup_format_frame(self):
- """Not used in bare report dialogs. Override in the subclass."""
- pass
-
- #------------------------------------------------------------------------
- #
- # 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 config.get('paths.report-directory')
-
- 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."""
- config.set('paths.report-directory', value)
-
- #------------------------------------------------------------------------
- #
- # Functions related to setting up the dialog window.
- #
- #------------------------------------------------------------------------
- def setup_init(self):
- # add any elements that we are going to need:
- hid = self.style_name
- if hid[-4:] == ".xml":
- hid = hid[0:-4]
- self.target_fileentry = FileEntry(hid, _("Save As"))
- spath = self.get_default_directory()
- self.target_fileentry.set_filename(spath)
- # need any labels at top:
- 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.row, self.row+1, gtk.FILL)
- self.row += 1
-
- 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
- self.doc_label = gtk.Label("%s:" % _("Filename"))
- self.doc_label.set_alignment(0.0, 0.5)
-
- self.tbl.attach(self.doc_label, 1, 2, self.row, self.row+1,
- xoptions=gtk.SHRINK|gtk.FILL,yoptions=gtk.SHRINK)
- self.tbl.attach(self.target_fileentry, 2, 4, self.row, self.row+1,
- xoptions=gtk.EXPAND|gtk.FILL,yoptions=gtk.SHRINK)
- self.row += 1
-
- #------------------------------------------------------------------------
- #
- # Functions related to retrieving data from the dialog window
- #
- #------------------------------------------------------------------------
- def parse_target_frame(self):
- """Parse the target frame of the dialog. If the target
- filename is empty this routine returns a special value of None
- to tell the calling routine to give up. This function also
- saves the current directory so that any future reports will
- default to the most recently used directory."""
- self.target_path = self.target_fileentry.get_full_path(0)
- if not self.target_path:
- return None
-
- # First we check whether the selected path exists
- if os.path.exists(self.target_path):
-
- # selected path is an existing dir and we need a dir
- if os.path.isdir(self.target_path):
-
- # check whether the dir has rwx permissions
- if not os.access(self.target_path, os.R_OK|os.W_OK|os.X_OK):
- ErrorDialog(_('Permission problem'),
- _("You do not have permission to write "
- "under the directory %s\n\n"
- "Please select another directory or correct "
- "the permissions.") % self.target_path
- )
- return None
-
- # selected path is an existing file and we need a file
- if os.path.isfile(self.target_path):
- a = OptionDialog(_('File already exists'),
- _('You can choose to either overwrite the '
- 'file, or change the selected filename.'),
- _('_Overwrite'), None,
- _('_Change filename'), None)
-
- if a.get_response() == gtk.RESPONSE_YES:
- return None
-
- # selected path does not exist yet
- else:
- # we will need to create the file/dir
- # need to make sure we can create in the parent dir
- parent_dir = os.path.dirname(os.path.normpath(self.target_path))
- if not os.access(parent_dir, os.W_OK):
- ErrorDialog(_('Permission problem'),
- _("You do not have permission to create "
- "%s\n\n"
- "Please select another path or correct "
- "the permissions.") % self.target_path
- )
- return None
-
- self.set_default_directory(os.path.dirname(self.target_path) + os.sep)
- self.options.handler.output = self.target_path
- return 1
-
- def parse_style_frame(self):
- """Parse the style frame of the dialog. Save the user
- selected output style for later use. Note that this routine
- retrieves a value whether or not the menu is displayed on the
- screen. The subclass will know whether this menu was enabled.
- This is for simplicity of programming."""
- if not self.default_style.is_empty():
- (style_name, self.selected_style) = self.style_menu.get_value()
- self.options.handler.set_default_stylesheet_name(style_name)
-
- #------------------------------------------------------------------------
- #
- # Callback functions from the dialog
- #
- #------------------------------------------------------------------------
- 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():
- self.window.run()
-
- # Preparation
- self.parse_style_frame()
- self.parse_user_options()
-
- # Save options
- self.options.handler.save_options()
-
- def on_cancel(self, *obj):
- pass
-
- def on_help_clicked(self, *obj):
- import GrampsDisplay
- GrampsDisplay.help(URL_REPORT_PAGE, self.report_name.replace(" ", "_"))
-
- def on_style_edit_clicked(self, *obj):
- """The user has clicked on the 'Edit Styles' button. Create a
- style sheet editor object and let them play. When they are
- done, the previous routine will be called to update the dialog
- menu for selecting a style."""
- StyleListDisplay(self.style_sheet_list, self.build_style_menu,
- self.window)
-
-#------------------------------------------------------------------------
-#
-# Generic task function a standalone GUI report
-#
-#------------------------------------------------------------------------
-def report(dbstate, uistate, person, report_class, options_class,
- trans_name, name, category, require_active):
- """
- report - task starts the report. The plugin system requires that the
- task be in the format of task that takes a database and a person as
- its arguments.
- """
-
- if require_active and not person:
- ErrorDialog(
- _('Active person has not been set'),
- _('You must select an active person for this report to work '
- 'properly.'))
- return
-
- if category == CATEGORY_TEXT:
- from _textreportdialog import TextReportDialog
- dialog_class = TextReportDialog
- elif category == CATEGORY_DRAW:
- from _drawreportdialog import DrawReportDialog
- dialog_class = DrawReportDialog
- elif category == CATEGORY_GRAPHVIZ:
- from _graphvizreportdialog import GraphvizReportDialog
- dialog_class = GraphvizReportDialog
- elif category == CATEGORY_WEB:
- from _webreportdialog import WebReportDialog
- dialog_class = WebReportDialog
- elif category in (CATEGORY_BOOK, CATEGORY_CODE):
- try:
- report_class(dbstate, uistate)
- except Errors.WindowActiveError:
- pass
- return
- else:
- dialog_class = ReportDialog
-
- dialog = dialog_class(dbstate, uistate, options_class, name, trans_name)
-
- while True:
- response = dialog.window.run()
- if response == gtk.RESPONSE_OK:
- dialog.close()
- try:
- MyReport = report_class(dialog.db, dialog.options)
- MyReport.doc.init()
- MyReport.begin_report()
- MyReport.write_report()
- MyReport.end_report()
- except Errors.FilterError, msg:
- (m1, m2) = msg.messages()
- ErrorDialog(m1, m2)
- except IOError, msg:
- ErrorDialog(_("Report could not be created"), str(msg))
- except Errors.ReportError, msg:
- (m1, m2) = msg.messages()
- ErrorDialog(m1, m2)
- except Errors.DatabaseError,msg:
- ErrorDialog(_("Report could not be created"), str(msg))
-# The following except statement will catch all "NoneType" exceptions.
-# This is useful for released code where the exception is most likely
-# a corrupt database. But it is less useful for developing new reports
-# where the exception is most likely a report bug.
-# except AttributeError,msg:
-# if str(msg).startswith("'NoneType' object has no attribute"):
-# # "'NoneType' object has no attribute ..." usually means
-# # database corruption
-# RunDatabaseRepair(str(msg))
-# else:
-# raise
- raise
- except:
- LOG.error("Failed to run report.", exc_info=True)
- break
- elif response == gtk.RESPONSE_CANCEL:
- dialog.close()
- break
- elif response == gtk.RESPONSE_DELETE_EVENT:
- #just stop, in ManagedWindow, delete-event is already coupled to
- #correct action.
- break
diff --git a/src/gui/plug/report/_stylecombobox.py b/src/gui/plug/report/_stylecombobox.py
index e5a3ad292..b19a1ad13 100644
--- a/src/gui/plug/report/_stylecombobox.py
+++ b/src/gui/plug/report/_stylecombobox.py
@@ -26,180 +26,6 @@ from gen.ggettext import gettext as _
import gtk
import gobject
-#-------------------------------------------------------------------------
-#
-# StyleComboBox
-#
-#-------------------------------------------------------------------------
-class StyleComboBox(gtk.ComboBox):
- """
- Derived from the ComboBox, this widget provides handling of Report
- Styles.
- """
-
- def __init__(self,model=None):
- """
- Initialize the combobox, building the display column.
- """
- gtk.ComboBox.__init__(self,model)
- cell = gtk.CellRendererText()
- self.pack_start(cell,True)
- self.add_attribute(cell,'text',0)
-
- def set(self,style_map,default):
- """
- Set the options for the ComboBox, using the passed style
- map as the data.
-
- @param style_map: dictionary of style names and the corresponding
- style sheet
- @type style_map: dictionary
- @param default: Default selection in the ComboBox
- @type default: str
- """
- self.store = gtk.ListStore(gobject.TYPE_STRING)
- self.set_model(self.store)
- self.style_map = style_map
- start_index = 0
- for index, key in enumerate(sorted(style_map)):
- if key == "default":
- self.store.append(row=[_('default')])
- else:
- self.store.append(row=[key])
- if key == default:
- start_index = index
-
- self.set_active(start_index)
-
- def get_value(self):
- """
- Return the selected key (style sheet name).
-
- @returns: Returns the name of the selected style sheet
- @rtype: str
- """
- active = self.get_active()
- if active < 0:
- return None
- key = unicode(self.store[active][0])
- if key == _('default'):
- key = "default"
- return (key,self.style_map[key])
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-from gen.ggettext import gettext as _
-
-import gtk
-import gobject
-
-#-------------------------------------------------------------------------
-#
-# StyleComboBox
-#
-#-------------------------------------------------------------------------
-class StyleComboBox(gtk.ComboBox):
- """
- Derived from the ComboBox, this widget provides handling of Report
- Styles.
- """
-
- def __init__(self,model=None):
- """
- Initialize the combobox, building the display column.
- """
- gtk.ComboBox.__init__(self,model)
- cell = gtk.CellRendererText()
- self.pack_start(cell,True)
- self.add_attribute(cell,'text',0)
-
- def set(self,style_map,default):
- """
- Set the options for the ComboBox, using the passed style
- map as the data.
-
- @param style_map: dictionary of style names and the corresponding
- style sheet
- @type style_map: dictionary
- @param default: Default selection in the ComboBox
- @type default: str
- """
- self.store = gtk.ListStore(gobject.TYPE_STRING)
- self.set_model(self.store)
- self.style_map = style_map
- start_index = 0
- for index, key in enumerate(sorted(style_map)):
- if key == "default":
- self.store.append(row=[_('default')])
- else:
- self.store.append(row=[key])
- if key == default:
- start_index = index
-
- self.set_active(start_index)
-
- def get_value(self):
- """
- Return the selected key (style sheet name).
-
- @returns: Returns the name of the selected style sheet
- @rtype: str
- """
- active = self.get_active()
- if active < 0:
- return None
- key = unicode(self.store[active][0])
- if key == _('default'):
- key = "default"
- return (key,self.style_map[key])
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-from gen.ggettext import gettext as _
-
-import gtk
-import gobject
-
#-------------------------------------------------------------------------
#
# StyleComboBox
diff --git a/src/gui/plug/report/_styleeditor.py b/src/gui/plug/report/_styleeditor.py
index 6cd13e981..0eae7e740 100644
--- a/src/gui/plug/report/_styleeditor.py
+++ b/src/gui/plug/report/_styleeditor.py
@@ -377,761 +377,3 @@ def dummy_callback(obj):
the signals of the other must be connected too
"""
pass
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2000-2005 Donald N. Allingham
-# Copyright (C) 2007-2008 Brian G. Matherly
-# Copyright (C) 2008 Peter Landgren
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-"""
-Paragraph/Font style editor
-"""
-
-#------------------------------------------------------------------------
-#
-# Python modules
-#
-#------------------------------------------------------------------------
-from gen.ggettext import sgettext as _
-import logging
-log = logging.getLogger(".")
-
-#------------------------------------------------------------------------
-#
-# GNOME/GTK modules
-#
-#------------------------------------------------------------------------
-import gtk
-from gtk.gdk import Color
-
-#------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#------------------------------------------------------------------------
-import Utils
-import const
-from gen.plug.docgen import (StyleSheet, FONT_SERIF, FONT_SANS_SERIF,
- PARA_ALIGN_RIGHT, PARA_ALIGN_CENTER, PARA_ALIGN_LEFT,
- PARA_ALIGN_JUSTIFY)
-import ListModel
-import ManagedWindow
-from glade import Glade
-
-#------------------------------------------------------------------------
-#
-# StyleList class
-#
-#------------------------------------------------------------------------
-class StyleListDisplay(object):
- """
- Shows the available paragraph/font styles. Allows the user to select,
- add, edit, and delete styles from a StyleSheet.
- """
-
- def __init__(self, stylesheetlist, callback, parent_window):
- """
- Create a StyleListDisplay object that displays the styles in the
- StyleSheet.
-
- stylesheetlist - styles that can be editied
- callback - task called with an object has been added.
- """
- self.callback = callback
-
- self.sheetlist = stylesheetlist
-
- self.top = Glade(toplevel='styles')
- self.window = self.top.toplevel
-
- ManagedWindow.set_titles( self.window,
- self.top.get_object('title'),
- _('Document Styles') )
-
- self.top.connect_signals({
- "destroy_passed_object" : self.__close,
- "on_ok_clicked" : self.on_ok_clicked,
- "on_add_clicked" : self.on_add_clicked,
- "on_delete_clicked" : self.on_delete_clicked,
- "on_button_press" : self.on_button_press,
- "on_edit_clicked" : self.on_edit_clicked,
- "on_save_style_clicked" : dummy_callback,
- })
-
- title_label = self.top.get_object('title')
- title_label.set_text(Utils.title(_('Style Editor')))
- title_label.set_use_markup(True)
-
- self.list = ListModel.ListModel(self.top.get_object("list"),
- [(_('Style'), -1, 10)], )
- self.redraw()
- if parent_window:
- self.window.set_transient_for(parent_window)
- self.window.run()
- self.window.destroy()
-
- def __close(self, obj):
- self.top.destroy()
-
- def redraw(self):
- """Redraws the list of styles that are current available"""
-
- self.list.model.clear()
- self.list.add(["default"])
-
- index = 1
- for style in self.sheetlist.get_style_names():
- if style == "default":
- continue
- self.list.add([style])
- index += 1
-
- def on_add_clicked(self, obj):
- """Called with the ADD button is clicked. Invokes the StyleEditor to
- create a new style"""
- style = self.sheetlist.get_style_sheet("default")
- StyleEditor("New Style", style, self)
-
- def on_ok_clicked(self, obj):
- """Called with the OK button is clicked; Calls the callback task,
- then saves the stylesheet."""
- if self.callback is not None:
- self.callback()
- try:
- self.sheetlist.save()
- except IOError, msg:
- from QuestionDialog import ErrorDialog
- ErrorDialog(_("Error saving stylesheet"), str(msg))
- except:
- log.error("Failed to save stylesheet", exc_info=True)
-
- def on_button_press(self, obj, event):
- if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
- self.on_edit_clicked(obj)
-
- def on_edit_clicked(self, obj):
- """
- Called with the EDIT button is clicked.
- Calls the StyleEditor to edit the selected style.
- """
- store, node = self.list.selection.get_selected()
- if not node:
- return
-
- name = unicode(self.list.model.get_value(node, 0))
- style = self.sheetlist.get_style_sheet(name)
- StyleEditor(name, style, self)
-
- def on_delete_clicked(self, obj):
- """Deletes the selected style."""
- store, node = self.list.selection.get_selected()
- if not node:
- return
- name = unicode(self.list.model.get_value(node, 0))
- self.sheetlist.delete_style_sheet(name)
- self.redraw()
-
-#------------------------------------------------------------------------
-#
-# StyleEditor class
-#
-#------------------------------------------------------------------------
-class StyleEditor(object):
- """
- Edits the current style definition. Presents a dialog allowing the values
- of the paragraphs in the style to be altered.
- """
-
- def __init__(self, name, style, parent):
- """
- Create the StyleEditor.
-
- name - name of the style that is to be edited
- style - style object that is to be edited
- parent - StyleListDisplay object that called the editor
- """
- self.current_p = None
- self.current_name = None
-
- self.style = StyleSheet(style)
- self.parent = parent
- self.top = Glade(toplevel='editor')
- self.window = self.top.toplevel
-
- self.top.connect_signals({
- "on_save_style_clicked" : self.on_save_style_clicked,
- "destroy_passed_object" : self.__close,
- "on_ok_clicked" : dummy_callback,
- "on_add_clicked" : dummy_callback,
- "on_delete_clicked" : dummy_callback,
- "on_button_press" : dummy_callback,
- "on_edit_clicked" : dummy_callback,
- })
-
- self.pname = self.top.get_object('pname')
- self.pdescription = self.top.get_object('pdescription')
-
- ManagedWindow.set_titles( self.window,
- self.top.get_object('title'),
- _('Style editor'))
- self.top.get_object("label6").set_text(_("point size|pt"))
-
- titles = [(_('Paragraph'), 0, 130)]
- self.plist = ListModel.ListModel(self.top.get_object("ptree"), titles,
- self.change_display)
-
- self.top.get_object('color').connect('color-set', self.fg_color_set)
- self.top.get_object('bgcolor').connect('color-set', self.bg_color_set)
- self.top.get_object("style_name").set_text(name)
-
- names = self.style.get_paragraph_style_names()
- names.reverse()
- for p_name in names:
- self.plist.add([p_name], self.style.get_paragraph_style(p_name))
- self.plist.select_row(0)
-
- if self.parent:
- self.window.set_transient_for(parent.window)
- self.window.run()
- self.window.destroy()
-
- def __close(self, obj):
- self.window.destroy()
-
- def draw(self):
- """Updates the display with the selected paragraph."""
-
- p = self.current_p
- self.pname.set_text( '%s' %
- self.current_name )
- self.pname.set_use_markup(True)
-
- descr = p.get_description()
- self.pdescription.set_text(descr or _("No description available") )
-
- font = p.get_font()
- self.top.get_object("size").set_value(font.get_size())
- if font.get_type_face() == FONT_SERIF:
- self.top.get_object("roman").set_active(1)
- else:
- self.top.get_object("swiss").set_active(1)
- self.top.get_object("bold").set_active(font.get_bold())
- self.top.get_object("italic").set_active(font.get_italic())
- self.top.get_object("underline").set_active(font.get_underline())
- if p.get_alignment() == PARA_ALIGN_LEFT:
- self.top.get_object("lalign").set_active(1)
- elif p.get_alignment() == PARA_ALIGN_RIGHT:
- self.top.get_object("ralign").set_active(1)
- elif p.get_alignment() == PARA_ALIGN_CENTER:
- self.top.get_object("calign").set_active(1)
- else:
- self.top.get_object("jalign").set_active(1)
- self.top.get_object("rmargin").set_value(p.get_right_margin())
- self.top.get_object("lmargin").set_value(p.get_left_margin())
- self.top.get_object("pad").set_value(p.get_padding())
- self.top.get_object("tmargin").set_value(p.get_top_margin())
- self.top.get_object("bmargin").set_value(p.get_bottom_margin())
- self.top.get_object("indent").set_value(p.get_first_indent())
- self.top.get_object("tborder").set_active(p.get_top_border())
- self.top.get_object("lborder").set_active(p.get_left_border())
- self.top.get_object("rborder").set_active(p.get_right_border())
- self.top.get_object("bborder").set_active(p.get_bottom_border())
-
- self.fg_color = font.get_color()
- c = Color(self.fg_color[0] << 8,
- self.fg_color[1] << 8,
- self.fg_color[2] << 8)
- self.top.get_object("color").set_color(c)
- self.top.get_object('color_code').set_text(
- "#%02X%02X%02X" % self.fg_color)
-
- self.bg_color = p.get_background_color()
- c = Color(self.bg_color[0] << 8,
- self.bg_color[1] << 8,
- self.bg_color[2] << 8)
- self.top.get_object("bgcolor").set_color(c)
- self.top.get_object('bgcolor_code').set_text(
- "#%02X%02X%02X" % self.bg_color)
-
- def bg_color_set(self, x):
- c = x.get_color()
- self.bg_color = (c.red >> 8, c.green >> 8, c.blue >> 8)
- self.top.get_object('bgcolor_code').set_text(
- "#%02X%02X%02X" % self.bg_color)
-
- def fg_color_set(self, x):
- c = x.get_color()
- self.fg_color = (c.red >> 8, c.green >> 8, c.blue >> 8)
- self.top.get_object('color_code').set_text(
- "#%02X%02X%02X" % self.fg_color)
-
- def save_paragraph(self):
- """Saves the current paragraph displayed on the dialog"""
- p = self.current_p
- font = p.get_font()
- font.set_size(self.top.get_object("size").get_value_as_int())
-
- if self.top.get_object("roman").get_active():
- font.set_type_face(FONT_SERIF)
- else:
- font.set_type_face(FONT_SANS_SERIF)
-
- font.set_bold(self.top.get_object("bold").get_active())
- font.set_italic(self.top.get_object("italic").get_active())
- font.set_underline(self.top.get_object("underline").get_active())
- if self.top.get_object("lalign").get_active():
- p.set_alignment(PARA_ALIGN_LEFT)
- elif self.top.get_object("ralign").get_active():
- p.set_alignment(PARA_ALIGN_RIGHT)
- elif self.top.get_object("calign").get_active():
- p.set_alignment(PARA_ALIGN_CENTER)
- else:
- p.set_alignment(PARA_ALIGN_JUSTIFY)
-
- p.set_right_margin(self.top.get_object("rmargin").get_value())
- p.set_left_margin(self.top.get_object("lmargin").get_value())
- p.set_top_margin(self.top.get_object("tmargin").get_value())
- p.set_bottom_margin(self.top.get_object("bmargin").get_value())
- p.set_padding(self.top.get_object("pad").get_value())
- p.set_first_indent(self.top.get_object("indent").get_value())
- p.set_top_border(self.top.get_object("tborder").get_active())
- p.set_left_border(self.top.get_object("lborder").get_active())
- p.set_right_border(self.top.get_object("rborder").get_active())
- p.set_bottom_border(self.top.get_object("bborder").get_active())
-
- font.set_color(self.fg_color)
- p.set_background_color(self.bg_color)
-
- self.style.add_paragraph_style(self.current_name, self.current_p)
-
- def on_save_style_clicked(self, obj):
- """
- Saves the current style sheet and causes the parent to be updated with
- the changes.
- """
- name = unicode(self.top.get_object("style_name").get_text())
-
- self.save_paragraph()
- self.style.set_name(name)
- self.parent.sheetlist.set_style_sheet(name, self.style)
- self.parent.redraw()
- self.window.destroy()
-
- def change_display(self, obj):
- """Called when the paragraph selection has been changed. Saves the
- old paragraph, then draws the newly selected paragraph"""
- # Don't save until current_name is defined
- # If it's defined, save under the current paragraph name
- if self.current_name:
- self.save_paragraph()
- # Then change to new paragraph
- objs = self.plist.get_selected_objects()
- store, node = self.plist.get_selected()
- self.current_name = store.get_value(node, 0)
- self.current_p = objs[0]
- self.draw()
-
-def dummy_callback(obj):
- """Dummy callback to satisfy gtkbuilder on connect of signals.
- There are two widgets in the glade file, although only one is needed,
- the signals of the other must be connected too
- """
- pass
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2000-2005 Donald N. Allingham
-# Copyright (C) 2007-2008 Brian G. Matherly
-# Copyright (C) 2008 Peter Landgren
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-"""
-Paragraph/Font style editor
-"""
-
-#------------------------------------------------------------------------
-#
-# Python modules
-#
-#------------------------------------------------------------------------
-from gen.ggettext import sgettext as _
-import logging
-log = logging.getLogger(".")
-
-#------------------------------------------------------------------------
-#
-# GNOME/GTK modules
-#
-#------------------------------------------------------------------------
-import gtk
-from gtk.gdk import Color
-
-#------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#------------------------------------------------------------------------
-import Utils
-import const
-from gen.plug.docgen import (StyleSheet, FONT_SERIF, FONT_SANS_SERIF,
- PARA_ALIGN_RIGHT, PARA_ALIGN_CENTER, PARA_ALIGN_LEFT,
- PARA_ALIGN_JUSTIFY)
-import ListModel
-import ManagedWindow
-from glade import Glade
-
-#------------------------------------------------------------------------
-#
-# StyleList class
-#
-#------------------------------------------------------------------------
-class StyleListDisplay(object):
- """
- Shows the available paragraph/font styles. Allows the user to select,
- add, edit, and delete styles from a StyleSheet.
- """
-
- def __init__(self, stylesheetlist, callback, parent_window):
- """
- Create a StyleListDisplay object that displays the styles in the
- StyleSheet.
-
- stylesheetlist - styles that can be editied
- callback - task called with an object has been added.
- """
- self.callback = callback
-
- self.sheetlist = stylesheetlist
-
- self.top = Glade(toplevel='styles')
- self.window = self.top.toplevel
-
- ManagedWindow.set_titles( self.window,
- self.top.get_object('title'),
- _('Document Styles') )
-
- self.top.connect_signals({
- "destroy_passed_object" : self.__close,
- "on_ok_clicked" : self.on_ok_clicked,
- "on_add_clicked" : self.on_add_clicked,
- "on_delete_clicked" : self.on_delete_clicked,
- "on_button_press" : self.on_button_press,
- "on_edit_clicked" : self.on_edit_clicked,
- "on_save_style_clicked" : dummy_callback,
- })
-
- title_label = self.top.get_object('title')
- title_label.set_text(Utils.title(_('Style Editor')))
- title_label.set_use_markup(True)
-
- self.list = ListModel.ListModel(self.top.get_object("list"),
- [(_('Style'), -1, 10)], )
- self.redraw()
- if parent_window:
- self.window.set_transient_for(parent_window)
- self.window.run()
- self.window.destroy()
-
- def __close(self, obj):
- self.top.destroy()
-
- def redraw(self):
- """Redraws the list of styles that are current available"""
-
- self.list.model.clear()
- self.list.add(["default"])
-
- index = 1
- for style in self.sheetlist.get_style_names():
- if style == "default":
- continue
- self.list.add([style])
- index += 1
-
- def on_add_clicked(self, obj):
- """Called with the ADD button is clicked. Invokes the StyleEditor to
- create a new style"""
- style = self.sheetlist.get_style_sheet("default")
- StyleEditor("New Style", style, self)
-
- def on_ok_clicked(self, obj):
- """Called with the OK button is clicked; Calls the callback task,
- then saves the stylesheet."""
- if self.callback is not None:
- self.callback()
- try:
- self.sheetlist.save()
- except IOError, msg:
- from QuestionDialog import ErrorDialog
- ErrorDialog(_("Error saving stylesheet"), str(msg))
- except:
- log.error("Failed to save stylesheet", exc_info=True)
-
- def on_button_press(self, obj, event):
- if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
- self.on_edit_clicked(obj)
-
- def on_edit_clicked(self, obj):
- """
- Called with the EDIT button is clicked.
- Calls the StyleEditor to edit the selected style.
- """
- store, node = self.list.selection.get_selected()
- if not node:
- return
-
- name = unicode(self.list.model.get_value(node, 0))
- style = self.sheetlist.get_style_sheet(name)
- StyleEditor(name, style, self)
-
- def on_delete_clicked(self, obj):
- """Deletes the selected style."""
- store, node = self.list.selection.get_selected()
- if not node:
- return
- name = unicode(self.list.model.get_value(node, 0))
- self.sheetlist.delete_style_sheet(name)
- self.redraw()
-
-#------------------------------------------------------------------------
-#
-# StyleEditor class
-#
-#------------------------------------------------------------------------
-class StyleEditor(object):
- """
- Edits the current style definition. Presents a dialog allowing the values
- of the paragraphs in the style to be altered.
- """
-
- def __init__(self, name, style, parent):
- """
- Create the StyleEditor.
-
- name - name of the style that is to be edited
- style - style object that is to be edited
- parent - StyleListDisplay object that called the editor
- """
- self.current_p = None
- self.current_name = None
-
- self.style = StyleSheet(style)
- self.parent = parent
- self.top = Glade(toplevel='editor')
- self.window = self.top.toplevel
-
- self.top.connect_signals({
- "on_save_style_clicked" : self.on_save_style_clicked,
- "destroy_passed_object" : self.__close,
- "on_ok_clicked" : dummy_callback,
- "on_add_clicked" : dummy_callback,
- "on_delete_clicked" : dummy_callback,
- "on_button_press" : dummy_callback,
- "on_edit_clicked" : dummy_callback,
- })
-
- self.pname = self.top.get_object('pname')
- self.pdescription = self.top.get_object('pdescription')
-
- ManagedWindow.set_titles( self.window,
- self.top.get_object('title'),
- _('Style editor'))
- self.top.get_object("label6").set_text(_("point size|pt"))
-
- titles = [(_('Paragraph'), 0, 130)]
- self.plist = ListModel.ListModel(self.top.get_object("ptree"), titles,
- self.change_display)
-
- self.top.get_object('color').connect('color-set', self.fg_color_set)
- self.top.get_object('bgcolor').connect('color-set', self.bg_color_set)
- self.top.get_object("style_name").set_text(name)
-
- names = self.style.get_paragraph_style_names()
- names.reverse()
- for p_name in names:
- self.plist.add([p_name], self.style.get_paragraph_style(p_name))
- self.plist.select_row(0)
-
- if self.parent:
- self.window.set_transient_for(parent.window)
- self.window.run()
- self.window.destroy()
-
- def __close(self, obj):
- self.window.destroy()
-
- def draw(self):
- """Updates the display with the selected paragraph."""
-
- p = self.current_p
- self.pname.set_text( '%s' %
- self.current_name )
- self.pname.set_use_markup(True)
-
- descr = p.get_description()
- self.pdescription.set_text(descr or _("No description available") )
-
- font = p.get_font()
- self.top.get_object("size").set_value(font.get_size())
- if font.get_type_face() == FONT_SERIF:
- self.top.get_object("roman").set_active(1)
- else:
- self.top.get_object("swiss").set_active(1)
- self.top.get_object("bold").set_active(font.get_bold())
- self.top.get_object("italic").set_active(font.get_italic())
- self.top.get_object("underline").set_active(font.get_underline())
- if p.get_alignment() == PARA_ALIGN_LEFT:
- self.top.get_object("lalign").set_active(1)
- elif p.get_alignment() == PARA_ALIGN_RIGHT:
- self.top.get_object("ralign").set_active(1)
- elif p.get_alignment() == PARA_ALIGN_CENTER:
- self.top.get_object("calign").set_active(1)
- else:
- self.top.get_object("jalign").set_active(1)
- self.top.get_object("rmargin").set_value(p.get_right_margin())
- self.top.get_object("lmargin").set_value(p.get_left_margin())
- self.top.get_object("pad").set_value(p.get_padding())
- self.top.get_object("tmargin").set_value(p.get_top_margin())
- self.top.get_object("bmargin").set_value(p.get_bottom_margin())
- self.top.get_object("indent").set_value(p.get_first_indent())
- self.top.get_object("tborder").set_active(p.get_top_border())
- self.top.get_object("lborder").set_active(p.get_left_border())
- self.top.get_object("rborder").set_active(p.get_right_border())
- self.top.get_object("bborder").set_active(p.get_bottom_border())
-
- self.fg_color = font.get_color()
- c = Color(self.fg_color[0] << 8,
- self.fg_color[1] << 8,
- self.fg_color[2] << 8)
- self.top.get_object("color").set_color(c)
- self.top.get_object('color_code').set_text(
- "#%02X%02X%02X" % self.fg_color)
-
- self.bg_color = p.get_background_color()
- c = Color(self.bg_color[0] << 8,
- self.bg_color[1] << 8,
- self.bg_color[2] << 8)
- self.top.get_object("bgcolor").set_color(c)
- self.top.get_object('bgcolor_code').set_text(
- "#%02X%02X%02X" % self.bg_color)
-
- def bg_color_set(self, x):
- c = x.get_color()
- self.bg_color = (c.red >> 8, c.green >> 8, c.blue >> 8)
- self.top.get_object('bgcolor_code').set_text(
- "#%02X%02X%02X" % self.bg_color)
-
- def fg_color_set(self, x):
- c = x.get_color()
- self.fg_color = (c.red >> 8, c.green >> 8, c.blue >> 8)
- self.top.get_object('color_code').set_text(
- "#%02X%02X%02X" % self.fg_color)
-
- def save_paragraph(self):
- """Saves the current paragraph displayed on the dialog"""
- p = self.current_p
- font = p.get_font()
- font.set_size(self.top.get_object("size").get_value_as_int())
-
- if self.top.get_object("roman").get_active():
- font.set_type_face(FONT_SERIF)
- else:
- font.set_type_face(FONT_SANS_SERIF)
-
- font.set_bold(self.top.get_object("bold").get_active())
- font.set_italic(self.top.get_object("italic").get_active())
- font.set_underline(self.top.get_object("underline").get_active())
- if self.top.get_object("lalign").get_active():
- p.set_alignment(PARA_ALIGN_LEFT)
- elif self.top.get_object("ralign").get_active():
- p.set_alignment(PARA_ALIGN_RIGHT)
- elif self.top.get_object("calign").get_active():
- p.set_alignment(PARA_ALIGN_CENTER)
- else:
- p.set_alignment(PARA_ALIGN_JUSTIFY)
-
- p.set_right_margin(self.top.get_object("rmargin").get_value())
- p.set_left_margin(self.top.get_object("lmargin").get_value())
- p.set_top_margin(self.top.get_object("tmargin").get_value())
- p.set_bottom_margin(self.top.get_object("bmargin").get_value())
- p.set_padding(self.top.get_object("pad").get_value())
- p.set_first_indent(self.top.get_object("indent").get_value())
- p.set_top_border(self.top.get_object("tborder").get_active())
- p.set_left_border(self.top.get_object("lborder").get_active())
- p.set_right_border(self.top.get_object("rborder").get_active())
- p.set_bottom_border(self.top.get_object("bborder").get_active())
-
- font.set_color(self.fg_color)
- p.set_background_color(self.bg_color)
-
- self.style.add_paragraph_style(self.current_name, self.current_p)
-
- def on_save_style_clicked(self, obj):
- """
- Saves the current style sheet and causes the parent to be updated with
- the changes.
- """
- name = unicode(self.top.get_object("style_name").get_text())
-
- self.save_paragraph()
- self.style.set_name(name)
- self.parent.sheetlist.set_style_sheet(name, self.style)
- self.parent.redraw()
- self.window.destroy()
-
- def change_display(self, obj):
- """Called when the paragraph selection has been changed. Saves the
- old paragraph, then draws the newly selected paragraph"""
- # Don't save until current_name is defined
- # If it's defined, save under the current paragraph name
- if self.current_name:
- self.save_paragraph()
- # Then change to new paragraph
- objs = self.plist.get_selected_objects()
- store, node = self.plist.get_selected()
- self.current_name = store.get_value(node, 0)
- self.current_p = objs[0]
- self.draw()
-
-def dummy_callback(obj):
- """Dummy callback to satisfy gtkbuilder on connect of signals.
- There are two widgets in the glade file, although only one is needed,
- the signals of the other must be connected too
- """
- pass
diff --git a/src/gui/plug/report/_textreportdialog.py b/src/gui/plug/report/_textreportdialog.py
index 230bfd5f2..f2b9a9891 100644
--- a/src/gui/plug/report/_textreportdialog.py
+++ b/src/gui/plug/report/_textreportdialog.py
@@ -39,224 +39,6 @@ from gui.pluginmanager import GuiPluginManager
from gen.plug.report._constants import CATEGORY_TEXT
from _docreportdialog import DocReportDialog
-#-------------------------------------------------------------------------
-#
-# _TextFormatComboBox
-#
-#-------------------------------------------------------------------------
-class _TextFormatComboBox(gtk.ComboBox):
- """
- This class is a combo box that allows the selection of a docgen plugin
- from all textdoc plugins.
- """
- def __init__(self, active):
-
- gtk.ComboBox.__init__(self)
-
- pmgr = GuiPluginManager.get_instance()
- self.__textdoc_plugins = []
- for plugin in pmgr.get_docgen_plugins():
- if plugin.get_text_support():
- self.__textdoc_plugins.append(plugin)
-
- self.store = gtk.ListStore(gobject.TYPE_STRING)
- self.set_model(self.store)
- cell = gtk.CellRendererText()
- self.pack_start(cell, True)
- self.add_attribute(cell, 'text', 0)
-
- index = 0
- active_index = 0
- for plugin in self.__textdoc_plugins:
- name = plugin.get_name()
- self.store.append(row=[name])
- if plugin.get_extension() == active:
- active_index = index
- index += 1
- self.set_active(active_index)
-
- def get_active_plugin(self):
- """
- Get the plugin represented by the currently active selection.
- """
- return self.__textdoc_plugins[self.get_active()]
-
-#-----------------------------------------------------------------------
-#
-# TextReportDialog
-#
-#-----------------------------------------------------------------------
-class TextReportDialog(DocReportDialog):
- """
- A class of ReportDialog customized for text based reports.
- """
- def __init__(self, dbstate, uistate, options, name, translated_name):
- """
- Initialize a dialog to request that the user select options
- for a basic text report. See the ReportDialog class for more
- information.
- """
- self.format_menu = None
- self.category = CATEGORY_TEXT
- DocReportDialog.__init__(self, dbstate, uistate, options,
- name, translated_name)
-
- def make_doc_menu(self, active=None):
- """
- Build a menu of document types that are appropriate for
- this text report.
- """
- self.format_menu = _TextFormatComboBox( active )
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2008-2009 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# GTK modules
-#
-#-------------------------------------------------------------------------
-import gtk
-import gobject
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-from gui.pluginmanager import GuiPluginManager
-from gen.plug.report._constants import CATEGORY_TEXT
-from _docreportdialog import DocReportDialog
-
-#-------------------------------------------------------------------------
-#
-# _TextFormatComboBox
-#
-#-------------------------------------------------------------------------
-class _TextFormatComboBox(gtk.ComboBox):
- """
- This class is a combo box that allows the selection of a docgen plugin
- from all textdoc plugins.
- """
- def __init__(self, active):
-
- gtk.ComboBox.__init__(self)
-
- pmgr = GuiPluginManager.get_instance()
- self.__textdoc_plugins = []
- for plugin in pmgr.get_docgen_plugins():
- if plugin.get_text_support():
- self.__textdoc_plugins.append(plugin)
-
- self.store = gtk.ListStore(gobject.TYPE_STRING)
- self.set_model(self.store)
- cell = gtk.CellRendererText()
- self.pack_start(cell, True)
- self.add_attribute(cell, 'text', 0)
-
- index = 0
- active_index = 0
- for plugin in self.__textdoc_plugins:
- name = plugin.get_name()
- self.store.append(row=[name])
- if plugin.get_extension() == active:
- active_index = index
- index += 1
- self.set_active(active_index)
-
- def get_active_plugin(self):
- """
- Get the plugin represented by the currently active selection.
- """
- return self.__textdoc_plugins[self.get_active()]
-
-#-----------------------------------------------------------------------
-#
-# TextReportDialog
-#
-#-----------------------------------------------------------------------
-class TextReportDialog(DocReportDialog):
- """
- A class of ReportDialog customized for text based reports.
- """
- def __init__(self, dbstate, uistate, options, name, translated_name):
- """
- Initialize a dialog to request that the user select options
- for a basic text report. See the ReportDialog class for more
- information.
- """
- self.format_menu = None
- self.category = CATEGORY_TEXT
- DocReportDialog.__init__(self, dbstate, uistate, options,
- name, translated_name)
-
- def make_doc_menu(self, active=None):
- """
- Build a menu of document types that are appropriate for
- this text report.
- """
- self.format_menu = _TextFormatComboBox( active )
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2001-2006 Donald N. Allingham
-# Copyright (C) 2008-2009 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# GTK modules
-#
-#-------------------------------------------------------------------------
-import gtk
-import gobject
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-from gui.pluginmanager import GuiPluginManager
-from gen.plug.report._constants import CATEGORY_TEXT
-from _docreportdialog import DocReportDialog
-
#-------------------------------------------------------------------------
#
# _TextFormatComboBox
diff --git a/src/gui/plug/report/_webreportdialog.py b/src/gui/plug/report/_webreportdialog.py
index 0396a85fb..6a3f500f1 100644
--- a/src/gui/plug/report/_webreportdialog.py
+++ b/src/gui/plug/report/_webreportdialog.py
@@ -29,122 +29,6 @@
from _reportdialog import ReportDialog
from gen.plug.report import CATEGORY_WEB
-#-------------------------------------------------------------------------
-#
-# WebReportDialog class
-#
-#-------------------------------------------------------------------------
-class WebReportDialog(ReportDialog):
- """
- The WebReportDialog base class. This is a base class for generating
- dialogs for web page reports.
- """
-
- def __init__(self, dbstate, uistate, option_class, name, trans_name):
- """Initialize a dialog"""
- self.category = CATEGORY_WEB
- ReportDialog.__init__(self, dbstate, uistate, option_class,
- name, trans_name)
-
- def setup_init(self):
- pass
-
- def setup_target_frame(self):
- """Target frame is not used."""
- pass
-
- def parse_target_frame(self):
- """Target frame is not used."""
- return 1
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2008 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-from _reportdialog import ReportDialog
-from gen.plug.report import CATEGORY_WEB
-
-#-------------------------------------------------------------------------
-#
-# WebReportDialog class
-#
-#-------------------------------------------------------------------------
-class WebReportDialog(ReportDialog):
- """
- The WebReportDialog base class. This is a base class for generating
- dialogs for web page reports.
- """
-
- def __init__(self, dbstate, uistate, option_class, name, trans_name):
- """Initialize a dialog"""
- self.category = CATEGORY_WEB
- ReportDialog.__init__(self, dbstate, uistate, option_class,
- name, trans_name)
-
- def setup_init(self):
- pass
-
- def setup_target_frame(self):
- """Target frame is not used."""
- pass
-
- def parse_target_frame(self):
- """Target frame is not used."""
- return 1
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2008 Brian G. Matherly
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-from _reportdialog import ReportDialog
-from gen.plug.report import CATEGORY_WEB
-
#-------------------------------------------------------------------------
#
# WebReportDialog class
diff --git a/src/gui/plug/tool.py b/src/gui/plug/tool.py
index 81d82c569..a4d28db45 100644
--- a/src/gui/plug/tool.py
+++ b/src/gui/plug/tool.py
@@ -234,628 +234,6 @@ class CommandLineTool(object):
#------------------------------------------------------------------------
# Standard GUI tool generic task
-def gui_tool(dbstate, uistate, tool_class, options_class, translated_name,
- name, category, callback):
- """
- tool - task starts the report. The plugin system requires that the
- task be in the format of task that takes a database and a person as
- its arguments.
- """
-
- try:
- tool_class(dbstate, uistate, options_class, name, callback)
- except Errors.WindowActiveError:
- pass
- except:
- log.error("Failed to start tool.", exc_info=True)
-
-# Command-line generic task
-def cli_tool(dbstate, name, category, tool_class, options_class, options_str_dict):
-
- clt = CommandLineTool(dbstate.db, name, category,
- options_class, options_str_dict)
-
- # Exit here if show option was given
- if clt.show:
- return
-
- # run tool
- try:
- tool_class(dbstate, None, options_class, name, None)
- except:
- log.error("Failed to start tool.", exc_info=True)
-
-#-------------------------------------------------------------------------
-#
-# Class handling options for plugins
-#
-#-------------------------------------------------------------------------
-class ToolOptionHandler(OptionHandler):
- """
- Implements handling of the options for the plugins.
- """
- def __init__(self, module_name, options_dict, person_id=None):
- OptionHandler.__init__(self, module_name, options_dict, person_id)
-
- def init_subclass(self):
- self.collection_class = OptionListCollection
- self.list_class = OptionList
- self.filename = const.TOOL_OPTIONS
-
-#------------------------------------------------------------------------
-#
-# Tool Options class
-#
-#------------------------------------------------------------------------
-class ToolOptions(Options):
-
- """
- Defines options and provides handling interface.
-
- This is a base Options class for the tools. All tools, options
- classes should derive from it.
- """
-
- def __init__(self, name, person_id=None):
- """
- Initialize the class, performing usual house-keeping tasks.
- Subclasses MUST call this in their __init__() method.
- """
- self.name = name
- self.person_id = person_id
- self.options_dict = {}
- self.options_help = {}
- self.handler = None
-
- def load_previous_values(self):
- self.handler = ToolOptionHandler(self.name, self.options_dict, self.person_id)
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2005-2007 Donald N. Allingham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-"ToolGeneration Framework"
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-from gen.ggettext import gettext as _
-import logging
-log = logging.getLogger(".")
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-import const
-import Utils
-from gen.display.name import displayer as name_displayer
-import Errors
-from gen.plug._options import (Options, OptionHandler, OptionList,
- OptionListCollection)
-from gen.plug import (TOOL_DEBUG, TOOL_ANAL, TOOL_DBPROC, TOOL_DBFIX,
- TOOL_REVCTL, TOOL_UTILS)
-
-#-------------------------------------------------------------------------
-#
-# Constants
-#
-#-------------------------------------------------------------------------
-
-tool_categories = {
- TOOL_DEBUG : _("Debug"),
- TOOL_ANAL : _("Analysis and Exploration"),
- TOOL_DBPROC : _("Database Processing"),
- TOOL_DBFIX : _("Database Repair"),
- TOOL_REVCTL : _("Revision Control"),
- TOOL_UTILS : _("Utilities"),
- }
-
-#-------------------------------------------------------------------------
-#
-# Tool
-#
-#-------------------------------------------------------------------------
-class Tool(object):
- """
- The Tool base class. This is a base class for generating
- customized tools. It cannot be used as is, but it can be easily
- sub-classed to create a functional tool.
- """
-
- def __init__(self, dbstate, options_class, name):
- from gui.plug import MenuToolOptions
- self.db = dbstate.db
- try:
- if issubclass(options_class, MenuToolOptions):
- # FIXME: pass in person_id
- self.options = options_class(name, None, dbstate)
- else: # must be some kind of class or we get a TypeError
- self.options = options_class(name)
- except TypeError:
- self.options = options_class
-
- self.options.load_previous_values()
-
- def run_tool(self):
- pass
-
-
-class BatchTool(Tool):
- """
- Same as Tool, except the warning is displayed about the potential
- loss of undo history. Should be used for tools using batch transactions.
-
- """
-
- def __init__(self, dbstate, options_class, name):
- # TODO: should we replace this with a callback?
- from QuestionDialog import QuestionDialog2
- warn_dialog = QuestionDialog2(
- _('Undo history warning'),
- _('Proceeding with this tool will erase the undo history '
- 'for this session. In particular, you will not be able '
- 'to revert the changes made by this tool or any changes '
- 'made prior to it.\n\n'
- 'If you think you may want to revert running this tool, '
- 'please stop here and backup your database.'),
- _('_Proceed with the tool'), _('_Stop'))
- if not warn_dialog.run():
- self.fail = True
- return
-
- Tool.__init__(self, dbstate, options_class, name)
- self.fail = False
-
-
-class ActivePersonTool(Tool):
- """
- Same as Tool , except the existence of the active person is checked
- and the tool is aborted if no active person exists. Should be used
- for tools that depend on active person.
- """
-
- def __init__(self, dbstate, uistate, options_class, name):
-
- if not uistate.get_active('Person'):
- # TODO: should we replace this with a callback?
- from QuestionDialog import ErrorDialog
-
- ErrorDialog(_('Active person has not been set'),
- _('You must select an active person for this '
- 'tool to work properly.'))
- self.fail = True
- return
-
- Tool.__init__(self, dbstate, options_class, name)
- self.fail = False
-
-#------------------------------------------------------------------------
-#
-# Command-line tool
-#
-#------------------------------------------------------------------------
-class CommandLineTool(object):
- """
- Provide a way to run tool from the command line.
-
- """
-
- def __init__(self, database, name, category, option_class, options_str_dict,
- noopt=False):
- self.database = database
- self.category = category
- self.option_class = option_class(name)
- self.option_class.load_previous_values()
- self.show = options_str_dict.pop('show', None)
- self.options_str_dict = options_str_dict
- self.init_options(noopt)
- self.parse_option_str()
- self.show_options()
-
- def init_options(self, noopt):
- self.options_dict = {'id' : ''}
- self.options_help = {'id' : ["=ID", "Gramps ID of a central person."], }
-
- if noopt:
- return
-
- # Add tool-specific options
- for key in self.option_class.handler.options_dict:
- if key not in self.options_dict:
- self.options_dict[key] = self.option_class.handler.options_dict[key]
-
- # Add help for tool-specific options
- for key in self.option_class.options_help:
- if key not in self.options_help:
- self.options_help[key] = self.option_class.options_help[key]
-
- def parse_option_str(self):
- for opt in self.options_str_dict:
- if opt in self.options_dict:
- converter = Utils.get_type_converter(self.options_dict[opt])
- self.options_dict[opt] = converter(self.options_str_dict[opt])
- self.option_class.handler.options_dict[opt] = self.options_dict[opt]
- else:
- print "Ignoring unknown option: %s" % opt
-
- person_id = self.options_dict['id']
- self.person = self.database.get_person_from_gramps_id(person_id)
- id_list = []
-
- for person in self.database.iter_people():
- id_list.append("%s\t%s" % (
- person.get_gramps_id(),
- name_displayer.display(person)))
- self.options_help['id'].append(id_list)
- self.options_help['id'].append(False)
-
- def show_options(self):
- if not self.show:
- return
- elif self.show == 'all':
- print " Available options:"
- for key in self.options_dict:
- print " %s" % key
- print " Use 'show=option' to see description and acceptable values"
- elif self.show in self.options_dict:
- print ' %s%s\t%s' % (self.show,
- self.options_help[self.show][0],
- self.options_help[self.show][1])
- print " Available values are:"
- vals = self.options_help[self.show][2]
- if isinstance(vals, (list, tuple)):
- if self.options_help[self.show][3]:
- for num in range(len(vals)):
- print " %d\t%s" % (num, vals[num])
- else:
- for val in vals:
- print " %s" % val
- else:
- print " %s" % self.options_help[self.show][2]
-
- else:
- self.show = None
-
-#------------------------------------------------------------------------
-#
-# Generic task functions for tools
-#
-#------------------------------------------------------------------------
-# Standard GUI tool generic task
-
-def gui_tool(dbstate, uistate, tool_class, options_class, translated_name,
- name, category, callback):
- """
- tool - task starts the report. The plugin system requires that the
- task be in the format of task that takes a database and a person as
- its arguments.
- """
-
- try:
- tool_class(dbstate, uistate, options_class, name, callback)
- except Errors.WindowActiveError:
- pass
- except:
- log.error("Failed to start tool.", exc_info=True)
-
-# Command-line generic task
-def cli_tool(dbstate, name, category, tool_class, options_class, options_str_dict):
-
- clt = CommandLineTool(dbstate.db, name, category,
- options_class, options_str_dict)
-
- # Exit here if show option was given
- if clt.show:
- return
-
- # run tool
- try:
- tool_class(dbstate, None, options_class, name, None)
- except:
- log.error("Failed to start tool.", exc_info=True)
-
-#-------------------------------------------------------------------------
-#
-# Class handling options for plugins
-#
-#-------------------------------------------------------------------------
-class ToolOptionHandler(OptionHandler):
- """
- Implements handling of the options for the plugins.
- """
- def __init__(self, module_name, options_dict, person_id=None):
- OptionHandler.__init__(self, module_name, options_dict, person_id)
-
- def init_subclass(self):
- self.collection_class = OptionListCollection
- self.list_class = OptionList
- self.filename = const.TOOL_OPTIONS
-
-#------------------------------------------------------------------------
-#
-# Tool Options class
-#
-#------------------------------------------------------------------------
-class ToolOptions(Options):
-
- """
- Defines options and provides handling interface.
-
- This is a base Options class for the tools. All tools, options
- classes should derive from it.
- """
-
- def __init__(self, name, person_id=None):
- """
- Initialize the class, performing usual house-keeping tasks.
- Subclasses MUST call this in their __init__() method.
- """
- self.name = name
- self.person_id = person_id
- self.options_dict = {}
- self.options_help = {}
- self.handler = None
-
- def load_previous_values(self):
- self.handler = ToolOptionHandler(self.name, self.options_dict, self.person_id)
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2005-2007 Donald N. Allingham
-# Copyright (C) 2010 Jakim Friant
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-# $Id$
-
-"ToolGeneration Framework"
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-from gen.ggettext import gettext as _
-import logging
-log = logging.getLogger(".")
-
-#-------------------------------------------------------------------------
-#
-# GRAMPS modules
-#
-#-------------------------------------------------------------------------
-import const
-import Utils
-from gen.display.name import displayer as name_displayer
-import Errors
-from gen.plug._options import (Options, OptionHandler, OptionList,
- OptionListCollection)
-from gen.plug import (TOOL_DEBUG, TOOL_ANAL, TOOL_DBPROC, TOOL_DBFIX,
- TOOL_REVCTL, TOOL_UTILS)
-
-#-------------------------------------------------------------------------
-#
-# Constants
-#
-#-------------------------------------------------------------------------
-
-tool_categories = {
- TOOL_DEBUG : _("Debug"),
- TOOL_ANAL : _("Analysis and Exploration"),
- TOOL_DBPROC : _("Database Processing"),
- TOOL_DBFIX : _("Database Repair"),
- TOOL_REVCTL : _("Revision Control"),
- TOOL_UTILS : _("Utilities"),
- }
-
-#-------------------------------------------------------------------------
-#
-# Tool
-#
-#-------------------------------------------------------------------------
-class Tool(object):
- """
- The Tool base class. This is a base class for generating
- customized tools. It cannot be used as is, but it can be easily
- sub-classed to create a functional tool.
- """
-
- def __init__(self, dbstate, options_class, name):
- from gui.plug import MenuToolOptions
- self.db = dbstate.db
- try:
- if issubclass(options_class, MenuToolOptions):
- # FIXME: pass in person_id
- self.options = options_class(name, None, dbstate)
- else: # must be some kind of class or we get a TypeError
- self.options = options_class(name)
- except TypeError:
- self.options = options_class
-
- self.options.load_previous_values()
-
- def run_tool(self):
- pass
-
-
-class BatchTool(Tool):
- """
- Same as Tool, except the warning is displayed about the potential
- loss of undo history. Should be used for tools using batch transactions.
-
- """
-
- def __init__(self, dbstate, options_class, name):
- # TODO: should we replace this with a callback?
- from QuestionDialog import QuestionDialog2
- warn_dialog = QuestionDialog2(
- _('Undo history warning'),
- _('Proceeding with this tool will erase the undo history '
- 'for this session. In particular, you will not be able '
- 'to revert the changes made by this tool or any changes '
- 'made prior to it.\n\n'
- 'If you think you may want to revert running this tool, '
- 'please stop here and backup your database.'),
- _('_Proceed with the tool'), _('_Stop'))
- if not warn_dialog.run():
- self.fail = True
- return
-
- Tool.__init__(self, dbstate, options_class, name)
- self.fail = False
-
-
-class ActivePersonTool(Tool):
- """
- Same as Tool , except the existence of the active person is checked
- and the tool is aborted if no active person exists. Should be used
- for tools that depend on active person.
- """
-
- def __init__(self, dbstate, uistate, options_class, name):
-
- if not uistate.get_active('Person'):
- # TODO: should we replace this with a callback?
- from QuestionDialog import ErrorDialog
-
- ErrorDialog(_('Active person has not been set'),
- _('You must select an active person for this '
- 'tool to work properly.'))
- self.fail = True
- return
-
- Tool.__init__(self, dbstate, options_class, name)
- self.fail = False
-
-#------------------------------------------------------------------------
-#
-# Command-line tool
-#
-#------------------------------------------------------------------------
-class CommandLineTool(object):
- """
- Provide a way to run tool from the command line.
-
- """
-
- def __init__(self, database, name, category, option_class, options_str_dict,
- noopt=False):
- self.database = database
- self.category = category
- self.option_class = option_class(name)
- self.option_class.load_previous_values()
- self.show = options_str_dict.pop('show', None)
- self.options_str_dict = options_str_dict
- self.init_options(noopt)
- self.parse_option_str()
- self.show_options()
-
- def init_options(self, noopt):
- self.options_dict = {'id' : ''}
- self.options_help = {'id' : ["=ID", "Gramps ID of a central person."], }
-
- if noopt:
- return
-
- # Add tool-specific options
- for key in self.option_class.handler.options_dict:
- if key not in self.options_dict:
- self.options_dict[key] = self.option_class.handler.options_dict[key]
-
- # Add help for tool-specific options
- for key in self.option_class.options_help:
- if key not in self.options_help:
- self.options_help[key] = self.option_class.options_help[key]
-
- def parse_option_str(self):
- for opt in self.options_str_dict:
- if opt in self.options_dict:
- converter = Utils.get_type_converter(self.options_dict[opt])
- self.options_dict[opt] = converter(self.options_str_dict[opt])
- self.option_class.handler.options_dict[opt] = self.options_dict[opt]
- else:
- print "Ignoring unknown option: %s" % opt
-
- person_id = self.options_dict['id']
- self.person = self.database.get_person_from_gramps_id(person_id)
- id_list = []
-
- for person in self.database.iter_people():
- id_list.append("%s\t%s" % (
- person.get_gramps_id(),
- name_displayer.display(person)))
- self.options_help['id'].append(id_list)
- self.options_help['id'].append(False)
-
- def show_options(self):
- if not self.show:
- return
- elif self.show == 'all':
- print " Available options:"
- for key in self.options_dict:
- print " %s" % key
- print " Use 'show=option' to see description and acceptable values"
- elif self.show in self.options_dict:
- print ' %s%s\t%s' % (self.show,
- self.options_help[self.show][0],
- self.options_help[self.show][1])
- print " Available values are:"
- vals = self.options_help[self.show][2]
- if isinstance(vals, (list, tuple)):
- if self.options_help[self.show][3]:
- for num in range(len(vals)):
- print " %d\t%s" % (num, vals[num])
- else:
- for val in vals:
- print " %s" % val
- else:
- print " %s" % self.options_help[self.show][2]
-
- else:
- self.show = None
-
-#------------------------------------------------------------------------
-#
-# Generic task functions for tools
-#
-#------------------------------------------------------------------------
-# Standard GUI tool generic task
-
def gui_tool(dbstate, uistate, tool_class, options_class, translated_name,
name, category, callback):
"""