5326: Add Alphabetical Index and Table of Contents generation for pdf reports
svn: r18870
This commit is contained in:
@@ -38,6 +38,8 @@ import sys
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import libcairodoc
|
||||
from gen.plug.docgen import INDEX_TYPE_ALP, INDEX_TYPE_TOC
|
||||
from gen.plug.report.toc_index import write_toc, write_index
|
||||
import Errors
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
@@ -109,11 +111,69 @@ class PdfDoc(libcairodoc.CairoDoc):
|
||||
cr.update_context(pango_context)
|
||||
|
||||
# paginate the document
|
||||
finished = self.paginate(layout, page_width, page_height, DPI, DPI)
|
||||
while not finished:
|
||||
finished = self.paginate(layout, page_width, page_height, DPI, DPI)
|
||||
self.paginate_document(layout, page_width, page_height, DPI, DPI)
|
||||
body_pages = self._pages
|
||||
|
||||
# build the table of contents and alphabetical index
|
||||
toc_page = None
|
||||
index_page = None
|
||||
toc = []
|
||||
index = {}
|
||||
for page_nr, page in enumerate(body_pages):
|
||||
if page.has_toc():
|
||||
toc_page = page_nr
|
||||
if page.has_index():
|
||||
index_page = page_nr
|
||||
for mark in page.get_marks():
|
||||
if mark.type == INDEX_TYPE_ALP:
|
||||
if mark.key in index:
|
||||
if page_nr + 1 not in index[mark.key]:
|
||||
index[mark.key].append(page_nr + 1)
|
||||
else:
|
||||
index[mark.key] = [page_nr + 1]
|
||||
elif mark.type == INDEX_TYPE_TOC:
|
||||
toc.append([mark, page_nr + 1])
|
||||
|
||||
# paginate the table of contents
|
||||
rebuild_required = False
|
||||
if toc_page is not None:
|
||||
toc_pages = self.__generate_toc(layout, page_width, page_height,
|
||||
toc)
|
||||
offset = len(toc_pages) - 1
|
||||
if offset > 0:
|
||||
self.__increment_pages(toc, index, toc_page, offset)
|
||||
rebuild_required = True
|
||||
else:
|
||||
toc_pages = []
|
||||
|
||||
# paginate the index
|
||||
if index_page is not None:
|
||||
index_pages = self.__generate_index(layout, page_width, page_height,
|
||||
index)
|
||||
offset = len(index_pages) - 1
|
||||
if offset > 0:
|
||||
self.__increment_pages(toc, index, index_page, offset)
|
||||
rebuild_required = True
|
||||
else:
|
||||
index_pages = []
|
||||
|
||||
# rebuild the table of contents and index if required
|
||||
if rebuild_required:
|
||||
if toc_page is not None:
|
||||
toc_pages = self.__generate_toc(layout, page_width, page_height,
|
||||
toc)
|
||||
if index_page is not None:
|
||||
index_pages = self.__generate_index(layout, page_width,
|
||||
page_height, index)
|
||||
|
||||
# render the pages
|
||||
if toc_page is not None:
|
||||
body_pages = body_pages[:toc_page] + toc_pages + \
|
||||
body_pages[toc_page+1:]
|
||||
if index_page is not None:
|
||||
body_pages = body_pages[:index_page] + index_pages + \
|
||||
body_pages[index_page+1:]
|
||||
self._pages = body_pages
|
||||
for page_nr in range(len(self._pages)):
|
||||
cr.save()
|
||||
cr.translate(left_margin, top_margin)
|
||||
@@ -130,3 +190,96 @@ class PdfDoc(libcairodoc.CairoDoc):
|
||||
# if we don't restore the resolution.
|
||||
fontmap.set_resolution(saved_resolution)
|
||||
|
||||
def __increment_pages(self, toc, index, start_page, offset):
|
||||
"""
|
||||
Increment the page numbers in the table of contents and index.
|
||||
"""
|
||||
for n, value in enumerate(toc):
|
||||
page_nr = toc[n][1]
|
||||
toc[n][1] = page_nr + (offset if page_nr > start_page else 0)
|
||||
for key, value in index.iteritems():
|
||||
index[key] = [page_nr + (offset if page_nr > start_page else 0)
|
||||
for page_nr in value]
|
||||
|
||||
def __generate_toc(self, layout, page_width, page_height, toc):
|
||||
"""
|
||||
Generate the table of contents.
|
||||
"""
|
||||
self._doc = libcairodoc.GtkDocDocument()
|
||||
self._active_element = self._doc
|
||||
self._pages = []
|
||||
write_toc(toc, self)
|
||||
self.paginate_document(layout, page_width, page_height, DPI, DPI)
|
||||
return self._pages
|
||||
|
||||
def __generate_index(self, layout, page_width, page_height, index):
|
||||
"""
|
||||
Generate the index.
|
||||
"""
|
||||
self._doc = libcairodoc.GtkDocDocument()
|
||||
self._active_element = self._doc
|
||||
self._pages = []
|
||||
write_index(index, self)
|
||||
self.paginate_document(layout, page_width, page_height, DPI, DPI)
|
||||
return self._pages
|
||||
|
||||
def write_toc(toc, doc):
|
||||
"""
|
||||
Write the table of contents.
|
||||
"""
|
||||
if not toc:
|
||||
return
|
||||
|
||||
doc.start_paragraph('TOC-Title')
|
||||
doc.write_text(_('Contents'))
|
||||
doc.end_paragraph()
|
||||
|
||||
doc.start_table('toc', 'TOC-Table')
|
||||
for mark, page_nr in toc:
|
||||
doc.start_row()
|
||||
doc.start_cell('TOC-Cell')
|
||||
if mark.level == 1:
|
||||
style_name = "TOC-Heading1"
|
||||
elif mark.level == 2:
|
||||
style_name = "TOC-Heading2"
|
||||
else:
|
||||
style_name = "TOC-Heading3"
|
||||
doc.start_paragraph(style_name)
|
||||
doc.write_text(mark.key)
|
||||
doc.end_paragraph()
|
||||
doc.end_cell()
|
||||
doc.start_cell('TOC-Cell')
|
||||
doc.start_paragraph('TOC-Number')
|
||||
doc.write_text(str(page_nr))
|
||||
doc.end_paragraph()
|
||||
doc.end_cell()
|
||||
doc.end_row()
|
||||
doc.end_table()
|
||||
|
||||
def write_index(index, doc):
|
||||
"""
|
||||
Write the alphabetical index.
|
||||
"""
|
||||
if not index:
|
||||
return
|
||||
|
||||
doc.start_paragraph('Index-Title')
|
||||
doc.write_text(_('Index'))
|
||||
doc.end_paragraph()
|
||||
|
||||
doc.start_table('index', 'Index-Table')
|
||||
for key in sorted(index.iterkeys()):
|
||||
doc.start_row()
|
||||
doc.start_cell('Index-Cell')
|
||||
doc.start_paragraph('Index-Number')
|
||||
doc.write_text(key)
|
||||
doc.end_paragraph()
|
||||
doc.end_cell()
|
||||
doc.start_cell('Index-Cell')
|
||||
doc.start_paragraph('Index-Number')
|
||||
pages = [str(page_nr) for page_nr in index[key]]
|
||||
doc.write_text(', '.join(pages))
|
||||
doc.end_paragraph()
|
||||
doc.end_cell()
|
||||
doc.end_row()
|
||||
doc.end_table()
|
||||
|
||||
Reference in New Issue
Block a user