[POS-commit] r3857 - stoqlib/trunk/stoqlib/reporting/base
Henrique Romano
henrique at async.com.br
Thu Jul 6 10:57:19 BRT 2006
Author: henrique
Date: Thu Jul 6 10:57:19 2006
New Revision: 3857
Modified:
stoqlib/trunk/stoqlib/reporting/base/flowables.py
Log:
Adding reportlab's Paragraph extension, which include ellipsis support.
This patch is part of the improvements being done on Stoqlib Reporting,
bug #2430.
Modified: stoqlib/trunk/stoqlib/reporting/base/flowables.py
==============================================================================
--- stoqlib/trunk/stoqlib/reporting/base/flowables.py (original)
+++ stoqlib/trunk/stoqlib/reporting/base/flowables.py Thu Jul 6 10:57:19 2006
@@ -28,8 +28,12 @@
from reportlab.lib.units import mm
from reportlab.platypus import Flowable, ActionFlowable
+from reportlab.platypus.paragraph import (Paragraph as RParagraph,
+ _getFragWords)
+from reportlab.pdfbase.pdfmetrics import stringWidth
-from stoqlib.reporting.base.default_style import SIGNATURE_FONT, SPACING
+from stoqlib.reporting.base.default_style import (SIGNATURE_FONT, SPACING,
+ STYLE_SHEET)
# We use enums here only to help to find typos. Reportlab uses strings for
# alignment settings. Reportlab also defines other numeric enums for text
@@ -38,6 +42,8 @@
CENTER = 'CENTER'
RIGHT = 'RIGHT'
+ELLIPSIS_STRING = "..."
+
#
# Flowables
#
@@ -232,3 +238,102 @@
% self.align)
self.build_signatures(canvas, x, x1, x2, y, default_x2)
canvas.restoreState()
+
+class Paragraph(RParagraph):
+ def __init__(self, text, style=None, ellipsize=True, bulletText=None,
+ frags=None, caseSensitive=1):
+ """
+ @param text: The paragraph text. You can use the same features
+ available on reportlab's Paragraph.
+ @type text: basestring
+
+ @param style: a string or ParagraphStyle instance representing
+ the paragraph style. If you do use a string, it'll
+ be searched in the styles provided by
+ default_style module.
+ @type style: object
+
+ @param ellipsis: Define if the paragraph must use ellipsis when
+ the text doesn't fits in the available width. If
+ not set, reportlab will try break the text into
+ multiple lines (which can be fail if the
+ text haven't the required amount of space chars)
+ @type ellipsis: bool
+ """
+ if not style:
+ style = STYLE_SHEET["Raw"]
+ if isinstance(style, basestring):
+ if not style in STYLE_SHEET:
+ raise ValueError("The style requested does not exists.")
+ style = STYLE_SHEET[style]
+ self._ellipsize = ellipsize
+ # [total_width, [frag0, frag1, ...fragN]]
+ self._first_line_frags = []
+ RParagraph.__init__(self, text, style, bulletText, frags,
+ caseSensitive)
+
+ #
+ # Reportlab's Paragraph overwrites
+ #
+
+ def breakLines(self, widths):
+ avail_width = widths[0]
+ if self._ellipsize and self._first_line_frags:
+ total_width, frags = self._first_line_frags
+ for frag in frags[::-1]:
+ ellipsis_width = stringWidth(ELLIPSIS_STRING, frag.fontName,
+ frag.fontSize)
+ frag_width = stringWidth(frag.text, frag.fontName,
+ frag.fontSize)
+ if total_width + ellipsis_width >= avail_width:
+ if (frag_width - (total_width - avail_width)
+ > ellipsis_width):
+ for letter in frag.text[::-1]:
+ frag.text = frag.text[:-1]
+ total_width -= stringWidth(letter, frag.fontName,
+ frag.fontSize)
+ if total_width + ellipsis_width < avail_width:
+ break
+ else:
+ total_width -= frag_width
+ frags.pop()
+ continue
+ else:
+ total_width -= frag_width
+ frags.pop()
+ continue
+ frag.text += ELLIPSIS_STRING
+ self.frags = frags
+ break
+ return RParagraph.breakLines(self, widths)
+
+ # XXX: We need to overwrite RParagraph's wrap since there the requested
+ # width is the maximum possible (that is the "avail_width" parameter).
+ # Here we need request just what we need, so it can be properly aligned
+ # when needed (in a table, for instance).
+ def wrap(self, width, height):
+ if not self._ellipsize:
+ return RParagraph.wrap(self, self.minWidth(), height)
+ if self.frags:
+ total_width = 0.0
+ first_line_frags = []
+ for entry in _getFragWords(self.frags):
+ frag_words = entry[1:]
+ for frag, word in frag_words:
+ total_width += stringWidth(word, frag.fontName,
+ frag.fontSize)
+ first_line_frags.append(frag.clone(text=word))
+ if total_width > width:
+ self._first_line_frags = [total_width, first_line_frags]
+ width = min(total_width, width)
+ break
+ else:
+ total_width += stringWidth(" ", frag.fontName,
+ frag.fontSize)
+ continue
+ break
+ else:
+ # No need to ellipsize if the frags width is lesser than
+ # the available width
+ self._ellipsize = False
+ return RParagraph.wrap(self, width, height)
More information about the POS-commit
mailing list