Repair duplicated file contents resulting from 0003796 (Make export available when no GUI available).

svn: r15332
This commit is contained in:
Brian Matherly 2010-05-06 03:40:30 +00:00
parent e067a9b010
commit ecbde74066
26 changed files with 0 additions and 16715 deletions

View File

@ -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

View File

@ -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("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
f.write('<options>\n')
self.write_common(f)
for module_name in self.get_module_names():
option_list = self.get_option_list(module_name)
f.write('<module name=%s>\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(' <option name=%s value="" length="%d">\n' % (
quoteattr(option_name),
len(option_data) ) )
for list_index, list_data in enumerate(option_data):
f.write(' <listitem number="%d" value=%s/>\n' % (
list_index,
quoteattr(unicode(list_data))) )
f.write(' </option>\n')
else:
f.write(' <option name=%s value=%s/>\n' % (
quoteattr(option_name),
quoteattr(unicode(option_data))) )
self.write_module_common(f, option_list)
f.write('</module>\n')
f.write('</options>\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("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
f.write('<options>\n')
self.write_common(f)
for module_name in self.get_module_names():
option_list = self.get_option_list(module_name)
f.write('<module name=%s>\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(' <option name=%s value="" length="%d">\n' % (
quoteattr(option_name),
len(option_data) ) )
for list_index, list_data in enumerate(option_data):
f.write(' <listitem number="%d" value=%s/>\n' % (
list_index,
quoteattr(unicode(list_data))) )
f.write(' </option>\n')
else:
f.write(' <option name=%s value=%s/>\n' % (
quoteattr(option_name),
quoteattr(unicode(option_data))) )
self.write_module_common(f, option_list)
f.write('</module>\n')
f.write('</options>\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

View File

@ -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

View File

@ -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

View File

@ -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 <robhealey1@gmail.com>
# 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 <robhealey1@gmail.com>
# 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'],

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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 <jfriedmannj@gmail.com>
# 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 <jfriedmannj@gmail.com>
# 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

View File

@ -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):
"""

View File

@ -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('<span weight="bold" size="larger">%s</span>' \
% 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('<span weight="bold" size="larger">%s</span>' \
% 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)

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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('<b>%s</b>'%_("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('<b>%s</b>' % _("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('<b>%s</b>'%_("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('<b>%s</b>' % _("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()

View File

@ -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

View File

@ -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):

File diff suppressed because it is too large Load Diff

View File

@ -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])

View File

@ -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()

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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( '<span size="larger" weight="bold">%s</span>' %
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( '<span size="larger" weight="bold">%s</span>' %
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

View File

@ -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

View File

@ -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

View File

@ -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):
"""