Index: includes/tablesort.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/tablesort.inc,v
retrieving revision 1.58
diff -u -p -r1.58 tablesort.inc
--- includes/tablesort.inc	5 Dec 2009 20:17:02 -0000	1.58
+++ includes/tablesort.inc	24 Aug 2010 08:40:52 -0000
@@ -174,13 +174,15 @@ function tablesort_header($cell, $header
       $image = theme('tablesort_indicator', array('style' => $ts['sort']));
     }
     else {
-      // If the user clicks a different header, we want to sort ascending initially.
-      $ts['sort'] = 'asc';
+      // This determines the sort order when the column gets first clicked by
+      // the user. It is "asc" by default, but if $cell['descending'] is TRUE,
+      // then it will be "desc".
+      $ts['sort'] = empty($cell['descending']) ? 'asc' : 'desc';
       $image = '';
     }
     $cell['data'] = l($cell['data'] . $image, $_GET['q'], array('attributes' => array('title' => $title), 'query' => array_merge($ts['query'], array('sort' => $ts['sort'], 'order' => $cell['data'])), 'html' => TRUE));
 
-    unset($cell['field'], $cell['sort']);
+    unset($cell['field'], $cell['sort'], $cell['descending']);
   }
   return $cell;
 }
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.606
diff -u -p -r1.606 theme.inc
--- includes/theme.inc	22 Aug 2010 12:46:21 -0000	1.606
+++ includes/theme.inc	24 Aug 2010 08:40:53 -0000
@@ -1556,7 +1556,12 @@ function theme_breadcrumb($variables) {
  *     - "data": The localized title of the table column.
  *     - "field": The database field represented in the table column (required
  *       if user is to be able to sort on this column).
- *     - "sort": A default sort order for this column ("asc" or "desc").
+ *     - "sort": "asc" or "desc"; determines the column and order of the table's
+ *       sort when it is rendered for the first time. This attribute should only
+ *       be assigned to one column in a table.
+ *     - "descending": Set to TRUE if the column should sort descending when its
+ *       header is clicked for the first time. This attribute can be applied to
+ *       multiple columns in a table.
  *     - Any HTML attributes, such as "colspan", to apply to the column header
  *       cell.
  *   - rows: An array of table rows. Every row is an array of cells, or an
Index: modules/simpletest/tests/theme.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/theme.test,v
retrieving revision 1.20
diff -u -p -r1.20 theme.test
--- modules/simpletest/tests/theme.test	22 Aug 2010 12:46:21 -0000	1.20
+++ modules/simpletest/tests/theme.test	24 Aug 2010 08:40:53 -0000
@@ -134,6 +134,39 @@ class ThemeTableUnitTest extends DrupalW
     $this->assertRaw('<thead><tr><th>Header 1</th>', t('Table header was printed.'));
   }
 
