Index: privatemsg.admin.inc
===================================================================
RCS file: /cvs/drupal/contributions/modules/privatemsg/privatemsg.admin.inc,v
retrieving revision 1.10
diff -u -r1.10 privatemsg.admin.inc
--- privatemsg.admin.inc	22 Oct 2010 08:47:34 -0000	1.10
+++ privatemsg.admin.inc	11 Jan 2011 18:57:22 -0000
@@ -130,7 +130,8 @@
       'thread_started'  => t('Started'),
       'count'           => t('Messages'),
     ),
-    '#default_value' => variable_get('privatemsg_display_fields', array('participants')),
+    '#default_value' => variable_get('privatemsg_display_fields', array('subject', 'participants', 'last_updated')),
+    '#process' => array('privatemsg_process_display_fields'),
   );
 
   $form['privatemsg_listing']['privatemsg_url_prefix'] = array(
@@ -222,6 +223,65 @@
 }
 
 /**
+ * After build handler to make privatemsg_list fields drag and drop sortable.
+ */
+function privatemsg_process_display_fields($element) {
+  // Add 'Subject' and 'Last updated' to our element for sorting.
+  $element['#options'] = array_merge(array('subject' => t('Subject'), 'last_updated' => t('Last updated')), $element['#options']);
+
+  // Expand checkboxes.
+  $element = expand_checkboxes($element);
+
+  // Disable 'Subject' and 'Last updated' and make sure they are always checked.
+  $element['subject']['#disabled'] = TRUE;
+  $element['subject']['#default_value'] = 'subject';
+  $element['last_updated']['#disabled'] = TRUE;
+  $element['last_updated']['#default_value'] = 'last_updated';
+
+  // Get weight settings.
+  $weights = variable_get('privatemsg_display_fields_weights', array(
+    'subject' => -20,
+    'participants' => -15,
+    'thread_started' => -10,
+    'count' => -5,
+    'last_updated' => 20,
+  ));
+
+  // We are going to save the checkbox values in addition to weights, so
+  // unset #tree.  We will use the #parents property to control
+  // the structure of $form_state['values'];
+  $element['#tree'] = FALSE;
+  foreach (element_children($element) as $child) {
+    $parents = $element['#parents'];
+    $parents[] = $child;
+    $element[$child]['#parents'] = $parents;
+
+    // Set checkbox weight.
+    $element[$child]['#weight'] = isset($weights[$child]) ? $weights[$child] : 0;
+  }
+
+  // Add weight fields for each display field.
+  foreach (element_children($element) as $child) {
+    $element['privatemsg_display_fields_weights'][$child] = array(
+      '#type' => 'weight',
+      '#title' => t('!field weight', array('!field' => $element[$child]['#title'])),
+      '#default_value' => isset($weights[$child]) ? $weights[$child] : 0,
+      '#delta' => 20,
+    );
+  }
+  $element['privatemsg_display_fields_weights']['#tree'] = TRUE;
+
+  // Style the whole element as a fieldset, and theme the contents as a
+  // drag and drop table.
+  $element['#type'] = 'fieldset';
+  $element['#collapsible'] = FALSE;
+  $element['#default_value'] = NULL;
+  $element['#value'] = NULL;
+  $element['#theme'] = 'privatemsg_admin_settings_display_fields';
+  return $element;
+}
+
+/**
  * Submit handler to check if URL prefixes have changes and rebuild the menu
  * cache if this is true.
  */
Index: privatemsg.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/privatemsg/privatemsg.module,v
retrieving revision 1.158
diff -u -r1.158 privatemsg.module
--- privatemsg.module	27 Dec 2010 09:33:03 -0000	1.158
+++ privatemsg.module	11 Jan 2011 18:57:22 -0000
@@ -711,6 +711,12 @@
       'path'                  => drupal_get_path('module', 'privatemsg'),
       'arguments'             => array('recipient' => NULL, 'options' => array()),
     ),
+    // Admin settings theme callbacks.
+    'privatemsg_admin_settings_display_fields' => array(
+      'file'                  => 'privatemsg.theme.inc',
+      'path'                  => drupal_get_path('module', 'privatemsg'),
+      'arguments'             => array('element' => array()),
+    ),
   );
 }
 
@@ -2325,6 +2331,21 @@
     // No header definition returned, fallback to the default.
     $header += _privatemsg_list_headers_fallback($keys);
   }
