Merge BareReportDialog with ReportDialog. BareReportDialog is now gone.

svn: r10620
This commit is contained in:
Brian Matherly 2008-04-22 03:45:09 +00:00
parent b00c68a972
commit 26cdcd680e
9 changed files with 391 additions and 568 deletions

View File

@ -341,7 +341,6 @@ src/PluginUtils/_PluginWindows.py
src/PluginUtils/_MenuOptions.py
# ReportBase package
src/ReportBase/_BareReportDialog.py
src/ReportBase/_BookFormatComboBox.py
src/ReportBase/_CommandLineReport.py
src/ReportBase/_Constants.py

View File

@ -425,7 +425,7 @@ class ManagedWindow:
Connect the OK button to a method that checks if all is ok,
Do not call close, close is called here.
(if not ok, do self.window.run() to obtain new response )
TODO: remove close here and do close in BareReportDialog,
TODO: remove close here and do close in ReportDialog,
this can only be done, once all methods use modal_call()
instead of their own implementation
Connect Cancel to do close, delete event is connected to close

View File

@ -445,7 +445,7 @@ class Options:
Set up UI controls (widgets) for the options specific for this modul.
This method MUST be overridden by modules that define new options.
The single argument 'dialog' is the Report.BareReportDialog instance.
The single argument 'dialog' is the Report.ReportDialog instance.
Any attribute of the dialog is available.
After the widgets are defined, they MUST be added to the dialog
@ -463,7 +463,7 @@ class Options:
Parses UI controls (widgets) for the options specific for this module.
This method MUST be overridden by modules that define new options.
The single argument 'dialog' is the Report.BareReportDialog instance.
The single argument 'dialog' is the Report.ReportDialog instance.
Any attribute of the dialog is available.
After obtaining values from the widgets, they MUST be used to set the

View File

@ -195,7 +195,6 @@ class ToolManagedWindowBase(ManagedWindow.ManagedWindow):
"""
Copied from src/ReportBase/_BareReportDialog.py BareReportDialog
"""
frame_pad = 5
border_pad = 6
HELP_TOPIC = None
def __init__(self, dbstate, uistate, option_class, name, callback=None):

View File

@ -4,7 +4,6 @@ pkgdatadir = $(datadir)/@PACKAGE@/ReportBase
pkgdata_PYTHON = \
__init__.py\
_BareReportDialog.py\
_Bibliography.py\
_BookFormatComboBox.py\
_CommandLineReport.py\

View File

