commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnue] r9033 - trunk/gnue-common/src/printing/pdftable


From: jcater
Subject: [gnue] r9033 - trunk/gnue-common/src/printing/pdftable
Date: Mon, 13 Nov 2006 12:05:01 -0600 (CST)

Author: jcater
Date: 2006-11-13 12:04:59 -0600 (Mon, 13 Nov 2006)
New Revision: 9033

Modified:
   trunk/gnue-common/src/printing/pdftable/pdftable.py
Log:
added optional 'actual-size' calculations so there's no need to guess at the 
column sizes; misc reformatting

Modified: trunk/gnue-common/src/printing/pdftable/pdftable.py
===================================================================
--- trunk/gnue-common/src/printing/pdftable/pdftable.py 2006-11-13 14:47:25 UTC 
(rev 9032)
+++ trunk/gnue-common/src/printing/pdftable/pdftable.py 2006-11-13 18:04:59 UTC 
(rev 9033)
@@ -56,13 +56,13 @@
 CENTER=2
 
 # ----------------------------------------------------------------------------
-# Some sample font definitions 
+# Some sample font definitions
 # ----------------------------------------------------------------------------
 fontDefs = {               # Font name       Pt Size  Vert Spacing
   'dataFont' :             ('Times-Roman',      10,        11),
   'subtotalFont' :         ('Times-Bold',       10,        12),
   'tableHeaderFont' :      ('Times-Bold',       10,        12),
-  
+
   'titleFont' :            ('Helvetica-Bold',   14,        14),
   'title2Font' :           ('Helvetica',        12,        14),
   'title3Font' :           ('Helvetica-Oblique',12,        14),
@@ -72,6 +72,9 @@
   'subtitleFont' :         ('Times-Bold',       12,        13),
   'subtitleLabelFont' :    ('Times-Roman',      12,        13),
   'subtitleContinueFont' : ('Times-Italic',     10,        13),
+
+  'parameterNameFont' :    ('Helvetica',         8,        9),
+  'parameterValueFont' :   ('Helvetica-Bold',    8,        9),
 }
 
 # ----------------------------------------------------------------------------
@@ -95,10 +98,13 @@
 leftmargin = .75*inch
 topmargin = .75*inch
 
+# Maximum scale % before we rotate to landscape
+# (only useful if using precalcRowSizes)
+max_scale_before_rotate = 0.90
+
 # This is nothing but voodoo guesses...
 # Greatly depends on pointsize of self.fontDefs['dataFont']
-# TODO: This should probably be computed based on width of a "0"
-# TODO: and the width of the report.  But, eh, this works for now...
+# (only useful is not using precalcRowSizes)
 maxColsForPortraitNonscaled = 100   # Number of columns before we start 
scaling down
 maxColsForPortraitScaled = 120      # Number of columns before we switch to 
landscape
 maxColsForLandscapeNonscaled = 140  # Number of columns before landscape + 
scaling
@@ -111,26 +117,25 @@
   # ==========================================================================
   # Creation/closure functions
   # ==========================================================================
-  
+
   # --------------------------------------------------------------------------
   # Initialize
   # --------------------------------------------------------------------------
-  def __init__(self, destination, parameterBox = ()):    
+  def __init__(self, destination):
     """
     A simple table based report generator.
-    
+
     The class provides the following features:
       - Border support for columns, rows.
       - Automatic adjustments of the data when it is unable to fit on one page.
       - Multiple sections of a report handled automatically.
-    
+
     @param destination: A python file handle used for output
-    @param parameterBox: Unused?
     """
     self._titleList = ['Your Report','Your Report']
-    
+
     self.destination = destination
-#     self.parameterBox = parameterBox
+    self.parameters = ()
 
     self.highlightColor = colors.HexColor("0xffffcc")
     self.headingColor = self.subtotalColor = colors.HexColor("0xe6e6ff")
@@ -152,33 +157,33 @@
     self._currentSectionType = "default"
     self._currentSection = {}
     self.definedSectionTypes = {}
-    
-    self.columnGap = 6 # in pts, Amount of gap to leave between columns... 
doesn't need to be too much
 
