Index: trac/ticket/report.py
===================================================================
--- trac/ticket/report.py	(revision 5194)
+++ trac/ticket/report.py	(working copy)
@@ -36,9 +36,13 @@
                             Chrome
 from trac.wiki import IWikiSyntaxProvider, WikiParser
 
+import math,urllib
 
 class ReportModule(Component):
 
+    tickets_per_page = IntOption('ticket', 'default_per_page', default=10,
+                                 doc="The number of tickets shown per page in queries")
+    
     implements(INavigationContributor, IPermissionRequestor, IRequestHandler,
                IWikiSyntaxProvider)
 
@@ -322,6 +326,40 @@
                 header_groups.append([])
             header_group.append(header)
 
+        # Update/retrieve the number of tickets per page
+        perpage = int(req.args.get("per_page", 0))
+        if not perpage:
+            perpage = req.session.get('tickets_perpage')
+            if not perpage:
+                perpage = self.tickets_per_page
+            else:
+                perpage = int(perpage)
+        else:
+            req.session['tickets_perpage'] = perpage
+            
+        # Calculate number of pages and current page
+        numpages = int(math.ceil(len(results) * 1.0 / perpage))
+        curpage = int(req.args.get('page', 1))
+        if curpage <= 0 or curpage > numpages:
+            raise TracError, 'Invalid page %s'%(curpage)
+                
+        # Calculate the start and end point
+        start = perpage * (curpage-1)
+        end = start + perpage
+        results = results[start:end]
+
+        page_query = {}
+        page_query['perpage'] = perpage
+        page_query['numpages'] = range(1, numpages+1)
+        page_query['curpage'] = curpage
+        params = {}
+        if req.args.has_key('sort'):
+            params['sort'] = req.args['sort']
+        if req.args.has_key('asc'):
+            params['asc'] = req.args['asc']
+        page_query['baseparams'] = urllib.urlencode(params)
+            
+
         # Structure the rows and cells:
         #  - group rows according to __group__ value, if defined
         #  - group cells the same way headers are grouped
@@ -377,7 +415,8 @@
                      'row_groups': row_groups,
                      'numrows': len(results),
                      'sorting_enabled': len(row_groups)==1,
-                     'email_map': email_map})
+                     'email_map': email_map,
+                     'page_query': page_query})
 
         if id:
             self.add_alternate_links(req, args)
Index: trac/ticket/templates/report_view.html
===================================================================
--- trac/ticket/templates/report_view.html	(revision 5194)
+++ trac/ticket/templates/report_view.html	(working copy)
@@ -27,6 +27,34 @@
       </h1>
 
       <div py:if="report.description" id="description">${wiki_to_html(context, report.description)}</div>
+      <div py:if="report.id != -1">
+        <form id="query" method="get" action="">
+          <p class="option">
+            Page:
+             <py:for each="n in page_query.numpages">
+               <py:if test="n == page_query.curpage">
+                 ${n}
+               </py:if>
+               <py:if test="n != page_query.curpage">
+                 <py:if test="page_query.baseparams">
+                   <a href="?${page_query.baseparams}&amp;page=${n}">${n}</a>
+                 </py:if>
+                 <py:if test="not page_query.baseparams">
+                   <a href="?page=${n}">${n}</a>
+                 </py:if>
+               </py:if>
+             </py:for>
+          </p>
+          <p class="option">
+            <label>Ticket per page:
+             <input type="text" class="textwidget" name="per_page" value="${page_query.perpage}" size="6" />
+            </label>
+          </p>
+           <div class="buttons">
+            <input type="submit" name="update" value="Update" />
+          </div>
+        </form>
+      </div>
 
       <div py:if="report.id != -1 and report.perms" class="buttons">
         <form py:if="'MODIFY' in report.perms" action="" method="get">

