diff --git a/po/POTFILES.in b/po/POTFILES.in
index 62c53ba7f..dd1a2db3a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -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
diff --git a/src/ManagedWindow.py b/src/ManagedWindow.py
index 4994f3680..cf2d52630 100644
--- a/src/ManagedWindow.py
+++ b/src/ManagedWindow.py
@@ -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
diff --git a/src/PluginUtils/_Options.py b/src/PluginUtils/_Options.py
index fb74f6cc3..8afb59a6c 100644
--- a/src/PluginUtils/_Options.py
+++ b/src/PluginUtils/_Options.py
@@ -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
diff --git a/src/PluginUtils/_PluginWindows.py b/src/PluginUtils/_PluginWindows.py
index 0ffc732b6..f86c5c306 100644
--- a/src/PluginUtils/_PluginWindows.py
+++ b/src/PluginUtils/_PluginWindows.py
@@ -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):
diff --git a/src/ReportBase/Makefile.am b/src/ReportBase/Makefile.am
index 82a67b861..762ee899d 100644
--- a/src/ReportBase/Makefile.am
+++ b/src/ReportBase/Makefile.am
@@ -4,7 +4,6 @@ pkgdatadir = $(datadir)/@PACKAGE@/ReportBase
pkgdata_PYTHON = \
__init__.py\
- _BareReportDialog.py\
_Bibliography.py\
_BookFormatComboBox.py\
_CommandLineReport.py\
diff --git a/src/ReportBase/_BareReportDialog.py b/src/ReportBase/_BareReportDialog.py
deleted file mode 100644
index 47b31e686..000000000
--- a/src/ReportBase/_BareReportDialog.py
+++ /dev/null
@@ -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('%s' % 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("%s" % _('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("%s" % _("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("%s" % _(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("%s" % 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
diff --git a/src/ReportBase/_DocReportDialog.py b/src/ReportBase/_DocReportDialog.py
index 559e7b3a4..11f53769b 100644
--- a/src/ReportBase/_DocReportDialog.py
+++ b/src/ReportBase/_DocReportDialog.py
@@ -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(),
diff --git a/src/ReportBase/_GraphvizReportDialog.py b/src/ReportBase/_GraphvizReportDialog.py
index 5726bae47..b576bdd8c 100644
--- a/src/ReportBase/_GraphvizReportDialog.py
+++ b/src/ReportBase/_GraphvizReportDialog.py
@@ -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('%s'%_("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
diff --git a/src/ReportBase/_ReportDialog.py b/src/ReportBase/_ReportDialog.py
index 8810d1c97..2489cff10 100644
--- a/src/ReportBase/_ReportDialog.py
+++ b/src/ReportBase/_ReportDialog.py
@@ -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('%s' %
+ 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("%s" % _("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("%s" % _(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("%s" % 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("%s" % _('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):