Update
svn: r6119
This commit is contained in:
		
							
								
								
									
										513
									
								
								gramps2/src/PluginUtils/_Options.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										513
									
								
								gramps2/src/PluginUtils/_Options.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,513 @@
 | 
			
		||||
#
 | 
			
		||||
# Gramps - a GTK+/GNOME based genealogy program
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2004-2005  Donald N. Allingham
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
# the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
# (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
# This program is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
# GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with this program; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
#
 | 
			
		||||
# $Id$
 | 
			
		||||
 | 
			
		||||
# Written by Alex Roitman
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
General option handling, including saving and parsing.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Standard Python modules
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
import os
 | 
			
		||||
from gettext import gettext as _
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# SAX interface
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
try:
 | 
			
		||||
    from xml.sax import make_parser,handler,SAXParseException
 | 
			
		||||
except:
 | 
			
		||||
    from _xmlplus.sax import make_parser,handler,SAXParseException
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# gramps modules
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
import Utils
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# List of options for a single module
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
class OptionList:
 | 
			
		||||
    """
 | 
			
		||||
    Implements a set of options to parse and store for a given module.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.options = {}
 | 
			
		||||
    
 | 
			
		||||
    def set_options(self,options):
 | 
			
		||||
        """
 | 
			
		||||
        Sets 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):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the whole bunch of  options for the OptionList.
 | 
			
		||||
        @returns: list of options
 | 
			
		||||
        @rtype: list
 | 
			
		||||
        """
 | 
			
		||||
        return self.options
 | 
			
		||||
 | 
			
		||||
    def set_option(self,name,value):
 | 
			
		||||
        """
 | 
			
		||||
        Sets 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):
 | 
			
		||||
        """
 | 
			
		||||
        Removes a particular option from the OptionList.
 | 
			
		||||
        @param name: name of the option to remove.
 | 
			
		||||
        @type name: str
 | 
			
		||||
        """
 | 
			
		||||
        if self.options.has_key(name):
 | 
			
		||||
            del self.options[name]
 | 
			
		||||
 | 
			
		||||
    def get_option(self,name):
 | 
			
		||||
        """
 | 
			
		||||
        Returns 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:
 | 
			
		||||
    """
 | 
			
		||||
    Implements a collection of option lists.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self,filename):
 | 
			
		||||
        """
 | 
			
		||||
        Creates 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):
 | 
			
		||||
        """
 | 
			
		||||
        Returns 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):
 | 
			
		||||
        """
 | 
			
		||||
        Returns 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):
 | 
			
		||||
        """
 | 
			
		||||
        Returns 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):
 | 
			
		||||
        """
 | 
			
		||||
        Adds or replaces an option_list in the OptionListCollection. 
 | 
			
		||||
        @param name: name assocated 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' % module_name)
 | 
			
		||||
            options = option_list.get_options()
 | 
			
		||||
            for option_name in options.keys():
 | 
			
		||||
                if type(options[option_name]) in (type(list()),type(tuple())):
 | 
			
		||||
                    f.write('  <option name="%s" value="" length="%d">\n' % (
 | 
			
		||||
                                option_name, len(options[option_name]) ) )
 | 
			
		||||
                    for list_index in range(len(options[option_name])):
 | 
			
		||||
                        f.write('    <listitem number="%d" value="%s"/>\n' % (
 | 
			
		||||
                                list_index, options[option_name][list_index]) )
 | 
			
		||||
                    f.write('  </option>\n')
 | 
			
		||||
                else:
 | 
			
		||||
                    f.write('  <option name="%s" value="%s"/>\n' % (
 | 
			
		||||
                            option_name,options[option_name]) )
 | 
			
		||||
 | 
			
		||||
            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:
 | 
			
		||||
            p = make_parser()
 | 
			
		||||
            p.setContentHandler(OptionParser(self))
 | 
			
		||||
            p.parse('file://' + self.filename)
 | 
			
		||||
        except (IOError,OSError,SAXParseException):
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# OptionParser
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
class OptionParser(handler.ContentHandler):
 | 
			
		||||
    """
 | 
			
		||||
    SAX parsing class for the OptionListCollection XML file.
 | 
			
		||||
    """
 | 
			
		||||
    
 | 
			
		||||
    def __init__(self,collection):
 | 
			
		||||
        """
 | 
			
		||||
        Creates 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:
 | 
			
		||||
    """
 | 
			
		||||
    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):
 | 
			
		||||
        """
 | 
			
		||||
        Sets 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 in options.keys():
 | 
			
		||||
            if not self.options_dict.has_key(option_name):
 | 
			
		||||
                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(options[option_name])
 | 
			
		||||
            except ValueError:
 | 
			
		||||
                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 in self.options_dict.keys():
 | 
			
		||||
            if self.options_dict[option_name] == 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_filter_number(self):
 | 
			
		||||
        if self.default_options_dict.has_key('filter'):
 | 
			
		||||
            return self.options_dict.get('filter',
 | 
			
		||||
                    self.default_options_dict['filter'])
 | 
			
		||||
        else:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
    def set_filter_number(self,val):
 | 
			
		||||
        self.options_dict['filter'] = val
 | 
			
		||||
 | 
			
		||||
    def get_person_id(self):
 | 
			
		||||
        return self.person_id
 | 
			
		||||
 | 
			
		||||
    def set_person_id(self,val):
 | 
			
		||||
        self.person_id = val
 | 
			
		||||
 | 
			
		||||
#------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Base Options class
 | 
			
		||||
#
 | 
			
		||||
#------------------------------------------------------------------------
 | 
			
		||||
