gramps/src/docgen/TextBufDoc.py
Gerald Britton 1f2469b09f Simplify with built-in functions where possible. e.g.
change [x for x in y if x] to filter(None, y)
change [f(x) for x in y] to map(f, x)
change [x for x in y] to list(y)

These changes reduce source code size and complexity and produce some minor performance gains

svn: r14104
2010-01-21 18:42:53 +00:00

350 lines
12 KiB
Python

#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
# Copyright (C) 2007-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
# 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 gen.ggettext import gettext as _
import gtk
import pango
#------------------------------------------------------------------------
#
# Gramps modules
#
#------------------------------------------------------------------------
from gen.plug.docgen import (BaseDoc, TextDoc, FONT_SERIF, PARA_ALIGN_RIGHT,
FONT_SANS_SERIF, FONT_MONOSPACE, PARA_ALIGN_CENTER,
PARA_ALIGN_LEFT)
import ManagedWindow
try:
import pangocairo
RESOLUTION = pangocairo.cairo_font_map_get_default().get_resolution()
except:
RESOLUTION = 96
def pixels(cm):
return int (RESOLUTION/2.54 * cm)
#------------------------------------------------------------------------
#
# Constants
#
#------------------------------------------------------------------------
LEFT,RIGHT,CENTER = 'LEFT','RIGHT','CENTER'
_WIDTH_IN_CHARS = 72
class DisplayBuf(ManagedWindow.ManagedWindow):
def __init__(self, title, document):
self.title = title
ManagedWindow.ManagedWindow.__init__(self, document.uistate, [],
document)
self.set_window(gtk.Dialog("",document.uistate.window,
gtk.DIALOG_DESTROY_WITH_PARENT,
(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)),
None, title)
self.window.set_size_request(600,400)
scrolled_window = gtk.ScrolledWindow()
scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
document.text_view = gtk.TextView()
document.text_view.set_buffer(document.buffer)
self.window.connect('response', self.close)
scrolled_window.add(document.text_view)
self.window.vbox.add(scrolled_window)
self.window.show_all()
def build_menu_names(self, obj):
return ('View', _('Quick View'))
def get_title(self):
return self.title
class DocumentManager(object):
def __init__(self, title, document, text_view):
self.title = title
self.document = document
document.text_view = text_view
text_view.set_buffer(document.buffer)
#------------------------------------------------------------------------
#
# TextBuf
#
#------------------------------------------------------------------------
class TextBufDoc(BaseDoc, TextDoc):
#--------------------------------------------------------------------
#
# Opens the file, resets the text buffer.
#
#--------------------------------------------------------------------
def open(self, filename, container=None):
self.type = "gtk"
self.tag_table = gtk.TextTagTable()
sheet = self.get_style_sheet()
for name in sheet.get_paragraph_style_names():
tag = gtk.TextTag(name)
style = sheet.get_paragraph_style(name)
font = style.get_font()
if font.get_type_face() == FONT_SERIF:
tag.set_property("family", "Serif")
elif font.get_type_face() == FONT_SANS_SERIF:
tag.set_property("family", "Sans")
elif font.get_type_face() == FONT_MONOSPACE:
tag.set_property("family", "MonoSpace")
tag.set_property("size-points", float(font.get_size()))
if font.get_bold():
tag.set_property("weight", pango.WEIGHT_BOLD)
if style.get_alignment() == PARA_ALIGN_RIGHT:
tag.set_property("justification", gtk.JUSTIFY_RIGHT)
elif style.get_alignment() == PARA_ALIGN_LEFT:
tag.set_property("justification", gtk.JUSTIFY_LEFT)
elif style.get_alignment() == PARA_ALIGN_CENTER:
tag.set_property("justification", gtk.JUSTIFY_CENTER)
else:
tag.set_property("justification", gtk.JUSTIFY_FILL)
if font.get_italic():
tag.set_property("style", pango.STYLE_ITALIC)
if style.get_first_indent():
tag.set_property("indent", pixels(style.get_first_indent()))
#tag.set_property("tabs", [pixels(abs(style.get_first_indent()))])
tag.set_property("left-margin", pixels(style.get_left_margin()))
tag.set_property("right-margin", pixels(style.get_right_margin()))
tag.set_property("pixels-above-lines", pixels(style.get_top_margin()))
tag.set_property("pixels-below-lines", pixels(style.get_bottom_margin()))
tag.set_property("wrap-mode", gtk.WRAP_WORD)
new_tabs = style.get_tabs()
tab_array = pango.TabArray(len(new_tabs)+1,True)
index = 0
for tab in map(pixels, new_tabs):
tab_array.set_tab(index, pango.TAB_LEFT, tab)
index += 1
tag.set_property("tabs", tab_array)
self.tag_table.add(tag)
self.buffer = gtk.TextBuffer(self.tag_table)
if container:
return DocumentManager(_('Quick View'), self, container)
else:
DisplayBuf(_('Quick View'), self)
return
#--------------------------------------------------------------------
#
# Close the file. Call the app if required.
#
#--------------------------------------------------------------------
def close(self):
pass
def get_usable_width(self):
return _WIDTH_IN_CHARS
#--------------------------------------------------------------------
#
# Force a section page break
#
#--------------------------------------------------------------------
def end_page(self):
return
self.f.write('\012')
def start_bold(self):
pass
def end_bold(self):
pass
def page_break(self):
pass
def start_superscript(self):
return
def end_superscript(self):
return
#--------------------------------------------------------------------
#
# Starts a paragraph.
#
#--------------------------------------------------------------------
def start_paragraph(self, style_name, leader=None):
self.style_name = style_name
if leader:
self.text = leader + "\t"
else:
self.text = ""
#--------------------------------------------------------------------
#
# End a paragraph. First format it to the desired widths.
# If not in table cell, write it immediately. If in the cell,
# add it to the list for this cell after formatting.
#
#--------------------------------------------------------------------
def end_paragraph(self):
self.buffer.insert_with_tags_by_name(
self.buffer.get_end_iter(),
self.text + "\n",
self.style_name)
#--------------------------------------------------------------------
#
# Start a table. Grab the table style, and store it.
#
#--------------------------------------------------------------------
def start_table(self, name,style_name):
return
styles = self.get_style_sheet()
self.tbl_style = styles.get_table_style(style_name)
self.ncols = self.tbl_style.get_columns()
#--------------------------------------------------------------------
#
# End a table. Turn off the self.in_cell flag
#
#--------------------------------------------------------------------
def end_table(self):
return
self.in_cell = 0
#--------------------------------------------------------------------
#
# Start a row. Initialize lists for cell contents, number of lines,
# and the widths. It is necessary to keep a list of cell contents
# that is to be written after all the cells are defined.
#
#--------------------------------------------------------------------
def start_row(self):
return
self.cellpars = [''] * self.ncols
self.cell_lines = [0] * self.ncols
self.cell_widths = [0] * self.ncols
self.cellnum = -1
self.maxlines = 0
table_width = self.get_usable_width() * self.tbl_style.get_width() / 100.0
for cell in range(self.ncols):
self.cell_widths[cell] = int( table_width * \
self.tbl_style.get_column_width(cell) / 100.0 )
#--------------------------------------------------------------------
#
# End a row. Write the cell contents. Write the line of spaces
# if the cell has fewer lines than the maximum number.
#
#--------------------------------------------------------------------
def end_row(self):
return
self.in_cell = 0
cell_text = [None]*self.ncols
for cell in range(self.ncols):
if self.cell_widths[cell]:
blanks = ' '*self.cell_widths[cell] + '\n'
if self.cell_lines[cell] < self.maxlines:
self.cellpars[cell] = self.cellpars[cell] \
+ blanks * (self.maxlines-self.cell_lines[cell])
cell_text[cell] = self.cellpars[cell].split('\n')
for line in range(self.maxlines):
for cell in range(self.ncols):
if self.cell_widths[cell]:
self.f.write(cell_text[cell][line])
self.f.write('\n')
#--------------------------------------------------------------------
#
# Start a cell. Set the self.in_cell flag, increment the curren cell number.
#
#--------------------------------------------------------------------
def start_cell(self,style_name,span=1):
return
self.in_cell = 1
self.cellnum = self.cellnum + span
span -= 1
while span:
self.cell_widths[self.cellnum-span] = 0
span -= 1
#--------------------------------------------------------------------
#
# End a cell. Find out the number of lines in this cell, correct
# the maximum number of lines if necessary.
#
#--------------------------------------------------------------------
def end_cell(self):
return
self.in_cell = 0
self.cell_lines[self.cellnum] = self.cellpars[self.cellnum].count('\n')
if self.cell_lines[self.cellnum] > self.maxlines:
self.maxlines = self.cell_lines[self.cellnum]
def add_media_object(self, name, align, w_cm, h_cm, alt=''):
return
this_text = '(photo)'
if self.in_cell:
self.cellpars[self.cellnum] = self.cellpars[self.cellnum] + this_text
else:
self.f.write(this_text)
def write_note(self,text,format,style_name):
return
if format == 1:
for line in text.split('\n'):
self.start_paragraph(style_name)
self.write_text(line)
self.end_paragraph()
elif format == 0:
for line in text.split('\n\n'):
self.start_paragraph(style_name)
line = line.replace('\n',' ')
line = ' '.join(line.split())
self.write_text(line)
self.end_paragraph()
#--------------------------------------------------------------------
#
# Writes text.
#--------------------------------------------------------------------
def write_text(self,text,mark=None):
self.text = self.text + text