@ -1,490 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2001-2007 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$
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
from types import ClassType, InstanceType
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
import gtk
#-------------------------------------------------------------------------
#
# gramps modules
#
#-------------------------------------------------------------------------
from BasicUtils import name_displayer
import BaseDoc
import ManagedWindow
from _StyleComboBox import StyleComboBox
from _StyleEditor import StyleListDisplay
import logging
log = logging.getLogger(".")
#-------------------------------------------------------------------------
#
# Private Constants
#
#-------------------------------------------------------------------------
URL_REPORT_PAGE = "Gramps_3.0_Wiki_Manual_-_Reports"
#-------------------------------------------------------------------------
#
# BareReportDialog class
#
#-------------------------------------------------------------------------
class BareReportDialog(ManagedWindow.ManagedWindow):
"""
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, dbstate, uistate, option_class,
name, translated_name, track=[]):
"""Initialize a dialog to request that the user select options
for a basic *bare* report."""
self.raw_name = name
self.dbstate = dbstate
self.db = dbstate.db
self.report_name = translated_name
ManagedWindow.ManagedWindow.__init__(self, uistate, track, self)
self.init_options(option_class)
self.init_interface()
def init_options(self, option_class):
if type(option_class) == ClassType:
self.options = option_class(self.raw_name, self.db)
elif type(option_class) == InstanceType:
self.options = option_class
self.options.load_previous_values()
def build_window_key(self, obj):
key = self.raw_name
return key
def build_menu_names(self, obj):
return (_("Configuration"),self.report_name)
def init_interface(self):
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()
window = gtk.Dialog('GRAMPS')
self.set_window(window,None,self.get_title())
self.window.set_has_separator(False)
self.window.set_modal(True)
self.help = self.window.add_button(gtk.STOCK_HELP, gtk.RESPONSE_HELP)
self.help.connect('clicked',self.on_help_clicked)
self.cancel = self.window.add_button(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL)
self.cancel.connect('clicked',self.on_cancel)
self.ok = self.window.add_button(gtk.STOCK_OK,gtk.RESPONSE_OK)
self.ok.connect('clicked',self.on_ok_clicked)
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.row = 0
# Build the list of widgets that are used to extend the Options
# frame and to create other frames
self.add_user_options()
self.setup_main_options()
self.setup_init()
self.setup_format_frame()
self.setup_target_frame()
self.setup_style_frame()
self.notebook = gtk.Notebook()
self.notebook.set_scrollable(True)
self.notebook.set_border_width(6)
self.window.vbox.add(self.notebook)
self.setup_report_options_frame()
self.setup_other_frames()
self.notebook.set_current_page(0)
self.window.vbox.add(self.tbl)
self.show()
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"
#------------------------------------------------------------------------
#
# 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):
"""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))
def add_frame_option(self, frame_name, label_text, widget):
"""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)
#------------------------------------------------------------------------
#
# 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 = ''
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,
BareReportDialog.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.row, self.row+1, gtk.FILL|gtk.EXPAND)
self.row += 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."""
# Build the default style set for this report.
self.default_style = BaseDoc.StyleSheet()
self.options.make_default_style(self.default_style)
if self.default_style.is_empty():
# Don't display the option of no styles are used
return
# Styles Frame
label = gtk.Label("%s:" % _("Style"))
label.set_alignment(0.0,0.5)
self.style_menu = StyleComboBox()
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.row,self.row+1,gtk.SHRINK|gtk.FILL)
self.tbl.attach(self.style_menu,2,3,self.row,self.row+1,
yoptions=gtk.SHRINK)
self.tbl.attach(self.style_button,3,4,self.row,self.row+1,
xoptions=gtk.SHRINK|gtk.FILL,yoptions=gtk.SHRINK)
self.row += 1
# 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 is used in most
(but not all) dialog boxes."""
row = 0
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
# 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:
if key == "":
continue
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
def setup_init(self):
pass
def setup_main_options(self):
if self.frames.has_key(""):
flist = self.frames[""]
for (text,widget) in flist:
label = gtk.Label("<b>%s</b>" % text)
label.set_use_markup(True)
label.set_alignment(0.0,0.5)
self.tbl.set_border_width(12)
self.tbl.attach(label,0,4,self.row,self.row+1)
self.row += 1
self.tbl.attach(widget,2,4,self.row,self.row+1)
self.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
#------------------------------------------------------------------------
#
# 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."""
if not self.default_style.is_empty():
(style_name, self.selected_style) = self.style_menu.get_value()
self.options.handler.set_default_stylesheet_name(style_name)
#------------------------------------------------------------------------
#
# Callback functions from the dialog
#
#------------------------------------------------------------------------
def on_cancel(self,*obj):
pass
def on_help_clicked(self, *obj):
import GrampsDisplay
GrampsDisplay.help(URL_REPORT_PAGE, self.report_name.replace(" ", "_"))
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_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)
#------------------------------------------------------------------------
#
# 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

View File

@ -129,16 +129,15 @@ class DocReportDialog(ReportDialog):
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)
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)
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:
@ -170,12 +169,9 @@ class DocReportDialog(ReportDialog):
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)
base = self.get_default_basename()
spath = os.path.normpath("%s/%s%s" % (spath, base, ext))
self.target_fileentry.set_filename(spath)
def setup_report_options_frame(self):
self.paper_frame = PaperFrame(self.options.handler.get_paper_metric(),

View File

@ -887,12 +887,9 @@ class GraphvizReportDialog(ReportDialog):
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)
base = self.get_default_basename()
spath = os.path.normpath("%s/%s%s" % (spath, base, ext))
self.target_fileentry.set_filename(spath)
def setup_report_options_frame(self):
self.paper_label = gtk.Label('<b>%s</b>'%_("Paper Options"))
@ -980,5 +977,5 @@ class GraphvizReportDialog(ReportDialog):
self.options.handler.set_format_name(format_name)
def setup_style_frame(self):
"""Required by ReportDialog:BareReportDialog"""
"""Required by ReportDialog"""
pass

View File