+  /**
+   * Tests correct sort links are generated for headers where requested.
+   */
+  function testThemeTableSort() {
+    $header = array(
+      array(
+        'data' => 'Header1',
+        'field' => 'a',
+        'sort' => 'asc',
+      ),
+      array(
+        'data' => 'Header2',
+        'field' => 'b',
+      ),
+      array(
+        'data' => 'Header3',
+        'field' => 'c',
+        'descending' => TRUE,
+      ),
+      'Header4',
+    );
+    $rows = array(array(1, 2, 3, 4));
+    $this->content = theme('table', array('header' => $header, 'rows' => $rows));
+    $this->assertRaw('sort=desc&amp;order=Header1', t('Correct link for active sort-column.'));
+    $this->assertRaw('sort=asc&amp;order=Header2', t('Correct link for sort-column with default settings.'));
+    $this->assertRaw('sort=desc&amp;order=Header3', t('Correct link for sort-column defaulting to descending order.'));
+    $this->assertNoRaw('order=Header4', t('No link for normal column.'));
+    $this->assertNoRaw(' data="', t('"data" not set as HTML attribute.'));
+    $this->assertNoRaw(' field="', t('"field" not set as HTML attribute.'));
+    $this->assertNoRaw(' sort="', t('"sort" not set as HTML attribute.'));
+    $this->assertNoRaw(' descending="', t('"descending" not set as HTML attribute.'));
+  }
+
 }
 
 /**
Index: modules/statistics/statistics.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/statistics/statistics.admin.inc,v
retrieving revision 1.40
diff -u -p -r1.40 statistics.admin.inc
--- modules/statistics/statistics.admin.inc	26 Jun 2010 21:32:20 -0000	1.40
+++ modules/statistics/statistics.admin.inc	24 Aug 2010 08:40:53 -0000
@@ -11,7 +11,7 @@
  */
 function statistics_recent_hits() {
   $header = array(
-    array('data' => t('Timestamp'), 'field' => 'a.timestamp', 'sort' => 'desc'),
+    array('data' => t('Timestamp'), 'field' => 'a.timestamp', 'descending' => TRUE, 'sort' => 'desc'),
     array('data' => t('Page'), 'field' => 'a.path'),
     array('data' => t('User'), 'field' => 'u.name'),
     array('data' => t('Operations'))
@@ -50,10 +50,10 @@ function statistics_recent_hits() {
  */
 function statistics_top_pages() {
   $header = array(
-    array('data' => t('Hits'), 'field' => 'hits', 'sort' => 'desc'),
+    array('data' => t('Hits'), 'field' => 'hits', 'descending' => TRUE, 'sort' => 'desc'),
     array('data' => t('Page'), 'field' => 'path'),
-    array('data' => t('Average page generation time'), 'field' => 'average_time'),
-    array('data' => t('Total page generation time'), 'field' => 'total_time')
+    array('data' => t('Average page generation time'), 'field' => 'average_time', 'descending' => TRUE),
+    array('data' => t('Total page generation time'), 'field' => 'total_time', 'descending' => TRUE)
   );
 
   $query = db_select('accesslog', 'a', array('target' => 'slave'))->extend('PagerDefault')->extend('TableSort');
@@ -96,9 +96,9 @@ function statistics_top_pages() {
 function statistics_top_visitors() {
 
   $header = array(
-    array('data' => t('Hits'), 'field' => 'hits', 'sort' => 'desc'),
+    array('data' => t('Hits'), 'field' => 'hits', 'descending' => TRUE, 'sort' => 'desc'),
     array('data' => t('Visitor'), 'field' => 'u.name'),
-    array('data' => t('Total page generation time'), 'field' => 'total'),
+    array('data' => t('Total page generation time'), 'field' => 'total', 'descending' => TRUE),
     array('data' => user_access('block IP addresses') ? t('Operations') : '', 'colspan' => 2),
   );
   $query = db_select('accesslog', 'a', array('target' => 'slave'))->extend('PagerDefault')->extend('TableSort');
@@ -150,7 +150,7 @@ function statistics_top_referrers() {
   drupal_set_title(t('Top referrers in the past %interval', array('%interval' => format_interval(variable_get('statistics_flush_accesslog_timer', 259200)))), PASS_THROUGH);
 
   $header = array(
-    array('data' => t('Hits'), 'field' => 'hits', 'sort' => 'desc'),
+    array('data' => t('Hits'), 'field' => 'hits', 'descending' => TRUE, 'sort' => 'desc'),
     array('data' => t('Url'), 'field' => 'url'),
     array('data' => t('Last visit'), 'field' => 'last'),
   );
Index: modules/statistics/statistics.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/statistics/statistics.pages.inc,v
retrieving revision 1.23
diff -u -p -r1.23 statistics.pages.inc
--- modules/statistics/statistics.pages.inc	9 Jan 2010 21:54:01 -0000	1.23
+++ modules/statistics/statistics.pages.inc	24 Aug 2010 08:40:53 -0000
@@ -10,7 +10,7 @@ function statistics_node_tracker() {
   if ($node = node_load(arg(1))) {
 
     $header = array(
-        array('data' => t('Time'), 'field' => 'a.timestamp', 'sort' => 'desc'),
+        array('data' => t('Time'), 'field' => 'a.timestamp', 'descending' => TRUE, 'sort' => 'desc'),
         array('data' => t('Referrer'), 'field' => 'a.url'),
         array('data' => t('User'), 'field' => 'u.name'),
         array('data' => t('Operations')));
@@ -57,7 +57,7 @@ function statistics_user_tracker() {
   if ($account = user_load(arg(1))) {
 
     $header = array(
-        array('data' => t('Timestamp'), 'field' => 'timestamp', 'sort' => 'desc'),
+        array('data' => t('Timestamp'), 'field' => 'timestamp', 'descending' => TRUE, 'sort' => 'desc'),
         array('data' => t('Page'), 'field' => 'path'),
         array('data' => t('Operations')));
     $query = db_select('accesslog', 'a', array('target' => 'slave'))->extend('PagerDefault')->extend('TableSort');
