Index: templates/report.cs
===================================================================
--- templates/report.cs	(revision 533)
+++ templates/report.cs	(working copy)
@@ -216,8 +216,9 @@
  ?>xml.png" alt="RSS Feed" style="vertical-align: bottom"/></a>&nbsp;
    <a href="?format=rss<?cs var $vars ?><?cs var $sortInfo ?>">(RSS 2.0)</a>&nbsp;|
    <a href="?format=csv<?cs var $vars ?><?cs var $sortInfo ?>">Comma-delimited</a>&nbsp;|
-   <a href="?format=tab<?cs var $vars ?><?cs var $sortInfo
-   ?>">Tab-delimited</a><?cs if $trac.acl.REPORT_SQL_VIEW ?>&nbsp;|
+   <a href="?format=tab<?cs var $vars ?><?cs var $sortInfo ?>">Tab-delimited</a>&nbsp;|
+   <a href="?format=print<?cs var $vars ?><?cs var $sortInfo ?>">Print</a>
+   <?cs if $trac.acl.REPORT_SQL_VIEW ?>&nbsp;|
    <a href="?format=sql">SQL Query</a><?cs /if ?>
    <br />
   </div>
Index: templates/report_print.cs
===================================================================
--- templates/report_print.cs	(revision 0)
+++ templates/report_print.cs	(revision 0)
@@ -0,0 +1,180 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+        "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html>
+ <head>
+  <?cs if:project.name ?>
+   <title><?cs var:project.name?><?cs if:title ?>: <?cs var:title ?><?cs
+   /if ?> - Trac</title>
+  <?cs else ?>
+   <title>Trac: <?cs var:title ?></title>
+  <?cs /if ?>
+  <style type="text/css">
+   @import url("<?cs var:htdocs_location ?>css/trac.css");
+   @import url("<?cs var:htdocs_location ?>css/report.css");
+   <?cs include "site_css.cs" ?>
+  </style>
+ </head>
+<body>
+<div id="page-content">
+<hr class="hide"/>
+<div id="main">
+    <div id="main-content">
+<?cs if report.message ?>
+ <div class="error"><?cs var report.message ?></div>
+<?cs else ?>
+ <?cs def:report_hdr(header) ?>
+   <?cs if $header ?>
+     <?cs if idx > 0 ?>
+       </table>
+     <?cs /if ?>
+     <hr class="hide"/>
+     <h2 class="report-hdr"><?cs var:header ?></h2>
+   <?cs /if ?>
+   <?cs if $report.id == -1 ?>
+     <table class="report-list-reports" cellspacing="0" cellpadding="0">
+   <?cs else ?>
+     <table class="report-list" cellspacing="0" cellpadding="0">
+   <?cs /if ?>
+     <tr>
+       <?cs set numcols = #0 ?>
+       <?cs each header = report.headers ?>
+         <?cs if $header.fullrow ?>
+           </tr><tr><th class="header-left" colspan="100"><?cs var:header ?></th>
+         <?cs else ?>
+           <?cs if $report.sorting.enabled ?>
+             <?cs set sortValue = '' ?>
+             <?cs if $header.asc == '1' ?>
+               <?cs set sortValue = '?sort='+$header.real+'&asc=0' ?>
+             <?cs else ?>
+               <?cs set sortValue = '?sort='+$header.real+'&asc=1' ?>
+             <?cs /if ?>
+             <?cs if $header ?>
+             <th class="header-left"><a href="<?cs var:sortValue ?>"><?cs var:header ?></a></th>
+             <?cs /if ?>
+           <?cs elif $header ?>
+             <th class="header-left"><?cs var:header ?></th>
+           <?cs /if ?>
+
+           <?cs if $header.breakrow ?>
+              </tr><tr>
+           <?cs /if ?>
+         <?cs /if ?>
+         <?cs set numcols = numcols + #1 ?>
+       <?cs /each ?>
+     </tr>
+ <?cs /def ?>
+ 
+ <?cs def:report_cell(class,contents) ?>
+   <?cs if $cell.fullrow ?>
+     </tr><tr class="<?cs var: row_class ?>" style="<?cs var: row_style ?>;border: none; padding: 0;">
+ <td colspan="100" style="padding: 0;border: none"><div class="report-fullrow"><?cs var:$contents ?></div><hr class="hide"/></td>
+   <?cs else ?>
+   <td <?cs if $cell.breakrow || $col == $numcols ?>colspan="100" <?cs /if
+ ?>class="<?cs var:$class ?>"><?cs if $contents ?><?cs var:$contents ?><?cs /if ?></td>
+ 
+ <?cs if $cell.breakafter ?>
+     </tr><tr class="<?cs var: row_class ?>" style="<?cs var: row_style ?>;border: none; padding: 0">
+ <?cs /if ?>
+   <?cs /if ?>
+   <?cs set col = $col + #1 ?>
+ <?cs /def ?>
+ 
+ <?cs set idx = #0 ?>
+ <?cs set group = '' ?>
+ 
+ <?cs if report.mode == "list" ?>
+   <h1 id="report-hdr"><center><?cs var:report.title ?></center></h1>
+     <?cs if report.description ?>
+       <div id="report-descr"><div><?cs var:report.description ?></div></center></div>
+     <?cs /if ?>
+
+
+     <?cs each row = report.items ?>
+       <?cs if group != row.__group__ || idx == #0 ?>
+         <?cs set group = row.__group__ ?>
+         <?cs call:report_hdr(group) ?>
+       <?cs /if ?>
+
+       <?cs if row.__color__ ?>
+         <?cs set rstem='color'+$row.__color__ +'-' ?>
+       <?cs else ?>
+        <?cs set rstem='' ?>
+       <?cs /if ?>
+       <?cs if idx % #2 ?>
+         <?cs set row_class=$rstem+'even' ?>
+       <?cs else ?>
+         <?cs set row_class=$rstem+'odd' ?>
+       <?cs /if ?>
+
+       <?cs set row_style='' ?>
+       <?cs if row.__bgcolor__ ?>
+         <?cs set row_style='background: ' + row.__bgcolor__ + ';' ?>
+       <?cs /if ?>
+       <?cs if row.__fgcolor__ ?>
+         <?cs set row_style=$row_style + 'color: ' + row.__fgcolor__ + ';' ?>
+       <?cs /if ?>
+       <?cs if row.__style__ ?>
+         <?cs set row_style=$row_style + row.__style__ + ';' ?>
+       <?cs /if ?>
+
+       <tr class="<?cs var: row_class ?>" style="<?cs var: row_style ?>">
+       <?cs set idx = idx + #1 ?>
+       <?cs set col = #0 ?>
+       <?cs each cell = row ?>
+         <?cs if cell.hidden || cell.hidehtml ?>
+         <?cs elif name(cell) == "ticket" ?>
+           <?cs call:report_cell('ticket-col',
+                                 '<a title="View ticket #'+$cell+'" class="block" href="'+
+                                 $cell.ticket_href+'">#'+$cell+'</a>') ?>
+         <?cs elif name(cell) == "report" ?>
+           <?cs call:report_cell('report-col',
+                '<a title="View Report" class="block" href="'+$cell.report_href+'">{'+$cell+'}</a>') ?>
+           <?cs set:report_href=$cell.report_href ?>
+         <?cs elif name(cell) == "time" ?>
+           <?cs call:report_cell('date-column', $cell.date) ?>
+         <?cs elif name(cell) == "date" || name(cell) == "created" || name(cell) == "modified" ?>
+           <?cs call:report_cell('date-column', $cell.date) ?>
+         <?cs elif name(cell) == "datetime"  ?>
+           <?cs call:report_cell('date-column', $cell.datetime) ?>
+         <?cs elif name(cell) == "description" ?>
+           <?cs call:report_cell('', $cell.parsed) ?>
+         <?cs elif name(cell) == "title" && $report.id == -1 ?>
+           <?cs call:report_cell('title-col',
+                                 '<a  title="View Report" class="block" href="'+
+                                 $report_href+'">'+$cell+'</a>') ?>
+         <?cs else ?>
+           <?cs call:report_cell(name(cell)+'-col', $cell) ?>
+         <?cs /if ?>
+       <?cs /each ?>
+       </tr>
+     <?cs /each ?>
+   </table>
+ <?cs /if ?>
+ 
+   <?cs if $idx == #0 ?>
+    <div id="report-notfound">No matches found.</div>
+   <?cs /if ?>
+
+   <?cs if:report.numrows && report.id != -1 ?><span id="numrows">(<?cs var:report.numrows ?> matches)</span><?cs /if ?> 
+ <?cs if report.id > #0 ?>
+ <?cs set vars='' ?>
+ <?cs each arg = $report.var ?>
+   <?cs set vars=$vars+'&'+name($arg)+'='+$arg ?>
+ <?cs /each ?>
+
+ <?cs set sortInfo='' ?>
+ <?cs if args.sort ?>
+   <?cs set sortInfo=$sortInfo+'&sort='+$args.sort ?>
+ <?cs /if ?>
+ <?cs if args.asc ?>
+   <?cs set sortInfo=$sortInfo+'&asc='+$args.asc ?>
+ <?cs /if ?>
+
+ <?cs /if ?>
+
+<?cs /if ?>
+  </div>
+ </div>
+</div>
+</body>
+</html>
Index: trac/Report.py
===================================================================
--- trac/Report.py	(revision 533)
+++ trac/Report.py	(working copy)
@@ -71,6 +71,7 @@
     template_name = 'report.cs'
     template_rss_name = 'report_rss.cs'
     template_csv_name = 'report_csv.cs'
+    template_print_name = 'report_print.cs'
 
     def sql_sub_vars(self, sql, args):
         m = re.search(dynvars_re, sql)
@@ -402,3 +403,7 @@
             descr = '-- %s\n\n' % '\n-- '.join(row[1].splitlines())
             self.req.write(descr)
         self.req.write(sql)
+
+    def display_print(self):
+	self.req.display(self.template_print_name, 'text/html')
+	

