enhance Book class (to allow non-identical Book copies to be made)

Historically, a new Book made from an old Book argument would
contain the exact same BookItem objects as the original Book.
That behavior is retained (even though I can't see that it is
ever used), but now copies are possible where the BookItems
are of the same number and type as the original, but not the
exact same BookItem objects.  (No "paper" options are copied.)

In the process of doing that, the "save" method was slightly
tweaked, so its recently-changed (for pylint reasons) strings
have their XML terminator on the same (Python) line as the
XML-start of the keyword, for more clarity.  In the process of
checking that a pathological case was noticed where the metric
paper option could be Boolean in some cases (instead of the
expected zero/one), so that was coped with also.
This commit is contained in:
Paul Franklin 2016-07-08 09:21:39 -07:00
parent ed1fa65569
commit 4e3706072e

View File

@ -52,7 +52,7 @@ from xml.sax.saxutils import escape
#-------------------------------------------------------------------------
#
# gramps modules
# Gramps modules
#
#-------------------------------------------------------------------------
from ...const import GRAMPS_LOCALE as glocale
@ -83,6 +83,7 @@ class BookItem:
def __init__(self, dbase, name):
"""
Create a new empty BookItem.
TODO: it should be possible to make a non-empty BookItem, a copy
name: the book item is retrieved
from the book item registry using name for lookup
@ -153,15 +154,21 @@ class Book:
Interface into the user-defined Book -- a collection of book items.
"""
def __init__(self, obj=None):
def __init__(self, obj=None, exact_copy=True):
"""
Create a new empty Book.
obj: if not None, creates the Book from the values in
obj, instead of creating an empty Book.
@param obj: if not None, creates the Book from obj, from the
items in obj, instead of creating an empty Book.
@type obj: a :class:`.Book` instance
@param exact_copy: if True (and obj is not None) the exact same
BookItem objects will be in the new Book;
if False (and obj is not None) the same number
and same type of BookItem objects will be created
@type exact_copy: boolean
"""
self.name = ""
self.name = "" # this is tested for, in several places
self.dbname = ""
self.paper_name = None
self.paper_orientation = None
@ -170,10 +177,14 @@ class Book:
self.paper_margins = None
self.paper_format = None
self.paper_output = None
self.item_list = []
if obj:
self.item_list = obj.item_list
else:
self.item_list = []
if exact_copy:
self.item_list = obj.item_list
else:
for item in obj.get_item_list():
self.item_list.append(BookItem(item.dbase,
item.get_name()))
def set_name(self, name):
"""
@ -481,8 +492,8 @@ class BookList:
for name in sorted(self.bookmap): # enable a diff of archived copies
book = self.get_book(name)
dbname = book.get_dbname()
b_f.write(' <book name="%s" database="%s"'
'>\n' % (name, dbname))
b_f.write(' <book name="%s" database="%s">'
'\n' % (name, dbname))
for item in book.get_item_list():
b_f.write(' <item name="%s" '
'trans_name="%s">\n' % (
@ -517,33 +528,36 @@ class BookList:
option_type,
value))
b_f.write(' <style name="%s"'
'/>\n' % item.get_style_name())
b_f.write(' <style name="%s"/>'
'\n' % item.get_style_name())
b_f.write(' </item>\n')
if book.get_paper_name():
b_f.write(' <paper name="%s"'
'/>\n' % book.get_paper_name())
b_f.write(' <paper name="%s"/>'
'\n' % book.get_paper_name())
if book.get_orientation() is not None: # 0 is legal
b_f.write(' <orientation value="%s"'
'/>\n' % book.get_orientation())
b_f.write(' <orientation value="%s"/>'
'\n' % book.get_orientation())
if book.get_paper_metric() is not None: # 0 is legal
b_f.write(' <metric value="%s"'
'/>\n' % book.get_paper_metric())
b_p_metric = book.get_paper_metric()
if isinstance(b_p_metric, bool):
b_p_metric = int(b_p_metric)
b_f.write(' <metric value="%s"/>'
'\n' % b_p_metric)
if book.get_custom_paper_size():
size = book.get_custom_paper_size()
b_f.write(' <size value="%f %f"'
'/>\n' % (size[0], size[1]))
b_f.write(' <size value="%f %f"/>'
'\n' % (size[0], size[1]))
if book.get_margins():
for pos in range(len(book.get_margins())):
b_f.write(' <margin number="%s" '
'value="%f"/>\n' % (
pos, book.get_margin(pos)))
if book.get_format_name():
b_f.write(' <format name="%s"'
'/>\n' % book.get_format_name())
b_f.write(' <format name="%s"/>'
'\n' % book.get_format_name())
if book.get_output():
b_f.write(' <output name="%s"'
'/>\n' % book.get_output())
b_f.write(' <output name="%s"/>'
'\n' % book.get_output())
b_f.write(' </book>\n')
b_f.write('</booklist>\n')
@ -559,7 +573,7 @@ class BookList:
parser.parse(the_file)
except (IOError, OSError, ValueError, SAXParseException, KeyError,
AttributeError):
pass
LOG.debug("Failed to parse book list", exc_info=True)
#-------------------------------------------------------------------------