class Options:
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    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):
 | 
			
		||||
        """
 | 
			
		||||
        Initializes the class, performing usual house-keeping tasks.
 | 
			
		||||
        Subclasses MUST call this in their __init__() method.
 | 
			
		||||
        """
 | 
			
		||||
        self.set_new_options()
 | 
			
		||||
        self.enable_options()
 | 
			
		||||
 | 
			
		||||
        if self.enable_dict:
 | 
			
		||||
            self.options_dict.update(self.enable_dict)
 | 
			
		||||
        self.handler = OptionHandler(name,self.options_dict,person_id)
 | 
			
		||||
 | 
			
		||||
    def set_new_options(self):
 | 
			
		||||
        """
 | 
			
		||||
        Sets options specific for this module. 
 | 
			
		||||
        
 | 
			
		||||
        Modules that need custom options need to override this method.
 | 
			
		||||
        Two dictionaries MUST be defined here: 
 | 
			
		||||
 | 
			
		||||
            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.
 | 
			
		||||
 | 
			
		||||
        NOTE:   If a particular module does not use custom options,
 | 
			
		||||
                then it should not override this method. 
 | 
			
		||||
        """
 | 
			
		||||
        self.options_dict = {}
 | 
			
		||||
        self.options_help = {}
 | 
			
		||||
 | 
			
		||||
    def enable_options(self):
 | 
			
		||||
        """
 | 
			
		||||
        Enables semi-common options for this module.
 | 
			
		||||
        
 | 
			
		||||
        The semi-common option is the option which GRAMPS is aware of,
 | 
			
		||||
        but not common enough to be present in all modules. Here's the list
 | 
			
		||||
        of possible keys for semi-commons:
 | 
			
		||||
        
 | 
			
		||||
            'filter'    - Filter number, selected among filters
 | 
			
		||||
                          available for this module. If defined,
 | 
			
		||||
                          get_module_filters() method must be defined
 | 
			
		||||
                          which returns the list of available filters.
 | 
			
		||||
 | 
			
		||||
        A self.enable_dict dictionary MUST be defined here, whose keys
 | 
			
		||||
        are the valid semi-common keys above, and whose values are the
 | 
			
		||||
        desired default values for semi-commons.
 | 
			
		||||
 | 
			
		||||
        NOTE:   If a particular module does not use semi-common options,
 | 
			
		||||
                then it should not override this method. 
 | 
			
		||||
        """
 | 
			
		||||
        self.enable_dict = {}
 | 
			
		||||
 | 
			
		||||
    def add_user_options(self,dialog):
 | 
			
		||||
        """
 | 
			
		||||
        Sets 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.BareReportDialog 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.BareReportDialog 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
 | 
			
		||||
    
 | 
			
		||||
    def get_filter_number(self):
 | 
			
		||||
        """
 | 
			
		||||
        Return number of a filter to use.
 | 
			
		||||
        
 | 
			
		||||
        This method MUST NOT be overridden by subclasses.
 | 
			
		||||
        """
 | 
			
		||||
        return self.handler.get_filter_number()
 | 
			
		||||
							
								
								
									
										1942
									
								
								gramps2/src/PluginUtils/_Report.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1942
									
								
								gramps2/src/PluginUtils/_Report.py
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										600
									
								
								gramps2/src/PluginUtils/_ReportOptions.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										600
									
								
								gramps2/src/PluginUtils/_ReportOptions.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,600 @@
 | 
			
		||||
#
 | 
			
		||||
# Gramps - a GTK+/GNOME based genealogy program
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2004-2006  Donald N. Allingham
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
# the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
# (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
# This program is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
# GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with this program; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
#
 | 
			
		||||
# $Id$
 | 
			
		||||
 | 
			
		||||
# Written by Alex Roitman
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
Report option handling, including saving and parsing.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Standard Python modules
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
from gettext import gettext as _
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# SAX interface
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
try:
 | 
			
		||||
    from xml.sax import make_parser,handler,SAXParseException
 | 
			
		||||
except:
 | 
			
		||||
    from _xmlplus.sax import make_parser,handler,SAXParseException
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# gramps modules
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
import const
 | 
			
		||||
import Config
 | 
			
		||||
import Utils
 | 
			
		||||
import BaseDoc
 | 
			
		||||
from _Options import *
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# List of options for a single report
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
class OptionList(OptionList):
 | 
			
		||||
    """
 | 
			
		||||
    Implements a set of options to parse and store for a given report.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        OptionList.__init__(self)
 | 
			
		||||
        self.style_name = None
 | 
			
		||||
        self.paper_name = None
 | 
			
		||||
        self.orientation = None
 | 
			
		||||
        self.template_name = None
 | 
			
		||||
        self.format_name = None
 | 
			
		||||
    
 | 
			
		||||
    def set_style_name(self,style_name):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the style name for the OptionList.
 | 
			
		||||
        @param style_name: name of the style to set.
 | 
			
		||||
        @type style_name: str
 | 
			
		||||
        """
 | 
			
		||||
        self.style_name = style_name
 | 
			
		||||
 | 
			
		||||
    def get_style_name(self):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the style name of the OptionList.
 | 
			
		||||
        @returns: string representing the style name
 | 
			
		||||
        @rtype: str
 | 
			
		||||
        """
 | 
			
		||||
        return self.style_name
 | 
			
		||||
 | 
			
		||||
    def set_paper_name(self,paper_name):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the paper name for the OptionList.
 | 
			
		||||
        @param paper_name: name of the paper to set.
 | 
			
		||||
        @type paper_name: str
 | 
			
		||||
        """
 | 
			
		||||
        self.paper_name = paper_name
 | 
			
		||||
 | 
			
		||||
    def get_paper_name(self):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the paper name of the OptionList.
 | 
			
		||||
        @returns: returns the paper name
 | 
			
		||||
        @rtype: str
 | 
			
		||||
        """
 | 
			
		||||
        return self.paper_name
 | 
			
		||||
 | 
			
		||||
    def set_orientation(self,orientation):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the orientation for the OptionList.
 | 
			
		||||
        @param orientation: orientation to set. Possible values are
 | 
			
		||||
            BaseDoc.PAPER_LANDSCAPE or BaseDoc.PAPER_PORTRAIT
 | 
			
		||||
        @type orientation: int
 | 
			
		||||
        """
 | 
			
		||||
        self.orientation = orientation
 | 
			
		||||
 | 
			
		||||
    def get_orientation(self):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the orientation for the OptionList.
 | 
			
		||||
        @returns: returns the selected orientation. Valid values are
 | 
			
		||||
            BaseDoc.PAPER_LANDSCAPE or BaseDoc.PAPER_PORTRAIT
 | 
			
		||||
        @rtype: int
 | 
			
		||||
        """
 | 
			
		||||
        return self.orientation
 | 
			
		||||
 | 
			
		||||
    def set_template_name(self,template_name):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the template name for the OptionList.
 | 
			
		||||
        @param template_name: name of the template to set.
 | 
			
		||||
        @type template_name: str
 | 
			
		||||
        """
 | 
			
		||||
        self.template_name = template_name
 | 
			
		||||
 | 
			
		||||
    def get_template_name(self):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the template name of the OptionList.
 | 
			
		||||
        @returns: template name
 | 
			
		||||
        @rtype: str
 | 
			
		||||
        """
 | 
			
		||||
        return self.template_name
 | 
			
		||||
 | 
			
		||||
    def set_format_name(self,format_name):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the format name for the OptionList.
 | 
			
		||||
        @param format_name: name of the format to set.
 | 
			
		||||
        @type format_name: str
 | 
			
		||||
        """
 | 
			
		||||
        self.format_name = format_name
 | 
			
		||||
 | 
			
		||||
    def get_format_name(self):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the format name of the OptionList.
 | 
			
		||||
        @returns: returns the format name
 | 
			
		||||
        @rtype: str
 | 
			
		||||
        """
 | 
			
		||||
        return self.format_name
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Collection of option lists
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
class OptionListCollection(OptionListCollection):
 | 
			
		||||
    """
 | 
			
		||||
    Implements a collection of option lists.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self,filename):
 | 
			
		||||
        OptionListCollection.__init__(self,filename)
 | 
			
		||||
 | 
			
		||||
    def init_common(self):
 | 
			
		||||
        # Default values for common options
 | 
			
		||||
        self.default_style_name = "default"
 | 
			
		||||
        self.default_paper_name = Config.get_paper_preference()
 | 
			
		||||
        self.default_template_name = ""
 | 
			
		||||
        self.default_orientation = BaseDoc.PAPER_PORTRAIT
 | 
			
		||||
        self.default_format_name = 'print'
 | 
			
		||||
 | 
			
		||||
        self.last_paper_name = self.default_paper_name
 | 
			
		||||
        self.last_orientation = self.default_orientation
 | 
			
		||||
        self.last_template_name = self.default_template_name
 | 
			
		||||
        self.last_format_name = self.default_format_name
 | 
			
		||||
        self.option_list_map = {}
 | 
			
		||||
 | 
			
		||||
    def set_last_paper_name(self,paper_name):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the last paper name used for the any report in this collection.
 | 
			
		||||
        @param paper_name: name of the paper to set.
 | 
			
		||||
        @type paper_name: str
 | 
			
		||||
        """
 | 
			
		||||
        self.last_paper_name = paper_name
 | 
			
		||||
 | 
			
		||||
    def get_last_paper_name(self):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the last paper name used for the any report in this collection.
 | 
			
		||||
        @returns: returns the name of the paper
 | 
			
		||||
        @rtype: str
 | 
			
		||||
        """
 | 
			
		||||
        return self.last_paper_name
 | 
			
		||||
 | 
			
		||||
    def set_last_orientation(self,orientation):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the last orientation used for the any report in this collection.
 | 
			
		||||
        @param orientation: orientation to set.
 | 
			
		||||
        @type orientation: int
 | 
			
		||||
        """
 | 
			
		||||
        self.last_orientation = orientation
 | 
			
		||||
 | 
			
		||||
    def get_last_orientation(self):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the last orientation used for the any report in this
 | 
			
		||||
        collection.
 | 
			
		||||
        @returns: last orientation used
 | 
			
		||||
        @rtype: int
 | 
			
		||||
        """
 | 
			
		||||
        return self.last_orientation
 | 
			
		||||
 | 
			
		||||
    def set_last_template_name(self,template_name):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the last template used for the any report in this collection.
 | 
			
		||||
        
 | 
			
		||||
        template_name: name of the style to set.
 | 
			
		||||
        """
 | 
			
		||||
        self.last_template_name = template_name
 | 
			
		||||
 | 
			
		||||
    def get_last_template_name(self):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the last template used for the any report in this collection.
 | 
			
		||||
        """
 | 
			
		||||
        return self.last_template_name
 | 
			
		||||
 | 
			
		||||
    def set_last_format_name(self,format_name):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the last format used for the any report in this collection.
 | 
			
		||||
        
 | 
			
		||||
        format_name: name of the format to set.
 | 
			
		||||
        """
 | 
			
		||||
        self.last_format_name = format_name
 | 
			
		||||
 | 
			
		||||
    def get_last_format_name(self):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the last format used for the any report in this collection.
 | 
			
		||||
        """
 | 
			
		||||
        return self.last_format_name
 | 
			
		||||
 | 
			
		||||
    def write_common(self,f):
 | 
			
		||||
        f.write('<last-common>\n')
 | 
			
		||||
        if self.get_last_paper_name() != self.default_paper_name:
 | 
			
		||||
            f.write('  <paper name="%s"/>\n' % self.get_last_paper_name() )
 | 
			
		||||
        if self.get_last_template_name() != self.default_template_name:
 | 
			
		||||
            f.write('  <template name="%s"/>\n' % self.get_last_template_name() )
 | 
			
		||||
        if self.get_last_format_name() != self.default_format_name:
 | 
			
		||||
            f.write('  <format name="%s"/>\n' % self.get_last_format_name() )
 | 
			
		||||
        if self.get_last_orientation() != self.default_orientation:
 | 
			
		||||
            f.write('  <orientation value="%d"/>\n' % self.get_last_orientation() )
 | 
			
		||||
        f.write('</last-common>\n')
 | 
			
		||||
 | 
			
		||||
    def write_module_common(self,f,option_list):
 | 
			
		||||
        if option_list.get_style_name() \
 | 
			
		||||
               and option_list.get_style_name() != self.default_style_name:
 | 
			
		||||
            f.write('  <style name="%s"/>\n' % option_list.get_style_name() )
 | 
			
		||||
        if option_list.get_paper_name() \
 | 
			
		||||
               and option_list.get_paper_name() != self.default_paper_name:
 | 
			
		||||
            f.write('  <paper name="%s"/>\n' % option_list.get_paper_name() )
 | 
			
		||||
        if option_list.get_template_name() \
 | 
			
		||||
               and option_list.get_template_name() != self.default_template_name:
 | 
			
		||||
            f.write('  <template name="%s"/>\n' % option_list.get_template_name() )
 | 
			
		||||
        if option_list.get_format_name() \
 | 
			
		||||
               and option_list.get_format_name() != self.default_format_name:
 | 
			
		||||
            f.write('  <format name="%s"/>\n' % option_list.get_format_name() )
 | 
			
		||||
        if option_list.get_orientation() \
 | 
			
		||||
               and option_list.get_orientation() != self.default_orientation:
 | 
			
		||||
            f.write('  <orientation value="%d"/>\n' % option_list.get_orientation() )
 | 
			
		||||
 | 
			
		||||
    def parse(self):
 | 
			
		||||
        """
 | 
			
		||||
        Loads the OptionList from the associated file, if it exists.
 | 
			
		||||
        """
 | 
			
		||||
        try:
 | 
			
		||||
            p = make_parser()
 | 
			
		||||
            p.setContentHandler(OptionParser(self))
 | 
			
		||||
            p.parse('file://' + self.filename)
 | 
			
		||||
        except (IOError,OSError,SAXParseException):
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# OptionParser
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
class OptionParser(OptionParser):
 | 
			
		||||
    """
 | 
			
		||||
    SAX parsing class for the OptionListCollection XML file.
 | 
			
		||||
    """
 | 
			
		||||
    
 | 
			
		||||
    def __init__(self,collection):
 | 
			
		||||
        """
 | 
			
		||||
        Creates a OptionParser class that populates the passed collection.
 | 
			
		||||
 | 
			
		||||
        collection:   BookList to be loaded from the file.
 | 
			
		||||
        """
 | 
			
		||||
        OptionParser.__init__(self,collection)
 | 
			
		||||
        self.common = False
 | 
			
		||||
        self.list_class = OptionList
 | 
			
		||||
 | 
			
		||||
    def startElement(self,tag,attrs):
 | 
			
		||||
        """
 | 
			
		||||
        Overridden class that handles the start of a XML element
 | 
			
		||||
        """
 | 
			
		||||
        # First we try report-specific tags
 | 
			
		||||
        if tag == "last-common":
 | 
			
		||||
            self.common = True
 | 
			
		||||
        elif tag == "style":
 | 
			
		||||
            self.option_list.set_style_name(attrs['name'])
 | 
			
		||||
        elif tag == "paper":
 | 
			
		||||
            if self.common:
 | 
			
		||||
                self.collection.set_last_paper_name(attrs['name'])
 | 
			
		||||
            else:
 | 
			
		||||
                self.option_list.set_paper_name(attrs['name'])
 | 
			
		||||
        elif tag == "template":
 | 
			
		||||
            if self.common:
 | 
			
		||||
                self.collection.set_last_template_name(attrs['name'])
 | 
			
		||||
            else:
 | 
			
		||||
                self.option_list.set_template_name(attrs['name'])
 | 
			
		||||
        elif tag == "format":
 | 
			
		||||
            if self.common:
 | 
			
		||||
                self.collection.set_last_format_name(attrs['name'])
 | 
			
		||||
            else:
 | 
			
		||||
                self.option_list.set_format_name(attrs['name'])
 | 
			
		||||
        elif tag == "orientation":
 | 
			
		||||
            if self.common:
 | 
			
		||||
                self.collection.set_last_orientation(int(attrs['value']))
 | 
			
		||||
            else:
 | 
			
		||||
                self.option_list.set_orientation(int(attrs['value']))
 | 
			
		||||
        else:
 | 
			
		||||
            # Tag is not report-specific, so we let the base class handle it.
 | 
			
		||||
            OptionParser.startElement(self,tag,attrs)
 | 
			
		||||
 | 
			
		||||
    def endElement(self,tag):
 | 
			
		||||
        "Overridden class that handles the end of a XML element"
 | 
			
		||||
        # First we try report-specific tags
 | 
			
		||||
        if tag == "last-common":
 | 
			
		||||
            self.common = False
 | 
			
		||||
        else:
 | 
			
		||||
            # Tag is not report-specific, so we let the base class handle it.
 | 
			
		||||
            OptionParser.endElement(self,tag)
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Class handling options for plugins 
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
class OptionHandler(OptionHandler):
 | 
			
		||||
    """
 | 
			
		||||
    Implements handling of the options for the plugins.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self,module_name,options_dict,person_id=None):
 | 
			
		||||
        OptionHandler.__init__(self,module_name,options_dict,person_id)
 | 
			
		||||
 | 
			
		||||
    def init_subclass(self):
 | 
			
		||||
        self.collection_class = OptionListCollection
 | 
			
		||||
        self.list_class = OptionList
 | 
			
		||||
        self.filename = const.report_options
 | 
			
		||||
 | 
			
		||||
    def init_common(self):
 | 
			
		||||
        """
 | 
			
		||||
        Specific initialization for reports.
 | 
			
		||||
        """
 | 
			
		||||
        # These are needed for running reports.
 | 
			
		||||
        # We will not need to save/retreive them, just keep around.
 | 
			
		||||
        self.doc = None
 | 
			
		||||
        self.output = None
 | 
			
		||||
        self.newpage = False
 | 
			
		||||
 | 
			
		||||
        # Retrieve our options from whole collection
 | 
			
		||||
        self.style_name = self.option_list_collection.default_style_name
 | 
			
		||||
        self.paper_name = self.option_list_collection.get_last_paper_name()
 | 
			
		||||
        self.orientation = self.option_list_collection.get_last_orientation()
 | 
			
		||||
        self.template_name = self.option_list_collection.get_last_template_name()
 | 
			
		||||
        self.format_name = self.option_list_collection.get_last_format_name()
 | 
			
		||||
 | 
			
		||||
    def set_common_options(self):
 | 
			
		||||
        if self.saved_option_list.get_style_name():
 | 
			
		||||
            self.style_name = self.saved_option_list.get_style_name()
 | 
			
		||||
        if self.saved_option_list.get_orientation():
 | 
			
		||||
            self.orientation = self.saved_option_list.get_orientation()
 | 
			
		||||
        if self.saved_option_list.get_template_name():
 | 
			
		||||
            self.template_name = self.saved_option_list.get_template_name()
 | 
			
		||||
        if self.saved_option_list.get_paper_name():
 | 
			
		||||
            self.paper_name = self.saved_option_list.get_paper_name()
 | 
			
		||||
        if self.saved_option_list.get_format_name():
 | 
			
		||||
            self.format_name = self.saved_option_list.get_format_name()
 | 
			
		||||
 | 
			
		||||
    def save_common_options(self):
 | 
			
		||||
        # First we save common options
 | 
			
		||||
        self.saved_option_list.set_style_name(self.style_name)
 | 
			
		||||
        self.saved_option_list.set_orientation(self.orientation)
 | 
			
		||||
        self.saved_option_list.set_template_name(self.template_name)
 | 
			
		||||
        self.saved_option_list.set_paper_name(self.paper_name)
 | 
			
		||||
        self.saved_option_list.set_format_name(self.format_name)
 | 
			
		||||
        self.option_list_collection.set_option_list(self.module_name,
 | 
			
		||||
                                                    self.saved_option_list)
 | 
			
		||||
 | 
			
		||||
        # Then save last-common options from the current selection
 | 
			
		||||
        self.option_list_collection.set_last_orientation(self.orientation)
 | 
			
		||||
        self.option_list_collection.set_last_template_name(self.template_name)
 | 
			
		||||
        self.option_list_collection.set_last_paper_name(self.paper_name)
 | 
			
		||||
        self.option_list_collection.set_last_format_name(self.format_name)
 | 
			
		||||
 | 
			
		||||
    def get_report_generations(self):
 | 
			
		||||
        if self.default_options_dict.has_key('gen'):
 | 
			
		||||
            max_gen = self.options_dict.get('gen',
 | 
			
		||||
                        self.default_options_dict['gen'])
 | 
			
		||||
            page_breaks = self.options_dict.get('pagebbg',
 | 
			
		||||
                        self.default_options_dict['pagebbg'])
 | 
			
		||||
            return (max_gen,page_breaks)
 | 
			
		||||
        else:
 | 
			
		||||
            return (0,0)
 | 
			
		||||
 | 
			
		||||
    def set_report_generations(self,max_gen,page_breaks):
 | 
			
		||||
        self.options_dict['gen'] = max_gen
 | 
			
		||||
        self.options_dict['pagebbg'] = page_breaks
 | 
			
		||||
 | 
			
		||||
    def get_stylesheet_savefile(self):
 | 
			
		||||
        """Where to save user defined styles for this report."""
 | 
			
		||||
        return "%s.xml" % self.module_name
 | 
			
		||||
 | 
			
		||||
    def get_default_stylesheet_name(self):
 | 
			
		||||
        return self.style_name
 | 
			
		||||
 | 
			
		||||
    def set_default_stylesheet_name(self,style_name):
 | 
			
		||||
        self.style_name = style_name
 | 
			
		||||
 | 
			
		||||
    def get_display_format(self):
 | 
			
		||||
        if self.default_options_dict.has_key('dispf'):
 | 
			
		||||
            return self.options_dict.get('dispf',
 | 
			
		||||
                    self.default_options_dict['dispf'])
 | 
			
		||||
        else:
 | 
			
		||||
            return []
 | 
			
		||||
 | 
			
		||||
    def set_display_format(self,val):
 | 
			
		||||
        if type(val) != list:
 | 
			
		||||
            val = val.split('\n')
 | 
			
		||||
        self.options_dict['dispf'] = val
 | 
			
		||||
 | 
			
		||||
    def get_format_name(self):
 | 
			
		||||
        return self.format_name
 | 
			
		||||
 | 
			
		||||
    def set_format_name(self,format_name):
 | 
			
		||||
        self.format_name = format_name
 | 
			
		||||
 | 
			
		||||
    def get_paper_name(self):
 | 
			
		||||
        return self.paper_name
 | 
			
		||||
 | 
			
		||||
    def set_paper_name(self,paper_name):
 | 
			
		||||
        self.paper_name = paper_name
 | 
			
		||||
 | 
			
		||||
    def get_paper(self):
 | 
			
		||||
        """
 | 
			
		||||
        This method is for temporary storage, not for saving/restoring.
 | 
			
		||||
        """
 | 
			
		||||
        return self.paper
 | 
			
		||||
 | 
			
		||||
    def set_paper(self,paper):
 | 
			
		||||
        """
 | 
			
		||||
        This method is for temporary storage, not for saving/restoring.
 | 
			
		||||
        """
 | 
			
		||||
        self.paper = paper
 | 
			
		||||
 | 
			
		||||
    def get_template_name(self):
 | 
			
		||||
        return self.template_name
 | 
			
		||||
 | 
			
		||||
    def set_template_name(self,template_name):
 | 
			
		||||
        self.template_name = template_name
 | 
			
		||||
 | 
			
		||||
    def get_orientation(self):
 | 
			
		||||
        return self.orientation
 | 
			
		||||
 | 
			
		||||
    def set_orientation(self,orientation):
 | 
			
		||||
        self.orientation = orientation
 | 
			
		||||
 | 
			
		||||
