Add MenuOptions class for report options.
svn: r8926
This commit is contained in:
parent
af618d3079
commit
febd6e9ed5
@ -1,3 +1,12 @@
|
||||
2007-09-04 Brian Matherly <brian@gramps-project.org>
|
||||
* src/ReportBase/__init__.py: Add MenuOptions
|
||||
* src/ReportBase/_MenuOptions.py: Added
|
||||
* src/ReportBase/Makefile.am: Add MenuOptions
|
||||
* src/plugins/DescendChart.py: Use MenuOptions
|
||||
* src/plugins/AncestorChart.py: Use MenuOptions
|
||||
* src/plugins/FanChart.py: Use MenuOptions
|
||||
* src/Utils.py (get_type_converter): Handle boolean types.
|
||||
|
||||
2007-09-03 Don Allingham <don@gramps-project.org>
|
||||
* plugins/WritePkg.py: fix package export
|
||||
* GrampsDbUtils/_WriteXML.py: fix package export
|
||||
|
@ -12,6 +12,7 @@ pkgdata_PYTHON = \
|
||||
_DrawReportDialog.py\
|
||||
_Endnotes.py\
|
||||
_FileEntry.py\
|
||||
_MenuOptions.py\
|
||||
__init__.py\
|
||||
_PaperMenu.py\
|
||||
_PrintTools.py\
|
||||
|
533
src/ReportBase/_MenuOptions.py
Normal file
533
src/ReportBase/_MenuOptions.py
Normal file
@ -0,0 +1,533 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2007 Brian G. Matherly
|
||||
#
|
||||
# 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: $
|
||||
|
||||
"""
|
||||
Abstracted option handling.
|
||||
"""
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# gtk
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from _ReportOptions import ReportOptions
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Option class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class Option:
|
||||
"""
|
||||
This class serves as a base class for all options. All Options must
|
||||
minimally provide the services provided by this class. Options are allowed
|
||||
to add additional functionality.
|
||||
"""
|
||||
def __init__(self,label,value):
|
||||
"""
|
||||
@param label: A friendly label to be applied to this option.
|
||||
Example: "Exclude living people"
|
||||
@type label: string
|
||||
@param value: An initial value for this option.
|
||||
Example: True
|
||||
@type value: The type will depend on the type of option.
|
||||
@return: nothing
|
||||
"""
|
||||
self.__value = value
|
||||
self.__label = label
|
||||
self.__help_str = ""
|
||||
|
||||
def get_label(self):
|
||||
"""
|
||||
Get the friendly label for this option.
|
||||
|
||||
@return: string
|
||||
"""
|
||||
return self.__label
|
||||
|
||||
def set_label(self,label):
|
||||
"""
|
||||
Set the friendly label for this option.
|
||||
|
||||
@param label: A friendly label to be applied to this option.
|
||||
Example: "Exclude living people"
|
||||
@type label: string
|
||||
@return: nothing
|
||||
"""
|
||||
self.__label = label
|
||||
|
||||
def get_value(self):
|
||||
"""
|
||||
Get the value of this option.
|
||||
|
||||
@return: The option value.
|
||||
"""
|
||||
return self.__value
|
||||
|
||||
def set_value(self,value):
|
||||
"""
|
||||
Set the value of this option.
|
||||
|
||||
@param value: A value for this option.
|
||||
Example: True
|
||||
@type value: The type will depend on the type of option.
|
||||
@return: nothing
|
||||
"""
|
||||
self.__value = value
|
||||
|
||||
def get_help(self):
|
||||
"""
|
||||
Get the help information for this option.
|
||||
|
||||
@return: A string that provides additional help beyond the label.
|
||||
"""
|
||||
return self.__help_str
|
||||
|
||||
def set_help(self,help):
|
||||
"""
|
||||
Set the help information for this option.
|
||||
|
||||
@param help: A string that provides additional help beyond the label.
|
||||
Example: "Whether to include or exclude people who are calculated
|
||||
to be alive at the time of the generation of this report"
|
||||
@type value: string
|
||||
@return: nothing
|
||||
"""
|
||||
self.__help_str = help
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# StringOption class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class StringOption(Option):
|
||||
"""
|
||||
This class describes an option that is a simple one-line string.
|
||||
"""
|
||||
def __init__(self,label,value):
|
||||
"""
|
||||
@param label: A friendly label to be applied to this option.
|
||||
Example: "Page header"
|
||||
@type label: string
|
||||
@param value: An initial value for this option.
|
||||
Example: "Generated by GRAMPS"
|
||||
@type value: string
|
||||
@return: nothing
|
||||
"""
|
||||
Option.__init__(self,label,value)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# NumberOption class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class NumberOption(Option):
|
||||
"""
|
||||
This class describes an option that is a simple number with defined maximum
|
||||
and minimum values.
|
||||
"""
|
||||
def __init__(self,label,value,min,max):
|
||||
"""
|
||||
@param label: A friendly label to be applied to this option.
|
||||
Example: "Number of generations to include"
|
||||
@type label: string
|
||||
@param value: An initial value for this option.
|
||||
Example: 5
|
||||
@type value: int
|
||||
@param min: The minimum value for this option.
|
||||
Example: 1
|
||||
@type min: int
|
||||
@param max: The maximum value for this option.
|
||||
Example: 10
|
||||
@type value: int
|
||||
@return: nothing
|
||||
"""
|
||||
Option.__init__(self,label,value)
|
||||
self.__min = min
|
||||
self.__max = max
|
||||
|
||||
def get_min(self):
|
||||
"""
|
||||
Get the minimum value for this option.
|
||||
|
||||
@return: an int that represents the minimum value for this option.
|
||||
"""
|
||||
return self.__min
|
||||
|
||||
def get_max(self):
|
||||
"""
|
||||
Get the maximum value for this option.
|
||||
|
||||
@return: an int that represents the maximum value for this option.
|
||||
"""
|
||||
return self.__max
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# TextOption class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class TextOption(Option):
|
||||
"""
|
||||
This class describes an option that is a multi-line string.
|
||||
"""
|
||||
def __init__(self,label,value):
|
||||
"""
|
||||
@param label: A friendly label to be applied to this option.
|
||||
Example: "Page header"
|
||||
@type label: string
|
||||
@param value: An initial value for this option.
|
||||
Example: "Generated by GRAMPS\nCopyright 2007"
|
||||
@type value: string
|
||||
@return: nothing
|
||||
"""
|
||||
Option.__init__(self,label,value)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# BooleanOption class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class BooleanOption(Option):
|
||||
"""
|
||||
This class describes an option that is a boolean (True or False).
|
||||
"""
|
||||
def __init__(self,label,value):
|
||||
"""
|
||||
@param label: A friendly label to be applied to this option.
|
||||
Example: "Exclude living people"
|
||||
@type label: string
|
||||
@param value: An initial value for this option.
|
||||
Example: True
|
||||
@type value: boolean
|
||||
@return: nothing
|
||||
"""
|
||||
Option.__init__(self,label,value)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# EnumeratedListOption class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class EnumeratedListOption(Option):
|
||||
"""
|
||||
This class describes an option that provides a finite number of values.
|
||||
Each possible value is assigned a value and a description.
|
||||
"""
|
||||
def __init__(self,label,value):
|
||||
"""
|
||||
@param label: A friendly label to be applied to this option.
|
||||
Example: "Paper Size"
|
||||
@type label: string
|
||||
@param value: An initial value for this option.
|
||||
Example: 5
|
||||
@type value: int
|
||||
@return: nothing
|
||||
"""
|
||||
Option.__init__(self,label,value)
|
||||
self.__items = []
|
||||
|
||||
def add_item(self,value,description):
|
||||
"""
|
||||
Add an item to the list of possible values.
|
||||
|
||||
@param value: The value that corresponds to this item.
|
||||
Example: 5
|
||||
@type value: int
|
||||
@param description: A description of this value.
|
||||
Example: "8.5 x 11"
|
||||
@type description: string
|
||||
@return: nothing
|
||||
"""
|
||||
self.__items.append((value, description))
|
||||
|
||||
def get_items(self):
|
||||
"""
|
||||
Get all the possible values for this option.
|
||||
|
||||
@return: an array of tuples containing (value,description) pairs.
|
||||
"""
|
||||
return self.__items
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Menu class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class Menu:
|
||||
"""
|
||||
Introduction
|
||||
============
|
||||
A Menu is used to maintain a collection of options that need to be
|
||||
represented to the user in a non-implementation specific way. The options
|
||||
can be described using the various option classes. A menu contains many
|
||||
options and associates them with a unique name and category.
|
||||
|
||||
Usage
|
||||
=====
|
||||
Menus are used in the following way.
|
||||
|
||||
1. Create a option object and configure all the attributes of the option.
|
||||
2. Add the option to the menu by specifying the option, name and category.
|
||||
3. Add as many options as necessary.
|
||||
4. When all the options are added, the menu can be stored and passed to
|
||||
the part of the system that will actually represent the menu to
|
||||
the user.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.__options = {}
|
||||
|
||||
def add_option(self,category,name,option):
|
||||
"""
|
||||
Add an option to the menu.
|
||||
|
||||
@param category: A label that describes the category that the option
|
||||
belongs to.
|
||||
Example: "Report Options"
|
||||
@type category: string
|
||||
@param name: A name that is unique to this option.
|
||||
Example: "generations"
|
||||
@type name: string
|
||||
@param option: The option instance to be added to this menu.
|
||||
@type option: Option
|
||||
@return: nothing
|
||||
"""
|
||||
if not self.__options.has_key(category):
|
||||
self.__options[category] = []
|
||||
self.__options[category].append((name,option))
|
||||
|
||||
def get_categories(self):
|
||||
"""
|
||||
Get a list of categories in this menu.
|
||||
|
||||
@return: a list of strings
|
||||
"""
|
||||
categories = []
|
||||
for category in self.__options:
|
||||
categories.append(category)
|
||||
return categories
|
||||
|
||||
def get_option_names(self,category):
|
||||
"""
|
||||
Get a list of option names for the specified category.
|
||||
|
||||
@return: a list of strings
|
||||
"""
|
||||
names = []
|
||||
for (name,option) in self.__options[category]:
|
||||
names.append(name)
|
||||
return names
|
||||
|
||||
def get_option(self,category,name):
|
||||
"""
|
||||
Get an option with the specified category and name.
|
||||
|
||||
@return: an Option instance or None on failure.
|
||||
"""
|
||||
for (oname,option) in self.__options[category]:
|
||||
if oname == name:
|
||||
return option
|
||||
return None
|
||||
|
||||
def get_all_option_names(self):
|
||||
"""
|
||||
Get a list of all the option names in this menu.
|
||||
|
||||
@return: a list of strings
|
||||
"""
|
||||
names = []
|
||||
for category in self.__options:
|
||||
for (name,option) in self.__options[category]:
|
||||
names.append(name)
|
||||
return names
|
||||
|
||||
def get_option_by_name(self,name):
|
||||
"""
|
||||
Get an option with the specified name.
|
||||
|
||||
@return: an Option instance or None on failure.
|
||||
"""
|
||||
for category in self.__options.keys():
|
||||
for (oname,option) in self.__options[category]:
|
||||
if oname == name:
|
||||
return option
|
||||
return None
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# MenuOptions class
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class MenuOptions(ReportOptions):
|
||||
"""
|
||||
The MenuOptions class implementes the ReportOptions functionality in a
|
||||
generic way so that the user does not need to be concerned with the
|
||||
graphical representation of the options.
|
||||
|
||||
The user should inherit the MenuOptions class and override the
|
||||
add_menu_options function. The user can add options to the menu and the
|
||||
MenuOptions class will worry about setting up the GUI.
|
||||
"""
|
||||
def __init__(self,name,person_id=None):
|
||||
self.menu = Menu()
|
||||
ReportOptions.__init__(self,name, person_id)
|
||||
|
||||
def make_default_style(self,default_style):
|
||||
pass
|
||||
|
||||
def set_new_options(self):
|
||||
self.options_dict = {}
|
||||
self.options_help = {}
|
||||
|
||||
self.add_menu_options(self.menu)
|
||||
|
||||
for name in self.menu.get_all_option_names():
|
||||
option = self.menu.get_option_by_name(name)
|
||||
self.options_dict[name] = option.get_value()
|
||||
self.options_help[name] = option.get_help()
|
||||
|
||||
def add_menu_options(self,menu):
|
||||
"""
|
||||
Add the user defined options to the menu.
|
||||
|
||||
@param menu: A menu class for the options to belong to.
|
||||
@type menu: Menu
|
||||
@return: nothing
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def add_user_options(self,dialog):
|
||||
self.gui = {}
|
||||
self.tooltips = gtk.Tooltips()
|
||||
|
||||
for category in self.menu.get_categories():
|
||||
for name in self.menu.get_option_names(category):
|
||||
option = self.menu.get_option(category,name)
|
||||
otype = option.__class__
|
||||
|
||||
if otype == NumberOption:
|
||||
self.__add_number_option(category,name,option,dialog)
|
||||
elif otype == TextOption:
|
||||
self.__add_text_option(category,name,option,dialog)
|
||||
elif otype == BooleanOption:
|
||||
self.__add_boolean_option(category,name,option,dialog)
|
||||
elif otype == EnumeratedListOption:
|
||||
self.__add_enumerated_list_option(category,name,option,
|
||||
dialog)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
def parse_user_options(self,dialog):
|
||||
for name in self.menu.get_all_option_names():
|
||||
option = self.menu.get_option_by_name(name)
|
||||
otype = option.__class__
|
||||
|
||||
if otype == NumberOption:
|
||||
self.__parse_number_option(name,option)
|
||||
elif otype == TextOption:
|
||||
self.__parse_text_option(name,option)
|
||||
elif otype == BooleanOption:
|
||||
self.__parse_boolean_option(name,option)
|
||||
elif otype == EnumeratedListOption:
|
||||
self.__parse_enumerated_list_option(name,option)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
def __add_number_option(self,category,name,option,dialog):
|
||||
"""
|
||||
Add a NumberOption to the dialog.
|
||||
"""
|
||||
adj = gtk.Adjustment(1,option.get_min(),option.get_max(),1)
|
||||
self.gui[name] = gtk.SpinButton(adj)
|
||||
self.gui[name].set_value(self.options_dict[name])
|
||||
dialog.add_frame_option(category,option.get_label(),self.gui[name])
|
||||
|
||||
self.tooltips.set_tip(self.gui[name],option.get_help())
|
||||
|
||||
def __parse_number_option(self,name,option):
|
||||
self.options_dict[name] = int(self.gui[name].get_value_as_int())
|
||||
|
||||
def __add_text_option(self,category,name,option,dialog):
|
||||
"""
|
||||
Add a TextOption to the dialog.
|
||||
"""
|
||||
self.gui[name] = gtk.TextView()
|
||||
self.gui[name].get_buffer().set_text("\n".join(self.options_dict[name]))
|
||||
self.gui[name].set_editable(1)
|
||||
swin = gtk.ScrolledWindow()
|
||||
swin.set_shadow_type(gtk.SHADOW_IN)
|
||||
swin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
|
||||
swin.add(self.gui[name])
|
||||
dialog.add_frame_option(category,option.get_label(),swin)
|
||||
|
||||
# Required for tooltip
|
||||
self.gui[name].add_events(gtk.gdk.ENTER_NOTIFY_MASK)
|
||||
self.gui[name].add_events(gtk.gdk.LEAVE_NOTIFY_MASK)
|
||||
self.tooltips.set_tip(self.gui[name],option.get_help())
|
||||
|
||||
def __parse_text_option(self,name,option):
|
||||
b = self.gui[name].get_buffer()
|
||||
text_val = unicode( b.get_text( b.get_start_iter(),
|
||||
b.get_end_iter(),
|
||||
False) )
|
||||
self.options_dict[name] = text_val.split('\n')
|
||||
|
||||
def __add_boolean_option(self,category,name,option,dialog):
|
||||
"""
|
||||
Add a BooleanOption to the dialog.
|
||||
"""
|
||||
self.gui[name] = gtk.CheckButton(option.get_label())
|
||||
self.gui[name].set_active(self.options_dict[name])
|
||||
dialog.add_frame_option(category,"",self.gui[name])
|
||||
|
||||
self.tooltips.set_tip(self.gui[name],option.get_help())
|
||||
|
||||
def __parse_boolean_option(self,name,option):
|
||||
self.options_dict[name] = self.gui[name].get_active()
|
||||
|
||||
def __add_enumerated_list_option(self,category,name,option,dialog):
|
||||
"""
|
||||
Add an EnumeratedListOption to the dialog.
|
||||
"""
|
||||
active_index = 0
|
||||
current_index = 0
|
||||
self.gui[name] = gtk.combo_box_new_text()
|
||||
for (value,description) in option.get_items():
|
||||
self.gui[name].append_text(description)
|
||||
if value == self.options_dict[name]:
|
||||
active_index = current_index
|
||||
current_index += 1
|
||||
self.gui[name].set_active( active_index )
|
||||
dialog.add_frame_option(category,option.get_label(),self.gui[name])
|
||||
|
||||
self.tooltips.set_tip(self.gui[name],option.get_help())
|
||||
|
||||
def __parse_enumerated_list_option(self,name,option):
|
||||
index = self.gui[name].get_active()
|
||||
items = option.get_items()
|
||||
(value,description) = items[index]
|
||||
self.options_dict[name] = value
|
@ -37,6 +37,8 @@ from _DrawReportDialog import DrawReportDialog
|
||||
from _TextReportDialog import TextReportDialog
|
||||
|
||||
from _ReportOptions import ReportOptions
|
||||
from _MenuOptions import MenuOptions, NumberOption, BooleanOption, TextOption, \
|
||||
EnumeratedListOption
|
||||
import _ReportUtils as ReportUtils
|
||||
|
||||
from _Bibliography import Bibliography, Citation
|
||||
|
@ -831,6 +831,11 @@ def get_new_filename(ext,folder='~/'):
|
||||
ix = ix + 1
|
||||
return os.path.expanduser(_NEW_NAME_PATTERN % (folder,os.path.sep,ix,ext))
|
||||
|
||||
def cast_to_bool(val):
|
||||
if val == str(True):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_type_converter(val):
|
||||
"""
|
||||
Returns function that converts strings into the type of val.
|
||||
@ -842,6 +847,8 @@ def get_type_converter(val):
|
||||
return int
|
||||
elif val_type == float:
|
||||
return float
|
||||
elif val_type == bool:
|
||||
return cast_to_bool
|
||||
elif val_type in (list,tuple):
|
||||
return list
|
||||
|
||||
|
@ -31,13 +31,6 @@
|
||||
import math
|
||||
from gettext import gettext as _
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# gtk
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
@ -46,7 +39,8 @@ import gtk
|
||||
import BaseDoc
|
||||
from SubstKeywords import SubstKeywords
|
||||
from PluginUtils import register_report
|
||||
from ReportBase import Report, ReportUtils, ReportOptions, \
|
||||
from ReportBase import Report, ReportUtils, \
|
||||
MenuOptions, NumberOption, BooleanOption, TextOption, \
|
||||
CATEGORY_DRAW, MODE_GUI, MODE_BKI, MODE_CLI
|
||||
from BasicUtils import name_displayer
|
||||
pt2cm = ReportUtils.pt2cm
|
||||
@ -235,7 +229,7 @@ class AncestorChart(Report):
|
||||
em = self.doc.string_width(font,"m")
|
||||
|
||||
subst = SubstKeywords(self.database,person_handle)
|
||||
self.text[index] = subst.replace_and_clean(self.display.split('\n'))
|
||||
self.text[index] = subst.replace_and_clean(self.display)
|
||||
|
||||
for line in self.text[index]:
|
||||
this_box_width = self.doc.string_width(font,line)
|
||||
@ -440,83 +434,38 @@ class AncestorChart(Report):
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class AncestorChartOptions(ReportOptions):
|
||||
class AncestorChartOptions(MenuOptions):
|
||||
|
||||
"""
|
||||
Defines options and provides handling interface.
|
||||
"""
|
||||
|
||||
def __init__(self,name,person_id=None):
|
||||
ReportOptions.__init__(self,name,person_id)
|
||||
|
||||
def set_new_options(self):
|
||||
# Options specific for this report
|
||||
self.options_dict = {
|
||||
'dispf' : "$n\n%s $b\n%s $d" % (_BORN,_DIED),
|
||||
'maxgen' : 10,
|
||||
'singlep' : 1,
|
||||
'incblank' : 1,
|
||||
'compress' : 1,
|
||||
}
|
||||
self.options_help = {
|
||||
'dispf' : ("=str","Display format for the outputbox.",
|
||||
"Allows you to customize the data in the boxes in the report",
|
||||
True),
|
||||
'maxgen' : ("=int","Generations",
|
||||
"The number of generations to include in the report",
|
||||
True),
|
||||
'singlep' : ("=0/1","Whether to scale to fit on a single page.",
|
||||
["Do not scale to fit","Scale to fit"],
|
||||
True),
|
||||
'incblank' : ("=0/1","Whether to include pages that are blank.",
|
||||
["Do not include blank pages","Include blank pages"],
|
||||
True),
|
||||
'compress' : ("=0/1","Whether to compress chart.",
|
||||
["Do not compress chart","Compress chart"],
|
||||
True),
|
||||
}
|
||||
|
||||
def add_user_options(self,dialog):
|
||||
"""
|
||||
Override the base class add_user_options task to add a menu that allows
|
||||
the user to select the sort method.
|
||||
"""
|
||||
self.max_gen = gtk.SpinButton(gtk.Adjustment(1,1,100,1))
|
||||
self.max_gen.set_value(self.options_dict['maxgen'])
|
||||
dialog.add_option(_('Generations'),self.max_gen)
|
||||
MenuOptions.__init__(self,name,person_id)
|
||||
|
||||
self.extra_textbox = gtk.TextView()
|
||||
self.extra_textbox.get_buffer().set_text(self.options_dict['dispf'])
|
||||
self.extra_textbox.set_editable(1)
|
||||
swin = gtk.ScrolledWindow()
|
||||
swin.set_shadow_type(gtk.SHADOW_IN)
|
||||
swin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
|
||||
swin.add(self.extra_textbox)
|
||||
dialog.add_option(_("Display Format"),swin)
|
||||
|
||||
self.scale = gtk.CheckButton(_('Sc_ale to fit on a single page'))
|
||||
self.scale.set_active(self.options_dict['singlep'])
|
||||
dialog.add_option('',self.scale)
|
||||
|
||||
self.blank = gtk.CheckButton(_('Include Blank Pages'))
|
||||
self.blank.set_active(self.options_dict['incblank'])
|
||||
dialog.add_option('',self.blank)
|
||||
|
||||
self.compress = gtk.CheckButton(_('Co_mpress chart'))
|
||||
self.compress.set_active(self.options_dict['compress'])
|
||||
dialog.add_option('',self.compress)
|
||||
|
||||
def parse_user_options(self,dialog):
|
||||
"""
|
||||
Parses the custom options that we have added.
|
||||
"""
|
||||
b = self.extra_textbox.get_buffer()
|
||||
text_val = unicode(b.get_text(b.get_start_iter(),b.get_end_iter(),False))
|
||||
self.options_dict['dispf'] = text_val
|
||||
self.options_dict['maxgen'] = int(self.max_gen.get_value_as_int())
|
||||
self.options_dict['singlep'] = int(self.scale.get_active ())
|
||||
self.options_dict['incblank'] = int(self.blank.get_active())
|
||||
self.options_dict['compress'] = int(self.compress.get_active ())
|
||||
def add_menu_options(self,menu):
|
||||
category_name = _("Report Options")
|
||||
|
||||
max_gen = NumberOption(_("Generations"),10,1,50)
|
||||
max_gen.set_help(_("The number of generations to include in the report"))
|
||||
menu.add_option(category_name,"maxgen",max_gen)
|
||||
|
||||
disp = TextOption(_("Display Format"),
|
||||
["$n","%s $b" % _BORN,"%s $d" %_DIED] )
|
||||
disp.set_help(_("Display format for the outputbox."))
|
||||
menu.add_option(category_name,"dispf",disp)
|
||||
|
||||
scale = BooleanOption(_('Sc_ale to fit on a single page'),True)
|
||||
scale.set_help(_("Whether to scale to fit on a single page."))
|
||||
menu.add_option(category_name,"singlep",scale)
|
||||
|
||||
blank = BooleanOption(_('Include Blank Pages'),True)
|
||||
blank.set_help(_("Whether to include pages that are blank."))
|
||||
menu.add_option(category_name,"incblank",blank)
|
||||
|
||||
compress = BooleanOption(_('Co_mpress chart'),True)
|
||||
compress.set_help(_("Whether to compress chart."))
|
||||
menu.add_option(category_name,"compress",compress)
|
||||
|
||||
def make_default_style(self,default_style):
|
||||
"""Make the default output style for the Ancestor Chart report."""
|
||||
|
@ -28,29 +28,23 @@
|
||||
# python modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import math
|
||||
from BasicUtils import name_displayer
|
||||
from PluginUtils import register_report
|
||||
from ReportBase import Report, ReportOptions, ReportUtils, \
|
||||
MenuOptions, NumberOption, BooleanOption, TextOption, \
|
||||
CATEGORY_DRAW, MODE_GUI, MODE_BKI, MODE_CLI
|
||||
from SubstKeywords import SubstKeywords
|
||||
from gettext import gettext as _
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# gtk
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import gtk
|
||||
import BaseDoc
|
||||
import math
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import BaseDoc
|
||||
from PluginUtils import register_report
|
||||
from ReportBase import Report, ReportOptions, ReportUtils, \
|
||||
CATEGORY_DRAW, MODE_GUI, MODE_BKI, MODE_CLI
|
||||
pt2cm = ReportUtils.pt2cm
|
||||
cm2pt = ReportUtils.cm2pt
|
||||
from SubstKeywords import SubstKeywords
|
||||
from BasicUtils import name_displayer
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@ -174,7 +168,7 @@ class DescendChart(Report):
|
||||
em = self.doc.string_width(font,"m")
|
||||
|
||||
subst = SubstKeywords(self.database,person_handle)
|
||||
self.text[(x,y)] = subst.replace_and_clean(self.display.split('\n'))
|
||||
self.text[(x,y)] = subst.replace_and_clean(self.display)
|
||||
for line in self.text[(x,y)]:
|
||||
this_box_width = self.doc.string_width(font,line) + 2*em
|
||||
self.box_width = max(self.box_width,this_box_width)
|
||||
@ -394,76 +388,39 @@ class DescendChart(Report):
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class DescendChartOptions(ReportOptions):
|
||||
class DescendChartOptions(MenuOptions):
|
||||
|
||||
"""
|
||||
Defines options and provides handling interface.
|
||||
"""
|
||||
|
||||
def __init__(self,name,person_id=None):
|
||||
ReportOptions.__init__(self,name,person_id)
|
||||
|
||||
def set_new_options(self):
|
||||
# Options specific for this report
|
||||
self.options_dict = {
|
||||
'dispf' : "$n\n%s $b\n%s $d" % (_BORN,_DIED),
|
||||
'maxgen' : 32,
|
||||
'singlep' : 1,
|
||||
'incblank' : 1,
|
||||
'incblank' : 1,
|
||||
}
|
||||
self.options_help = {
|
||||
'dispf' : ("=str","Display format for the outputbox.",
|
||||
"Allows you to customize the data in the boxes in the report",
|
||||
True),
|
||||
'maxgen' : ("=int","Generations",
|
||||
"The number of generations to include in the report",
|
||||
True),
|
||||
'singlep' : ("=0/1","Whether to scale to fit on a single page.",
|
||||
["Do not scale to fit","Scale to fit"],
|
||||
True),
|
||||
'incblank' : ("=0/1","Whether to include pages that are blank.",
|
||||
["Do not include blank pages","Include blank pages"],
|
||||
True),
|
||||
}
|
||||
|
||||
def add_user_options(self,dialog):
|
||||
"""
|
||||
Override the base class add_user_options task to add a menu that allows
|
||||
the user to select the sort method.
|
||||
"""
|
||||
self.max_gen = gtk.SpinButton(gtk.Adjustment(1,1,100,1))
|
||||
self.max_gen.set_value(self.options_dict['maxgen'])
|
||||
dialog.add_option(_('Generations'),self.max_gen)
|
||||
MenuOptions.__init__(self,name,person_id)
|
||||
|
||||
self.extra_textbox = gtk.TextView()
|
||||
self.extra_textbox.get_buffer().set_text(self.options_dict['dispf'])
|
||||
self.extra_textbox.set_editable(1)
|
||||
swin = gtk.ScrolledWindow()
|
||||
swin.set_shadow_type(gtk.SHADOW_IN)
|
||||
swin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
|
||||
swin.add(self.extra_textbox)
|
||||
dialog.add_option(_("Display Format"),swin)
|
||||
|
||||
self.scale = gtk.CheckButton(_('Sc_ale to fit on a single page'))
|
||||
self.scale.set_active(self.options_dict['singlep'])
|
||||
dialog.add_option('',self.scale)
|
||||
def add_menu_options(self,menu):
|
||||
category_name = _("Report Options")
|
||||
|
||||
max_gen = NumberOption(_("Generations"),10,1,50)
|
||||
max_gen.set_help(_("The number of generations to include in the report"))
|
||||
menu.add_option(category_name,"maxgen",max_gen)
|
||||
|
||||
disp = TextOption( _("Display Format"),
|
||||
["$n","%s $b" % _BORN,"%s $d" %_DIED] )
|
||||
disp.set_help(_("Display format for the outputbox."))
|
||||
menu.add_option(category_name,"dispf",disp)
|
||||
|
||||
scale = BooleanOption(_('Sc_ale to fit on a single page'),True)
|
||||
scale.set_help(_("Whether to scale to fit on a single page."))
|
||||
menu.add_option(category_name,"singlep",scale)
|
||||
|
||||
blank = BooleanOption(_('Include Blank Pages'),True)
|
||||
blank.set_help(_("Whether to include pages that are blank."))
|
||||
menu.add_option(category_name,"incblank",blank)
|
||||
|
||||
compress = BooleanOption(_('Co_mpress chart'),True)
|
||||
compress.set_help(_("Whether to compress chart."))
|
||||
menu.add_option(category_name,"compress",compress)
|
||||
|
||||
self.blank = gtk.CheckButton(_('Include Blank Pages'))
|
||||
self.blank.set_active(self.options_dict['incblank'])
|
||||
dialog.add_option('',self.blank)
|
||||
|
||||
def parse_user_options(self,dialog):
|
||||
"""
|
||||
Parses the custom options that we have added.
|
||||
"""
|
||||
b = self.extra_textbox.get_buffer()
|
||||
text_val = unicode(b.get_text(b.get_start_iter(),b.get_end_iter(),False))
|
||||
self.options_dict['dispf'] = text_val
|
||||
self.options_dict['maxgen'] = int(self.max_gen.get_value_as_int())
|
||||
self.options_dict['singlep'] = int(self.scale.get_active ())
|
||||
self.options_dict['incblank'] = int(self.blank.get_active())
|
||||
|
||||
def make_default_style(self,default_style):
|
||||
"""Make the default output style for the Ancestor Chart report."""
|
||||
## Paragraph Styles:
|
||||
@ -507,7 +464,7 @@ class DescendChartOptions(ReportOptions):
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
register_report(
|
||||
name = 'descend_chart2',
|
||||
name = 'descend_chart',
|
||||
category = CATEGORY_DRAW,
|
||||
report_class = DescendChart,
|
||||
options_class = DescendChartOptions,
|
||||
|
@ -28,13 +28,6 @@
|
||||
#------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# gnome/gtk
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
@ -43,8 +36,25 @@ import gtk
|
||||
import BaseDoc
|
||||
from PluginUtils import register_report
|
||||
from ReportBase import Report, ReportUtils, ReportOptions, \
|
||||
MenuOptions, NumberOption, EnumeratedListOption, \
|
||||
CATEGORY_DRAW, MODE_GUI, MODE_BKI, MODE_CLI
|
||||
from SubstKeywords import SubstKeywords
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# private constants
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
FULL_CIRCLE = 0
|
||||
HALF_CIRCLE = 1
|
||||
QUAR_CIRCLE = 2
|
||||
|
||||
BACKGROUND_WHITE = 0
|
||||
BACKGROUND_GEN = 1
|
||||
|
||||
RADIAL_UPRIGHT = 0
|
||||
RADIAL_ROUNDABOUT = 1
|
||||
|
||||
pt2cm = ReportUtils.pt2cm
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
@ -68,24 +78,20 @@ class FanChart(Report):
|
||||
that come in the options class.
|
||||
|
||||
maxgen - Maximum number of generations to include.
|
||||
full_circle - != 0: draw a full circle; half_circle and quar_circle should be 0.
|
||||
half_circle - != 0: draw a half circle; full_circle and quar_circle should be 0.
|
||||
quar_circle - != 0: draw a quarter circle; full_circle and half_circle should be 0.
|
||||
backgr_white - 0: Background color is generation dependent; 1: Background color is white.
|
||||
radial_upright - 0: Print radial texts roundabout; 1: Print radial texts as upright as possible.
|
||||
circle - Draw a full circle, half circle, or quarter circle.
|
||||
background - Background color is generation dependent or white.
|
||||
radial - Print radial texts roundabout or as upright as possible.
|
||||
"""
|
||||
|
||||
self.max_generations = options_class.handler.options_dict['maxgen']
|
||||
self.full_circle = options_class.handler.options_dict['full_circle']
|
||||
self.half_circle = options_class.handler.options_dict['half_circle']
|
||||
self.quar_circle = options_class.handler.options_dict['quar_circle']
|
||||
self.backgr_white = options_class.handler.options_dict['backgr_white']
|
||||
self.radial_upright = options_class.handler.options_dict['radial_upright']
|
||||
self.circle = options_class.handler.options_dict['circle']
|
||||
self.background = options_class.handler.options_dict['background']
|
||||
self.radial = options_class.handler.options_dict['radial']
|
||||
|
||||
self.background_style = []
|
||||
self.text_style = []
|
||||
for i in range (0, self.max_generations):
|
||||
if self.backgr_white:
|
||||
if self.background == BACKGROUND_WHITE:
|
||||
background_style_name = 'background_style_white'
|
||||
else:
|
||||
background_style_name = 'background_style' + '%d' % i
|
||||
@ -140,7 +146,7 @@ class FanChart(Report):
|
||||
self.apply_filter(self.start_person.get_handle(),1)
|
||||
n = self.start_person.get_primary_name().get_regular_name()
|
||||
|
||||
if self.full_circle:
|
||||
if self.circle == FULL_CIRCLE:
|
||||
max_angle = 360.0
|
||||
start_angle = 90
|
||||
max_circular = 5
|
||||
@ -148,7 +154,7 @@ class FanChart(Report):
|
||||
y = self.doc.get_usable_height() / 2.0
|
||||
min_xy = min (x, y)
|
||||
|
||||
elif self.half_circle:
|
||||
elif self.circle == HALF_CIRCLE:
|
||||
max_angle = 180.0
|
||||
start_angle = 180
|
||||
max_circular = 3
|
||||
@ -216,9 +222,9 @@ class FanChart(Report):
|
||||
else:
|
||||
name = pn.get_first_name() + pn.get_surname()
|
||||
|
||||
if self.full_circle:
|
||||
if self.circle == FULL_CIRCLE:
|
||||
return [ name, val ]
|
||||
elif self.half_circle:
|
||||
elif self.circle == HALF_CIRCLE:
|
||||
return [ name, val ]
|
||||
else:
|
||||
if (name != "") and (val != ""):
|
||||
@ -227,9 +233,9 @@ class FanChart(Report):
|
||||
string = name + val
|
||||
return [string]
|
||||
elif generation == 6:
|
||||
if self.full_circle:
|
||||
if self.circle == FULL_CIRCLE:
|
||||
return [ pn.get_first_name(), pn.get_surname(), val ]
|
||||
elif self.half_circle:
|
||||
elif self.circle == HALF_CIRCLE:
|
||||
return [ pn.get_first_name(), pn.get_surname(), val ]
|
||||
else:
|
||||
if (pn.get_first_name() != "") and (pn.get_surname() != ""):
|
||||
@ -257,7 +263,7 @@ class FanChart(Report):
|
||||
(xc,yc) = ReportUtils.draw_wedge(self.doc,background_style, x, y, rad2,
|
||||
start_angle, end_angle, rad1)
|
||||
if self.map[index]:
|
||||
if (generation == 0) and self.full_circle:
|
||||
if (generation == 0) and self.circle == FULL_CIRCLE:
|
||||
yc = y
|
||||
self.doc.rotate_text(text_style,
|
||||
self.get_info(self.map[index],
|
||||
@ -273,10 +279,10 @@ class FanChart(Report):
|
||||
text_angle = start_angle - delta / 2.0
|
||||
background_style = self.background_style[generation]
|
||||
text_style = self.text_style[generation]
|
||||
if self.full_circle:
|
||||
if self.circle == FULL_CIRCLE:
|
||||
rad1 = size * ((generation * 2) - 5)
|
||||
rad2 = size * ((generation * 2) - 3)
|
||||
elif self.half_circle:
|
||||
elif self.circle == HALF_CIRCLE:
|
||||
rad1 = size * ((generation * 2) - 3)
|
||||
rad2 = size * ((generation * 2) - 1)
|
||||
else: # quarter circle
|
||||
@ -290,7 +296,7 @@ class FanChart(Report):
|
||||
start_angle, end_angle, rad1)
|
||||
text_angle += delta
|
||||
if self.map[index]:
|
||||
if self.radial_upright and (start_angle >= 90) and (start_angle < 270):
|
||||
if self.radial == RADIAL_UPRIGHT and (start_angle >= 90) and (start_angle < 270):
|
||||
self.doc.rotate_text(text_style,
|
||||
self.get_info(self.map[index],
|
||||
generation),
|
||||
@ -306,95 +312,41 @@ class FanChart(Report):
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class FanChartOptions(ReportOptions):
|
||||
|
||||
"""
|
||||
Defines options and provides handling interface for Fan Chart.
|
||||
"""
|
||||
class FanChartOptions(MenuOptions):
|
||||
|
||||
def __init__(self,name,person_id=None):
|
||||
ReportOptions.__init__(self,name,person_id)
|
||||
|
||||
self.MAX_GENERATIONS = 8
|
||||
|
||||
def set_new_options(self):
|
||||
# Options specific for this report
|
||||
self.options_dict = {
|
||||
'maxgen' : 5,
|
||||
'full_circle' : 0,
|
||||
'half_circle' : 1,
|
||||
'quar_circle' : 0,
|
||||
'backgr_white' : 0,
|
||||
'backgr_generation' : 1,
|
||||
'radial_upright' : 1,
|
||||
'radial_roundabout' : 0,
|
||||
}
|
||||
self.options_help = {
|
||||
'maxgen' : ("=num","Number of generations to print.",
|
||||
[],
|
||||
True),
|
||||
'full_circle': ("=0/1","The form of the diagram shall be a full circle.",
|
||||
["half or quarter circle","full circle"],
|
||||
True),
|
||||
'half_circle': ("=0/1","The form of the diagram shall be a half circle.",
|
||||
["full or quarter circle","half circle"],
|
||||
True),
|
||||
'quar_circle': ("=0/1","The form of the diagram shall be a quarter circle.",
|
||||
["full or half circle","quarter circle"],
|
||||
True),
|
||||
'backgr_white': ("=0/1","Background color is white.",
|
||||
["generation dependent","white"],
|
||||
True),
|
||||
'backgr_generation': ("=0/1","Background color is generation dependent.",
|
||||
["white","generation dependent"],
|
||||
True),
|
||||
'radial_upright': ("=0/1","Print radial texts as upright as possible.",
|
||||
["roundabout","upright"],
|
||||
True),
|
||||
'radial_roundabout': ("=0/1","Print radial texts roundabout.",
|
||||
["upright","roundabout"],
|
||||
True),
|
||||
}
|
||||
|
||||
def add_user_options(self,dialog):
|
||||
"""
|
||||
Override the base class add_user_options task to add a menu that allows
|
||||
the user to select the number of generations to print, ....
|
||||
"""
|
||||
self.max_gen = gtk.SpinButton(gtk.Adjustment(5,2,self.MAX_GENERATIONS,1))
|
||||
self.max_gen.set_value(self.options_dict['maxgen'])
|
||||
self.max_gen.set_wrap(True)
|
||||
dialog.add_option(_('Generations'),self.max_gen)
|
||||
self.type_box = gtk.combo_box_new_text ()
|
||||
self.type_box.append_text (_('full circle'))
|
||||
self.type_box.append_text (_('half circle'))
|
||||
self.type_box.append_text (_('quarter circle'))
|
||||
self.type_box.set_active(self.options_dict['half_circle'] + 2 * self.options_dict['quar_circle'])
|
||||
dialog.add_option(_('Type of graph'),self.type_box)
|
||||
self.backgr_box = gtk.combo_box_new_text ()
|
||||
self.backgr_box.append_text (_('white'))
|
||||
self.backgr_box.append_text (_('generation dependent'))
|
||||
self.backgr_box.set_active(self.options_dict['backgr_generation'])
|
||||
dialog.add_option(_('Background color'),self.backgr_box)
|
||||
self.radial_box = gtk.combo_box_new_text ()
|
||||
self.radial_box.append_text (_('upright'))
|
||||
self.radial_box.append_text (_('roundabout'))
|
||||
self.radial_box.set_active(self.options_dict['radial_roundabout'])
|
||||
dialog.add_option(_('Orientation of radial texts'),self.radial_box)
|
||||
|
||||
def parse_user_options(self,dialog):
|
||||
"""
|
||||
Parses the custom options that we have added.
|
||||
"""
|
||||
self.options_dict['maxgen'] = int(self.max_gen.get_value_as_int())
|
||||
self.options_dict['full_circle'] = int(self.type_box.get_active() == 0)
|
||||
self.options_dict['half_circle'] = int(self.type_box.get_active() == 1)
|
||||
self.options_dict['quar_circle'] = int(self.type_box.get_active() == 2)
|
||||
self.options_dict['backgr_white'] = int(self.backgr_box.get_active() == 0)
|
||||
self.options_dict['backgr_generation'] = int(self.backgr_box.get_active() == 1)
|
||||
self.options_dict['radial_upright'] = int(self.radial_box.get_active() == 0)
|
||||
self.options_dict['radial_roundabout'] = int(self.radial_box.get_active() == 1)
|
||||
|
||||
|
||||
MenuOptions.__init__(self,name,person_id)
|
||||
|
||||
def add_menu_options(self,menu):
|
||||
category_name = _("Report Options")
|
||||
|
||||
max_gen = NumberOption(_("Generations"),5,1,self.MAX_GENERATIONS)
|
||||
max_gen.set_help(_("The number of generations to include in the report"))
|
||||
menu.add_option(category_name,"maxgen",max_gen)
|
||||
|
||||
circle = EnumeratedListOption(_('Type of graph'),HALF_CIRCLE)
|
||||
circle.add_item(FULL_CIRCLE,_('full circle'))
|
||||
circle.add_item(HALF_CIRCLE,_('half circle'))
|
||||
circle.add_item(QUAR_CIRCLE,_('quarter circle'))
|
||||
circle.set_help( _("The form of the graph: full circle, half circle,"
|
||||
" or quarter circle."))
|
||||
menu.add_option(category_name,"circle",circle)
|
||||
|
||||
background = EnumeratedListOption(_('Background color'),BACKGROUND_GEN)
|
||||
background.add_item(BACKGROUND_WHITE,_('white'))
|
||||
background.add_item(BACKGROUND_GEN,_('generation dependent'))
|
||||
background.set_help(_("Background color is either white or generation"
|
||||
" dependent"))
|
||||
menu.add_option(category_name,"background",background)
|
||||
|
||||
radial = EnumeratedListOption( _('Orientation of radial texts'),
|
||||
RADIAL_UPRIGHT )
|
||||
radial.add_item(RADIAL_UPRIGHT,_('upright'))
|
||||
radial.add_item(RADIAL_ROUNDABOUT,_('roundabout'))
|
||||
radial.set_help(_("Print raidal texts upright or roundabout"))
|
||||
menu.add_option(category_name,"radial",radial)
|
||||
|
||||
def make_default_style(self,default_style):
|
||||
"""Make the default output style for the Fan Chart report."""
|
||||
|
Loading…
Reference in New Issue
Block a user