GEPS 008: Move book code
svn: r20524
This commit is contained in:
parent
c8baa0fcb6
commit
289689ffa8
@ -47,13 +47,13 @@ from gramps.gen.ggettext import gettext as _
|
||||
#-------------------------------------------------------------------------
|
||||
from gramps.gen.recentfiles import recent_files
|
||||
from gramps.gen.utils.file import (rm_tempdir, get_empty_tempdir,
|
||||
get_unicode_path_from_env_var)
|
||||
get_unicode_path_from_env_var)
|
||||
from gramps.gen.db import DbBsddb
|
||||
from clidbman import CLIDbManager, NAME_FILE, find_locker_name
|
||||
|
||||
from gramps.gen.plug import BasePluginManager
|
||||
from gramps.gen.plug.report import CATEGORY_BOOK, CATEGORY_CODE
|
||||
from plug import cl_report
|
||||
from gramps.gen.plug.report import CATEGORY_BOOK, CATEGORY_CODE, BookList
|
||||
from plug import cl_report, cl_book
|
||||
from user import User
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@ -665,6 +665,31 @@ class ArgHandler(object):
|
||||
else:
|
||||
print >> sys.stderr, " %s\t- %s" % (pdata.id,
|
||||
pdata.name.encode(sys.getfilesystemencoding()))
|
||||
|
||||
elif action == "book":
|
||||
try:
|
||||
options_str_dict = _split_options(options_str)
|
||||
except:
|
||||
options_str_dict = {}
|
||||
print >> sys.stderr, _("Ignoring invalid options string.")
|
||||
|
||||
name = options_str_dict.pop('name', None)
|
||||
book_list = BookList('books.xml', self.dbstate.db)
|
||||
if name:
|
||||
if name in book_list.get_book_names():
|
||||
cl_book(self.dbstate.db, name, book_list.get_book(name),
|
||||
options_str_dict)
|
||||
return
|
||||
msg = _("Unknown book name.")
|
||||
else:
|
||||
msg = _("Book name not given. "
|
||||
"Please use one of %(donottranslate)s=bookname.") % \
|
||||
{'donottranslate' : '[-p|--options] name'}
|
||||
|
||||
print >> sys.stderr, _("%s\n Available names are:") % msg
|
||||
for name in sorted(book_list.get_book_names()):
|
||||
print >> sys.stderr, " %s" % name
|
||||
|
||||
else:
|
||||
print >> sys.stderr, _("Unknown action: %s.") % action
|
||||
sys.exit(0)
|
||||
|
@ -272,7 +272,7 @@ class ArgParser(object):
|
||||
self.exports.append((value, family_tree_format))
|
||||
elif option in ( '-a', '--action' ):
|
||||
action = value
|
||||
if action not in ( 'report', 'tool' ):
|
||||
if action not in ('report', 'tool', 'book'):
|
||||
print >> sys.stderr, "Unknown action: %s. Ignoring." % action
|
||||
continue
|
||||
options_str = ""
|
||||
|
@ -54,9 +54,10 @@ from gramps.gen.plug.menu import (FamilyOption, PersonOption, NoteOption,
|
||||
BooleanOption, DestinationOption, StringOption,
|
||||
TextOption, EnumeratedListOption, Option)
|
||||
from gramps.gen.display.name import displayer as name_displayer
|
||||
from gramps.gen.errors import ReportError
|
||||
from gramps.gen.errors import ReportError, FilterError
|
||||
from gramps.gen.plug.report import (CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK,
|
||||
CATEGORY_GRAPHVIZ, CATEGORY_CODE)
|
||||
CATEGORY_GRAPHVIZ, CATEGORY_CODE,
|
||||
ReportOptions)
|
||||
from gramps.gen.plug.report._paper import paper_sizes
|
||||
from gramps.gen.const import USER_HOME
|
||||
from gramps.gen.dbstate import DbState
|
||||
@ -650,3 +651,109 @@ def run_report(db, name, **options_str_dict):
|
||||
options_str_dict)
|
||||
return clr
|
||||
return clr
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Function to write books from command line
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def cl_book(database, name, book, options_str_dict):
|
||||
|
||||
clr = CommandLineReport(database, name, CATEGORY_BOOK,
|
||||
ReportOptions, options_str_dict)
|
||||
|
||||
# Exit here if show option was given
|
||||
if clr.show:
|
||||
return
|
||||
|
||||
selected_style = StyleSheet()
|
||||
|
||||
for item in book.get_item_list():
|
||||
handler = item.option_class.handler
|
||||
|
||||
# Set up default style
|
||||
handler.set_default_stylesheet_name(item.get_style_name())
|
||||
default_style = StyleSheet()
|
||||
make_default_style = item.option_class.make_default_style
|
||||
make_default_style(default_style)
|
||||
|
||||
# Read all style sheets available for this item
|
||||
style_file = handler.get_stylesheet_savefile()
|
||||
style_list = StyleSheetList(style_file, default_style)
|
||||
|
||||
# Get the selected stylesheet
|
||||
style_name = handler.get_default_stylesheet_name()
|
||||
style_sheet = style_list.get_style_sheet(style_name)
|
||||
|
||||
for this_style_name in style_sheet.get_paragraph_style_names():
|
||||
selected_style.add_paragraph_style(
|
||||
this_style_name,
|
||||
style_sheet.get_paragraph_style(this_style_name))
|
||||
|
||||
for this_style_name in style_sheet.get_draw_style_names():
|
||||
selected_style.add_draw_style(
|
||||
this_style_name,
|
||||
style_sheet.get_draw_style(this_style_name))
|
||||
|
||||
for this_style_name in style_sheet.get_table_style_names():
|
||||
selected_style.add_table_style(
|
||||
this_style_name,
|
||||
style_sheet.get_table_style(this_style_name))
|
||||
|
||||
for this_style_name in style_sheet.get_cell_style_names():
|
||||
selected_style.add_cell_style(
|
||||
this_style_name,
|
||||
style_sheet.get_cell_style(this_style_name))
|
||||
|
||||
# The option values were loaded magically by the book parser.
|
||||
# But they still need to be applied to the menu options.
|
||||
opt_dict = item.option_class.options_dict
|
||||
menu = item.option_class.menu
|
||||
for optname in opt_dict:
|
||||
menu_option = menu.get_option_by_name(optname)
|
||||
if menu_option:
|
||||
menu_option.set_value(opt_dict[optname])
|
||||
|
||||
# write report
|
||||
doc = clr.format(selected_style,
|
||||
PaperStyle(clr.paper, clr.orien, clr.marginl,
|
||||
clr.marginr, clr.margint, clr.marginb))
|
||||
user = User()
|
||||
rptlist = []
|
||||
for item in book.get_item_list():
|
||||
item.option_class.set_document(doc)
|
||||
report_class = item.get_write_item()
|
||||
obj = write_book_item(database,
|
||||
report_class, item.option_class, user)
|
||||
rptlist.append(obj)
|
||||
|
||||
doc.open(clr.option_class.get_output())
|
||||
doc.init()
|
||||
newpage = 0
|
||||
for item in rptlist:
|
||||
if newpage:
|
||||
doc.page_break()
|
||||
newpage = 1
|
||||
item.begin_report()
|
||||
item.write_report()
|
||||
doc.close()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Generic task function for book
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def write_book_item(database, report_class, options, user):
|
||||
"""Write the report using options set.
|
||||
All user dialog has already been handled and the output file opened."""
|
||||
try:
|
||||
return report_class(database, options, user)
|
||||
except ReportError, msg:
|
||||
(m1, m2) = msg.messages()
|
||||
print "ReportError", m1, m2
|
||||
except FilterError, msg:
|
||||
(m1, m2) = msg.messages()
|
||||
print "FilterError", m1, m2
|
||||
except:
|
||||
log.error("Failed to write book item.", exc_info=True)
|
||||
return None
|
||||
|
@ -32,4 +32,6 @@ from _reportbase import Report
|
||||
|
||||
from _bibliography import Bibliography, Citation
|
||||
|
||||
from _options import MenuReportOptions
|
||||
from _options import MenuReportOptions, ReportOptions
|
||||
|
||||
from _book import BookList, Book, BookItem
|
||||
|
442
gramps/gen/plug/report/_book.py
Normal file
442
gramps/gen/plug/report/_book.py
Normal file
@ -0,0 +1,442 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2003-2007 Donald N. Allingham
|
||||
# Copyright (C) 2007-2008 Brian G. Matherly
|
||||
# Copyright (C) 2010 Jakim Friant
|
||||
# Copyright (C) 2011-2012 Paul Franklin
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
# Written by Alex Roitman,
|
||||
# largely based on the BaseDoc classes by Don Allingham
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Standard Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from ...ggettext import gettext as _
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Set up logging
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import logging
|
||||
log = logging.getLogger(".Book")
|
||||
import os
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# SAX interface
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
try:
|
||||
from xml.sax import make_parser, handler, SAXParseException
|
||||
from xml.sax.saxutils import escape
|
||||
except:
|
||||
from _xmlplus.sax import make_parser, handler, SAXParseException
|
||||
from _xmlplus.sax.saxutils import escape
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from ...const import HOME_DIR
|
||||
from ...utils.cast import get_type_converter_by_name, type_name
|
||||
from .. import BasePluginManager
|
||||
from . import book_categories
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Private Constants
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
_UNSUPPORTED = _("Unsupported")
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Book Item class
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class BookItem(object):
|
||||
"""
|
||||
Interface into the book item -- a smallest element of the book.
|
||||
"""
|
||||
|
||||
def __init__(self, dbase, name):
|
||||
"""
|
||||
Create a new empty BookItem.
|
||||
|
||||
name: the book item is retrieved
|
||||
from the book item registry using name for lookup
|
||||
"""
|
||||
self.dbase = dbase
|
||||
self.style_name = "default"
|
||||
pmgr = BasePluginManager.get_instance()
|
||||
|
||||
for pdata in pmgr.get_reg_bookitems():
|
||||
if pdata.id == name:
|
||||
self.translated_name = pdata.name
|
||||
if not pdata.supported:
|
||||
self.category = _UNSUPPORTED
|
||||
else:
|
||||
self.category = book_categories[pdata.category]
|
||||
mod = pmgr.load_plugin(pdata)
|
||||
self.write_item = eval('mod.' + pdata.reportclass)
|
||||
self.name = pdata.id
|
||||
oclass = eval('mod.' + pdata.optionclass)
|
||||
self.option_class = oclass(self.name, self.dbase)
|
||||
self.option_class.load_previous_values()
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Return the name of the item.
|
||||
"""
|
||||
return self.name
|
||||
|
||||
def get_translated_name(self):
|
||||
"""
|
||||
Return the translated name of the item.
|
||||
"""
|
||||
return self.translated_name
|
||||
|
||||
def get_category(self):
|
||||
"""
|
||||
Return the category of the item.
|
||||
"""
|
||||
return self.category
|
||||
|
||||
def get_write_item(self):
|
||||
"""
|
||||
Return the report-writing function of the item.
|
||||
"""
|
||||
return self.write_item
|
||||
|
||||
def set_style_name(self, style_name):
|
||||
"""
|
||||
Set the style name for the item.
|
||||
|
||||
style_name: name of the style to set.
|
||||
"""
|
||||
self.style_name = style_name
|
||||
|
||||
def get_style_name(self):
|
||||
"""
|
||||
Return the style name of the item.
|
||||
"""
|
||||
return self.style_name
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Book class
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class Book(object):
|
||||
"""
|
||||
Interface into the user-defined book -- a collection of book items.
|
||||
"""
|
||||
|
||||
def __init__(self, obj=None):
|
||||
"""
|
||||
Create a new empty Book.
|
||||
|
||||
obj: if not None, creates the Book from the values in
|
||||
obj, instead of creating an empty Book.
|
||||
"""
|
||||
|
||||
self.name = ""
|
||||
self.dbname = ""
|
||||
if obj:
|
||||
self.item_list = obj.item_list
|
||||
else:
|
||||
self.item_list = []
|
||||
|
||||
def set_name(self, name):
|
||||
"""
|
||||
Set the name of the book.
|
||||
|
||||
name: the name to set.
|
||||
"""
|
||||
self.name = name
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Return the name of the book.
|
||||
"""
|
||||
return self.name
|
||||
|
||||
def get_dbname(self):
|
||||
"""
|
||||
Return the name of the database file used for the book.
|
||||
"""
|
||||
return self.dbname
|
||||
|
||||
def set_dbname(self, name):
|
||||
"""
|
||||
Set the name of the database file used for the book.
|
||||
|
||||
name: a filename to set.
|
||||
"""
|
||||
self.dbname = name
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
Clears the contents of the book.
|
||||
"""
|
||||
self.item_list = []
|
||||
|
||||
def append_item(self, item):
|
||||
"""
|
||||
Add an item to the book.
|
||||
|
||||
item: an item to append.
|
||||
"""
|
||||
self.item_list.append(item)
|
||||
|
||||
def insert_item(self, index, item):
|
||||
"""
|
||||
Inserts an item into the given position in the book.
|
||||
|
||||
index: a position index.
|
||||
item: an item to append.
|
||||
"""
|
||||
self.item_list.insert(index, item)
|
||||
|
||||
def pop_item(self, index):
|
||||
"""
|
||||
Pop an item from given position in the book.
|
||||
|
||||
index: a position index.
|
||||
"""
|
||||
return self.item_list.pop(index)
|
||||
|
||||
def get_item(self, index):
|
||||
"""
|
||||
Return an item at a given position in the book.
|
||||
|
||||
index: a position index.
|
||||
"""
|
||||
return self.item_list[index]
|
||||
|
||||
def set_item(self, index, item):
|
||||
"""
|
||||
Set an item at a given position in the book.
|
||||
|
||||
index: a position index.
|
||||
item: an item to set.
|
||||
"""
|
||||
self.item_list[index] = item
|
||||
|
||||
def get_item_list(self):
|
||||
"""
|
||||
Return list of items in the current book.
|
||||
"""
|
||||
return self.item_list
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# BookList class
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class BookList(object):
|
||||
"""
|
||||
Interface into the user-defined list of books.
|
||||
|
||||
BookList is loaded from a specified XML file if it exists.
|
||||
"""
|
||||
|
||||
def __init__(self, filename, dbase):
|
||||
"""
|
||||
Create a new BookList from the books that may be defined in the
|
||||
specified file.
|
||||
|
||||
file: XML file that contains book items definitions
|
||||
"""
|
||||
self.dbase = dbase
|
||||
self.bookmap = {}
|
||||
self.file = os.path.join(HOME_DIR, filename)
|
||||
self.parse()
|
||||
|
||||
def delete_book(self, name):
|
||||
"""
|
||||
Remove a book from the list. Since each book must have a
|
||||
unique name, the name is used to delete the book.
|
||||
|
||||
name: name of the book to delete
|
||||
"""
|
||||
del self.bookmap[name]
|
||||
|
||||
def get_book_map(self):
|
||||
"""
|
||||
Return the map of names to books.
|
||||
"""
|
||||
return self.bookmap
|
||||
|
||||
def get_book(self, name):
|
||||
"""
|
||||
Return the Book associated with the name
|
||||
|
||||
name: name associated with the desired Book.
|
||||
"""
|
||||
return self.bookmap[name]
|
||||
|
||||
def get_book_names(self):
|
||||
"Return a list of all the book names in the BookList, sorted"
|
||||
return sorted(self.bookmap.keys())
|
||||
|
||||
def set_book(self, name, book):
|
||||
"""
|
||||
Add or replaces a Book in the BookList.
|
||||
|
||||
name: name associated with the Book to add or replace.
|
||||
book: definition of the Book
|
||||
"""
|
||||
self.bookmap[name] = book
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
Saves the current BookList to the associated file.
|
||||
"""
|
||||
f = open(self.file, "w")
|
||||
f.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
|
||||
f.write('<booklist>\n')
|
||||
for name in sorted(self.bookmap): # enable a diff of archived copies
|
||||
book = self.get_book(name)
|
||||
dbname = book.get_dbname()
|
||||
f.write('<book name="%s" database="%s">\n' % (name, dbname) )
|
||||
for item in book.get_item_list():
|
||||
f.write(' <item name="%s" trans_name="%s">\n' %
|
||||
(item.get_name(),item.get_translated_name() ) )
|
||||
options = item.option_class.handler.options_dict
|
||||
for option_name, option_value in options.iteritems():
|
||||
if isinstance(option_value, (list, tuple)):
|
||||
f.write(' <option name="%s" value="" '
|
||||
'length="%d">\n' % (
|
||||
escape(option_name),
|
||||
len(options[option_name]) ) )
|
||||
for list_index in range(len(option_value)):
|
||||
option_type = type_name(option_value[list_index])
|
||||
value = escape(unicode(option_value[list_index]))
|
||||
value = value.replace('"', '"')
|
||||
f.write(' <listitem number="%d" type="%s" '
|
||||
'value="%s"/>\n' % (
|
||||
list_index,
|
||||
option_type,
|
||||
value ) )
|
||||
f.write(' </option>\n')
|
||||
else:
|
||||
option_type = type_name(option_value)
|
||||
value = escape(unicode(option_value))
|
||||
value = value.replace('"', '"')
|
||||
f.write(' <option name="%s" type="%s" '
|
||||
'value="%s"/>\n' % (
|
||||
escape(option_name),
|
||||
option_type,
|
||||
value) )
|
||||
|
||||
f.write(' <style name="%s"/>\n' % item.get_style_name() )
|
||||
f.write(' </item>\n')
|
||||
f.write('</book>\n')
|
||||
|
||||
f.write('</booklist>\n')
|
||||
f.close()
|
||||
|
||||
def parse(self):
|
||||
"""
|
||||
Loads the BookList from the associated file, if it exists.
|
||||
"""
|
||||
try:
|
||||
p = make_parser()
|
||||
p.setContentHandler(BookParser(self, self.dbase))
|
||||
the_file = open(self.file)
|
||||
p.parse(the_file)
|
||||
the_file.close()
|
||||
except (IOError, OSError, ValueError, SAXParseException, KeyError,
|
||||
AttributeError):
|
||||
pass
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# BookParser
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class BookParser(handler.ContentHandler):
|
||||
"""
|
||||
SAX parsing class for the Books XML file.
|
||||
"""
|
||||
|
||||
def __init__(self, booklist, dbase):
|
||||
"""
|
||||
Create a BookParser class that populates the passed booklist.
|
||||
|
||||
booklist: BookList to be loaded from the file.
|
||||
"""
|
||||
handler.ContentHandler.__init__(self)
|
||||
self.dbase = dbase
|
||||
self.booklist = booklist
|
||||
self.b = None
|
||||
self.i = None
|
||||
self.o = None
|
||||
self.an_o_name = None
|
||||
self.an_o_value = None
|
||||
self.s = None
|
||||
self.bname = None
|
||||
self.iname = None
|
||||
|
||||
def startElement(self, tag, attrs):
|
||||
"""
|
||||
Overridden class that handles the start of a XML element
|
||||
"""
|
||||
if tag == "book":
|
||||
self.b = Book()
|
||||
self.bname = attrs['name']
|
||||
self.b.set_name(self.bname)
|
||||
self.dbname = attrs['database']
|
||||
self.b.set_dbname(self.dbname)
|
||||
elif tag == "item":
|
||||
self.i = BookItem(self.dbase, attrs['name'])
|
||||
self.o = {}
|
||||
elif tag == "option":
|
||||
self.an_o_name = attrs['name']
|
||||
if attrs.has_key('length'):
|
||||
self.an_o_value = []
|
||||
else:
|
||||
converter = get_type_converter_by_name(attrs['type'])
|
||||
self.an_o_value = converter(attrs['value'])
|
||||
elif tag == "listitem":
|
||||
converter = get_type_converter_by_name(attrs['type'])
|
||||
self.an_o_value.append(converter(attrs['value']))
|
||||
elif tag == "style":
|
||||
self.s = attrs['name']
|
||||
else:
|
||||
pass
|
||||
|
||||
def endElement(self, tag):
|
||||
"Overridden class that handles the end of a XML element"
|
||||
if tag == "option":
|
||||
self.o[self.an_o_name] = self.an_o_value
|
||||
elif tag == "item":
|
||||
self.i.option_class.handler.options_dict.update(self.o)
|
||||
self.i.set_style_name(self.s)
|
||||
self.b.append_item(self.i)
|
||||
elif tag == "book":
|
||||
self.booklist.set_book(self.bname, self.b)
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkDialog" id="bookreport">
|
||||
<object class="GtkDialog" id="book">
|
||||
<property name="height_request">300</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type_hint">normal</property>
|
||||
@ -17,12 +17,10 @@
|
||||
<child>
|
||||
<object class="GtkButton" id="delete_button">
|
||||
<property name="label">gtk-delete</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_booklist_delete_clicked" object="top" swapped="yes"/>
|
||||
</object>
|
||||
@ -35,12 +33,10 @@
|
||||
<child>
|
||||
<object class="GtkButton" id="close_button">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_booklist_cancel_clicked" object="top" swapped="yes"/>
|
||||
</object>
|
||||
@ -53,12 +49,10 @@
|
||||
<child>
|
||||
<object class="GtkButton" id="ok_button">
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_booklist_ok_clicked" object="top" swapped="yes"/>
|
||||
</object>
|
||||
@ -209,13 +203,11 @@
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button61">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Clear the book</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<signal name="clicked" handler="on_clear_clicked" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="image33">
|
||||
@ -233,13 +225,11 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button62">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Save current set of configured selections</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<accelerator key="r" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
<signal name="clicked" handler="on_save_clicked" swapped="no"/>
|
||||
<child>
|
||||
@ -258,13 +248,11 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button63">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Open previously created book</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<signal name="clicked" handler="on_open_clicked" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="image35">
|
||||
@ -282,13 +270,11 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button64">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Manage previously created books</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
<signal name="clicked" handler="on_edit_clicked" swapped="no"/>
|
||||
<child>
|
||||
@ -444,13 +430,11 @@
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button52">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Add an item to the book</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<accelerator key="a" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
<signal name="clicked" handler="on_add_clicked" swapped="no"/>
|
||||
<child>
|
||||
@ -469,13 +453,11 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button53">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Remove currently selected item from the book</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<signal name="clicked" handler="on_remove_clicked" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="image25">
|
||||
@ -493,13 +475,11 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button54">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Move current selection one step up in the book</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<signal name="clicked" handler="on_up_clicked" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="image26">
|
||||
@ -517,13 +497,11 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button55">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Move current selection one step down in the book</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<signal name="clicked" handler="on_down_clicked" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="image27">
|
||||
@ -541,13 +519,11 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button56">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Configure currently selected item</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<signal name="clicked" handler="on_setup_clicked" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="image28">
|
||||
@ -598,12 +574,10 @@
|
||||
<child>
|
||||
<object class="GtkButton" id="button12">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="destroy_passed_object" object="top" swapped="yes"/>
|
||||
</object>
|
||||
@ -616,12 +590,10 @@
|
||||
<child>
|
||||
<object class="GtkButton" id="button13">
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_book_ok_clicked" swapped="no"/>
|
||||
</object>
|
@ -30,3 +30,4 @@
|
||||
from _reportdialog import report
|
||||
from _drawreportdialog import DrawReportDialog
|
||||
from _textreportdialog import TextReportDialog
|
||||
from _bookdialog import BookSelector
|
||||
|
@ -39,20 +39,7 @@ from gramps.gen.ggettext import gettext as _
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import logging
|
||||
log = logging.getLogger(".BookReport")
|
||||
import os
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# SAX interface
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
try:
|
||||
from xml.sax import make_parser, handler, SAXParseException
|
||||
from xml.sax.saxutils import escape
|
||||
except:
|
||||
from _xmlplus.sax import make_parser, handler, SAXParseException
|
||||
from _xmlplus.sax.saxutils import escape
|
||||
log = logging.getLogger(".Book")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -68,28 +55,25 @@ from gi.repository import GObject
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gramps.gen.const import HOME_DIR
|
||||
from gramps.gen.utils.cast import get_type_converter_by_name, type_name
|
||||
from gramps.gui.listmodel import ListModel
|
||||
from ...listmodel import ListModel
|
||||
from gramps.gen.errors import FilterError, ReportError
|
||||
from gramps.gui.pluginmanager import GuiPluginManager
|
||||
from gramps.gen.plug.docgen import StyleSheet, StyleSheetList, PaperStyle
|
||||
from gramps.gui.dialog import WarningDialog, ErrorDialog
|
||||
from ...pluginmanager import GuiPluginManager
|
||||
from gramps.gen.plug.docgen import StyleSheet, StyleSheetList
|
||||
from ...dialog import WarningDialog, ErrorDialog
|
||||
from gramps.gen.plug.menu import PersonOption, FilterOption, FamilyOption
|
||||
from gramps.gui.managedwindow import ManagedWindow, set_titles
|
||||
from gramps.gui.glade import Glade
|
||||
from gramps.gui.utils import is_right_click, open_file_with_default_application
|
||||
from gramps.gui.user import User
|
||||
from gramps.gui.plug import make_gui_option
|
||||
from ...managedwindow import ManagedWindow, set_titles
|
||||
from ...glade import Glade
|
||||
from ...utils import is_right_click, open_file_with_default_application
|
||||
from ...user import User
|
||||
from .. import make_gui_option
|
||||
from types import ClassType
|
||||
|
||||
# Import from specific modules in ReportBase
|
||||
from gramps.gen.plug.report import BookList, Book, BookItem
|
||||
from gramps.gen.plug.report import CATEGORY_BOOK, book_categories
|
||||
from gramps.gui.plug.report._reportdialog import ReportDialog
|
||||
from gramps.gui.plug.report._docreportdialog import DocReportDialog
|
||||
from gramps.gen.plug.report._options import ReportOptions
|
||||
from gramps.cli.plug import CommandLineReport
|
||||
from gramps.cli.user import User
|
||||
from _reportdialog import ReportDialog
|
||||
from _docreportdialog import DocReportDialog
|
||||
|
||||
from gramps.gen.display.name import displayer as _nd
|
||||
|
||||
@ -202,376 +186,6 @@ def _get_subject(options, dbase):
|
||||
|
||||
return ""
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Book Item class
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class BookItem(object):
|
||||
"""
|
||||
Interface into the book item -- a smallest element of the book.
|
||||
"""
|
||||
|
||||
def __init__(self, dbase, name):
|
||||
"""
|
||||
Create a new empty BookItem.
|
||||
|
||||
name: the book item is retrieved
|
||||
from the book item registry using name for lookup
|
||||
"""
|
||||
self.dbase = dbase
|
||||
self.style_name = "default"
|
||||
pmgr = GuiPluginManager.get_instance()
|
||||
|
||||
for pdata in pmgr.get_reg_bookitems():
|
||||
if pdata.id == name:
|
||||
self.translated_name = pdata.name
|
||||
if not pdata.supported:
|
||||
self.category = _UNSUPPORTED
|
||||
else:
|
||||
self.category = book_categories[pdata.category]
|
||||
mod = pmgr.load_plugin(pdata)
|
||||
self.write_item = eval('mod.' + pdata.reportclass)
|
||||
self.name = pdata.id
|
||||
oclass = eval('mod.' + pdata.optionclass)
|
||||
self.option_class = oclass(self.name, self.dbase)
|
||||
self.option_class.load_previous_values()
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Return the name of the item.
|
||||
"""
|
||||
return self.name
|
||||
|
||||
def get_translated_name(self):
|
||||
"""
|
||||
Return the translated name of the item.
|
||||
"""
|
||||
return self.translated_name
|
||||
|
||||
def get_category(self):
|
||||
"""
|
||||
Return the category of the item.
|
||||
"""
|
||||
return self.category
|
||||
|
||||
def get_write_item(self):
|
||||
"""
|
||||
Return the report-writing function of the item.
|
||||
"""
|
||||
return self.write_item
|
||||
|
||||
def set_style_name(self, style_name):
|
||||
"""
|
||||
Set the style name for the item.
|
||||
|
||||
style_name: name of the style to set.
|
||||
"""
|
||||
self.style_name = style_name
|
||||
|
||||
def get_style_name(self):
|
||||
"""
|
||||
Return the style name of the item.
|
||||
"""
|
||||
return self.style_name
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Book class
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class Book(object):
|
||||
"""
|
||||
Interface into the user-defined book -- a collection of book items.
|
||||
"""
|
||||
|
||||
def __init__(self, obj=None):
|
||||
"""
|
||||
Create a new empty Book.
|
||||
|
||||
obj: if not None, creates the Book from the values in
|
||||
obj, instead of creating an empty Book.
|
||||
"""
|
||||
|
||||
self.name = ""
|
||||
self.dbname = ""
|
||||
if obj:
|
||||
self.item_list = obj.item_list
|
||||
else:
|
||||
self.item_list = []
|
||||
|
||||
def set_name(self, name):
|
||||
"""
|
||||
Set the name of the book.
|
||||
|
||||
name: the name to set.
|
||||
"""
|
||||
self.name = name
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
Return the name of the book.
|
||||
"""
|
||||
return self.name
|
||||
|
||||
def get_dbname(self):
|
||||
"""
|
||||
Return the name of the database file used for the book.
|
||||
"""
|
||||
return self.dbname
|
||||
|
||||
def set_dbname(self, name):
|
||||
"""
|
||||
Set the name of the database file used for the book.
|
||||
|
||||
name: a filename to set.
|
||||
"""
|
||||
self.dbname = name
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
Clears the contents of the book.
|
||||
"""
|
||||
self.item_list = []
|
||||
|
||||
def append_item(self, item):
|
||||
"""
|
||||
Add an item to the book.
|
||||
|
||||
item: an item to append.
|
||||
"""
|
||||
self.item_list.append(item)
|
||||
|
||||
def insert_item(self, index, item):
|
||||
"""
|
||||
Inserts an item into the given position in the book.
|
||||
|
||||
index: a position index.
|
||||
item: an item to append.
|
||||
"""
|
||||
self.item_list.insert(index, item)
|
||||
|
||||
def pop_item(self, index):
|
||||
"""
|
||||
Pop an item from given position in the book.
|
||||
|
||||
index: a position index.
|
||||
"""
|
||||
return self.item_list.pop(index)
|
||||
|
||||
def get_item(self, index):
|
||||
"""
|
||||
Return an item at a given position in the book.
|
||||
|
||||
index: a position index.
|
||||
"""
|
||||
return self.item_list[index]
|
||||
|
||||
def set_item(self, index, item):
|
||||
"""
|
||||
Set an item at a given position in the book.
|
||||
|
||||
index: a position index.
|
||||
item: an item to set.
|
||||
"""
|
||||
self.item_list[index] = item
|
||||
|
||||
def get_item_list(self):
|
||||
"""
|
||||
Return list of items in the current book.
|
||||
"""
|
||||
return self.item_list
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# BookList class
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class BookList(object):
|
||||
"""
|
||||
Interface into the user-defined list of books.
|
||||
|
||||
BookList is loaded from a specified XML file if it exists.
|
||||
"""
|
||||
|
||||
def __init__(self, filename, dbase):
|
||||
"""
|
||||
Create a new BookList from the books that may be defined in the
|
||||
specified file.
|
||||
|
||||
file: XML file that contains book items definitions
|
||||
"""
|
||||
self.dbase = dbase
|
||||
self.bookmap = {}
|
||||
self.file = os.path.join(HOME_DIR, filename)
|
||||
self.parse()
|
||||
|
||||
def delete_book(self, name):
|
||||
"""
|
||||
Remove a book from the list. Since each book must have a
|
||||
unique name, the name is used to delete the book.
|
||||
|
||||
name: name of the book to delete
|
||||
"""
|
||||
del self.bookmap[name]
|
||||
|
||||
def get_book_map(self):
|
||||
"""
|
||||
Return the map of names to books.
|
||||
"""
|
||||
return self.bookmap
|
||||
|
||||
def get_book(self, name):
|
||||
"""
|
||||
Return the Book associated with the name
|
||||
|
||||
name: name associated with the desired Book.
|
||||
"""
|
||||
return self.bookmap[name]
|
||||
|
||||
def get_book_names(self):
|
||||
"Return a list of all the book names in the BookList, sorted"
|
||||
return sorted(self.bookmap.keys())
|
||||
|
||||
def set_book(self, name, book):
|
||||
"""
|
||||
Add or replaces a Book in the BookList.
|
||||
|
||||
name: name associated with the Book to add or replace.
|
||||
book: definition of the Book
|
||||
"""
|
||||
self.bookmap[name] = book
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
Saves the current BookList to the associated file.
|
||||
"""
|
||||
f = open(self.file, "w")
|
||||
f.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
|
||||
f.write('<booklist>\n')
|
||||
for name in sorted(self.bookmap): # enable a diff of archived copies
|
||||
book = self.get_book(name)
|
||||
dbname = book.get_dbname()
|
||||
f.write('<book name="%s" database="%s">\n' % (name, dbname) )
|
||||
for item in book.get_item_list():
|
||||
f.write(' <item name="%s" trans_name="%s">\n' %
|
||||
(item.get_name(),item.get_translated_name() ) )
|
||||
options = item.option_class.handler.options_dict
|
||||
for option_name, option_value in options.iteritems():
|
||||
if isinstance(option_value, (list, tuple)):
|
||||
f.write(' <option name="%s" value="" '
|
||||
'length="%d">\n' % (
|
||||
escape(option_name),
|
||||
len(options[option_name]) ) )
|
||||
for list_index in range(len(option_value)):
|
||||
option_type = type_name(option_value[list_index])
|
||||
value = escape(unicode(option_value[list_index]))
|
||||
value = value.replace('"', '"')
|
||||
f.write(' <listitem number="%d" type="%s" '
|
||||
'value="%s"/>\n' % (
|
||||
list_index,
|
||||
option_type,
|
||||
value ) )
|
||||
f.write(' </option>\n')
|
||||
else:
|
||||
option_type = type_name(option_value)
|
||||
value = escape(unicode(option_value))
|
||||
value = value.replace('"', '"')
|
||||
f.write(' <option name="%s" type="%s" '
|
||||
'value="%s"/>\n' % (
|
||||
escape(option_name),
|
||||
option_type,
|
||||
value) )
|
||||
|
||||
f.write(' <style name="%s"/>\n' % item.get_style_name() )
|
||||
f.write(' </item>\n')
|
||||
f.write('</book>\n')
|
||||
|
||||
f.write('</booklist>\n')
|
||||
f.close()
|
||||
|
||||
def parse(self):
|
||||
"""
|
||||
Loads the BookList from the associated file, if it exists.
|
||||
"""
|
||||
try:
|
||||
p = make_parser()
|
||||
p.setContentHandler(BookParser(self, self.dbase))
|
||||
the_file = open(self.file)
|
||||
p.parse(the_file)
|
||||
the_file.close()
|
||||
except (IOError, OSError, ValueError, SAXParseException, KeyError,
|
||||
AttributeError):
|
||||
pass
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# BookParser
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class BookParser(handler.ContentHandler):
|
||||
"""
|
||||
SAX parsing class for the Books XML file.
|
||||
"""
|
||||
|
||||
def __init__(self, booklist, dbase):
|
||||
"""
|
||||
Create a BookParser class that populates the passed booklist.
|
||||
|
||||
booklist: BookList to be loaded from the file.
|
||||
"""
|
||||
handler.ContentHandler.__init__(self)
|
||||
self.dbase = dbase
|
||||
self.booklist = booklist
|
||||
self.b = None
|
||||
self.i = None
|
||||
self.o = None
|
||||
self.an_o_name = None
|
||||
self.an_o_value = None
|
||||
self.s = None
|
||||
self.bname = None
|
||||
self.iname = None
|
||||
|
||||
def startElement(self, tag, attrs):
|
||||
"""
|
||||
Overridden class that handles the start of a XML element
|
||||
"""
|
||||
if tag == "book":
|
||||
self.b = Book()
|
||||
self.bname = attrs['name']
|
||||
self.b.set_name(self.bname)
|
||||
self.dbname = attrs['database']
|
||||
self.b.set_dbname(self.dbname)
|
||||
elif tag == "item":
|
||||
self.i = BookItem(self.dbase, attrs['name'])
|
||||
self.o = {}
|
||||
elif tag == "option":
|
||||
self.an_o_name = attrs['name']
|
||||
if attrs.has_key('length'):
|
||||
self.an_o_value = []
|
||||
else:
|
||||
converter = get_type_converter_by_name(attrs['type'])
|
||||
self.an_o_value = converter(attrs['value'])
|
||||
elif tag == "listitem":
|
||||
converter = get_type_converter_by_name(attrs['type'])
|
||||
self.an_o_value.append(converter(attrs['value']))
|
||||
elif tag == "style":
|
||||
self.s = attrs['name']
|
||||
else:
|
||||
pass
|
||||
|
||||
def endElement(self, tag):
|
||||
"Overridden class that handles the end of a XML element"
|
||||
if tag == "option":
|
||||
self.o[self.an_o_name] = self.an_o_value
|
||||
elif tag == "item":
|
||||
self.i.option_class.handler.options_dict.update(self.o)
|
||||
self.i.set_style_name(self.s)
|
||||
self.b.append_item(self.i)
|
||||
elif tag == "book":
|
||||
self.booklist.set_book(self.bname, self.b)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# BookList Display class
|
||||
@ -595,7 +209,7 @@ class BookListDisplay(object):
|
||||
|
||||
self.booklist = booklist
|
||||
self.dosave = dosave
|
||||
self.xml = Glade()
|
||||
self.xml = Glade('book.glade')
|
||||
self.top = self.xml.toplevel
|
||||
self.unsaved_changes = False
|
||||
|
||||
@ -666,7 +280,7 @@ class BookListDisplay(object):
|
||||
|
||||
def on_booklist_cancel_clicked(self, obj):
|
||||
if self.unsaved_changes:
|
||||
from gramps.gui.dialog import QuestionDialog2
|
||||
from ...dialog import QuestionDialog2
|
||||
q = QuestionDialog2(
|
||||
_('Discard Unsaved Changes'),
|
||||
_('You have made changes which have not been saved.'),
|
||||
@ -682,7 +296,7 @@ class BookListDisplay(object):
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
# Book Options
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class BookOptions(ReportOptions):
|
||||
@ -709,7 +323,7 @@ class BookOptions(ReportOptions):
|
||||
# Book creation dialog
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class BookReportSelector(ManagedWindow):
|
||||
class BookSelector(ManagedWindow):
|
||||
"""
|
||||
Interface into a dialog setting up the book.
|
||||
|
||||
@ -721,12 +335,12 @@ class BookReportSelector(ManagedWindow):
|
||||
self.db = dbstate.db
|
||||
self.dbstate = dbstate
|
||||
self.uistate = uistate
|
||||
self.title = _('Book Report')
|
||||
self.title = _('Book')
|
||||
self.file = "books.xml"
|
||||
|
||||
ManagedWindow.__init__(self, uistate, [], self.__class__)
|
||||
|
||||
self.xml = Glade(toplevel="top")
|
||||
self.xml = Glade('book.glade', toplevel="top")
|
||||
window = self.xml.toplevel
|
||||
|
||||
title_label = self.xml.get_object('title')
|
||||
@ -1002,7 +616,7 @@ class BookReportSelector(ManagedWindow):
|
||||
(Gtk.STOCK_CLEAR, self.on_clear_clicked, 1),
|
||||
(Gtk.STOCK_SAVE, self.on_save_clicked, 1),
|
||||
(Gtk.STOCK_OPEN, self.on_open_clicked, 1),
|
||||
(_("Edit"), self.on_edit_clicked,1 ),
|
||||
(_("Edit"), self.on_edit_clicked, 1),
|
||||
]
|
||||
|
||||
menu = Gtk.Menu()
|
||||
@ -1041,10 +655,10 @@ class BookReportSelector(ManagedWindow):
|
||||
|
||||
def on_book_ok_clicked(self, obj):
|
||||
"""
|
||||
Run final BookReportDialog with the current book.
|
||||
Run final BookDialog with the current book.
|
||||
"""
|
||||
if self.book.item_list:
|
||||
BookReportDialog(self.dbstate, self.uistate,
|
||||
BookDialog(self.dbstate, self.uistate,
|
||||
self.book, BookOptions)
|
||||
else:
|
||||
WarningDialog(_('No items'), _('This book has no items.'))
|
||||
@ -1064,7 +678,7 @@ class BookReportSelector(ManagedWindow):
|
||||
)
|
||||
return
|
||||
if name in self.book_list.get_book_names():
|
||||
from gramps.gui.dialog import QuestionDialog2
|
||||
from ...dialog import QuestionDialog2
|
||||
q = QuestionDialog2(
|
||||
_('Book name already exists'),
|
||||
_('You are about to save away a '
|
||||
@ -1230,7 +844,7 @@ class _BookFormatComboBox(Gtk.ComboBox):
|
||||
# The final dialog - paper, format, target, etc.
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class BookReportDialog(DocReportDialog):
|
||||
class BookDialog(DocReportDialog):
|
||||
"""
|
||||
A usual Report.Dialog subclass.
|
||||
|
||||
@ -1244,7 +858,7 @@ class BookReportDialog(DocReportDialog):
|
||||
self.page_html_added = False
|
||||
self.book = book
|
||||
DocReportDialog.__init__(self, dbstate, uistate, options,
|
||||
'book', _("Book Report"))
|
||||
'book', _("Book"))
|
||||
self.options.options_dict['bookname'] = self.book.name
|
||||
self.database = dbstate.db
|
||||
self.selected_style = StyleSheet()
|
||||
@ -1285,8 +899,8 @@ class BookReportDialog(DocReportDialog):
|
||||
response = self.window.run()
|
||||
if response == Gtk.ResponseType.OK:
|
||||
try:
|
||||
self.make_report()
|
||||
except (IOError,OSError),msg:
|
||||
self.make_book()
|
||||
except (IOError, OSError),msg:
|
||||
ErrorDialog(str(msg))
|
||||
self.close()
|
||||
|
||||
@ -1295,7 +909,7 @@ class BookReportDialog(DocReportDialog):
|
||||
def parse_style_frame(self): pass
|
||||
|
||||
def get_title(self):
|
||||
return _("Book Report")
|
||||
return _("Book")
|
||||
|
||||
def get_header(self, name):
|
||||
return _("Gramps Book")
|
||||
@ -1320,8 +934,8 @@ class BookReportDialog(DocReportDialog):
|
||||
self.rptlist.append(obj)
|
||||
self.doc.open(self.target_path)
|
||||
|
||||
def make_report(self):
|
||||
"""The actual book report. Start it out, then go through the item list
|
||||
def make_book(self):
|
||||
"""The actual book. Start it out, then go through the item list
|
||||
and call each item's write_book_item method."""
|
||||
|
||||
self.doc.init()
|
||||
@ -1350,107 +964,7 @@ class BookReportDialog(DocReportDialog):
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Function to write books from command line
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def cl_report(database, name, category, options_str_dict):
|
||||
|
||||
clr = CommandLineReport(database, name, category,
|
||||
BookOptions, options_str_dict)
|
||||
|
||||
# Exit here if show option was given
|
||||
if clr.show:
|
||||
return
|
||||
|
||||
if 'bookname' not in clr.options_dict or not clr.options_dict['bookname']:
|
||||
print _("Please specify a book name")
|
||||
return
|
||||
|
||||
book_list = BookList('books.xml', database)
|
||||
book_name = clr.options_dict['bookname']
|
||||
if book_name:
|
||||
if book_name not in book_list.get_book_names():
|
||||
print _("No such book '%s'") % book_name
|
||||
return
|
||||
book = book_list.get_book(book_name)
|
||||
else:
|
||||
print _("Please specify a book name")
|
||||
return
|
||||
selected_style = StyleSheet()
|
||||
|
||||
for item in book.get_item_list():
|
||||
handler = item.option_class.handler
|
||||
|
||||
# Set up default style
|
||||
handler.set_default_stylesheet_name(item.get_style_name())
|
||||
default_style = StyleSheet()
|
||||
make_default_style = item.option_class.make_default_style
|
||||
make_default_style(default_style)
|
||||
|
||||
# Read all style sheets available for this item
|
||||
style_file = handler.get_stylesheet_savefile()
|
||||
style_list = StyleSheetList(style_file, default_style)
|
||||
|
||||
# Get the selected stylesheet
|
||||
style_name = handler.get_default_stylesheet_name()
|
||||
style_sheet = style_list.get_style_sheet(style_name)
|
||||
|
||||
for this_style_name in style_sheet.get_paragraph_style_names():
|
||||
selected_style.add_paragraph_style(
|
||||
this_style_name,
|
||||
style_sheet.get_paragraph_style(this_style_name))
|
||||
|
||||
for this_style_name in style_sheet.get_draw_style_names():
|
||||
selected_style.add_draw_style(
|
||||
this_style_name,
|
||||
style_sheet.get_draw_style(this_style_name))
|
||||
|
||||
for this_style_name in style_sheet.get_table_style_names():
|
||||
selected_style.add_table_style(
|
||||
this_style_name,
|
||||
style_sheet.get_table_style(this_style_name))
|
||||
|
||||
for this_style_name in style_sheet.get_cell_style_names():
|
||||
selected_style.add_cell_style(
|
||||
this_style_name,
|
||||
style_sheet.get_cell_style(this_style_name))
|
||||
|
||||
# The option values were loaded magically by the book parser.
|
||||
# But they still need to be applied to the menu options.
|
||||
opt_dict = item.option_class.options_dict
|
||||
menu = item.option_class.menu
|
||||
for optname in opt_dict:
|
||||
menu_option = menu.get_option_by_name(optname)
|
||||
if menu_option:
|
||||
menu_option.set_value(opt_dict[optname])
|
||||
|
||||
# write report
|
||||
doc = clr.format(selected_style,
|
||||
PaperStyle(clr.paper, clr.orien, clr.marginl,
|
||||
clr.marginr, clr.margint, clr.marginb))
|
||||
user = User()
|
||||
rptlist = []
|
||||
for item in book.get_item_list():
|
||||
item.option_class.set_document(doc)
|
||||
report_class = item.get_write_item()
|
||||
obj = write_book_item(database,
|
||||
report_class, item.option_class, user)
|
||||
rptlist.append(obj)
|
||||
|
||||
doc.open(clr.option_class.get_output())
|
||||
doc.init()
|
||||
newpage = 0
|
||||
for item in rptlist:
|
||||
if newpage:
|
||||
doc.page_break()
|
||||
newpage = 1
|
||||
item.begin_report()
|
||||
item.write_report()
|
||||
doc.close()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Generic task function for book report
|
||||
# Generic task function for book
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def write_book_item(database, report_class, options, user):
|
@ -72,7 +72,7 @@ from gramps.gen.plug import (START, END)
|
||||
from gramps.gen.plug import REPORT
|
||||
from gramps.gen.plug.report._constants import standalone_categories
|
||||
from .plug import (PluginWindows, ReportPluginDialog, ToolPluginDialog)
|
||||
from .plug.report import report
|
||||
from .plug.report import report, BookSelector
|
||||
from gramps.gen.plug.utils import version_str_to_tup, load_addon_file
|
||||
from .pluginmanager import GuiPluginManager
|
||||
from gramps.gen.relationship import get_relationship_calculator
|
||||
@ -165,8 +165,12 @@ UIDEFAULT = '''<ui>
|
||||
<placeholder name="GoToBook"/>
|
||||
</menu>
|
||||
<menu action="ReportsMenu">
|
||||
<menuitem action="Books"/>
|
||||
<separator/>
|
||||
<placeholder name="P_ReportsMenu"/>
|
||||
</menu>
|
||||
<menu action="ToolsMenu">
|
||||
<placeholder name="P_ToolsMenu"/>
|
||||
</menu>
|
||||
<menu action="WindowsMenu">
|
||||
<placeholder name="WinMenu"/>
|
||||
@ -781,6 +785,7 @@ class ViewManager(CLIManager):
|
||||
_("Open the reports dialog"), self.reports_clicked),
|
||||
('GoMenu', None, _('_Go')),
|
||||
('ReportsMenu', None, _('_Reports')),
|
||||
('Books', None, _('Books...'), None, None, self.run_book),
|
||||
('WindowsMenu', None, _('_Windows')),
|
||||
('F2', None, 'F2', "F2", None, self.__keypress),
|
||||
('F3', None, 'F3', "F3", None, self.__keypress),
|
||||
@ -855,6 +860,12 @@ class ViewManager(CLIManager):
|
||||
_('Undo History...'), "<PRIMARY>H", None, self.undo_history),
|
||||
]
|
||||
|
||||
def run_book(self, action):
|
||||
"""
|
||||
Run a book.
|
||||
"""
|
||||
BookSelector(self.dbstate, self.uistate)
|
||||
|
||||
def __keypress(self, action):
|
||||
"""
|
||||
Callback that is called on a keypress. It works by extracting the
|
||||
@ -1757,7 +1768,8 @@ class ViewManager(CLIManager):
|
||||
"""
|
||||
actions = []
|
||||
ofile = StringIO()
|
||||
ofile.write('<ui><menubar name="MenuBar"><menu action="%s">' % text)
|
||||
ofile.write('<ui><menubar name="MenuBar"><menu action="%s">'
|
||||
'<placeholder name="%s">' % (text, 'P_'+ text))
|
||||
|
||||
menu = Gtk.Menu()
|
||||
menu.show()
|
||||
@ -1804,7 +1816,7 @@ class ViewManager(CLIManager):
|
||||
func(pdata, self.dbstate, self.uistate)))
|
||||
ofile.write('</menu>')
|
||||
|
||||
ofile.write('</menu></menubar></ui>')
|
||||
ofile.write('</placeholder></menu></menubar></ui>')
|
||||
return (ofile.getvalue(), actions)
|
||||
|
||||
def display_about_box(self, obj):
|
||||
|
@ -1,43 +0,0 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2009 Benny Malengier
|
||||
#
|
||||
# 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$
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Book plugin
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
register(REPORT,
|
||||
id = 'book',
|
||||
name = _("Book Report"),
|
||||
description = _("Produces a book containing several reports."),
|
||||
version = '1.0',
|
||||
gramps_target_version = '4.0',
|
||||
status = STABLE,
|
||||
fname = 'bookreport.py',
|
||||
authors = ["Alex Roitman"],
|
||||
authors_email = ["shura@gramps-project.org"],
|
||||
category = CATEGORY_BOOK,
|
||||
reportclass = 'BookReportSelector',
|
||||
optionclass = 'cl_report',
|
||||
report_modes = [REPORT_MODE_GUI, REPORT_MODE_CLI]
|
||||
)
|
Loading…
Reference in New Issue
Block a user