#------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Base Options class
 | 
			
		||||
#
 | 
			
		||||
#------------------------------------------------------------------------
 | 
			
		||||
class ReportOptions(Options):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    Defines options and provides handling interface.
 | 
			
		||||
    
 | 
			
		||||
    This is a base Options class for the reports. All reports' options
 | 
			
		||||
    classes should derive from it.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self,name,person_id=None):
 | 
			
		||||
        """
 | 
			
		||||
        Initializes the class, performing usual house-keeping tasks.
 | 
			
		||||
        Subclasses MUST call this in their __init__() method.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.set_new_options()
 | 
			
		||||
        self.enable_options()
 | 
			
		||||
 | 
			
		||||
        if self.enable_dict:
 | 
			
		||||
            self.options_dict.update(self.enable_dict)
 | 
			
		||||
        self.handler = OptionHandler(name,self.options_dict,person_id)
 | 
			
		||||
 | 
			
		||||
    def make_default_style(self,default_style):
 | 
			
		||||
        """
 | 
			
		||||
        Defines default style for this report.
 | 
			
		||||
        
 | 
			
		||||
        This method MUST be overridden by reports that use the
 | 
			
		||||
        user-adjustable paragraph styles.
 | 
			
		||||
 | 
			
		||||
        NOTE:   Unique names MUST be used for all style names, otherwise the
 | 
			
		||||
                styles will collide when making a book with duplicate style
 | 
			
		||||
                names. A rule of safety is to prepend style name with the
 | 
			
		||||
                acronym based on report name. The following acronyms are
 | 
			
		||||
                already taken:
 | 
			
		||||
                    AC-     Ancestor Chart
 | 
			
		||||
                    AC2-    Ancestor Chart 2 (Wall Chart)
 | 
			
		||||
                    AHN-    Ahnentafel Report
 | 
			
		||||
                    AR-     Comprehensive Ancestors report
 | 
			
		||||
                    CBT-    Custom Book Text
 | 
			
		||||
                    DG-     Descendant Graph
 | 
			
		||||
                    DR-     Descendant Report
 | 
			
		||||
                    DAR-    Detailed Ancestral Report
 | 
			
		||||
                    DDR-    Detailed Descendant Report
 | 
			
		||||
                    FGR-    Family Group Report
 | 
			
		||||
                    FC-     Fan Chart
 | 
			
		||||
                    FTA-    FTM Style Ancestral report
 | 
			
		||||
                    FTD-    FTM Style Descendant report
 | 
			
		||||
                    IDS-    Individual Complete Report
 | 
			
		||||
                    IVS-    Individual Summary Report
 | 
			
		||||
                    SBT-    Simple Boot Title
 | 
			
		||||
                    TLG-    Timeline Graph
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def get_document(self):
 | 
			
		||||
        """
 | 
			
		||||
        Return document instance.
 | 
			
		||||
        
 | 
			
		||||
        This method MUST NOT be overridden by subclasses.
 | 
			
		||||
        """
 | 
			
		||||
        return self.handler.doc
 | 
			
		||||
 | 
			
		||||
    def set_document(self,val):
 | 
			
		||||
        """
 | 
			
		||||
        Set document to a given instance.
 | 
			
		||||
        
 | 
			
		||||
        This method MUST NOT be overridden by subclasses.
 | 
			
		||||
        """
 | 
			
		||||
        self.handler.doc = val
 | 
			
		||||
 | 
			
		||||
    def get_output(self):
 | 
			
		||||
        """
 | 
			
		||||
        Return document output destination.
 | 
			
		||||
        
 | 
			
		||||
        This method MUST NOT be overridden by subclasses.
 | 
			
		||||
        """
 | 
			
		||||
        return self.handler.output
 | 
			
		||||
 | 
			
		||||
    def set_output(self,val):
 | 
			
		||||
        """
 | 
			
		||||
        Set output destination to a given string.
 | 
			
		||||
        
 | 
			
		||||
        This method MUST NOT be overridden by subclasses.
 | 
			
		||||
        """
 | 
			
		||||
        self.handler.output = val
 | 
			
		||||
 | 
			
		||||
    def get_newpage(self):
 | 
			
		||||
        """
 | 
			
		||||
        Return value of whether or not insert new page before the report.
 | 
			
		||||
        
 | 
			
		||||
        This method MUST NOT be overridden by subclasses.
 | 
			
		||||
        """
 | 
			
		||||
        return self.handler.newpage
 | 
			
		||||
 | 
			
		||||
    def set_newpage(self,val):
 | 
			
		||||
        """
 | 
			
		||||
        Set newpage to a given value.
 | 
			
		||||
        
 | 
			
		||||
        This method MUST NOT be overridden by subclasses.
 | 
			
		||||
        """
 | 
			
		||||
        self.handler.newpage = val
 | 
			
		||||
 | 
			
		||||
    def get_report_generations(self):
 | 
			
		||||
        """
 | 
			
		||||
        Return (max_generations,page_breaks) tuple.
 | 
			
		||||
        
 | 
			
		||||
        This method MUST NOT be overridden by subclasses.
 | 
			
		||||
        """
 | 
			
		||||
        return self.handler.get_report_generations()
 | 
			
		||||
 | 
			
		||||
    def get_display_format(self):
 | 
			
		||||
        """
 | 
			
		||||
        Return display format for the option box of graphical report.
 | 
			
		||||
        
 | 
			
		||||
        This method MUST NOT be overridden by subclasses.
 | 
			
		||||
        """
 | 
			
		||||
        return self.handler.get_display_format()
 | 
			
		||||
							
								
								
									
										2199
									
								
								gramps2/src/PluginUtils/_ReportUtils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2199
									
								
								gramps2/src/PluginUtils/_ReportUtils.py
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										279
									
								
								gramps2/src/PluginUtils/_Tool.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										279
									
								
								gramps2/src/PluginUtils/_Tool.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,279 @@
 | 
			
		||||