+    self.columnGap = 72 * .125 # in pts, Amount of gap to leave between 
columns... (1/8")
+
   # --------------------------------------------------------------------------
   # Finish up the output
   # --------------------------------------------------------------------------
   def close(self):
     """
     Finalize the report.
-    
+
     Should be called after all data was sent to the report.
     """
     self.canvas.showPage()
     self.canvas.save()
 
-    
+
   # ==========================================================================
   # Functions that effect report wide settings
   # ==========================================================================
-  
+
   # --------------------------------------------------------------------------
   # Sets the title of the report
-  # -------------------------------------------------------------------------- 
   
+  # --------------------------------------------------------------------------
   def setFullTitle(self,titleList):
     """
     Sets the title of the report
-    
+
     @param titleList: A list containing tuples of the following format
                       (text, font defintion)
                       Font defintions are also tuples in the format
@@ -186,30 +191,40 @@
                       ('Times-Roman',      10,    11)
     """
     self._titleList = titleList
-  
+
   # --------------------------------------------------------------------------
   # Define a column on the report
   # --------------------------------------------------------------------------
-  def addColumn(self, align, minSize, overflow="", highlight=None, 
+  def addColumn(self, align, minSize, overflow="", highlight=None,
                 leftBorder=0, rightBorder=0, topBorder=0, bottomBorder=0,
-                sectionType="default"):    
+                sectionType="default", 
+                borderTopStyle="single", 
+                borderBottomStyle="single", 
+                borderWidth="full"):
     """
     Defines a column on the record for the specified section
-    
+
     @param minSize: The minimum size in points of the column.
-    @param overflow: The text that should be printed if the contents of a 
column are too 
+    @param overflow: The text that should be printed if the contents of a 
column are too
                      large for the column width.
     @param highlight: The color of background to use in this column.
     @param leftBorder: The width of the left side border in points.
     @param rightBorder: The width of the right side border in points.
     @param topBorder: The width of the top side border in points.
-    @param bottomBorder: The width of the bottom side border in points.        
   
+    @param bottomBorder: The width of the bottom side border in points.
     @param sectionType: The name of the section to which this column should be 
added.
+    @param borderTopStyle: "single" or "double" (single or double lines)
+    @param borderBottomStyle: "single" or "double" (single or double lines)
+    @param borderWidth: "full" (horiz line for this column will touch next 
column)
+                        "text" (horiz line for this column will not touch next 
column)
     """
     try:
       secType = self.definedSectionTypes[sectionType]
     except KeyError:
-      self.definedSectionTypes[sectionType] = {'columnSizes'      :[],
+      secType = self.definedSectionTypes[sectionType] = {
+                                       'hasActualSizes'   :False,
+                                       'columnActualSizes':[],
+                                       'columnSizes'      :[],
                                        'columnAligns'     :[],
                                        'columnOverflow'   :[],
                                        'columnHighlight'  :[],
@@ -218,11 +233,14 @@
                                        'columnRightBorder':[],
                                        'columnTopBorder'  :[],
                                        'columnBottomBorder':[],
-                                       'headerList':    [[]],                  
                  
+                                       'columnBorderTopStyle': [], 
+                                       'columnBorderBottomStyle': [], 
+                                       'columnBorderWidth': [], 
+                                       'headerList':    [[]],
                                     }
-      secType = self.definedSectionTypes[sectionType]
-      
+
     secType['columnSizes'].append(minSize)
+    secType['columnActualSizes'].append(0)
     secType['columnAligns'].append(align)
     secType['columnOverflow'].append(overflow)
     secType['columnHighlight'].append(highlight)
@@ -230,33 +248,39 @@
     secType['columnRightBorder'].append(rightBorder)
     secType['columnTopBorder'].append(topBorder)
     secType['columnBottomBorder'].append(bottomBorder)
+    secType['columnBorderTopStyle'].append(borderTopStyle)
+    secType['columnBorderBottomStyle'].append(borderBottomStyle)
+    secType['columnBorderWidth'].append(borderWidth)
 
+    if not self._currentSection:
+        self._currentSection = secType
+
   # ==========================================================================
   # Section level functions
   # ==========================================================================
-  
+
   # --------------------------------------------------------------------------
   # Define a section header
   # --------------------------------------------------------------------------
-  def addHeader(self, heading, align, startColumn, endColumn, 
+  def addHeader(self, heading, align, startColumn, endColumn,
                 leftBorder=0, rightBorder=0, sectionType="default"):
     """
     Adds a column header to one or more columns
-    
+
     @param heading: The text to display
-    @param align:   The alignment to apply to the header text 
+    @param align:   The alignment to apply to the header text
                     LEFT, RIGHT, CENTER are defined in this module
     @param startColumn: The starting column number (starts at 0) for the header
     @param endColumn: The ending column number for the header
     @param leftBorder: The width of the left side border in points.
-    @param rightBorder: The width of the right side border in points.   
-    @param sectionType: The name of the section to which this header should be 
added.    
+    @param rightBorder: The width of the right side border in points.
+    @param sectionType: The name of the section to which this header should be 
added.
     """
     secType = self.definedSectionTypes[sectionType]
     if endColumn > len(secType['columnSizes'])-1:
       print "endColumn longer than defined columns"
       sys.exit()
-          
+
     heading = {'text':heading,
                'align':align,
                'start':startColumn,
@@ -265,27 +289,27 @@
                'rightBorder':rightBorder,
                }
     secType['headerList'][-1].append(heading)
-  
+
   # --------------------------------------------------------------------------
   # Add a row to a header
-  # -------------------------------------------------------------------------- 
 
+  # --------------------------------------------------------------------------
   def addHeaderRow(self, sectionType="default"):
     """
     Adds a new row to the header.  Subsequent calls to addHeader will now
     apply to this new row.
-    
-    @param sectionType: The name of the section to which this header row will 
be added.    
+
+    @param sectionType: The name of the section to which this header row will 
be added.
     """
     secType = self.definedSectionTypes[sectionType]
     secType['headerList'].append([])
-    
+
   # --------------------------------------------------------------------------
   # Inform the writer to switch to a new section
   # --------------------------------------------------------------------------
   def startNewSection(self, subtitle, sectionType="default", newPage=1):
     """
     Begins a new report section.
-  
+
     @param subtitle: The subtitle to display above the section
     @param sectionType: The name of the previous defined section to use.
     @param newPage: If 0 then the new page will be supressed.
@@ -293,40 +317,56 @@
                     to starting the section.
     """
     if sectionType != self._currentSectionType:
-      self.init = 1
-    self._currentSection = self.definedSectionTypes[sectionType]   
-    self._currentSectionType = sectionType    
+        self.init = True
+    self._currentSection = self.definedSectionTypes[sectionType]
+    self._currentSectionType = sectionType
     self.subtitle = subtitle
     if newPage:
-      self.highlightIndex = 0 
+        self.highlightIndex = 0
     if self.init:
-      self.init = 0
-      self.beginData()
-    self.continued = 0
+        self.init = False
+        self.beginData()
+    self.continued = False
     if newPage:
-      self.newPage()
+        self.newPage()
     else:
-      self.drawSectionHeading()
-      self.drawTableHeader()
+        self.drawSectionHeading()
+        self.drawTableHeader()
 
+
   # ==========================================================================
-  # Data functions 
+  # Data functions
   # ==========================================================================
-  
+
+  def precalcRowSize(self, data, style="Data"):
+      if style in ("Subtotal","Total"):
+          font, size, tracking = self.fontDefs['subtotalFont']
+      else:
+          font, size, tracking = self.fontDefs['dataFont']
+      stringWidth = getFont(font).stringWidth
+
+      for index, text in enumerate(data):
+        #print text, len(text), stringWidth(text, size), stringWidth(text, 
size)/ float(stringWidth('O', size))
+        current_max_size = self._currentSection['columnActualSizes'][index]
+        self._currentSection['columnActualSizes'][index] = max(
+                            current_max_size,
+                            stringWidth(text, size))
+        self._currentSection['hasActualSizes'] = True
+
   # --------------------------------------------------------------------------
   # Add data row
   # --------------------------------------------------------------------------
   def addRow(self, data, style="Data", displayBorders=True):
     """
     Adds a row of data to the current section
-    
+
     @param data: A list of strings containing the data to add to the current 
section
     @param style: The format style to use to render the row.
                   These are currently hardcoded into this class and include
                   Data (default), Subtotal, Total
-    @param displayBorders: Boolean that controls if a borders will be drawn 
for this
-                           row.  Makes it easy to produce a "blank" row for 
spacing
-                           output
+    @param displayBorders: Boolean that controls if a borders will be
+                           drawn for this row.  Makes it easy to produce
+                           a "blank" row for spacing output.
     """
     canvas = self.canvas
 
@@ -353,15 +393,16 @@
     else:
       self.highlightIndex = 0  # Reset highlighting after subtotals
 
-    boxy = self.y - (tracking-size)*1.5
+    boxy = self.y - (tracking - size) * 1.5
     boxh = tracking
 
     if style in ("Subtotal","Total"):
       self.drawHorizBorderedBox(leftmargin, boxy, self.width-leftmargin*2,
-                                boxh, self.subtotalColor, lines=lineWidth * 
self.scale)
+                                boxh, self.subtotalColor,
+                                lines=lineWidth * self.scale)
     elif highlighted:
       # If there is a bottom border we need to not draw over the top
-      # of the previous rows border.  Currently minimum must be 1 point      
+      # of the previous rows border.  Currently minimum must be 1 point
       adjustment = max([self._currentSection['columnBottomBorder'][0],1])
       self.drawHorizBorderedBox(leftmargin, boxy, self.width-leftmargin*2,
                                 boxh-adjustment, self.highlightColor, lines=0)
@@ -371,56 +412,56 @@
     i = 0
     while i < len(data):
       col = str(data[i])
-      # Find the hlx values (used for column highlight and borders)   
+      # Find the hlx values (used for column highlight and borders)
       if i > 0:
         hlx1 = self._currentSection['columnCoords'][i-1][1]+self.columnGap/2.0
       else:
         hlx1 = leftmargin
-      
+
       if i < len(self._currentSection['columnCoords'])-1:
         hlx2 = self._currentSection['columnCoords'][i+1][0]-self.columnGap/2.0
       else:
         hlx2 = self.width-leftmargin
-      
-      # Column highlight support          
+
+      # Column highlight support
       highlightColumn = self._currentSection['columnHighlight'][i]
       if highlightColumn and not style in ("Subtotal","Total"):
-        if self.highlightIndex==1: # We're on the first column (not 0 due to 
+= above)
-          adjust = lineWidth#*self.scale
+        if self.highlightIndex == 1: # We're on the first column (not 0 due to 
+= above)
+          adjust = lineWidth #*self.scale
         else:
           adjust = 0
         if highlighted:
           color = colors.Blacker(self.highlightColor,.98)
         else:
           color = highlightColumn