+
+  // Apply weight settings.
+  $column_weights = variable_get('privatemsg_display_fields_weights', array(
+    'subject' => -20,
+    'participants' => -15,
+    'thread_started' => -10,
+    'count' => -5,
+    'last_updated' => 20,
+  ));
+  foreach ($header as $key => $item) {
+    if (!isset($item['#weight'])) {
+      $header[$key]['#weight'] = isset($column_weights[$key]) ? $column_weights[$key] : 0;
+    }
+  }
+
   return $header;
 }
 
Index: privatemsg.theme.inc
===================================================================
RCS file: /cvs/drupal/contributions/modules/privatemsg/privatemsg.theme.inc,v
retrieving revision 1.6
diff -u -r1.6 privatemsg.theme.inc
--- privatemsg.theme.inc	22 Oct 2010 08:46:15 -0000	1.6
+++ privatemsg.theme.inc	11 Jan 2011 18:57:22 -0000
@@ -168,7 +168,6 @@
     'field'   => 'subject',
     'key'     => 'subject',
     'class'   => 'privatemsg-header-subject',
-    '#weight' => -40,
   );
 }
 
@@ -182,7 +181,6 @@
     'data'    => t('Messages'),
     'key'     => 'count',
     'class'   => 'privatemsg-header-count',
-    '#weight' => -25,
   );
 }
 
@@ -196,7 +194,6 @@
     'data'    => t('Participants'),
     'key'     => 'participants',
     'class'   => 'privatemsg-header-participants',
-    '#weight' => -30,
   );
 }
 
@@ -212,7 +209,6 @@
     'key'     => 'last_updated',
     'sort'    => 'desc',
     'class'   => 'privatemsg-header-lastupdated',
-    '#weight' => -20,
   );
 }
 
@@ -227,7 +223,6 @@
     'field'   => 'thread_started',
     'key'     => 'thread_started',
     'class'   => 'privatemsg-header-threadstarted',
-    '#weight' => -15,
   );
 }
 
@@ -243,7 +238,7 @@
   drupal_add_css(drupal_get_path('module', 'privatemsg') .'/styles/privatemsg-list.css');
 
   // Load the table columns.
-  $columns = array_merge(array('subject', 'last_updated'), array_filter(variable_get('privatemsg_display_fields', array('participants'))));
+  $columns = array_filter(variable_get('privatemsg_display_fields', array('subject', 'participants', 'last_updated')));
 
   // Load the themed list headers based on the available data.
   $headers = _privatemsg_list_headers(!empty($form['#data']), $columns);
@@ -331,5 +326,47 @@
 }
 
 /**
+ * Output the admin settings display fields and weight settings as a
+ * drag and drop sortable table.
+ */
+function theme_privatemsg_admin_settings_display_fields($element = array()) {
+  $header = array(
+    array('data' => t('Field'), 'class' => 'field'),
+    array('data' => t('Enable'), 'class' => 'enable'),
+    array('data' => t('Weight'), 'class' => 'weight'),
+  );
+  $rows = array();
+  foreach (element_children($element) as $child) {
+    if ($child !== 'privatemsg_display_fields_weights') {
+      $row = array();
+
+      // Title.
+      $row[] = array('data' => $element[$child]['#title'], 'class' => 'field');
+      unset($element[$child]['#title']);
+
+      // Enable checkbox.
+      $row[] = array('data' => drupal_render($element[$child]), 'class' => 'enable');
+
+      // Weight selector.
+      unset($element['privatemsg_display_fields_weights'][$child]['#title']);
+      $element['privatemsg_display_fields_weights'][$child]['#attributes']['class'] = 'privatemsg-display-fields-weight';
+      $row[] = array(
+        'data' => drupal_render($element['privatemsg_display_fields_weights'][$child]),
+        'class' => 'weight',
+      );
+
+      $rows[] = array('data' => $row, 'class' => 'draggable');
+    }
+  }
+  if (!empty($rows)) {
+    drupal_add_tabledrag('privatemsg-list-display-fields', 'order', 'sibling', 'privatemsg-display-fields-weight');
+    return theme('table', $header, $rows, array('id' => 'privatemsg-list-display-fields')) . drupal_render($element);
+  }
+  else {
+    return drupal_render($element);
+  }
+}
+
+/**
  * @}
  */