#
 | 
			
		||||
# Gramps - a GTK+/GNOME based genealogy program
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2005-2006  Donald N. Allingham
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
# the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
# (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
# This program is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
# GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with this program; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# $Id$
 | 
			
		||||
 | 
			
		||||
"ToolGeneration Framework"
 | 
			
		||||
 | 
			
		||||
__author__ =  "Alex Roitman"
 | 
			
		||||
__version__ = "$Revision$"
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Python modules
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
from types import ClassType, InstanceType
 | 
			
		||||
from gettext import gettext as _
 | 
			
		||||
import logging
 | 
			
		||||
log = logging.getLogger(".")
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# GRAMPS modules
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
import const
 | 
			
		||||
import Utils
 | 
			
		||||
import GenericFilter
 | 
			
		||||
import NameDisplay
 | 
			
		||||
from _Options import *
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Constants
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
# Modes for running tools
 | 
			
		||||
MODE_GUI = 1    # Standrt tool using GUI
 | 
			
		||||
MODE_CLI = 2    # Command line interface (CLI)
 | 
			
		||||
 | 
			
		||||
# Tool categories
 | 
			
		||||
TOOL_DEBUG  = -1
 | 
			
		||||
TOOL_ANAL   = 0
 | 
			
		||||
TOOL_DBPROC = 1
 | 
			
		||||
