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

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