@ -2,6 +2,7 @@
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2001-2006 Donald N. Allingham
# Copyright (C) 2008 Brian G. Matherly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -26,11 +27,11 @@
#
#-------------------------------------------------------------------------
import os
from types import ClassType, InstanceType
from gettext import gettext as _
import logging
log = logging.getLogger(".")
LOG = logging.getLogger(".")
#-------------------------------------------------------------------------
#
@ -47,24 +48,35 @@ import gtk
import Config
import Errors
from QuestionDialog import ErrorDialog, OptionDialog
from _Constants import (CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK,
from ReportBase import (CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK,
CATEGORY_CODE, CATEGORY_WEB, CATEGORY_GRAPHVIZ,
standalone_categories)
from _BareReportDialog import BareReportDialog
import BaseDoc
import ManagedWindow
from _StyleComboBox import StyleComboBox
from _StyleEditor import StyleListDisplay
from _FileEntry import FileEntry
#-------------------------------------------------------------------------
#
# Private Constants
#
#-------------------------------------------------------------------------
URL_REPORT_PAGE = "Gramps_3.0_Wiki_Manual_-_Reports"
#-------------------------------------------------------------------------
#
# ReportDialog class
#
#-------------------------------------------------------------------------
class ReportDialog(BareReportDialog):
class ReportDialog(ManagedWindow.ManagedWindow):
"""
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.
"""
border_pad = 6
def __init__(self, dbstate, uistate, option_class, name, trans_name,
track=[]):
@ -73,45 +85,332 @@ class ReportDialog(BareReportDialog):
self.style_name = "default"
self.page_html_added = False
BareReportDialog.__init__(self, dbstate, uistate, option_class,
name, trans_name, track)
self.raw_name = name
self.dbstate = dbstate
self.db = dbstate.db
self.report_name = trans_name
ManagedWindow.ManagedWindow.__init__(self, uistate, track, self)
# Allow for post processing of the format frame, since the
# show_all task calls events that may reset values
self.init_options(option_class)
self.init_interface()
def init_options(self, option_class):
if type(option_class) == ClassType:
self.options = option_class(self.raw_name, self.db)
elif type(option_class) == InstanceType:
self.options = option_class
self.options.load_previous_values()
def build_window_key(self, obj):
key = self.raw_name
return key
def build_menu_names(self, obj):
return (_("Configuration"), self.report_name)
def init_interface(self):
BareReportDialog.init_interface(self)
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()
window = gtk.Dialog('GRAMPS')
self.set_window(window, None, self.get_title())
self.window.set_has_separator(False)
self.window.set_modal(True)
self.help = self.window.add_button(gtk.STOCK_HELP, gtk.RESPONSE_HELP)
self.help.connect('clicked', self.on_help_clicked)
self.cancel = self.window.add_button(gtk.STOCK_CANCEL,
gtk.RESPONSE_CANCEL)
self.cancel.connect('clicked', self.on_cancel)
self.ok = self.window.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
self.ok.connect('clicked', self.on_ok_clicked)
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.row = 0
# Build the list of widgets that are used to extend the Options
# frame and to create other frames
self.add_user_options()
self.setup_main_options()
self.setup_init()
self.setup_format_frame()
self.setup_target_frame()
self.setup_style_frame()
self.notebook = gtk.Notebook()
self.notebook.set_scrollable(True)
self.notebook.set_border_width(6)
self.window.vbox.add(self.notebook)
self.setup_report_options_frame()
self.setup_other_frames()
self.notebook.set_current_page(0)
self.window.vbox.add(self.tbl)
self.show()
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 self.report_name
return "%s - %s - GRAMPS" % (name, category)
#------------------------------------------------------------------------
#
# 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_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_default_basename(self):
"""What should the default name be?
"""
spath = self.options.handler.get_stylesheet_savefile()
return spath.split('.')[0]
#------------------------------------------------------------------------
#
# 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):
"""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))
def add_frame_option(self, frame_name, label_text, widget):
"""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)
#------------------------------------------------------------------------
#
# 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.window.set_title(self.get_title())
def setup_header(self):
"""Set up the header line bar of the dialog."""
label = gtk.Label('<span size="larger" weight="bold">%s</span>' %
self.report_name)
label.set_use_markup(True)
self.window.vbox.pack_start(label, True, True, self.border_pad)
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."""
# Build the default style set for this report.
self.default_style = BaseDoc.StyleSheet()
self.options.make_default_style(self.default_style)
if self.default_style.is_empty():
# Don't display the option of no styles are used
return
# Styles Frame
label = gtk.Label("%s:" % _("Style"))
label.set_alignment(0.0, 0.5)
self.style_menu = StyleComboBox()
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.row, self.row+1, gtk.SHRINK|gtk.FILL)
self.tbl.attach(self.style_menu, 2, 3, self.row, self.row+1,
yoptions=gtk.SHRINK)
self.tbl.attach(self.style_button, 3, 4, self.row, self.row+1,
xoptions=gtk.SHRINK|gtk.FILL, yoptions=gtk.SHRINK)
self.row += 1
# 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 is used in most
(but not all) dialog boxes."""
row = 0
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
# 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:
if key == "":
continue
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
def setup_main_options(self):
if self.frames.has_key(""):
flist = self.frames[""]
for (text, widget) in flist:
label = gtk.Label("<b>%s</b>" % text)
label.set_use_markup(True)
label.set_alignment(0.0, 0.5)
self.tbl.set_border_width(12)
self.tbl.attach(label, 0, 4, self.row, self.row+1)
self.row += 1
self.tbl.attach(widget, 2, 4, self.row, self.row+1)
self.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
#------------------------------------------------------------------------
#
@ -132,7 +431,7 @@ class ReportDialog(BareReportDialog):
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)
Config.set(Config.REPORT_DIRECTORY, value)
#------------------------------------------------------------------------
#
@ -142,16 +441,16 @@ class ReportDialog(BareReportDialog):
def setup_init(self):
# add any elements that we are going to need:
hid = self.get_stylesheet_savefile()
if hid[-4:]==".xml":
if hid[-4:] == ".xml":
hid = hid[0:-4]
self.target_fileentry = FileEntry(hid,_("Save As"))
self.target_fileentry = FileEntry(hid, _("Save As"))
spath = self.get_default_directory()
self.target_fileentry.set_filename(spath)
self.target_fileentry.gtk_entry().set_position(len(spath))
# need any labels at top:
label = gtk.Label("<b>%s</b>" % _('Document Options'))
label.set_use_markup(1)
label.set_alignment(0.0,0.5)
label.set_alignment(0.0, 0.5)
self.tbl.set_border_width(12)
self.tbl.attach(label, 0, 4, self.row, self.row+1, gtk.FILL)
self.row += 1
@ -164,12 +463,8 @@ class ReportDialog(BareReportDialog):
directory should be used."""
# Save Frame
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.doc_label = gtk.Label("%s:" % _("Filename"))
self.doc_label.set_alignment(0.0, 0.5)
self.tbl.attach(self.doc_label, 1, 2, self.row, self.row+1,
xoptions=gtk.SHRINK|gtk.FILL,yoptions=gtk.SHRINK)
@ -196,8 +491,7 @@ class ReportDialog(BareReportDialog):
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():
if os.path.isdir(self.target_path):
# check whether the dir has rwx permissions
if not os.access(self.target_path, os.R_OK|os.W_OK|os.X_OK):
@ -210,13 +504,12 @@ class ReportDialog(BareReportDialog):
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():
if os.path.isfile(self.target_path):
a = OptionDialog(_('File already exists'),
_('You can choose to either overwrite the '
'file, or change the selected filename.'),
_('_Overwrite'),None,
_('_Change filename'),None)
_('_Overwrite'), None,
_('_Change filename'), None)
if a.get_response() == gtk.RESPONSE_YES:
return None
@ -238,7 +531,22 @@ class ReportDialog(BareReportDialog):
self.set_default_directory(os.path.dirname(self.target_path) + os.sep)
self.options.handler.output = self.target_path
return 1
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."""
if not self.default_style.is_empty():
(style_name, self.selected_style) = self.style_menu.get_value()
self.options.handler.set_default_stylesheet_name(style_name)
#------------------------------------------------------------------------
#
# Callback functions from the dialog
#
#------------------------------------------------------------------------
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
@ -254,14 +562,29 @@ class ReportDialog(BareReportDialog):
# Save options
self.options.handler.save_options()
def on_cancel(self, *obj):
pass
def on_help_clicked(self, *obj):
import GrampsDisplay
GrampsDisplay.help(URL_REPORT_PAGE, self.report_name.replace(" ", "_"))
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)
#------------------------------------------------------------------------
#
# Generic task function a standalone GUI report
#
#------------------------------------------------------------------------
def report(dbstate,uistate,person,report_class, options_class,
trans_name, name,category, require_active):
def report(dbstate, uistate, person, report_class, options_class,
trans_name, name, category, require_active):
"""
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
@ -289,7 +612,7 @@ def report(dbstate,uistate,person,report_class, options_class,
dialog_class = WebReportDialog
elif category in (CATEGORY_BOOK, CATEGORY_CODE):
try:
report_class(dbstate,uistate)
report_class(dbstate, uistate)
except Errors.WindowActiveError:
pass
return
@ -309,15 +632,15 @@ def report(dbstate,uistate,person,report_class, options_class,
MyReport.write_report()
MyReport.end_report()
except Errors.FilterError, msg:
(m1,m2) = msg.messages()
ErrorDialog(m1,m2)
(m1, m2) = msg.messages()
ErrorDialog(m1, m2)
except IOError, msg:
ErrorDialog(_("Report could not be created"),str(msg))
except Errors.ReportError, msg:
(m1,m2) = msg.messages()
ErrorDialog(m1,m2)
(m1, m2) = msg.messages()
ErrorDialog(m1, m2)
except Errors.DatabaseError,msg:
ErrorDialog(_("Report could not be created"),str(msg))
ErrorDialog(_("Report could not be created"), str(msg))
# The following except statement will catch all "NoneType" exceptions.
# This is useful for released code where the exception is most likely
# a corrupt database. But it is less useful for developing new reports
@ -331,7 +654,7 @@ def report(dbstate,uistate,person,report_class, options_class,
# raise
raise
except:
log.error("Failed to run report.", exc_info=True)
LOG.error("Failed to run report.", exc_info=True)
break
elif (response == gtk.RESPONSE_DELETE_EVENT or
response == gtk.RESPONSE_CANCEL):