-        
-        self.drawHorizBorderedBox(hlx1, boxy - adjust, 
-                                  hlx2-hlx1, boxh, 
+
+        self.drawHorizBorderedBox(hlx1, boxy - adjust,
+                                  hlx2-hlx1, boxh,
                                   color, lines=0)
-      
+
       # Column border support
       if displayBorders:
-        leftBorder = self._currentSection['columnLeftBorder'][i]      
+        leftBorder = self._currentSection['columnLeftBorder'][i]
         if leftBorder:
           canvas.setLineWidth(leftBorder*self.scale)
           canvas.line(hlx1, boxy, hlx1, boxy + boxh)
-          
+
         rightBorder =self._currentSection['columnRightBorder'][i]
         if rightBorder:
           canvas.setLineWidth(rightBorder*self.scale)
           canvas.line(hlx2, boxy, hlx2, boxy + boxh)
-  
+
         topBorder =self._currentSection['columnTopBorder'][i]
         if topBorder:
           canvas.setLineWidth(topBorder*self.scale)
           canvas.line(hlx1, boxy + boxh, hlx2, boxy + boxh)
-  
+
         bottomBorder = self._currentSection['columnBottomBorder'][i]
         if bottomBorder:
           canvas.setLineWidth(bottomBorder*self.scale)
           canvas.line(hlx1, boxy, hlx2, boxy)
-                      
-      if col:      
+
+      if col:
         align= self._currentSection['columnAligns'][i]
         x1, x2 = self._currentSection['columnCoords'][i]
 
@@ -454,9 +495,9 @@
   def addLine(self, string, borders=None):
     """
     Adds a single line of text instead of a row to a table.
-    
-    Usefull in reproducing a check register style printout.
-    
+
+    Useful in reproducing a check register style printout.
+
     @param string: The string to print
     @param borders: A list containing the border widths to use on the line.
                     Sequence is in the order Top, Right, Bottom, Left (TRBL)
@@ -475,12 +516,12 @@
 
     boxy = self.y - (tracking-size)*1.5
     boxh = tracking
-    
+
     # Use the same highlighting as the pervious row printed
-    highlighted = divmod((self.highlightIndex-1),4)[1]>1 # Use the same 
highlighting 
+    highlighted = divmod((self.highlightIndex-1),4)[1]>1 # Use the same 
highlighting
     if highlighted:
       # If there is a bottom border we need to not draw over the top
-      # of the previous rows border.  Currently minimum must be 1 point      
+      # of the previous rows border.  Currently minimum must be 1 point
       adjustment = max([self._currentSection['columnBottomBorder'][0],1])
       self.drawHorizBorderedBox(leftmargin, boxy, self.width-leftmargin*2,
                                 boxh-adjustment, self.highlightColor, lines=0)
@@ -493,12 +534,12 @@
       if topBorder:
         canvas.setLineWidth(topBorder*self.scale)
         canvas.line(leftmargin, boxy + boxh, self.width-leftmargin, boxy + 
boxh)
-        
+
       #Right
       if rightBorder:
         canvas.setLineWidth(rightBorder*self.scale)
         canvas.line(self.width-leftmargin, boxy, self.width-leftmargin, boxy + 
boxh)
-        
+
       # Bottom
       if bottomBorder:
         canvas.setLineWidth(bottomBorder*self.scale)
@@ -570,8 +611,10 @@
     font, size, tracking = self.fontDefs['footerFont']
     canvas.setFont(font, size)
     canvas.drawString(leftmargin, topmargin, self.timestamp)
-    canvas.drawRightString(self.width - leftmargin, topmargin, "Page %s" % 
self.page)
-    self.miny = topmargin + tracking*2
+    canvas.drawRightString(self.width - leftmargin,
+                           topmargin,
+                           "Page %s" % self.page)
+    self.miny = topmargin + tracking * 2
 
   # --------------------------------------------------------------------------
   # Draw full (first-page) header (Title)
@@ -595,7 +638,8 @@
   # --------------------------------------------------------------------------
   def drawSmallTitle(self):
     """
-    Private function that creates a short ( non first page) header on a new 
page.
+    Private function that creates a short (non-first page)
+    header on a new page.
     """
     canvas = self.canvas
     font, size, tracking = self.fontDefs['repeatTitleFont']
@@ -605,7 +649,7 @@
     canvas.drawRightString(self.width - leftmargin, self.y, 
self._titleList[1][0])
     self.y -= tracking
     self.drawSectionHeading()
-    
+
   # --------------------------------------------------------------------------
   # Draw the section header
   # --------------------------------------------------------------------------
@@ -615,7 +659,7 @@
     """
     canvas = self.canvas
 
-    if not self.subtitle:
+    if not self.subtitle or self.subtitle == self._titleList[0][0]:
       return
 
     self.y -= self.fontDefs['subtitleFont'][2]
@@ -666,18 +710,19 @@
 
     boxy = self.y + tracking - (tracking-size)/2.0
     boxh = -tracking*numRows - (tracking-size)/2.0 - lineWidth*self.scale
-    self.drawHorizBorderedBox(leftmargin, boxy, self.width-leftmargin*2,
+    self.drawHorizBorderedBox(leftmargin, boxy,
+                              self.width-leftmargin*2,
                               boxh, self.headingColor)
 
-    for list in self._currentSection['headerList']:
-      for header in list:
+    for hlist in self._currentSection['headerList']:
+      for header in hlist:
         c1 = header['start']
         c2 = header['end']
         x1 = self._currentSection['columnCoords'][c1][0]
         x2 = self._currentSection['columnCoords'][c2][1]
-        align = header['align']        
+        align = header['align']
         text = header['text']
-        
+
         canvas.saveState()
         path = canvas.beginPath()
         # Vertical is overkill, but only interested in horizontal
@@ -692,19 +737,38 @@
           canvas.drawCentredString(x1+(x2-x1)/2.0,self.y,text)
         canvas.restoreState()
         
+        if c1 != c2 and align == CENTER: 
+            width = canvas.stringWidth(text, font, size)
+            yoff = size*.75
+            gutter = 3.0
+            print text, width, x2, x1, x2 - x1, x2 - x1 - gutter * 2.0
+            if x2 - x1 - gutter * 2.0 > width: 
+                linesize = .5*self.scale
+                canvas.setLineWidth(linesize)
+                canvas.line(x1, boxy - yoff,
+                            x1+(x2-x1)/2.0-width/2.0-gutter, 
+                            boxy - yoff)
+                canvas.line(x1+(x2-x1)/2.0+width/2.0+gutter, 
+                            boxy - yoff,
+                            x2, 
+                            boxy - yoff)
+
         leftBorder = header['leftBorder']
         if leftBorder:
-          canvas.setLineWidth(leftBorder*self.scale)
-          canvas.line(x1-self.columnGap/2.0, boxy, x1-self.columnGap/2.0, boxy 
+ boxh)
-          
+            canvas.setLineWidth(leftBorder*self.scale)
+            canvas.line(x1-self.columnGap/2.0, boxy,
+                        x1-self.columnGap/2.0, boxy + boxh)
+
         rightBorder = header['rightBorder']
         if rightBorder:
-          canvas.setLineWidth(rightBorder*self.scale)
-          canvas.line(x2+self.columnGap/2.0, boxy, x2+self.columnGap/2.0, boxy 
+ boxh)
+            canvas.setLineWidth(rightBorder*self.scale)
+            canvas.line(x2+self.columnGap/2.0, boxy,
+                        x2+self.columnGap/2.0, boxy + boxh)
+
       self.y -= tracking
-      
 
 
+
   # --------------------------------------------------------------------------
   # Draws a box w/shading and a top/bottom border
   # --------------------------------------------------------------------------
@@ -724,66 +788,133 @@
   # --------------------------------------------------------------------------
   def beginData(self):
     """
-    Prepares the class to begin drawing a section on the report.  Figures out 
+    Prepares the class to begin drawing a section on the report.  Figures out
     the required orientation of the report as well as any scaling that is 
required
     """
-    # Calculate column sizes
-    totalCols = 0
-    for cs in self._currentSection['columnSizes']:
-      totalCols += cs
 
-    # Figure out the page orientation/scaling
+    section = self._currentSection
+    columnSizes = section['columnSizes']
+
+    has_actual_sizes = section['hasActualSizes']
+    column_count = len(columnSizes)
+
+    # Add in the sizes of the headings
+    if has_actual_sizes:
+        font, size, tracking = self.fontDefs['tableHeaderFont']
+        string_width = getFont(font).stringWidth
+        actual_sizes = section['columnActualSizes']
+
+        for hlist in self._currentSection['headerList'][::-1]:
+            for header in hlist:
+                text_size = string_width(header['text'], size)
+                current_size = 0.0
+                c1 = header['start']
+                c2 = header['end']
+
+                for w in actual_sizes[c1:c2+1]:
+                    current_size += w
+
+                if text_size + 6 > current_size:
+                    additional_padding = (text_size - current_size) / float(c2 
- c1 + 1)
+                    if additional_padding < 6: 
+                        additional_padding = 6
+                    for i in xrange(c1,c2+1):
+                        actual_sizes[i] += additional_padding
+
+
+
+    font, size, leading = self.fontDefs['dataFont']
+    self.dataFontWidth = getFont(font).stringWidth
+
+    font, size, leading = self.fontDefs['subtotalFont']
+    self.subtotalFontWidth = getFont(font).stringWidth
+
+
     if not self._scalingComplete:
-      self._scalingComplete = 1
-      self.pageSize = letter
-      self.scale = 1.0
-      if totalCols < maxColsForPortraitNonscaled:    # Guestimate of max # 
cols we can get on portrait
-        self.pageOrient = portrait
-        self.width, self.height = letter
-      elif totalCols < maxColsForPortraitScaled:
-        self.pageOrient = portrait
-        self.width, self.height = letter
-        self.scale = maxColsForPortraitNonscaled / float(totalCols)
-      elif totalCols < maxColsForLandscapeNonscaled:
-        self.pageOrient = landscape
-        self.height, self.width = letter
-      else:
-        self.pageOrient = landscape
-        self.height, self.width = letter
-        self.scale = maxColsForLandscapeNonscaled / float(totalCols)
-  
-      if self.scale < 1:
-        print "Scaling to %.2f%%" % (self.scale*100)
-  
-      # in pts, Amount of gap to leave between columns... 
-      # doesn't need to be too much
-      self.columnGap = self.columnGap * self.scale
 
-      if isinstance(self.destination, canvas.Canvas): 
-          self.canvas = self.destination
-      else: 
-          self.canvas = canvas.Canvas(self.destination, 
-              pagesize=self.pageOrient(self.pageSize))
-  
-      font, size, leading = self.fontDefs['dataFont']
-      self.dataFontWidth = getFont(font).stringWidth
-  
-      font, size, leading = self.fontDefs['subtotalFont']
-      self.subtotalFontWidth = getFont(font).stringWidth
-      
-    # This is not scaled down according to self.scale...
-    # we'll instead scale the point sizes down when we do setFont
-    usableHorizSpace = (self.width - 2*leftmargin - 
self.columnGap*(len(self._currentSection['columnSizes'])))
-    x = leftmargin + self.columnGap/2.0
-    for i in range(len(self._currentSection['columnSizes'])):
-      colSize = (self._currentSection['columnSizes'][i] / float(totalCols) * 
usableHorizSpace)
-      self._currentSection['columnCoords'].append ( ( x, x+colSize ) )
+        # Calculate column sizes
+        if has_actual_sizes:
+            totalCols = 0.0
+
+            for index, size in enumerate(section['columnActualSizes']):
+                columnSizes[index] = size
+                totalCols += size
+
+            for width, height in letter, landscape(letter):
+                usable_width = width - 2*leftmargin - self.columnGap * 
column_count
+                if totalCols <= usable_width:
+                    scale = 1.0
+                else:
+                    scale = usable_width / float(totalCols)
+
+                if scale >= max_scale_before_rotate:
+                    break
+
+            self.width = width
+            self.height = height
+            self.scale = scale
+            self.pageSize = (width, height)
+
+        else:
+
+            # This is the old mess, mostly untouched for backwards 
compatability
+
+            totalCols = 0
+            for cs in columnSizes:
+                totalCols += cs
+
+            # Figure out the page orientation/scaling
+            self.pageSize = letter
+            self.scale = 1.0
+            if totalCols < maxColsForPortraitNonscaled:    # Guestimate of max 
# cols we can get on portrait
+              self.pageOrient = portrait
+              self.width, self.height = letter
+            elif totalCols < maxColsForPortraitScaled:
+              self.pageOrient = portrait
+              self.width, self.height = letter
+              self.scale = maxColsForPortraitNonscaled / float(totalCols)
+            elif totalCols < maxColsForLandscapeNonscaled:
+              self.pageOrient = landscape
+              self.height, self.width = letter
+            else:
+              self.pageOrient = landscape
+              self.height, self.width = letter
+              self.scale = maxColsForLandscapeNonscaled / float(totalCols)
+
+            # This is not scaled down according to self.scale...
+            # we'll instead scale the point sizes down when we do setFont
+            usable_width = (self.width - 2*leftmargin - 
self.columnGap*(len(section['columnSizes'])))
+
+
+    self.columnGap = self.columnGap * self.scale
+
+    if isinstance(self.destination, canvas.Canvas):
+        self.canvas = self.destination
+    else:
+        self.canvas = canvas.Canvas(self.destination,
+            pagesize=(self.width, self.height))
+
+
+    x = leftmargin + self.columnGap / 2.0
+    for i, size in enumerate(section['columnSizes']):
+      colSize = (size / float(totalCols) * usable_width)
+      section['columnCoords'].append ( ( x, x + colSize ) )
       x += colSize + self.columnGap
 
+    self._scalingComplete = True
+
+
   def setHighlightColorHex(self, hexColor):
     self.highlightColor = colors.HexColor(hexColor)
-    
+
   def setFont(self, fontStyle, settings):
     assert fontStyle in self.fontDefs.keys(), 'Invalid font style: %s'
-    
+
     self.fontDefs[fontStyle] = settings
+
+  # --------------------------------------------------------------------------
+  # Set up the parameter list
+  # --------------------------------------------------------------------------
+  def setParameterList(self, parameters):
+      self.parameters = parameters
+





reply via email to

[Prev in Thread] Current Thread [Next in Thread]