2006-05-30 Alex Roitman <shura@gramps-project.org>
* various: break Report into a package. svn: r6820
This commit is contained in:
parent
2be70de189
commit
0ab5eb9a0d
@ -1,3 +1,6 @@
|
||||
2006-05-30 Alex Roitman <shura@gramps-project.org>
|
||||
* various: break Report into a package.
|
||||
|
||||
2006-05-29 Brian Matherly <brian@gramps-project.org>
|
||||
* src/plugins/DetDescendantReport.py: insert name keys for indexing.
|
||||
* src/plugins/DetAncestralReport.py: insert name keys for indexing.
|
||||
|
@ -56,7 +56,7 @@ import Utils
|
||||
import DateHandler
|
||||
import ImgManip
|
||||
import Errors
|
||||
from PluginUtils import ReportUtils
|
||||
from PluginUtils.Report import ReportUtils
|
||||
from Editors import EditPerson
|
||||
from DdTargets import DdTargets
|
||||
import cPickle as pickle
|
||||
|
@ -28,7 +28,7 @@ import GrampsWidgets
|
||||
import Errors
|
||||
import GrampsDb
|
||||
|
||||
from PluginUtils import ReportUtils
|
||||
from PluginUtils.Report import ReportUtils
|
||||
|
||||
_GenderCode = {
|
||||
RelLib.Person.MALE : u'\u2642',
|
||||
|
@ -71,7 +71,7 @@ import Config
|
||||
import Errors
|
||||
|
||||
from _EditPrimary import EditPrimary
|
||||
from PluginUtils import ReportUtils
|
||||
from PluginUtils.Report import ReportUtils
|
||||
from DdTargets import DdTargets
|
||||
from DisplayTabs import \
|
||||
EmbeddedList,EventEmbedList,SourceEmbedList,FamilyAttrEmbedList,\
|
||||
|
37
src/PluginUtils/Report/Makefile.am
Normal file
37
src/PluginUtils/Report/Makefile.am
Normal file
@ -0,0 +1,37 @@
|
||||
# This is the src/Report level Makefile for Gramps
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@/Report
|
||||
|
||||
pkgdata_PYTHON = \
|
||||
_BareReportDialog.py\
|
||||
_BookFormatComboBox.py\
|
||||
_BookReport.py\
|
||||
_CommandLineReport.py\
|
||||
_Constants.py\
|
||||
_DrawFormatComboBox.py\
|
||||
_DrawReportDialog.py\
|
||||
_FileEntry.py\
|
||||
__init__.py\
|
||||
_PaperMenu.py\
|
||||
_PrintTools.py\
|
||||
_ReportDialog.py\
|
||||
_ReportUtils.py\
|
||||
_ReportOptions.py\
|
||||
_Report.py\
|
||||
_StyleComboBox.py\
|
||||
_StyleEditor.py\
|
||||
_TemplateParser.py\
|
||||
_TextFormatComboBox.py\
|
||||
_TextReportDialog.py
|
||||
|
||||
pkgpyexecdir = @pkgpyexecdir@/Report
|
||||
pkgpythondir = @pkgpythondir@/Report
|
||||
|
||||
# Clean up all the byte-compiled files
|
||||
MOSTLYCLEANFILES = *pyc *pyo
|
||||
|
||||
GRAMPS_PY_MODPATH = "../"
|
||||
|
||||
pycheck:
|
||||
(export PYTHONPATH=$(GRAMPS_PY_MODPATH); \
|
||||
pychecker $(pkgdata_PYTHON));
|
642
src/PluginUtils/Report/_BareReportDialog.py
Normal file
642
src/PluginUtils/Report/_BareReportDialog.py
Normal file
@ -0,0 +1,642 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
|
||||
class BareReportDialog:
|
||||
"""
|
||||
The BareReportDialog base class. This is a base class for generating
|
||||
customized dialogs to solicit some options for a report. This class
|
||||
cannot be meaningfully used on its own since normally more options will
|
||||
have to be solicited. The ReportDialog class adds this functionality.
|
||||
The intended use of this class is either for ReportDialog or for being
|
||||
subclassed by Bare Reports that are part of the Book.
|
||||
"""
|
||||
|
||||
frame_pad = 5
|
||||
border_pad = 6
|
||||
|
||||
def __init__(self,database,person,option_class,name,translated_name):
|
||||
"""Initialize a dialog to request that the user select options
|
||||
for a basic *bare* report."""
|
||||
|
||||
self.db = database
|
||||
self.person = person
|
||||
if type(option_class) == ClassType:
|
||||
self.options = option_class(name)
|
||||
elif type(option_class) == InstanceType:
|
||||
self.options = option_class
|
||||
self.report_name = translated_name
|
||||
self.init_interface()
|
||||
|
||||
def init_interface(self):
|
||||
#self.output_notebook = None
|
||||
#self.notebook_page = 1
|
||||
self.pagecount_menu = None
|
||||
self.filter_combo = None
|
||||
self.extra_menu = None
|
||||
self.extra_textbox = None
|
||||
self.pagebreak_checkbox = None
|
||||
self.generations_spinbox = None
|
||||
self.widgets = []
|
||||
self.frame_names = []
|
||||
self.frames = {}
|
||||
self.format_menu = None
|
||||
self.style_button = None
|
||||
|
||||
self.style_name = self.options.handler.get_default_stylesheet_name()
|
||||
(self.max_gen,self.page_breaks) = self.options.handler.get_report_generations()
|
||||
try:
|
||||
self.local_filters = self.options.get_report_filters(self.person)
|
||||
except AttributeError:
|
||||
self.local_filters = []
|
||||
|
||||
self.window = gtk.Dialog('GRAMPS')
|
||||
self.window.set_has_separator(False)
|
||||
self.cancel = self.window.add_button(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL)
|
||||
self.ok = self.window.add_button(gtk.STOCK_OK,gtk.RESPONSE_OK)
|
||||
|
||||
self.ok.connect('clicked',self.on_ok_clicked)
|
||||
self.cancel.connect('clicked',self.on_cancel)
|
||||
|
||||
self.window.set_default_size(600,-1)
|
||||
|
||||
# Set up and run the dialog. These calls are not in top down
|
||||
# order when looking at the dialog box as there is some
|
||||
# interaction between the various frames.
|
||||
|
||||
self.setup_title()
|
||||
self.setup_header()
|
||||
self.tbl = gtk.Table(4,4,False)
|
||||
self.tbl.set_col_spacings(12)
|
||||
self.tbl.set_row_spacings(6)
|
||||
self.tbl.set_border_width(6)
|
||||
self.col = 0
|
||||
self.window.vbox.add(self.tbl)
|
||||
|
||||
# Build the list of widgets that are used to extend the Options
|
||||
# frame and to create other frames
|
||||
self.add_user_options()
|
||||
|
||||
self.setup_center_person()
|
||||
self.setup_target_frame()
|
||||
self.setup_format_frame()
|
||||
self.setup_style_frame()
|
||||
#self.setup_output_notebook()
|
||||
|
||||
self.notebook = gtk.Notebook()
|
||||
self.notebook.set_border_width(6)
|
||||
self.window.vbox.add(self.notebook)
|
||||
|
||||
self.setup_paper_frame()
|
||||
self.setup_html_frame()
|
||||
self.setup_report_options_frame()
|
||||
self.setup_other_frames()
|
||||
self.notebook.set_current_page(0)
|
||||
self.window.show_all()
|
||||
|
||||
def get_title(self):
|
||||
"""The window title for this dialog"""
|
||||
return "%s - GRAMPS Book" % self.report_name
|
||||
|
||||
def get_header(self, name):
|
||||
"""The header line to put at the top of the contents of the
|
||||
dialog box. By default this will just be the name of the
|
||||
selected person. Most subclasses will customize this to give
|
||||
some indication of what the report will be, i.e. 'Descendant
|
||||
Report for %s'."""
|
||||
return _("%(report_name)s for GRAMPS Book") % {
|
||||
'report_name' : self.report_name}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Customization hooks for subclasses
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def get_stylesheet_savefile(self):
|
||||
"""Where should new styles for this report be saved? This is
|
||||
the name of an XML file that will be located in the ~/.gramps
|
||||
directory. This file does not have to exist; it will be
|
||||
created when needed. All subclasses should probably override
|
||||
this function."""
|
||||
return "basic_report.xml"
|
||||
|
||||
def get_report_filters(self):
|
||||
"""Return the data used to fill out the 'filter' combo box in
|
||||
the report options box. The return value is the list of
|
||||
strings to be inserted into the pulldown."""
|
||||
return []
|
||||
|
||||
def get_report_generations(self):
|
||||
"""Return the default number of generations to start the
|
||||
spinbox (zero to disable) and whether or not to include the
|
||||
'page break between generations' check box"""
|
||||
return (10, 1)
|
||||
|
||||
def get_report_extra_menu_info(self):
|
||||
"""Return the data used to fill out the 'extra' option menu in
|
||||
the report options box. The first value is the string to be
|
||||
used as the label to the left of the menu. The second value
|
||||
is a mapping of string:value pairs. The strings will be used
|
||||
to label individual menu items, and the values are what will
|
||||
be returned if a given menu item is selected. The third value
|
||||
is the name of menu item to pre-select, and the final value is
|
||||
a string to use as the tooltip for the textbox."""
|
||||
return (None, None, None, None)
|
||||
|
||||
def get_report_extra_textbox_info(self):
|
||||
"""Return the data used to fill out the 'extra' textbox in the
|
||||
report options dialog. The first value is the string to be
|
||||
used as the label to the left of the textbox. The second
|
||||
value is the string to use as the default contents of the
|
||||
textbox. If None, then the text box will be hidden. The
|
||||
final value is a string to use as the tooltip for the
|
||||
textbox."""
|
||||
return (None, None, None)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Functions related to extending the options
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def add_user_options(self):
|
||||
"""Called to allow subclasses add widgets to the dialog form.
|
||||
It is called immediately before the window is displayed. All
|
||||
calls to add_option or add_frame_option should be called in
|
||||
this task."""
|
||||
self.options.add_user_options(self)
|
||||
|
||||
def parse_user_options(self):
|
||||
"""Called to allow parsing of added widgets.
|
||||
It is called when OK is pressed in a dialog.
|
||||
All custom widgets should provide a parsing code here."""
|
||||
try:
|
||||
self.options.parse_user_options(self)
|
||||
except:
|
||||
log.error("Failed to parse user options.", exc_info=True)
|
||||
|
||||
|
||||
def add_option(self,label_text,widget,tooltip=None):
|
||||
"""Takes a text string and a Gtk Widget, and stores them to be
|
||||
appended to the Options section of the dialog. The text string
|
||||
is used to create a label for the passed widget. This allows the
|
||||
subclass to extend the Options section with its own widgets. The
|
||||
subclass is reponsible for all managing of the widgets, including
|
||||
extracting the final value before the report executes. This task
|
||||
should only be called in the add_user_options task."""
|
||||
self.widgets.append((label_text,widget))
|
||||
if tooltip:
|
||||
self.add_tooltip(widget,tooltip)
|
||||
|
||||
def add_frame_option(self,frame_name,label_text,widget,tooltip=None):
|
||||
"""Similar to add_option this method takes a frame_name, a
|
||||
text string and a Gtk Widget. When the interface is built,
|
||||
all widgets with the same frame_name are grouped into a
|
||||
GtkFrame. This allows the subclass to create its own sections,
|
||||
filling them with its own widgets. The subclass is reponsible for
|
||||
all managing of the widgets, including extracting the final value
|
||||
before the report executes. This task should only be called in
|
||||
the add_user_options task."""
|
||||
|
||||
if self.frames.has_key(frame_name):
|
||||
self.frames[frame_name].append((label_text,widget))
|
||||
else:
|
||||
self.frames[frame_name] = [(label_text,widget)]
|
||||
self.frame_names.append(frame_name)
|
||||
if tooltip:
|
||||
self.add_tooltip(widget,tooltip)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Functions to create a default output style.
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
def build_style_menu(self,default=None):
|
||||
"""Build a menu of style sets that are available for use in
|
||||
this report. This menu will always have a default style
|
||||
available, and will have any other style set name that the
|
||||
user has previously created for this report. This menu is
|
||||
created here instead of inline with the rest of the style
|
||||
frame, because it must be recreated to reflect any changes
|
||||
whenever the user closes the style editor dialog."""
|
||||
|
||||
if default is None:
|
||||
default = self.style_name
|
||||
|
||||
style_sheet_map = self.style_sheet_list.get_style_sheet_map()
|
||||
self.style_menu.set(style_sheet_map,default)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Functions related to setting up the dialog window.
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def setup_title(self):
|
||||
"""Set up the title bar of the dialog. This function relies
|
||||
on the get_title() customization function for what the title
|
||||
should be."""
|
||||
self.name = NameDisplay.displayer.display(self.person)
|
||||
self.window.set_title(self.get_title())
|
||||
|
||||
def setup_header(self):
|
||||
"""Set up the header line bar of the dialog. This function
|
||||
relies on the get_header() customization function for what the
|
||||
header line should read. If no customization function is
|
||||
supplied by the subclass, the default is to use the full name
|
||||
of the currently selected person."""
|
||||
|
||||
title = self.get_header(self.name)
|
||||
label = gtk.Label('<span size="larger" weight="bold">%s</span>' % title)
|
||||
label.set_use_markup(True)
|
||||
self.window.vbox.pack_start(label, True, True,
|
||||
ReportDialog.border_pad)
|
||||
|
||||
def setup_target_frame(self):
|
||||
"""Bare report dialog only uses Doc Options header."""
|
||||
|
||||
label = gtk.Label("<b>%s</b>" % _('Document Options'))
|
||||
label.set_use_markup(1)
|
||||
label.set_alignment(0.0,0.5)
|
||||
self.tbl.set_border_width(12)
|
||||
self.tbl.attach(label, 0, 4, self.col, self.col+1, gtk.FILL|gtk.EXPAND)
|
||||
self.col += 1
|
||||
|
||||
def setup_center_person(self):
|
||||
"""Set up center person labels and change button.
|
||||
Should be overwritten by standalone report dialogs. """
|
||||
|
||||
center_label = gtk.Label("<b>%s</b>" % _("Center Person"))
|
||||
center_label.set_use_markup(True)
|
||||
center_label.set_alignment(0.0,0.5)
|
||||
self.tbl.set_border_width(12)
|
||||
self.tbl.attach(center_label,0,4,self.col,self.col+1)
|
||||
self.col += 1
|
||||
|
||||
name = NameDisplay.displayer.display(self.person)
|
||||
self.person_label = gtk.Label( "%s" % name )
|
||||
self.person_label.set_alignment(0.0,0.5)
|
||||
self.tbl.attach(self.person_label,2,3,self.col,self.col+1)
|
||||
|
||||
change_button = gtk.Button("%s..." % _('C_hange') )
|
||||
change_button.connect('clicked',self.on_center_person_change_clicked)
|
||||
self.tbl.attach(change_button,3,4,self.col,self.col+1,gtk.SHRINK)
|
||||
self.col += 1
|
||||
|
||||
def setup_style_frame(self):
|
||||
"""Set up the style frame of the dialog. This function relies
|
||||
on other routines create the default style for this report,
|
||||
and to read in any user defined styles for this report. It
|
||||
the builds a menu of all the available styles for the user to
|
||||
choose from."""
|
||||
|
||||
# Styles Frame
|
||||
label = gtk.Label("%s:" % _("Style"))
|
||||
label.set_alignment(0.0,0.5)
|
||||
|
||||
self.style_menu = GrampsStyleComboBox()
|
||||
self.style_button = gtk.Button("%s..." % _("Style Editor"))
|
||||
self.style_button.connect('clicked',self.on_style_edit_clicked)
|
||||
|
||||
self.tbl.attach(label,1,2,self.col,self.col+1,gtk.SHRINK|gtk.FILL)
|
||||
self.tbl.attach(self.style_menu,2,3,self.col,self.col+1,
|
||||
yoptions=gtk.SHRINK)
|
||||
self.tbl.attach(self.style_button,3,4,self.col,self.col+1,
|
||||
xoptions=gtk.SHRINK|gtk.FILL,yoptions=gtk.SHRINK)
|
||||
self.col += 1
|
||||
|
||||
# Build the default style set for this report.
|
||||
self.default_style = BaseDoc.StyleSheet()
|
||||
self.options.make_default_style(self.default_style)
|
||||
|
||||
# Build the initial list of available styles sets. This
|
||||
# includes the default style set and any style sets saved from
|
||||
# previous invocations of gramps.
|
||||
self.style_sheet_list = BaseDoc.StyleSheetList(
|
||||
self.options.handler.get_stylesheet_savefile(),
|
||||
self.default_style)
|
||||
|
||||
# Now build the actual menu.
|
||||
style = self.options.handler.get_default_stylesheet_name()
|
||||
self.build_style_menu(style)
|
||||
|
||||
def setup_report_options_frame(self):
|
||||
"""Set up the report options frame of the dialog. This
|
||||
function relies on several report_xxx() customization
|
||||
functions to determine which of the items should be present in
|
||||
this box. *All* of these items are optional, although the
|
||||
generations fields and the filter combo box are used in most
|
||||
(but not all) dialog boxes."""
|
||||
|
||||
(em_label, extra_map, preset, em_tip) = self.get_report_extra_menu_info()
|
||||
(et_label, string, et_tip) = self.get_report_extra_textbox_info()
|
||||
|
||||
row = 0
|
||||
max_rows = 0
|
||||
if self.max_gen:
|
||||
max_rows = max_rows + 2
|
||||
#if self.page_breaks:
|
||||
# max_rows = max_rows + 1
|
||||
if len(self.local_filters):
|
||||
max_rows = max_rows + 1
|
||||
if extra_map:
|
||||
max_rows = max_rows + 1
|
||||
if string:
|
||||
max_rows = max_rows + 1
|
||||
|
||||
max_rows = max_rows + len(self.widgets)
|
||||
|
||||
if max_rows == 0:
|
||||
return
|
||||
|
||||
table = gtk.Table(3,max_rows+1)
|
||||
table.set_col_spacings(12)
|
||||
table.set_row_spacings(6)
|
||||
|
||||
label = gtk.Label("<b>%s</b>" % _("Report Options"))
|
||||
label.set_alignment(0.0,0.5)
|
||||
label.set_use_markup(True)
|
||||
|
||||
table.set_border_width(6)
|
||||
self.notebook.append_page(table,label)
|
||||
row += 1
|
||||
|
||||
if len(self.local_filters):
|
||||
self.filter_combo = FilterComboBox()
|
||||
label = gtk.Label("%s:" % _("Filter"))
|
||||
label.set_alignment(0.0,0.5)
|
||||
table.attach(label, 1, 2, row, row+1, gtk.SHRINK|gtk.FILL,
|
||||
gtk.SHRINK|gtk.FILL)
|
||||
table.attach(self.filter_combo, 2, 3, row, row+1,
|
||||
gtk.SHRINK|gtk.FILL,gtk.SHRINK|gtk.FILL)
|
||||
|
||||
self.filter_combo.set(self.local_filters)
|
||||
self.filter_combo.set_active(self.options.handler.get_filter_number())
|
||||
row += 1
|
||||
|
||||
# Set up the generations spin and page break checkbox
|
||||
if self.max_gen:
|
||||
self.generations_spinbox = gtk.SpinButton(digits=0)
|
||||
self.generations_spinbox.set_numeric(1)
|
||||
adjustment = gtk.Adjustment(self.max_gen,1,999,1,0)
|
||||
self.generations_spinbox.set_adjustment(adjustment)
|
||||
adjustment.value_changed()
|
||||
label = gtk.Label("%s:" % _("Generations"))
|
||||
label.set_alignment(0.0,0.5)
|
||||
table.attach(label, 1, 2, row, row+1,
|
||||
gtk.SHRINK|gtk.FILL, gtk.SHRINK|gtk.FILL)
|
||||
table.attach(self.generations_spinbox, 2, 3, row, row+1,
|
||||
gtk.EXPAND|gtk.FILL,gtk.SHRINK|gtk.FILL)
|
||||
row += 1
|
||||
|
||||
#if self.page_breaks:
|
||||
msg = _("Page break between generations")
|
||||
self.pagebreak_checkbox = gtk.CheckButton(msg)
|
||||
self.pagebreak_checkbox.set_active(self.page_breaks)
|
||||
table.attach(self.pagebreak_checkbox,2,3,row,row+1,
|
||||
yoptions=gtk.SHRINK)
|
||||
row += 1
|
||||
|
||||
# Now the "extra" option menu
|
||||
if extra_map:
|
||||
self.extra_menu_label = gtk.Label("%s:" % em_label)
|
||||
self.extra_menu_label.set_alignment(0.0,0.5)
|
||||
self.extra_menu = gtk.OptionMenu()
|
||||
myMenu = Utils.build_string_optmenu(extra_map, preset)
|
||||
self.extra_menu.set_menu(myMenu)
|
||||
self.extra_menu.set_sensitive(len(extra_map) > 1)
|
||||
self.add_tooltip(self.extra_menu,em_tip)
|
||||
table.attach(self.extra_menu_label, 1, 2, row, row+1,
|
||||
gtk.SHRINK|gtk.FILL, gtk.SHRINK)
|
||||
table.attach(self.extra_menu, 2, 3, row, row+1,
|
||||
yoptions=gtk.SHRINK)
|
||||
row += 1
|
||||
|
||||
# Now the "extra" text box
|
||||
if string:
|
||||
self.extra_textbox_label = gtk.Label("%s:" % et_label)
|
||||
self.extra_textbox_label.set_alignment(0.0,0)
|
||||
swin = gtk.ScrolledWindow()
|
||||
swin.set_shadow_type(gtk.SHADOW_IN)
|
||||
swin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
|
||||
self.extra_textbox = gtk.TextView()
|
||||
swin.add(self.extra_textbox)
|
||||
|
||||
self.extra_textbox.get_buffer().set_text('\n'.join(string))
|
||||
self.extra_textbox.set_editable(1)
|
||||
self.add_tooltip(self.extra_textbox,et_tip)
|
||||
table.attach(self.extra_textbox_label, 1, 2, row, row+1,
|
||||
gtk.SHRINK|gtk.FILL,gtk.SHRINK)
|
||||
table.attach(swin, 2, 3, row, row+1,
|
||||
yoptions=gtk.SHRINK)
|
||||
row += 1
|
||||
|
||||
# Setup requested widgets
|
||||
for (text,widget) in self.widgets:
|
||||
if text:
|
||||
text_widget = gtk.Label("%s:" % text)
|
||||
text_widget.set_alignment(0.0,0.0)
|
||||
table.attach(text_widget, 1, 2, row, row+1,
|
||||
gtk.SHRINK|gtk.FILL, gtk.SHRINK)
|
||||
table.attach(widget, 2, 3, row, row+1,
|
||||
yoptions=gtk.SHRINK)
|
||||
else:
|
||||
table.attach(widget, 2, 3, row, row+1,
|
||||
yoptions=gtk.SHRINK)
|
||||
row += 1
|
||||
|
||||
def setup_other_frames(self):
|
||||
for key in self.frame_names:
|
||||
flist = self.frames[key]
|
||||
table = gtk.Table(3,len(flist))
|
||||
table.set_col_spacings(12)
|
||||
table.set_row_spacings(6)
|
||||
table.set_border_width(6)
|
||||
l = gtk.Label("<b>%s</b>" % _(key))
|
||||
l.set_use_markup(True)
|
||||
self.notebook.append_page(table,l)
|
||||
|
||||
row = 0
|
||||
for (text,widget) in flist:
|
||||
if text:
|
||||
text_widget = gtk.Label('%s:' % text)
|
||||
text_widget.set_alignment(0.0,0.5)
|
||||
table.attach(text_widget, 1, 2, row, row+1,
|
||||
gtk.SHRINK|gtk.FILL, gtk.SHRINK)
|
||||
table.attach(widget, 2, 3, row, row+1,
|
||||
yoptions=gtk.SHRINK)
|
||||
else:
|
||||
table.attach(widget, 2, 3, row, row+1,
|
||||
yoptions=gtk.SHRINK)
|
||||
row = row + 1
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Customization hooks for stand-alone reports (subclass ReportDialog)
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def setup_format_frame(self):
|
||||
"""Not used in bare report dialogs. Override in the subclass."""
|
||||
pass
|
||||
|
||||
def setup_paper_frame(self):
|
||||
"""Not used in bare report dialogs. Override in the subclass."""
|
||||
pass
|
||||
|
||||
def setup_html_frame(self):
|
||||
"""Not used in bare report dialogs. Override in the subclass."""
|
||||
pass
|
||||
|
||||
def setup_output_notebook(self):
|
||||
"""Not used in bare report dialogs. Override in the subclass."""
|
||||
pass
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Functions related to retrieving data from the dialog window
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def parse_style_frame(self):
|
||||
"""Parse the style frame of the dialog. Save the user
|
||||
selected output style for later use. Note that this routine
|
||||
retrieves a value whether or not the menu is displayed on the
|
||||
screen. The subclass will know whether this menu was enabled.
|
||||
This is for simplicity of programming."""
|
||||
(style_name,self.selected_style) = self.style_menu.get_value()
|
||||
self.options.handler.set_default_stylesheet_name(style_name)
|
||||
|
||||
def parse_report_options_frame(self):
|
||||
"""Parse the report options frame of the dialog. Save the
|
||||
user selected choices for later use. Note that this routine
|
||||
retrieves a value from all fields in the frame, regardless of
|
||||
whether or not they are displayed on the screen. The subclass
|
||||
will know which ones it has enabled. This is for simplicity
|
||||
of programming."""
|
||||
|
||||
if self.generations_spinbox:
|
||||
self.max_gen = self.generations_spinbox.get_value_as_int()
|
||||
else:
|
||||
self.max_gen = 0
|
||||
|
||||
if self.pagebreak_checkbox and self.pagebreak_checkbox.get_active():
|
||||
self.pg_brk = 1
|
||||
else:
|
||||
self.pg_brk = 0
|
||||
|
||||
if self.max_gen or self.pg_brk:
|
||||
self.options.handler.set_report_generations(self.max_gen,self.pg_brk)
|
||||
|
||||
if self.filter_combo:
|
||||
try:
|
||||
self.filter = self.filter_combo.get_value()
|
||||
active = max(0,self.filter_combo.get_active())
|
||||
self.options.handler.set_filter_number(active)
|
||||
except:
|
||||
print "Error setting filter. Proceeding with 'Everyone'"
|
||||
self.filter = Rules.Person.Everyone([])
|
||||
else:
|
||||
self.filter = None
|
||||
|
||||
if self.extra_menu:
|
||||
self.report_menu = self.extra_menu.get_menu().get_active().get_data("d")
|
||||
else:
|
||||
self.report_menu = None
|
||||
|
||||
if self.extra_textbox:
|
||||
b = self.extra_textbox.get_buffer()
|
||||
text_val = unicode(b.get_text(b.get_start_iter(),b.get_end_iter(),False))
|
||||
self.report_text = text_val.split('\n')
|
||||
self.options.handler.set_display_format(self.report_text)
|
||||
else:
|
||||
self.report_text = []
|
||||
|
||||
def parse_other_frames(self):
|
||||
"""Do nothing. This sole purpose of this function is to give
|
||||
subclass a place to hang a routine to parser any other frames
|
||||
that are unique to that specific report."""
|
||||
pass
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Callback functions from the dialog
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def on_cancel(self,*obj):
|
||||
pass
|
||||
|
||||
def on_ok_clicked(self, obj):
|
||||
"""The user is satisfied with the dialog choices. Parse all options
|
||||
and close the window."""
|
||||
|
||||
# Preparation
|
||||
self.parse_style_frame()
|
||||
self.parse_report_options_frame()
|
||||
self.parse_other_frames()
|
||||
self.parse_user_options()
|
||||
|
||||
# Save options
|
||||
self.options.handler.save_options()
|
||||
|
||||
def on_style_edit_clicked(self, *obj):
|
||||
"""The user has clicked on the 'Edit Styles' button. Create a
|
||||
style sheet editor object and let them play. When they are
|
||||
done, the previous routine will be called to update the dialog
|
||||
menu for selecting a style."""
|
||||
StyleListDisplay(self.style_sheet_list,self.build_style_menu,
|
||||
self.window)
|
||||
|
||||
def on_center_person_change_clicked(self,*obj):
|
||||
from Selectors import selector_factory
|
||||
SelectPerson = selector_factory('Person')
|
||||
sel_person = SelectPerson(self.db,_('Select Person'))
|
||||
new_person = sel_person.run()
|
||||
if new_person:
|
||||
self.new_person = new_person
|
||||
new_name = NameDisplay.displayer.display(new_person)
|
||||
if new_name:
|
||||
self.person_label.set_text( "<i>%s</i>" % new_name )
|
||||
self.person_label.set_use_markup(True)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Functions related to creating the actual report document.
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def make_report(self):
|
||||
"""Create the contents of the report. This is the meat and
|
||||
potatoes of reports. The whole purpose of the dialog is to
|
||||
get to this routine so that data is written to a file. This
|
||||
routine should either write the data directly to the file, or
|
||||
better yet, should create a subclass of a Report that will
|
||||
write the data to a file."""
|
||||
pass
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Miscellaneous functions.
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def add_tooltip(self,widget,string):
|
||||
"""Adds a tooltip to the specified widget"""
|
||||
if not widget or not string:
|
||||
return
|
||||
tip = gtk.Tooltips()
|
||||
tip.set_tip(widget,string)
|
71
src/PluginUtils/Report/_BookFormatComboBox.py
Normal file
71
src/PluginUtils/Report/_BookFormatComboBox.py
Normal file
@ -0,0 +1,71 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# get_text_doc_menu
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class BookFormatComboBox(gtk.ComboBox):
|
||||
|
||||
def set(self,tables,callback,obj=None,active=None):
|
||||
self.store = gtk.ListStore(str)
|
||||
self.set_model(self.store)
|
||||
cell = gtk.CellRendererText()
|
||||
self.pack_start(cell,True)
|
||||
self.add_attribute(cell,'text',0)
|
||||
|
||||
out_pref = Config.get(Config.OUTPUT_PREFERENCE)
|
||||
index = 0
|
||||
_PluginMgr.drawdoc_list.sort()
|
||||
active_index = 0
|
||||
self.data = []
|
||||
for item in _PluginMgr.bookdoc_list:
|
||||
if tables and item[2] == 0:
|
||||
continue
|
||||
self.data.append(item)
|
||||
name = item[0]
|
||||
self.store.append(row=[name])
|
||||
if item[7] == active:
|
||||
active_index = index
|
||||
elif not active and name == out_pref:
|
||||
active_index = index
|
||||
index += 1
|
||||
self.set_active(active_index)
|
||||
|
||||
def get_reference(self):
|
||||
return self.data[self.get_active()][1]
|
||||
|
||||
def get_label(self):
|
||||
return self.data[self.get_active()][0]
|
||||
|
||||
def get_paper(self):
|
||||
return self.data[self.get_active()][3]
|
||||
|
||||
def get_ext(self):
|
||||
return self.data[self.get_active()][5]
|
||||
|
||||
def get_printable(self):
|
||||
return self.data[self.get_active()][6]
|
||||
|
||||
def get_clname(self):
|
||||
return self.data[self.get_active()][7]
|
@ -66,6 +66,7 @@ from RelLib import Person
|
||||
import const
|
||||
import Utils
|
||||
import ListModel
|
||||
import Errors
|
||||
from PluginUtils import Plugins, Report, ReportOptions, \
|
||||
bkitems_list, register_report
|
||||
import BaseDoc
|
||||
@ -1112,20 +1113,44 @@ def cl_report(database,name,category,options_str_dict):
|
||||
item.write_report()
|
||||
doc.close()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Generic task function for book report
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
# Book item generic task
|
||||
def write_book_item(database,person,report_class,options_class):
|
||||
"""Write the Timeline Graph using options set.
|
||||
All user dialog has already been handled and the output file opened."""
|
||||
try:
|
||||
if options_class.handler.get_person_id():
|
||||
person = database.get_person_from_gramps_id(
|
||||
options_class.handler.get_person_id())
|
||||
return report_class(database,person,options_class)
|
||||
except Errors.ReportError, msg:
|
||||
(m1,m2) = msg.messages()
|
||||
ErrorDialog(m1,m2)
|
||||
except Errors.FilterError, msg:
|
||||
(m1,m2) = msg.messages()
|
||||
ErrorDialog(m1,m2)
|
||||
except:
|
||||
log.error("Failed to write book item.", exc_info=True)
|
||||
return None
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
register_report(
|
||||
name = 'book',
|
||||
category = Report.CATEGORY_BOOK,
|
||||
report_class = BookReportSelector,
|
||||
options_class = cl_report,
|
||||
modes = Report.MODE_GUI | Report.MODE_CLI,
|
||||
translated_name = _("Book Report"),
|
||||
status = _("Stable"),
|
||||
description = _("Creates a book containing several reports."),
|
||||
author_name = "Alex Roitman",
|
||||
author_email = "shura@gramps-project.org"
|
||||
)
|
||||
## register_report(
|
||||
## name = 'book',
|
||||
## category = Report.CATEGORY_BOOK,
|
||||
## report_class = BookReportSelector,
|
||||
## options_class = cl_report,
|
||||
## modes = Report.MODE_GUI | Report.MODE_CLI,
|
||||
## translated_name = _("Book Report"),
|
||||
## status = _("Stable"),
|
||||
## description = _("Creates a book containing several reports."),
|
||||
## author_name = "Alex Roitman",
|
||||
## author_email = "shura@gramps-project.org"
|
||||
## )
|
265
src/PluginUtils/Report/_CommandLineReport.py
Normal file
265
src/PluginUtils/Report/_CommandLineReport.py
Normal file
@ -0,0 +1,265 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(".")
|
||||
|
||||
import PluginUtils
|
||||
import NameDisplay
|
||||
import Utils
|
||||
import BaseDoc
|
||||
from Report import CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK
|
||||
from _PaperMenu import paper_sizes
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Command-line report
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class CommandLineReport:
|
||||
"""
|
||||
Provides a way to generate report 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 = {
|
||||
'of' : self.option_class.handler.module_name,
|
||||
'off' : self.option_class.handler.get_format_name(),
|
||||
'style' : \
|
||||
self.option_class.handler.get_default_stylesheet_name(),
|
||||
'papers' : self.option_class.handler.get_paper_name(),
|
||||
'papero' : self.option_class.handler.get_orientation(),
|
||||
'template' : self.option_class.handler.get_template_name(),
|
||||
'id' : ''
|
||||
}
|
||||
|
||||
self.options_help = {
|
||||
'of' : ["=filename","Output file name. MANDATORY"],
|
||||
'off' : ["=format","Output file format."],
|
||||
'style' : ["=name","Style name."],
|
||||
'papers' : ["=name","Paper size name."],
|
||||
'papero' : ["=num","Paper orientation number."],
|
||||
'template' : ["=name","Template name (HTML only)."],
|
||||
'id' : ["=ID","Gramps ID of a central person. MANDATORY"],
|
||||
'filter' : ["=num","Filter number."],
|
||||
'gen' : ["=num","Number of generations to follow."],
|
||||
'pagebbg' : ["=0/1","Page break between generations."],
|
||||
'dispf' : ["=str","Display format for the outputbox."],
|
||||
}
|
||||
|
||||
if noopt:
|
||||
return
|
||||
|
||||
# Add report-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 report-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
|
||||
CustomFilters.get_filters() ]
|
||||
filt_list.extend(cust_filt_list)
|
||||
self.options_help['filter'].append(filt_list)
|
||||
self.options_help['filter'].append(True)
|
||||
|
||||
if self.options_dict.has_key('gen'):
|
||||
max_gen = self.options_dict['gen']
|
||||
page_breaks = self.options_dict['pagebbg']
|
||||
self.option_class.handler.set_report_generations(max_gen,
|
||||
page_breaks)
|
||||
|
||||
self.options_help['gen'].append("Whatever Number You Wish")
|
||||
self.options_help['pagebbg'].append([
|
||||
"No page break","Page break"])
|
||||
self.options_help['pagebbg'].append(True)
|
||||
|
||||
if self.options_dict.has_key('dispf'):
|
||||
dispf = ''.join(self.options_dict['dispf']).replace('\\n','\n')
|
||||
self.option_class.handler.set_display_format(dispf)
|
||||
|
||||
self.options_help['dispf'].append(
|
||||
"Any string -- may use keyword substitutions")
|
||||
|
||||
self.option_class.handler.output = self.options_dict['of']
|
||||
self.options_help['of'].append(os.path.join(const.user_home,
|
||||
"whatever_name"))
|
||||
|
||||
if self.category == CATEGORY_TEXT:
|
||||
for item in PluginUtils.textdoc_list:
|
||||
if item[7] == self.options_dict['off']:
|
||||
self.format = item[1]
|
||||
self.options_help['off'].append(
|
||||
[ item[7] for item in PluginUtils.textdoc_list ]
|
||||
)
|
||||
self.options_help['off'].append(False)
|
||||
elif self.category == CATEGORY_DRAW:
|
||||
for item in PluginUtils.drawdoc_list:
|
||||
if item[6] == self.options_dict['off']:
|
||||
self.format = item[1]
|
||||
self.options_help['off'].append(
|
||||
[ item[6] for item in PluginUtils.drawdoc_list ]
|
||||
)
|
||||
self.options_help['off'].append(False)
|
||||
elif self.category == CATEGORY_BOOK:
|
||||
for item in PluginUtils.bookdoc_list:
|
||||
if item[6] == self.options_dict['off']:
|
||||
self.format = item[1]
|
||||
self.options_help['off'].append(
|
||||
[ item[6] for item in PluginUtils.bookdoc_list ]
|
||||
)
|
||||
self.options_help['off'].append(False)
|
||||
else:
|
||||
self.format = None
|
||||
|
||||
for paper in paper_sizes:
|
||||
if paper.get_name() == self.options_dict['papers']:
|
||||
self.paper = paper
|
||||
self.option_class.handler.set_paper(self.paper)
|
||||
self.options_help['papers'].append(
|
||||
[ paper.get_name() for paper in paper_sizes
|
||||
if paper.get_name() != 'Custom Size' ] )
|
||||
self.options_help['papers'].append(False)
|
||||
|
||||
self.orien = self.options_dict['papero']
|
||||
self.options_help['papero'].append([
|
||||
"%d\tPortrait" % BaseDoc.PAPER_PORTRAIT,
|
||||
"%d\tLandscape" % BaseDoc.PAPER_LANDSCAPE ] )
|
||||
self.options_help['papero'].append(False)
|
||||
|
||||
self.template_name = self.options_dict['template']
|
||||
self.options_help['template'].append(os.path.join(const.user_home,
|
||||
"whatever_name"))
|
||||
|
||||
if self.category in (CATEGORY_TEXT,CATEGORY_DRAW):
|
||||
default_style = BaseDoc.StyleSheet()
|
||||
self.option_class.make_default_style(default_style)
|
||||
|
||||
# Read all style sheets available for this item
|
||||
style_file = self.option_class.handler.get_stylesheet_savefile()
|
||||
self.style_list = BaseDoc.StyleSheetList(style_file,default_style)
|
||||
|
||||
# Get the selected stylesheet
|
||||
style_name =self.option_class.handler.get_default_stylesheet_name()
|
||||
self.selected_style = self.style_list.get_style_sheet(style_name)
|
||||
|
||||
self.options_help['style'].append(
|
||||
self.style_list.get_style_names() )
|
||||
self.options_help['style'].append(False)
|
||||
|
||||
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
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Command-line report generic task
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def cl_report(database,name,category,report_class,
|
||||
options_class,options_str_dict):
|
||||
|
||||
clr = CommandLineReport(database,name,category,
|
||||
options_class,options_str_dict)
|
||||
|
||||
# Exit here if show option was given
|
||||
if clr.show:
|
||||
return
|
||||
|
||||
# write report
|
||||
try:
|
||||
clr.option_class.handler.doc = clr.format(
|
||||
clr.selected_style,clr.paper,clr.template_name,clr.orien)
|
||||
MyReport = report_class(database, clr.person, clr.option_class)
|
||||
MyReport.doc.init()
|
||||
MyReport.begin_report()
|
||||
MyReport.write_report()
|
||||
MyReport.end_report()
|
||||
except:
|
||||
log.error("Failed to write report.", exc_info=True)
|
63
src/PluginUtils/Report/_Constants.py
Normal file
63
src/PluginUtils/Report/_Constants.py
Normal file
@ -0,0 +1,63 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
"Report Generation Framework"
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# standard python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Constants
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
# Modes for generating reports
|
||||
MODE_GUI = 1 # Standalone report using GUI
|
||||
MODE_BKI = 2 # Book Item interface using GUI
|
||||
MODE_CLI = 4 # Command line interface (CLI)
|
||||
|
||||
# Report categories
|
||||
CATEGORY_TEXT = 0
|
||||
CATEGORY_DRAW = 1
|
||||
CATEGORY_CODE = 2
|
||||
CATEGORY_WEB = 3
|
||||
CATEGORY_VIEW = 4
|
||||
CATEGORY_BOOK = 5
|
||||
|
||||
standalone_categories = {
|
||||
CATEGORY_TEXT : _("Text Reports"),
|
||||
CATEGORY_DRAW : _("Graphical Reports"),
|
||||
CATEGORY_CODE : _("Code Generators"),
|
||||
CATEGORY_WEB : _("Web Page"),
|
||||
CATEGORY_VIEW : _("View"),
|
||||
CATEGORY_BOOK : _("Books"),
|
||||
}
|
||||
|
||||
book_categories = {
|
||||
CATEGORY_TEXT : _("Text"),
|
||||
CATEGORY_DRAW : _("Graphics"),
|
||||
}
|
78
src/PluginUtils/Report/_DrawFormatComboBox.py
Normal file
78
src/PluginUtils/Report/_DrawFormatComboBox.py
Normal file
@ -0,0 +1,78 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
import gtk
|
||||
import Config
|
||||
import PluginUtils
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# get_text_doc_menu
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class DrawFormatComboBox(gtk.ComboBox):
|
||||
|
||||
def set(self,tables,callback,obj=None,active=None):
|
||||
self.store = gtk.ListStore(str)
|
||||
self.set_model(self.store)
|
||||
cell = gtk.CellRendererText()
|
||||
self.pack_start(cell,True)
|
||||
self.add_attribute(cell,'text',0)
|
||||
|
||||
out_pref = Config.get(Config.OUTPUT_PREFERENCE)
|
||||
index = 0
|
||||
PluginUtils.drawdoc_list.sort()
|
||||
active_index = 0
|
||||
for item in PluginUtils.drawdoc_list:
|
||||
if tables and item[2] == 0:
|
||||
continue
|
||||
name = item[0]
|
||||
self.store.append(row=[name])
|
||||
#if callback:
|
||||
# menuitem.connect("activate",callback)
|
||||
if item[6] == active:
|
||||
active_index = index
|
||||
elif not active and name == out_pref:
|
||||
active_index = index
|
||||
index = index + 1
|
||||
self.set_active(active_index)
|
||||
|
||||
def get_reference(self):
|
||||
return PluginUtils.drawdoc_list[self.get_active()][1]
|
||||
|
||||
def get_label(self):
|
||||
return PluginUtils.drawdoc_list[self.get_active()][0]
|
||||
|
||||
def get_paper(self):
|
||||
return PluginUtils.drawdoc_list[self.get_active()][2]
|
||||
|
||||
def get_styles(self):
|
||||
return PluginUtils.drawdoc_list[self.get_active()][3]
|
||||
|
||||
def get_ext(self):
|
||||
return PluginUtils.drawdoc_list[self.get_active()][4]
|
||||
|
||||
def get_printable(self):
|
||||
return PluginUtil.drawdoc_list[self.get_active()][5]
|
||||
|
||||
def get_clname(self):
|
||||
return PluginUtils.drawdoc_list[self.get_active()][6]
|
50
src/PluginUtils/Report/_DrawReportDialog.py
Normal file
50
src/PluginUtils/Report/_DrawReportDialog.py
Normal file
@ -0,0 +1,50 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
from _Constants import CATEGORY_DRAW
|
||||
from _ReportDialog import ReportDialog
|
||||
from _DrawFormatComboBox import DrawFormatComboBox
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
#
|
||||
# Drawing reports
|
||||
#
|
||||
#-----------------------------------------------------------------------
|
||||
class DrawReportDialog(ReportDialog):
|
||||
"""A class of ReportDialog customized for drawing based reports."""
|
||||
def __init__(self,database,person,opt,name,translated_name):
|
||||
"""Initialize a dialog to request that the user select options
|
||||
for a basic drawing report. See the ReportDialog class for
|
||||
more information."""
|
||||
self.category = CATEGORY_DRAW
|
||||
ReportDialog.__init__(self,database,person,opt,name,translated_name)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Functions related to selecting/changing the current file format.
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def make_doc_menu(self,active=None):
|
||||
"""Build a menu of document types that are appropriate for
|
||||
this drawing report."""
|
||||
self.format_menu = DrawFormatComboBox()
|
||||
self.format_menu.set(False,self.doc_type_changed, None, active)
|
88
src/PluginUtils/Report/_FileEntry.py
Normal file
88
src/PluginUtils/Report/_FileEntry.py
Normal file
@ -0,0 +1,88 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
class FileEntry(gtk.HBox):
|
||||
def __init__(self,defname,title):
|
||||
gtk.HBox.__init__(self)
|
||||
|
||||
self.title = title
|
||||
self.dir = False
|
||||
self.entry = gtk.Entry()
|
||||
self.entry.set_text(defname)
|
||||
self.set_filename(defname)
|
||||
self.set_spacing(6)
|
||||
self.set_homogeneous(False)
|
||||
self.button = gtk.Button()
|
||||
im = gtk.Image()
|
||||
im.set_from_stock(gtk.STOCK_OPEN,gtk.ICON_SIZE_BUTTON)
|
||||
self.button.add(im)
|
||||
self.button.connect('clicked',self.select_file)
|
||||
self.pack_start(self.entry,True,True)
|
||||
self.pack_end(self.button,False,False)
|
||||
|
||||
def select_file(self,obj):
|
||||
if self.dir:
|
||||
my_action = gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER
|
||||
else:
|
||||
my_action = gtk.FILE_CHOOSER_ACTION_SAVE
|
||||
|
||||
f = gtk.FileChooserDialog(self.title,
|
||||
action=my_action,
|
||||
buttons=(gtk.STOCK_CANCEL,
|
||||
gtk.RESPONSE_CANCEL,
|
||||
gtk.STOCK_OPEN,
|
||||
gtk.RESPONSE_OK))
|
||||
|
||||
name = os.path.basename(self.entry.get_text())
|
||||
if self.dir:
|
||||
if os.path.isdir(name):
|
||||
f.set_current_name(name)
|
||||
elif os.path.isdir(os.path.basename(name)):
|
||||
f.set_current_name(os.path.basename(name))
|
||||
else:
|
||||
f.set_current_name(name)
|
||||
f.set_current_folder(self.spath)
|
||||
status = f.run()
|
||||
if status == gtk.RESPONSE_OK:
|
||||
self.set_filename(f.get_filename())
|
||||
f.destroy()
|
||||
|
||||
def set_filename(self,path):
|
||||
if not path:
|
||||
return
|
||||
if os.path.dirname(path):
|
||||
self.spath = os.path.dirname(path)
|
||||
self.defname = os.path.basename(path)
|
||||
|
||||
else:
|
||||
self.spath = os.getcwd()
|
||||
self.defname = path
|
||||
self.entry.set_text(os.path.join(self.spath,self.defname))
|
||||
|
||||
def gtk_entry(self):
|
||||
return self.entry
|
||||
|
||||
def get_full_path(self,val):
|
||||
return self.entry.get_text()
|
||||
|
||||
def set_directory_entry(self,opt):
|
||||
self.dir = opt
|
52
src/PluginUtils/Report/_PrintTools.py
Normal file
52
src/PluginUtils/Report/_PrintTools.py
Normal file
@ -0,0 +1,52 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
"Report Generation Framework"
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# standard python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import os
|
||||
from gettext import gettext as _
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Support for printing generated files
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def get_print_dialog_app ():
|
||||
"""Return the name of a program which sends stdin (or the program's
|
||||
arguments) to the printer."""
|
||||
for printdialog in ["/usr/bin/kprinter --stdin",
|
||||
"/usr/share/printconf/util/print.py"]:
|
||||
if os.access (printdialog.split (' ')[0], os.X_OK):
|
||||
return printdialog
|
||||
|
||||
return "lpr"
|
||||
|
||||
def run_print_dialog (filename):
|
||||
"""Send file to the printer, possibly throwing up a dialog to
|
||||
ask which one etc."""
|
||||
os.environ["FILE"] = filename
|
||||
return os.system ('cat "$FILE" | %s &' % get_print_dialog_app ())
|
141
src/PluginUtils/Report/_Report.py
Normal file
141
src/PluginUtils/Report/_Report.py
Normal file
@ -0,0 +1,141 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001 David R. Hampton
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
import Utils
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Report
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class Report:
|
||||
"""
|
||||
The Report base class. This is a base class for generating
|
||||
customized reports. It cannot be used as is, but it can be easily
|
||||
sub-classed to create a functional report generator.
|
||||
"""
|
||||
|
||||
def __init__(self, database, person, options_class):
|
||||
self.database = database
|
||||
self.start_person = person
|
||||
self.options_class = options_class
|
||||
|
||||
self.doc = options_class.get_document()
|
||||
|
||||
creator = database.get_researcher().get_name()
|
||||
self.doc.creator(creator)
|
||||
|
||||
output = options_class.get_output()
|
||||
if output:
|
||||
self.standalone = True
|
||||
self.doc.open(options_class.get_output())
|
||||
else:
|
||||
self.standalone = False
|
||||
|
||||
self.define_table_styles()
|
||||
self.define_graphics_styles()
|
||||
|
||||
def begin_report(self):
|
||||
if self.options_class.get_newpage():
|
||||
self.doc.page_break()
|
||||
|
||||
def write_report(self):
|
||||
pass
|
||||
|
||||
def end_report(self):
|
||||
if self.standalone:
|
||||
self.doc.close()
|
||||
|
||||
def define_table_styles(self):
|
||||
"""
|
||||
This method MUST be used for adding table and cell styles.
|
||||
"""
|
||||
pass
|
||||
|
||||
def define_graphics_styles(self):
|
||||
"""
|
||||
This method MUST be used for adding drawing styles.
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_progressbar_data(self):
|
||||
"""The window title for this dialog, and the header line to
|
||||
put at the top of the contents of the dialog box."""
|
||||
return ("%s - GRAMPS" % _("Progress Report"), _("Working"))
|
||||
|
||||
def progress_bar_title(self,name,length):
|
||||
markup = '<span size="larger" weight="bold">%s</span>'
|
||||
self.lbl.set_text(markup % name)
|
||||
self.lbl.set_use_markup(True)
|
||||
self.pbar.set_fraction(0.0)
|
||||
|
||||
progress_steps = length
|
||||
if length > 1:
|
||||
progress_steps = progress_steps+1
|
||||
progress_steps = progress_steps+1
|
||||
self.pbar_max = length
|
||||
|
||||
def progress_bar_setup(self,total):
|
||||
"""Create a progress dialog. This routine calls a
|
||||
customization function to find out how to fill out the dialog.
|
||||
The argument to this function is the maximum number of items
|
||||
that the report will progress; i.e. what's considered 100%,
|
||||
i.e. the maximum number of times this routine will be
|
||||
called."""
|
||||
|
||||
# Customize the dialog for this report
|
||||
(title, header) = self.get_progressbar_data()
|
||||
self.ptop = gtk.Dialog()
|
||||
self.ptop.set_has_separator(False)
|
||||
self.ptop.set_title(title)
|
||||
self.ptop.set_border_width(12)
|
||||
self.lbl = gtk.Label(header)
|
||||
self.lbl.set_use_markup(True)
|
||||
self.ptop.vbox.add(self.lbl)
|
||||
self.ptop.vbox.set_spacing(10)
|
||||
self.ptop.vbox.set_border_width(24)
|
||||
self.pbar = gtk.ProgressBar()
|
||||
self.pbar_max = total
|
||||
self.pbar_index = 0.0
|
||||
|
||||
self.ptop.set_size_request(350,100)
|
||||
self.ptop.vbox.add(self.pbar)
|
||||
self.ptop.show_all()
|
||||
|
||||
def progress_bar_step(self):
|
||||
"""Click the progress bar over to the next value. Be paranoid
|
||||
and insure that it doesn't go over 100%."""
|
||||
self.pbar_index = self.pbar_index + 1.0
|
||||
if (self.pbar_index > self.pbar_max):
|
||||
self.pbar_index = self.pbar_max
|
||||
|
||||
val = self.pbar_index/self.pbar_max
|
||||
|
||||
self.pbar.set_text("%d of %d (%.1f%%)" % (self.pbar_index,self.pbar_max,(val*100)))
|
||||
self.pbar.set_fraction(val)
|
||||
while gtk.events_pending():
|
||||
gtk.main_iteration()
|
||||
|
||||
def progress_bar_done(self):
|
||||
"""Done with the progress bar. It can be destroyed now."""
|
||||
Utils.destroy_passed_object(self.ptop)
|
609
src/PluginUtils/Report/_ReportDialog.py
Normal file
609
src/PluginUtils/Report/_ReportDialog.py
Normal file
@ -0,0 +1,609 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
from _BareReportDialog import BareReportDialog
|
||||
|
||||
class ReportDialog(BareReportDialog):
|
||||
"""
|
||||
The ReportDialog base class. This is a base class for generating
|
||||
customized dialogs to solicit options for a report. It cannot be
|
||||
used as is, but it can be easily sub-classed to create a functional
|
||||
dialog for a stand-alone report.
|
||||
"""
|
||||
|
||||
def __init__(self,database,person,option_class,name,translated_name):
|
||||
"""Initialize a dialog to request that the user select options
|
||||
for a basic *stand-alone* report."""
|
||||
|
||||
self.style_name = "default"
|
||||
self.page_html_added = False
|
||||
BareReportDialog.__init__(self,database,person,option_class,
|
||||
name,translated_name)
|
||||
|
||||
# Allow for post processing of the format frame, since the
|
||||
# show_all task calls events that may reset values
|
||||
|
||||
def init_interface(self):
|
||||
BareReportDialog.init_interface(self)
|
||||
if self.format_menu:
|
||||
self.doc_type_changed(self.format_menu)
|
||||
self.setup_post_process()
|
||||
|
||||
def setup_post_process(self):
|
||||
pass
|
||||
|
||||
def setup_center_person(self):
|
||||
pass
|
||||
|
||||
def get_title(self):
|
||||
"""The window title for this dialog"""
|
||||
name = self.report_name
|
||||
category = standalone_categories[self.category]
|
||||
return "%s - %s - GRAMPS" % (name,category)
|
||||
|
||||
def get_header(self, name):
|
||||
"""The header line to put at the top of the contents of the
|
||||
dialog box. By default this will just be the name of the
|
||||
report for the selected person. """
|
||||
return _("%(report_name)s for %(person_name)s") % {
|
||||
'report_name' : self.report_name,
|
||||
'person_name' : name}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Customization hooks for subclasses
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def get_target_is_directory(self):
|
||||
"""Is the user being asked to input the name of a file or a
|
||||
directory in the 'Save As' File Entry widget. This item
|
||||
currently only selects the Filename/Directory prompt, and
|
||||
whether or not the browser accepts filenames. In the future it
|
||||
may also control checking of the selected filename."""
|
||||
return None
|
||||
|
||||
def get_default_basename(self):
|
||||
"""What should the default name be?
|
||||
"""
|
||||
spath = self.options.handler.get_stylesheet_savefile()
|
||||
return spath.split('.')[0]
|
||||
|
||||
def get_print_pagecount_map(self):
|
||||
"""Return the data used to fill out the 'pagecount' option
|
||||
menu in the print options box. The first value is a mapping
|
||||
of string:value pairs. The strings will be used to label
|
||||
individual menu items, and the values are what will be
|
||||
returned if a given menu item is selected. The second value
|
||||
is the name of menu item to pre-select."""
|
||||
return (None, None)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Functions related getting/setting the default directory for a dialog.
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def get_default_directory(self):
|
||||
"""Get the name of the directory to which the target dialog
|
||||
box should default. This value can be set in the preferences
|
||||
panel."""
|
||||
return Config.get(Config.REPORT_DIRECTORY)
|
||||
|
||||
def set_default_directory(self, value):
|
||||
"""Save the name of the current directory, so that any future
|
||||
reports will default to the most recently used directory.
|
||||
This also changes the directory name that will appear in the
|
||||
preferences panel, but does not change the preference in disk.
|
||||
This means that the last directory used will only be
|
||||
remembered for this session of gramps unless the user saves
|
||||
his/her preferences."""
|
||||
Config.set(Config.REPORT_DIRECTORY,value)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Functions related to selecting/changing the current file format.
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def make_doc_menu(self,active=None):
|
||||
"""Build a menu of document types that are appropriate for
|
||||
this report. This menu will be generated based upon the type
|
||||
of document (text, draw, graph, etc. - a subclass), whether or
|
||||
not the document requires table support, etc."""
|
||||
return None
|
||||
|
||||
def make_document(self):
|
||||
"""Create a document of the type requested by the user."""
|
||||
|
||||
self.doc = self.format(self.selected_style,self.paper,
|
||||
self.template_name,self.orien)
|
||||
self.options.set_document(self.doc)
|
||||
if self.print_report.get_active ():
|
||||
self.doc.print_requested ()
|
||||
|
||||
def doc_type_changed(self, obj):
|
||||
"""This routine is called when the user selects a new file
|
||||
formats for the report. It adjust the various dialog sections
|
||||
to reflect the appropriate values for the currently selected
|
||||
file format. For example, a HTML document doesn't need any
|
||||
paper size/orientation options, but it does need a template
|
||||
file. Those chances are made here."""
|
||||
|
||||
label = obj.get_printable()
|
||||
if label:
|
||||
self.print_report.set_label (label)
|
||||
self.print_report.set_sensitive (True)
|
||||
else:
|
||||
self.print_report.set_label (_("Print a copy"))
|
||||
self.print_report.set_sensitive (False)
|
||||
|
||||
# Is this to be a printed report or an electronic report
|
||||
# (i.e. a set of web pages)
|
||||
|
||||
if self.page_html_added:
|
||||
self.notebook.remove_page(0)
|
||||
if obj.get_paper() == 1:
|
||||
self.paper_label = gtk.Label('<b>%s</b>'%_("Paper Options"))
|
||||
self.paper_label.set_use_markup(True)
|
||||
self.notebook.insert_page(self.paper_table,self.paper_label,0)
|
||||
self.paper_table.show_all()
|
||||
else:
|
||||
self.html_label = gtk.Label('<b>%s</b>' % _("HTML Options"))
|
||||
self.html_label.set_use_markup(True)
|
||||
self.notebook.insert_page(self.html_table,self.html_label,0)
|
||||
self.html_table.show_all()
|
||||
|
||||
if not self.get_target_is_directory():
|
||||
fname = self.target_fileentry.get_full_path(0)
|
||||
(spath,ext) = os.path.splitext(fname)
|
||||
|
||||
ext_val = obj.get_ext()
|
||||
if ext_val:
|
||||
fname = spath + ext_val
|
||||
else:
|
||||
fname = spath
|
||||
self.target_fileentry.set_filename(fname)
|
||||
|
||||
# Does this report format use styles?
|
||||
if self.style_button:
|
||||
self.style_button.set_sensitive(obj.get_styles())
|
||||
self.style_menu.set_sensitive(obj.get_styles())
|
||||
self.page_html_added = True
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Functions related to setting up the dialog window.
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def setup_target_frame(self):
|
||||
"""Set up the target frame of the dialog. This function
|
||||
relies on several target_xxx() customization functions to
|
||||
determine whether the target is a directory or file, what the
|
||||
title of any browser window should be, and what default
|
||||
directory should be used."""
|
||||
|
||||
# Save Frame
|
||||
|
||||
label = gtk.Label("<b>%s</b>" % _('Document Options'))
|
||||
label.set_use_markup(1)
|
||||
label.set_alignment(0.0,0.5)
|
||||
self.tbl.set_border_width(12)
|
||||
self.tbl.attach(label, 0, 4, self.col, self.col+1, gtk.FILL)
|
||||
self.col += 1
|
||||
|
||||
hid = self.get_stylesheet_savefile()
|
||||
if hid[-4:]==".xml":
|
||||
hid = hid[0:-4]
|
||||
self.target_fileentry = FileEntry(hid,_("Save As"))
|
||||
|
||||
if self.get_target_is_directory():
|
||||
self.target_fileentry.set_directory_entry(1)
|
||||
self.doc_label = gtk.Label("%s:" % _("Directory"))
|
||||
else:
|
||||
self.doc_label = gtk.Label("%s:" % _("Filename"))
|
||||
self.doc_label.set_alignment(0.0,0.5)
|
||||
|
||||
self.tbl.attach(self.doc_label, 1, 2, self.col, self.col+1,
|
||||
xoptions=gtk.SHRINK|gtk.FILL,yoptions=gtk.SHRINK)
|
||||
self.tbl.attach(self.target_fileentry, 2, 4, self.col, self.col+1,
|
||||
xoptions=gtk.EXPAND|gtk.FILL,yoptions=gtk.SHRINK)
|
||||
self.col += 1
|
||||
|
||||
spath = self.get_default_directory()
|
||||
|
||||
self.target_fileentry.set_filename(spath)
|
||||
self.target_fileentry.gtk_entry().set_position(len(spath))
|
||||
|
||||
def setup_format_frame(self):
|
||||
"""Set up the format frame of the dialog. This function
|
||||
relies on the make_doc_menu() function to do all the hard
|
||||
work."""
|
||||
|
||||
self.print_report = gtk.CheckButton (_("Print a copy"))
|
||||
self.tbl.attach(self.print_report,2,4,self.col,self.col+1,
|
||||
yoptions=gtk.SHRINK)
|
||||
self.col += 1
|
||||
|
||||
self.make_doc_menu(self.options.handler.get_format_name())
|
||||
self.format_menu.connect('changed',self.doc_type_changed)
|
||||
label = gtk.Label("%s:" % _("Output Format"))
|
||||
label.set_alignment(0.0,0.5)
|
||||
self.tbl.attach(label,1,2,self.col,self.col+1,gtk.SHRINK|gtk.FILL)
|
||||
self.tbl.attach(self.format_menu,2,4,self.col,self.col+1,
|
||||
yoptions=gtk.SHRINK)
|
||||
self.col += 1
|
||||
|
||||
ext = self.format_menu.get_ext()
|
||||
if ext == None:
|
||||
ext = ""
|
||||
else:
|
||||
spath = self.get_default_directory()
|
||||
if self.get_target_is_directory():
|
||||
self.target_fileentry.set_filename(spath)
|
||||
else:
|
||||
base = self.get_default_basename()
|
||||
spath = os.path.normpath("%s/%s%s" % (spath,base,ext))
|
||||
self.target_fileentry.set_filename(spath)
|
||||
|
||||
def setup_output_notebook(self):
|
||||
"""Set up the output notebook of the dialog. This sole
|
||||
purpose of this function is to grab a pointer for later use in
|
||||
the callback from when the file format is changed."""
|
||||
pass
|
||||
|
||||
def size_changed(self,obj):
|
||||
(paper,name) = self.papersize_menu.get_value()
|
||||
|
||||
if name == "Custom Size":
|
||||
self.pwidth.set_sensitive(1)
|
||||
self.pheight.set_sensitive(1)
|
||||
else:
|
||||
self.pwidth.set_sensitive(0)
|
||||
self.pheight.set_sensitive(0)
|
||||
|
||||
if paper.get_width() > 0 and paper.get_height() > 0:
|
||||
self.pwidth.set_text("%.2f" % paper.get_width())
|
||||
self.pheight.set_text("%.2f" % paper.get_height())
|
||||
|
||||
def setup_paper_frame(self):
|
||||
"""Set up the paper selection frame of the dialog. This
|
||||
function relies on a paper_xxx() customization functions to
|
||||
determine whether the pagecount menu should appear and what
|
||||
its strings should be."""
|
||||
|
||||
(pagecount_map, start_text) = self.get_print_pagecount_map()
|
||||
|
||||
if pagecount_map:
|
||||
self.paper_table = gtk.Table(2,6)
|
||||
else:
|
||||
self.paper_table = gtk.Table(3,6)
|
||||
self.paper_table.set_col_spacings(12)
|
||||
self.paper_table.set_row_spacings(6)
|
||||
self.paper_table.set_border_width(6)
|
||||
|
||||
self.papersize_menu = _PaperMenu.GrampsPaperComboBox()
|
||||
self.papersize_menu.connect('changed',self.size_changed)
|
||||
|
||||
self.orientation_menu = _PaperMenu.GrampsOrientationComboBox()
|
||||
l = gtk.Label("%s:" % _("Size"))
|
||||
l.set_alignment(0.0,0.5)
|
||||
|
||||
self.paper_table.attach(l,1,2,0,1,gtk.SHRINK|gtk.FILL)
|
||||
self.paper_table.attach(self.papersize_menu,2,3,0,1,
|
||||
yoptions=gtk.SHRINK)
|
||||
l = gtk.Label("%s:" % _("Height"))
|
||||
l.set_alignment(0.0,0.5)
|
||||
self.paper_table.attach(l,3,4,0,1,gtk.SHRINK|gtk.FILL)
|
||||
|
||||
self.pheight = gtk.Entry()
|
||||
self.pheight.set_sensitive(0)
|
||||
self.paper_table.attach(self.pheight,4,5,0,1)
|
||||
|
||||
l = gtk.Label(_("cm"))
|
||||
l.set_alignment(0.0,0.5)
|
||||
self.paper_table.attach(l,5,6,0,1,gtk.SHRINK|gtk.FILL)
|
||||
|
||||
l = gtk.Label("%s:" % _("Orientation"))
|
||||
l.set_alignment(0.0,0.5)
|
||||
self.paper_table.attach(l,1,2,1,2,gtk.SHRINK|gtk.FILL)
|
||||
self.paper_table.attach(self.orientation_menu,2,3,1,2,
|
||||
yoptions=gtk.SHRINK)
|
||||
l = gtk.Label("%s:" % _("Width"))
|
||||
l.set_alignment(0.0,0.5)
|
||||
self.paper_table.attach(l,3,4,1,2,gtk.SHRINK|gtk.FILL)
|
||||
|
||||
self.pwidth = gtk.Entry()
|
||||
self.pwidth.set_sensitive(0)
|
||||
self.paper_table.attach(self.pwidth,4,5,1,2)
|
||||
|
||||
l = gtk.Label(_("cm"))
|
||||
l.set_alignment(0.0,0.5)
|
||||
self.paper_table.attach(l,5,6,1,2,gtk.SHRINK|gtk.FILL)
|
||||
|
||||
self.papersize_menu.set(_PaperMenu.paper_sizes,
|
||||
self.options.handler.get_paper_name())
|
||||
self.orientation_menu.set(self.options.handler.get_orientation())
|
||||
|
||||
# The optional pagecount stuff.
|
||||
if pagecount_map:
|
||||
self.pagecount_menu = gtk.OptionMenu()
|
||||
myMenu = Utils.build_string_optmenu(pagecount_map, start_text)
|
||||
self.pagecount_menu.set_menu(myMenu)
|
||||
l = gtk.Label("%s:" % _("Page Count"))
|
||||
l.set_alignment(0.0,0.5)
|
||||
self.paper_table.attach(l,1,2,2,3,gtk.SHRINK|gtk.FILL)
|
||||
self.paper_table.attach(self.pagecount_menu,2,3,2,3)
|
||||
|
||||
def html_file_enable(self,obj):
|
||||
active = obj.get_active()
|
||||
text = unicode(obj.get_model()[active][0])
|
||||
if _template_map.has_key(text):
|
||||
if _template_map[text]:
|
||||
self.html_fileentry.set_sensitive(0)
|
||||
else:
|
||||
self.html_fileentry.set_sensitive(1)
|
||||
else:
|
||||
self.html_fileentry.set_sensitive(0)
|
||||
|
||||
|
||||
def setup_html_frame(self):
|
||||
"""Set up the html frame of the dialog. This sole purpose of
|
||||
this function is to grab a pointer for later use in the parse
|
||||
html frame function."""
|
||||
|
||||
self.html_table = gtk.Table(3,3)
|
||||
self.html_table.set_col_spacings(12)
|
||||
self.html_table.set_row_spacings(6)
|
||||
self.html_table.set_border_width(0)
|
||||
|
||||
label = gtk.Label("%s:" % _("Template"))
|
||||
label.set_alignment(0.0,0.5)
|
||||
self.html_table.attach(label, 1, 2, 1, 2, gtk.SHRINK|gtk.FILL)
|
||||
|
||||
self.template_combo = gtk.combo_box_new_text()
|
||||
tlist = _template_map.keys()
|
||||
tlist.sort()
|
||||
|
||||
template_name = self.options.handler.get_template_name()
|
||||
|
||||
self.template_combo.append_text(_default_template)
|
||||
template_index = 1
|
||||
active_index = 0
|
||||
for template in tlist:
|
||||
if template != _user_template:
|
||||
self.template_combo.append_text(template)
|
||||
if _template_map[template] == template_name:
|
||||
active_index = template_index
|
||||
template_index = template_index + 1
|
||||
self.template_combo.append_text(_user_template)
|
||||
|
||||
self.template_combo.connect('changed',self.html_file_enable)
|
||||
|
||||
self.html_table.attach(self.template_combo,2,3,1,2)
|
||||
label = gtk.Label("%s:" % _("User Template"))
|
||||
label.set_alignment(0.0,0.5)
|
||||
self.html_table.attach(label, 1, 2, 2, 3, gtk.SHRINK|gtk.FILL)
|
||||
self.html_fileentry = FileEntry("HTML_Template",
|
||||
_("Choose File"))
|
||||
if template_name and not active_index:
|
||||
active_index = template_index
|
||||
user_template = template_name
|
||||
self.html_fileentry.set_sensitive(True)
|
||||
else:
|
||||
user_template = ''
|
||||
self.html_fileentry.set_sensitive(False)
|
||||
|
||||
if os.path.isfile(user_template):
|
||||
self.html_fileentry.set_filename(user_template)
|
||||
self.html_table.attach(self.html_fileentry,2,3,2,3)
|
||||
self.template_combo.set_active(active_index)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Functions related to retrieving data from the dialog window
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def parse_target_frame(self):
|
||||
"""Parse the target frame of the dialog. If the target
|
||||
filename is empty this routine returns a special value of None
|
||||
to tell the calling routine to give up. This function also
|
||||
saves the current directory so that any future reports will
|
||||
default to the most recently used directory."""
|
||||
self.target_path = self.target_fileentry.get_full_path(0)
|
||||
if not self.target_path:
|
||||
return None
|
||||
|
||||
# First we check whether the selected path exists
|
||||
if os.path.exists(self.target_path):
|
||||
|
||||
# selected path is an existing dir and we need a dir
|
||||
if os.path.isdir(self.target_path) \
|
||||
and self.get_target_is_directory():
|
||||
|
||||
# check whether the dir has rwx permissions
|
||||
if not os.access(self.target_path,os.R_OK|os.W_OK|os.X_OK):
|
||||
ErrorDialog(_('Permission problem'),
|
||||
_("You do not have permission to write "
|
||||
"under the directory %s\n\n"
|
||||
"Please select another directory or correct "
|
||||
"the permissions." % self.target_path)
|
||||
)
|
||||
return None
|
||||
|
||||
# selected path is an exsting file and we need a file
|
||||
if os.path.isfile(self.target_path) \
|
||||
and not self.get_target_is_directory():
|
||||
a = OptionDialog(_('File already exists'),
|
||||
_('You can choose to either overwrite the '
|
||||
'file, or change the selected filename.'),
|
||||
_('_Overwrite'),None,
|
||||
_('_Change filename'),None)
|
||||
|
||||
if a.get_response() == gtk.RESPONSE_YES:
|
||||
return None
|
||||
|
||||
# selected path does not exist yet
|
||||
else:
|
||||
# we will need to create the file/dir
|
||||
# need to make sure we can create in the parent dir
|
||||
parent_dir = os.path.dirname(os.path.normpath(self.target_path))
|
||||
if not os.access(parent_dir,os.W_OK):
|
||||
ErrorDialog(_('Permission problem'),
|
||||
_("You do not have permission to create "
|
||||
"%s\n\n"
|
||||
"Please select another path or correct "
|
||||
"the permissions." % self.target_path)
|
||||
)
|
||||
return None
|
||||
|
||||
self.set_default_directory(os.path.dirname(self.target_path) + os.sep)
|
||||
self.options.handler.output = self.target_path
|
||||
return 1
|
||||
|
||||
def parse_format_frame(self):
|
||||
"""Parse the format frame of the dialog. Save the user
|
||||
selected output format for later use."""
|
||||
self.format = self.format_menu.get_reference()
|
||||
format_name = self.format_menu.get_clname()
|
||||
self.options.handler.set_format_name(format_name)
|
||||
|
||||
def parse_paper_frame(self):
|
||||
"""Parse the paper frame of the dialog. Save the user
|
||||
selected choices for later use. Note that this routine
|
||||
retrieves a value from the pagecount menu, whether or not it
|
||||
is displayed on the screen. The subclass will know which ones
|
||||
it has enabled. This is for simplicity of programming."""
|
||||
|
||||
(self.paper,paper_name) = self.papersize_menu.get_value()
|
||||
|
||||
self.options.handler.set_paper_name(paper_name)
|
||||
self.options.handler.set_paper(self.paper)
|
||||
|
||||
if self.paper.get_height() <= 0 or self.paper.get_width() <= 0:
|
||||
try:
|
||||
h = float(unicode(self.pheight.get_text()))
|
||||
w = float(unicode(self.pwidth.get_text()))
|
||||
|
||||
if h <= 1.0 or w <= 1.0:
|
||||
self.paper.set_height(29.7)
|
||||
self.paper.set_width(21.0)
|
||||
else:
|
||||
self.paper.set_height(h)
|
||||
self.paper.set_width(w)
|
||||
except:
|
||||
self.paper.set_height(29.7)
|
||||
self.paper.set_width(21.0)
|
||||
|
||||
self.orien = self.orientation_menu.get_value()
|
||||
self.options.handler.set_orientation(self.orien)
|
||||
|
||||
if self.pagecount_menu == None:
|
||||
self.pagecount = 0
|
||||
else:
|
||||
self.pagecount = self.pagecount_menu.get_menu().get_active().get_data("d")
|
||||
|
||||
def parse_html_frame(self):
|
||||
"""Parse the html frame of the dialog. Save the user selected
|
||||
html template name for later use. Note that this routine
|
||||
retrieves a value whether or not the file entry box is
|
||||
displayed on the screen. The subclass will know whether this
|
||||
entry was enabled. This is for simplicity of programming."""
|
||||
|
||||
model = self.template_combo.get_model()
|
||||
text = unicode(model[self.template_combo.get_active()][0])
|
||||
|
||||
if _template_map.has_key(text):
|
||||
if text == _user_template:
|
||||
self.template_name = self.html_fileentry.get_full_path(0)
|
||||
else:
|
||||
self.template_name = "%s/%s" % (const.template_dir,_template_map[text])
|
||||
else:
|
||||
self.template_name = ""
|
||||
self.options.handler.set_template_name(self.template_name)
|
||||
|
||||
def on_ok_clicked(self, obj):
|
||||
"""The user is satisfied with the dialog choices. Validate
|
||||
the output file name before doing anything else. If there is
|
||||
a file name, gather the options and create the report."""
|
||||
|
||||
# Is there a filename? This should also test file permissions, etc.
|
||||
if not self.parse_target_frame():
|
||||
self.window.run()
|
||||
|
||||
# Preparation
|
||||
self.parse_format_frame()
|
||||
self.parse_style_frame()
|
||||
self.parse_paper_frame()
|
||||
self.parse_html_frame()
|
||||
self.parse_report_options_frame()
|
||||
self.parse_other_frames()
|
||||
self.parse_user_options()
|
||||
|
||||
# Create the output document.
|
||||
self.make_document()
|
||||
|
||||
# Save options
|
||||
self.options.handler.save_options()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Generic task function a standalone GUI report
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def report(database,person,report_class,options_class,
|
||||
translated_name,name,category):
|
||||
"""
|
||||
report - 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.
|
||||
"""
|
||||
|
||||
if category == CATEGORY_TEXT:
|
||||
dialog_class = TextReportDialog
|
||||
elif category == CATEGORY_DRAW:
|
||||
dialog_class = DrawReportDialog
|
||||
elif category in (CATEGORY_BOOK,CATEGORY_VIEW,
|
||||
CATEGORY_CODE,CATEGORY_WEB):
|
||||
report_class(database,person)
|
||||
return
|
||||
else:
|
||||
dialog_class = ReportDialog
|
||||
|
||||
dialog = dialog_class(database,person,options_class,name,translated_name)
|
||||
response = dialog.window.run()
|
||||
if response == gtk.RESPONSE_OK:
|
||||
try:
|
||||
MyReport = report_class(dialog.db,dialog.person,dialog.options)
|
||||
MyReport.doc.init()
|
||||
MyReport.begin_report()
|
||||
MyReport.write_report()
|
||||
MyReport.end_report()
|
||||
except Errors.FilterError, msg:
|
||||
(m1,m2) = msg.messages()
|
||||
ErrorDialog(m1,m2)
|
||||
except Errors.ReportError, msg:
|
||||
(m1,m2) = msg.messages()
|
||||
ErrorDialog(m1,m2)
|
||||
except Errors.DatabaseError,msg:
|
||||
ErrorDialog(_("Report could not be created"),str(msg))
|
||||
except:
|
||||
log.error("Failed to run report.", exc_info=True)
|
||||
dialog.window.destroy()
|
@ -51,7 +51,7 @@ import const
|
||||
import Config
|
||||
import Utils
|
||||
import BaseDoc
|
||||
import _Options
|
||||
from PluginUtils import _Options
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
85
src/PluginUtils/Report/_StyleComboBox.py
Normal file
85
src/PluginUtils/Report/_StyleComboBox.py
Normal file
@ -0,0 +1,85 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# StyleComboBox
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class StyleComboBox(gtk.ComboBox):
|
||||
"""
|
||||
Derived from the ComboBox, this widget provides handling of Report
|
||||
Styles.
|
||||
"""
|
||||
|
||||
def __init__(self,model=None):
|
||||
"""
|
||||
Initializes the combobox, building the display column.
|
||||
"""
|
||||
gtk.ComboBox.__init__(self,model)
|
||||
cell = gtk.CellRendererText()
|
||||
self.pack_start(cell,True)
|
||||
self.add_attribute(cell,'text',0)
|
||||
|
||||
def set(self,style_map,default):
|
||||
"""
|
||||
Sets the options for the ComboBox, using the passed style
|
||||
map as the data.
|
||||
|
||||
@param style_map: dictionary of style names and the corresponding
|
||||
style sheet
|
||||
@type style_map: dictionary
|
||||
@param default: Default selection in the ComboBox
|
||||
@type default: str
|
||||
"""
|
||||
self.store = gtk.ListStore(str)
|
||||
self.set_model(self.store)
|
||||
self.style_map = style_map
|
||||
keys = style_map.keys()
|
||||
keys.sort()
|
||||
index = 0
|
||||
start_index = 0
|
||||
for key in keys:
|
||||
if key == "default":
|
||||
self.store.append(row=[_('default')])
|
||||
else:
|
||||
self.store.append(row=[key])
|
||||
if key == default:
|
||||
start_index = index
|
||||
index += 1
|
||||
|
||||
self.set_active(start_index)
|
||||
|
||||
def get_value(self):
|
||||
"""
|
||||
Returns the selected key (style sheet name).
|
||||
|
||||
@returns: Returns the name of the selected style sheet
|
||||
@rtype: str
|
||||
"""
|
||||
active = self.get_active()
|
||||
if active < 0:
|
||||
return None
|
||||
key = self.store[active][0]
|
||||
if key == _('default'):
|
||||
key = "default"
|
||||
return (key,self.style_map[key])
|
111
src/PluginUtils/Report/_TemplateParser.py
Normal file
111
src/PluginUtils/Report/_TemplateParser.py
Normal file
@ -0,0 +1,111 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
from gettext import gettext as _
|
||||
import os
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
#
|
||||
# XML modules
|
||||
#
|
||||
#-----------------------------------------------------------------------
|
||||
try:
|
||||
from xml.sax import make_parser,handler,SAXParseException
|
||||
except:
|
||||
from _xmlplus.sax import make_parser,handler,SAXParseException
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#-----------------------------------------------------------------------
|
||||
import const
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
#
|
||||
# Parser for templates file
|
||||
#
|
||||
#-----------------------------------------------------------------------
|
||||
class TemplateParser(handler.ContentHandler):
|
||||
"""
|
||||
Interface to the document template file
|
||||
"""
|
||||
def __init__(self,data,fpath):
|
||||
"""
|
||||
Creates a template parser. The parser loads map of tempate names
|
||||
to the file containing the tempate.
|
||||
|
||||
data - dictionary that holds the name to path mappings
|
||||
fpath - filename of the XML file
|
||||
"""
|
||||
handler.ContentHandler.__init__(self)
|
||||
self.data = data
|
||||
self.path = fpath
|
||||
|
||||
def setDocumentLocator(self,locator):
|
||||
"""Sets the XML document locator"""
|
||||
self.locator = locator
|
||||
|
||||
def startElement(self,tag,attrs):
|
||||
"""
|
||||
Loads the dictionary when an XML tag of 'template' is found. The format
|
||||
XML tag is <template title=\"name\" file=\"path\">
|
||||
"""
|
||||
|
||||
if tag == "template":
|
||||
self.data[attrs['title']] = attrs['file']
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
#
|
||||
# Initialization
|
||||
#
|
||||
#-----------------------------------------------------------------------
|
||||
_default_template = _("Default Template")
|
||||
_user_template = _("User Defined Template")
|
||||
|
||||
_template_map = {
|
||||
_user_template : ""
|
||||
}
|
||||
try:
|
||||
template_path = const.template_dir
|
||||
xmlfile = os.path.join(const.template_dir,"templates.xml")
|
||||
|
||||
if os.path.isfile(xmlfile):
|
||||
parser = make_parser()
|
||||
parser.setContentHandler(TemplateParser(_template_map,template_path))
|
||||
parser.parse(xmlfile)
|
||||
|
||||
template_path = os.path.join(const.home_dir,"templates")
|
||||
xmlfile = os.path.join(template_path,"templates.xml")
|
||||
if os.path.isfile(xmlfile):
|
||||
parser = make_parser()
|
||||
parser.setContentHandler(TemplateParser(_template_map,template_path))
|
||||
parser.parse(xmlfile)
|
||||
|
||||
except (IOError,OSError,SAXParseException):
|
||||
pass
|
78
src/PluginUtils/Report/_TextFormatComboBox.py
Normal file
78
src/PluginUtils/Report/_TextFormatComboBox.py
Normal file
@ -0,0 +1,78 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
import gtk
|
||||
import Config
|
||||
import PluginUtils
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# get_text_doc_menu
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class TextFormatComboBox(gtk.ComboBox):
|
||||
|
||||
def set(self,tables,callback,obj=None,active=None):
|
||||
self.store = gtk.ListStore(str)
|
||||
self.set_model(self.store)
|
||||
cell = gtk.CellRendererText()
|
||||
self.pack_start(cell,True)
|
||||
self.add_attribute(cell,'text',0)
|
||||
|
||||
out_pref = Config.get(Config.OUTPUT_PREFERENCE)
|
||||
index = 0
|
||||
_PluginMgr.textdoc_list.sort()
|
||||
active_index = 0
|
||||
for item in PluginUtils.textdoc_list:
|
||||
if tables and item[2] == 0:
|
||||
continue
|
||||
name = item[0]
|
||||
self.store.append(row=[name])
|
||||
#if callback:
|
||||
# menuitem.connect("activate",callback)
|
||||
if item[7] == active:
|
||||
active_index = index
|
||||
elif not active and name == out_pref:
|
||||
active_index = index
|
||||
index = index + 1
|
||||
self.set_active(active_index)
|
||||
|
||||
def get_label(self):
|
||||
return PluginUtils.textdoc_list[self.get_active()][0]
|
||||
|
||||
def get_reference(self):
|
||||
return PluginUtils.textdoc_list[self.get_active()][1]
|
||||
|
||||
def get_paper(self):
|
||||
return PluginUtils.textdoc_list[self.get_active()][3]
|
||||
|
||||
def get_styles(self):
|
||||
return PluginUtils.textdoc_list[self.get_active()][4]
|
||||
|
||||
def get_ext(self):
|
||||
return PluginUtils.textdoc_list[self.get_active()][5]
|
||||
|
||||
def get_printable(self):
|
||||
return PluginUtil.textdoc_list[self.get_active()][6]
|
||||
|
||||
def get_clname(self):
|
||||
return PluginUtils.textdoc_list[self.get_active()][7]
|
64
src/PluginUtils/Report/_TextReportDialog.py
Normal file
64
src/PluginUtils/Report/_TextReportDialog.py
Normal file
@ -0,0 +1,64 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-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: _Report.py 6669 2006-05-15 15:53:42Z rshura $
|
||||
|
||||
from _Constants import CATEGORY_TEXT
|
||||
from _ReportDialog import ReportDialog
|
||||
from _TextFormatComboBox import TextFormatComboBox
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
#
|
||||
# Textual reports
|
||||
#
|
||||
#-----------------------------------------------------------------------
|
||||
class TextReportDialog(ReportDialog):
|
||||
"""A class of ReportDialog customized for text based reports."""
|
||||
|
||||
def __init__(self,database,person,options,name,translated_name):
|
||||
"""Initialize a dialog to request that the user select options
|
||||
for a basic text report. See the ReportDialog class for more
|
||||
information."""
|
||||
self.category = CATEGORY_TEXT
|
||||
ReportDialog.__init__(self,database,person,options,name,translated_name)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Customization hooks for subclasses
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def doc_uses_tables(self):
|
||||
"""Does this report require the ability to generate tables in
|
||||
the file format. Override this for documents that do need
|
||||
table support."""
|
||||
return 0
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Functions related to selecting/changing the current file format.
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def make_doc_menu(self,active=None):
|
||||
"""Build a menu of document types that are appropriate for
|
||||
this text report. This menu will be generated based upon
|
||||
whether the document requires table support, etc."""
|
||||
self.format_menu = TextFormatComboBox()
|
||||
self.format_menu.set(self.doc_uses_tables(),
|
||||
self.doc_type_changed, None, active)
|
38
src/PluginUtils/Report/__init__.py
Normal file
38
src/PluginUtils/Report/__init__.py
Normal file
@ -0,0 +1,38 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001 David R. Hampton
|
||||
# Copyright (C) 2001-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$
|
||||
|
||||
"Report Generation Framework"
|
||||
|
||||
__author__ = "David R. Hampton, Donald N. Allingham"
|
||||
__version__ = "$Revision$"
|
||||
|
||||
from _Constants import *
|
||||
from _TemplateParser import _template_map
|
||||
|
||||
import _ReportOptions as ReportOptions
|
||||
import _ReportUtils as ReportUtils
|
||||
|
||||
from _Report import Report
|
||||
from _ReportDialog import report
|
||||
from _DrawReportDialog import DrawReportDialog
|
||||
from _TextReportDialog import TextReportDialog
|
@ -57,7 +57,7 @@ import const
|
||||
import Utils
|
||||
import Config
|
||||
import Errors
|
||||
import _Report
|
||||
from Report import report, standalone_categories
|
||||
import _Tool
|
||||
import _PluginMgr
|
||||
import _PluginStatus
|
||||
@ -152,7 +152,7 @@ class PluginDialog(ManagedWindow.ManagedWindow):
|
||||
|
||||
(item_class,options_class,title,category,name) = self.item
|
||||
if self.content == REPORTS:
|
||||
_Report.report(self.state.db,self.state.active,
|
||||
report(self.state.db,self.state.active,
|
||||
item_class,options_class,title,name,category)
|
||||
else:
|
||||
_Tool.gui_tool(self.state,self.uistate,
|
||||
@ -260,7 +260,7 @@ class ReportPlugins(PluginDialog):
|
||||
uistate,
|
||||
track,
|
||||
_PluginMgr.report_list,
|
||||
_Report.standalone_categories,
|
||||
standalone_categories,
|
||||
_("Report Selection"),
|
||||
_("Select a report from those available on the left."),
|
||||
_("_Generate"), _("Generate selected report"),
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,9 +30,6 @@ from _PluginMgr import \
|
||||
report_list, tool_list, \
|
||||
register_text_doc, register_draw_doc, register_book_doc
|
||||
|
||||
import _Report as Report
|
||||
import _ReportOptions as ReportOptions
|
||||
import _ReportUtils as ReportUtils
|
||||
import _Tool as Tool
|
||||
import _Plugins as Plugins
|
||||
import _PluginStatus as PluginStatus
|
||||
|
@ -10,7 +10,6 @@ pkgdata_PYTHON = \
|
||||
AncestorChart2.py\
|
||||
AncestorReport.py\
|
||||
Ancestors.py\
|
||||
BookReport.py\
|
||||
Calendar.py \
|
||||
ChangeTypes.py\
|
||||
ChangeNames.py\
|
||||
|
Loading…
Reference in New Issue
Block a user