Repair duplicated file contents resulting from 0003796 (Make export available when no GUI available).
svn: r15332
This commit is contained in:
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
@@ -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
|
||||
|
@@ -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()
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user