TOOL_DBFIX  = 2
 | 
			
		||||
TOOL_REVCTL = 3
 | 
			
		||||
TOOL_UTILS  = 4
 | 
			
		||||
 | 
			
		||||
tool_categories = {
 | 
			
		||||
    TOOL_DEBUG  : _("Debug"),
 | 
			
		||||
    TOOL_ANAL   : _("Analysis and Exploration"),
 | 
			
		||||
    TOOL_DBPROC : _("Database Processing"),
 | 
			
		||||
    TOOL_DBFIX  : _("Database Repair"),
 | 
			
		||||
    TOOL_REVCTL : _("Revision Control"),
 | 
			
		||||
    TOOL_UTILS  : _("Utilities"),
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Report
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
class Tool:
 | 
			
		||||
    """
 | 
			
		||||
    The Tool base class.  This is a base class for generating
 | 
			
		||||
    customized tools.  It cannot be used as is, but it can be easily
 | 
			
		||||
    sub-classed to create a functional tool.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self,database,person,options_class,name):
 | 
			
		||||
        self.db = database
 | 
			
		||||
        self.person = person
 | 
			
		||||
        if type(options_class) == ClassType:
 | 
			
		||||
            self.options = options_class(name)
 | 
			
		||||
        elif type(options_class) == InstanceType:
 | 
			
		||||
            self.options = options_class
 | 
			
		||||
 | 
			
		||||
    def run_tool(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Command-line tool
 | 
			
		||||
#
 | 
			
		||||
#------------------------------------------------------------------------
 | 
			
		||||
class CommandLineTool:
 | 
			
		||||
    """
 | 
			
		||||
    Provides a way to run tool from the command line.
 | 
			
		||||
    
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self,database,name,category,option_class,options_str_dict,
 | 
			
		||||
                 noopt=False):
 | 
			
		||||
        self.database = database
 | 
			
		||||
        self.category = category
 | 
			
		||||
        self.option_class = option_class(name)
 | 
			
		||||
        self.show = options_str_dict.pop('show',None)
 | 
			
		||||
        self.options_str_dict = options_str_dict
 | 
			
		||||
        self.init_options(noopt)
 | 
			
		||||
        self.parse_option_str()
 | 
			
		||||
        self.show_options()
 | 
			
		||||
 | 
			
		||||
    def init_options(self,noopt):
 | 
			
		||||
        self.options_dict = {
 | 
			
		||||
            'id'        : ''
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        self.options_help = {
 | 
			
		||||
            'id'        : ["=ID","Gramps ID of a central person."],
 | 
			
		||||
            'filter'    : ["=num","Filter number."],
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        if noopt:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        # Add tool-specific options
 | 
			
		||||
        for key in self.option_class.handler.options_dict.keys():
 | 
			
		||||
            if key not in self.options_dict.keys():
 | 
			
		||||
                self.options_dict[key] = self.option_class.handler.options_dict[key]
 | 
			
		||||
 | 
			
		||||
        # Add help for tool-specific options
 | 
			
		||||
        for key in self.option_class.options_help.keys():
 | 
			
		||||
            if key not in self.options_help.keys():
 | 
			
		||||
                self.options_help[key] = self.option_class.options_help[key]
 | 
			
		||||
 | 
			
		||||
    def parse_option_str(self):
 | 
			
		||||
        for opt in self.options_str_dict.keys():
 | 
			
		||||
            if opt in self.options_dict.keys():
 | 
			
		||||
                converter = Utils.get_type_converter(self.options_dict[opt])
 | 
			
		||||
                self.options_dict[opt] = converter(self.options_str_dict[opt])
 | 
			
		||||
                self.option_class.handler.options_dict[opt] = self.options_dict[opt]
 | 
			
		||||
            else:
 | 
			
		||||
                print "Ignoring unknown option: %s" % opt
 | 
			
		||||
 | 
			
		||||
        person_id = self.options_dict['id']
 | 
			
		||||
        self.person = self.database.get_person_from_gramps_id(person_id)
 | 
			
		||||
        id_list = []
 | 
			
		||||
        for person_handle in self.database.get_person_handles():
 | 
			
		||||
            person = self.database.get_person_from_handle(person_handle)
 | 
			
		||||
            id_list.append("%s\t%s" % (
 | 
			
		||||
                person.get_gramps_id(),
 | 
			
		||||
                NameDisplay.displayer.display(person)))
 | 
			
		||||
        self.options_help['id'].append(id_list)
 | 
			
		||||
        self.options_help['id'].append(False)
 | 
			
		||||
 | 
			
		||||
        if self.options_dict.has_key('filter'):
 | 
			
		||||
            filter_num = self.options_dict['filter']
 | 
			
		||||
            self.filters = self.option_class.get_report_filters(self.person)
 | 
			
		||||
            self.option_class.handler.set_filter_number(filter_num)
 | 
			
		||||
            
 | 
			
		||||
            filt_list = [ filt.get_name() for filt in self.filters ]
 | 
			
		||||
            cust_filt_list = [ filt2.get_name() for filt2 in 
 | 
			
		||||
                                GenericFilter.CustomFilters.get_filters() ]
 | 
			
		||||
            filt_list.extend(cust_filt_list)
 | 
			
		||||
            self.options_help['filter'].append(filt_list)
 | 
			
		||||
            self.options_help['filter'].append(True)
 | 
			
		||||
 | 
			
		||||
    def show_options(self):
 | 
			
		||||
        if not self.show:
 | 
			
		||||
            return
 | 
			
		||||
        elif self.show == 'all':
 | 
			
		||||
            print "   Available options:"
 | 
			
		||||
            for key in self.options_dict.keys():
 | 
			
		||||
                print "      %s" % key
 | 
			
		||||
            print "   Use 'show=option' to see description and acceptable values"
 | 
			
		||||
        elif self.show in self.options_dict.keys():
 | 
			
		||||
            print '   %s%s\t%s' % (self.show,
 | 
			
		||||
                                    self.options_help[self.show][0],
 | 
			
		||||
                                    self.options_help[self.show][1])
 | 
			
		||||
            print "   Available values are:"
 | 
			
		||||
            vals = self.options_help[self.show][2]
 | 
			
		||||
            if type(vals) in [list,tuple]:
 | 
			
		||||
                if self.options_help[self.show][3]:
 | 
			
		||||
                    for num in range(len(vals)):
 | 
			
		||||
                        print "      %d\t%s" % (num,vals[num])
 | 
			
		||||
                else:
 | 
			
		||||
                    for val in vals:
 | 
			
		||||
                        print "      %s" % val
 | 
			
		||||
            else:
 | 
			
		||||
                print "      %s" % self.options_help[self.show][2]
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
            self.show = None
 | 
			
		||||
 | 
			
		||||
#------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Generic task functions for tools
 | 
			
		||||
#
 | 
			
		||||
#------------------------------------------------------------------------
 | 
			
		||||
# Standard GUI tool generic task
 | 
			
		||||
def gui_tool(database,person,tool_class,options_class,translated_name,
 | 
			
		||||
             name,category,callback,parent):
 | 
			
		||||
    """
 | 
			
		||||
    tool - task starts the report. The plugin system requires that the
 | 
			
		||||
    task be in the format of task that takes a database and a person as
 | 
			
		||||
    its arguments.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        tool_class(database,person,options_class,name,callback,parent)
 | 
			
		||||
    except:
 | 
			
		||||
        log.error("Failed to start tool.", exc_info=True)
 | 
			
		||||
 | 
			
		||||
# Command-line generic task
 | 
			
		||||
def cli_tool(database,name,category,tool_class,options_class,options_str_dict):
 | 
			
		||||
    
 | 
			
		||||
    clt = CommandLineTool(database,name,category,
 | 
			
		||||
                          options_class,options_str_dict)
 | 
			
		||||
 | 
			
		||||
    # Exit here if show option was given
 | 
			
		||||
    if clt.show:
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    # run tool
 | 
			
		||||
    try:
 | 
			
		||||
        tool_class(database,clt.person,clt.option_class,name)
 | 
			
		||||
    except:
 | 
			
		||||
        log.error("Failed to start tool.", exc_info=True)
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Class handling options for plugins 
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
class OptionHandler(OptionHandler):
 | 
			
		||||
    """
 | 
			
		||||
    Implements handling of the options for the plugins.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self,module_name,options_dict,person_id=None):
 | 
			
		||||
        OptionHandler.__init__(self,module_name,options_dict,person_id)
 | 
			
		||||
 | 
			
		||||
    def init_subclass(self):
 | 
			
		||||
        self.collection_class = OptionListCollection
 | 
			
		||||
        self.list_class = OptionList
 | 
			
		||||
        self.filename = const.tool_options
 | 
			
		||||
 | 
			
		||||
#------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Tool Options class
 | 
			
		||||
#
 | 
			
		||||
#------------------------------------------------------------------------
 | 
			
		||||
class ToolOptions(Options):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    Defines options and provides handling interface.
 | 
			
		||||
    
 | 
			
		||||
    This is a base Options class for the tools. All tools' options
 | 
			
		||||
    classes should derive from it.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self,name,person_id=None):
 | 
			
		||||
        """
 | 
			
		||||
        Initializes the class, performing usual house-keeping tasks.
 | 
			
		||||
        Subclasses MUST call this in their __init__() method.
 | 
			
		||||
        """
 | 
			
		||||
        self.set_new_options()
 | 
			
		||||
        self.enable_options()
 | 
			
		||||
 | 
			
		||||
        if self.enable_dict:
 | 
			
		||||
            self.options_dict.update(self.enable_dict)
 | 
			
		||||
        self.handler = OptionHandler(name,self.options_dict,person_id)
 | 
			
		||||
@@ -20,6 +20,5 @@
 | 
			
		||||
 | 
			
		||||
# $Id: Report.py 6044 2006-03-03 00:10:52Z rshura $
 | 
			
		||||
 | 
			
		||||
from _Report import *
 | 
			
		||||
from _Tool import *
 | 
			
		||||
from _ReportUtils import *
 | 
			
		||||
import Report
 | 
			
		||||
import Tool
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user