Index: privatemsg.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg.module,v
retrieving revision 1.70.2.30.2.91.2.64.2.94
diff -u -p -r1.70.2.30.2.91.2.64.2.94 privatemsg.module
--- privatemsg.module	24 Nov 2010 20:10:42 -0000	1.70.2.30.2.91.2.64.2.94
+++ privatemsg.module	9 Dec 2010 09:52:21 -0000
@@ -1011,12 +1011,12 @@ function privatemsg_sql_list($account, $
     if (db_driver() == 'pgsql') {
       $query->addExpression("array_to_string(array(SELECT DISTINCT pmia.recipient
                                                           FROM {pm_index} pmia
-                                                          WHERE pmia.type = 'user' AND pmia.thread_id = pmi.thread_id), ',')", 'participants');
+                                                          WHERE pmia.type = 'user' AND pmia.thread_id = pmi.thread_id AND pmia.recipient <> :current), ',')", 'participants', array(':current' => $account->uid));
     }
     else {
       $query->addExpression("(SELECT GROUP_CONCAT(DISTINCT pmia.recipient SEPARATOR ',')
                                      FROM {pm_index} pmia
-                                     WHERE pmia.type = 'user' AND pmia.thread_id = pmi.thread_id)", 'participants');
+                                     WHERE pmia.type = 'user' AND pmia.thread_id = pmi.thread_id AND pmia.recipient <> :current)", 'participants', array(':current' => $account->uid));
     }
   }
   if (in_array('thread_started', $fields)) {
@@ -2166,10 +2166,12 @@ function privatemsg_privatemsg_thread_op
   );
   if (privatemsg_user_access('delete privatemsg')) {
     $operations['delete'] = array(
+      'label' => t('Delete'),
       'callback' => 'privatemsg_thread_change_delete',
       'callback arguments' => array('delete' => 1),
       'undo callback' => 'privatemsg_thread_change_delete',
       'undo callback arguments' => array('delete' => 0),
+      'button' => TRUE,
     );
   }
   return $operations;
Index: privatemsg.pages.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg.pages.inc,v
retrieving revision 1.1.2.33
diff -u -p -r1.1.2.33 privatemsg.pages.inc
--- privatemsg.pages.inc	24 Nov 2010 20:09:44 -0000	1.1.2.33
+++ privatemsg.pages.inc	9 Dec 2010 09:52:21 -0000
@@ -20,48 +20,64 @@
  * @return
  *   The FAPI definitions for the thread action form.
  */
-function _privatemsg_action_form() {
+function _privatemsg_action_form($type) {
   $form = array(
-      '#type'        => 'fieldset',
-      '#title'       => t('Actions'),
       '#prefix'      => '<div class="container-inline">',
       '#suffix'      => '</div>',
-      '#collapsible' => TRUE,
-      '#collapsed'   => FALSE,
-      '#weight'      => 15,
+      '#weight'      => -5,
   );
-  if (privatemsg_user_access('delete privatemsg')) {
-    $form['delete'] = array(
-        '#type'   => 'submit',
-        '#value'  => t('Delete'),
-    );
-  }
   // Display all operations which have a label.
-  $options = array(0 => t('More actions...'));
-  foreach (module_invoke_all('privatemsg_thread_operations') as $operation => $array) {
-    if (isset($array['label'])) {
+  $operations = module_invoke_all('privatemsg_thread_operations', $type);
+  drupal_alter('privatemsg_thread_operations', $operations, $type);
+  foreach ($operations as $operation => $array) {
+    if (!empty($array['button'])) {
+      $form[$operation] = array(
+        '#type'   => 'submit',
+        '#value'  => $array['label'],
+        '#ajax' => array(
+          'callback' => 'privatemsg_list_js',
+          'wrapper' => 'privatemsg-list-form',
+          'effect' => 'fade',
+        ),
+      );
+    }
+    elseif (isset($array['label'])) {
       $options[$operation] = $array['label'];
     }
   }
-  $form['operation'] = array(
+  if (!empty($options)) {
+    array_unshift($options, t('Actions...'));
+    $form['operation'] = array(
       '#type'          => 'select',
       '#options'       => $options,
-      '#default_value' => 0,
-      // Execute the submit button if a operation has been selected.
-      '#attributes'    => array('onchange' => "(function ($) { $('#edit-submit').click() })(jQuery);"),
-  );
-  $form['submit'] = array(
-      '#prefix'     => '<div class="privatemsg-op-button">',
-      '#suffix'    => '</div>',
+      '#ajax' => array(
+        'callback' => 'privatemsg_list_js',
+        'wrapper' => 'privatemsg-list-form',
+        'effect' => 'fade',
+      ),
+      '#executes_submit_callback' => TRUE,
+    );
+    $form['submit'] = array(
       '#type'       => 'submit',
       '#value'      => t('Execute'),
-      '#submit'     => array('privatemsg_list_submit'),
-  );
-  // JS for hiding the execute button.
-  drupal_add_js(drupal_get_path('module', 'privatemsg') .'/privatemsg-list.js');
+      '#attributes' => array('class' => array('form-item')),
+      '#states' => array(
+        'visible' => array(
+          // This is never true, button is always hidden when JS is enabled.
+          ':input[name=operation]' => array('value' => 'fake'),
+        ),
+      ),
+    );
+  }
   return $form;
 }
 
+/**
+ * AJAX callback to return the form again.
+ */
+function privatemsg_list_js($form, $form_state) {
+  return $form['updated'];
+}
 
 function privatemsg_delete($form, $form_state, $thread, $message) {
   $form['pmid'] = array(
@@ -149,8 +165,15 @@ function privatemsg_list($form, &$form_s
   $headers = _privatemsg_list_headers($columns);
   uasort($headers, 'element_sort');
 
-  $form = array('#list_argument' => $argument);
-  $form['list'] = array(
+  $form = array(
+    '#list_argument' => $argument,
+    '#submit' => array('privatemsg_list_submit'),
+    'updated' => array(
+      '#prefix' => '<div id="privatemsg-list-form">',
+      '#suffix' => '</div>',
+    ),
+  );
+  $form['updated']['list'] = array(
     '#type' => 'tableselect',
     '#header' => $headers,
     '#options' => array(),
@@ -164,24 +187,21 @@ function privatemsg_list($form, &$form_s
   $i = 0;
   foreach ($query->execute() as $row) {
     // Store the raw row data.
-    $form['list']['#options'][$row->thread_id] = (array)$row;
+    $form['updated']['list']['#options'][$row->thread_id] = (array)$row;
     // Tableselect sorts the options, set a weight so that the order doesn't get
     // changed.
-    $form['list']['#options'][$row->thread_id]['#weight'] = $i++;
+    $form['updated']['list']['#options'][$row->thread_id]['#weight'] = $i++;
   }
 
-  if (!empty($form['list']['#options'])) {
-    $form['actions'] = _privatemsg_action_form();
+  if (!empty($form['updated']['list']['#options'])) {
+    $form['updated']['actions'] = _privatemsg_action_form($argument);
   }
 
   // Save the currently active account, used for actions.
   $form['account'] = array('#type' => 'value', '#value' => $account);
 
   // Define checkboxes, pager and theme
-  $form['pager'] = array('#theme' => 'pager', '#weight' => 20);
-
-  // Store the account for which the threads are displayed.
-  $form['#account'] = $account;
+  $form['updated']['pager'] = array('#theme' => 'pager', '#weight' => 20);
   return $form;
 }
 
@@ -194,7 +214,8 @@ function privatemsg_list($form, &$form_s
  */
 function privatemsg_list_submit($form, &$form_state) {
   // Load all available operation definitions.
-  $operations = module_invoke_all('privatemsg_thread_operations');
+  $operations = module_invoke_all('privatemsg_thread_operations', $form['#list_argument']);
+  drupal_alter('privatemsg_thread_operations', $operations, $for['#list_argument']);
 
   // Default "default" operation, which won't do anything.
   $operation = array('callback' => 0);
@@ -218,6 +239,9 @@ function privatemsg_list_submit($form, &
   if (!empty($operation['callback'])) {
     privatemsg_operation_execute($operation, $form_state['values']['list'], $form_state['values']['account']);
   }
+
+  $form_state['rebuild'] = TRUE;
+  $form_state['input'] = array();
 }
 
 
Index: privatemsg_filter/privatemsg_filter.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg_filter/privatemsg_filter.css,v
retrieving revision 1.1.4.1
diff -u -p -r1.1.4.1 privatemsg_filter.css
--- privatemsg_filter/privatemsg_filter.css	24 Nov 2010 20:09:44 -0000	1.1.4.1
+++ privatemsg_filter/privatemsg_filter.css	9 Dec 2010 09:52:22 -0000
@@ -1,19 +1,21 @@
-
-form#privatemsg-filter-dropdown #edit-author-wrapper, form#privatemsg-filter-dropdown #edit-tags-wrapper {
-  float: left;
-  margin-right: 3em;
+fieldset#edit-filter {
+    padding-bottom: 5px;
 }
 
-form#privatemsg-filter-dropdown #privatemsg-filter-buttons {
-  clear: left;
+fieldset#edit-filter div.form-actions {
+    margin: 0;
+    padding: 0;
 }
 
-form#privatemsg-filter-form div.form-item {
+fieldset#edit-filter div.form-item label {
     float: left;
-    margin-right: 5px;
+    margin-right: 10px;
+    width: 150px;
+    text-align: right;
+    padding-top: 5px;
 }
 
-form#privatemsg-filter-form {
+fieldset#edit-filter div.form-item {
     clear: both;
 }
 
Index: privatemsg_filter/privatemsg_filter.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg_filter/privatemsg_filter.module,v
retrieving revision 1.1.2.17.2.31
diff -u -p -r1.1.2.17.2.31 privatemsg_filter.module
--- privatemsg_filter/privatemsg_filter.module	24 Nov 2010 20:09:44 -0000	1.1.2.17.2.31
+++ privatemsg_filter/privatemsg_filter.module	9 Dec 2010 09:52:22 -0000
@@ -348,16 +348,16 @@ function privatemsg_filter_dropdown(&$fo
   );
   $form['filter']['search'] = array(
     '#type' => 'textfield',
-    '#title' => variable_get('privatemsg_filter_searchbody', FALSE) ? t('Search messages') : t('Search subjects'),
-    '#weight' => -20
+    '#title' => variable_get('privatemsg_filter_searchbody', FALSE) ? t('By content') : t('By subject'),
+    '#weight' => -20,
+    '#size' => 25,
   );
 
   $form['filter']['author'] = array(
     '#type'               => 'textfield',
-    '#title'              => t('Participants'),
-    '#description'        => t('Separate multiple names with commas.'),
+    '#title'              => t('By participant'),
     '#weight'             => -5,
-    '#size'               => 50,
+    '#size'               => 25,
     '#autocomplete_path'  => 'messages/filter/autocomplete',
   );
 
@@ -365,25 +365,26 @@ function privatemsg_filter_dropdown(&$fo
   if (count($tag_data = privatemsg_filter_get_tags_data($account))) {
     $form['filter']['tags'] = array(
       '#type' => 'select',
-      '#title' => t('Tags'),
+      '#title' => t('By tags'),
       '#options' => $tag_data,
       '#multiple' => TRUE,
-      '#size' => 5,
       '#weight' => 0
     );
   }
-  $form['filter']['submit'] = array(
+  $form['filter']['actions'] = array(
+    '#type' => 'actions',
+    '#attributes' => array('class' => array('privatemsg-filter-actions')),
+  );
+  $form['filter']['actions']['submit'] = array(
     '#type'     => 'submit',
     '#value'    => t('Filter'),
-    '#prefix'   => '<div id="privatemsg-filter-buttons">',
     '#weight'   => 10,
     '#submit'   => array('privatemsg_filter_dropdown_submit'),
   );
 
-  $form['filter']['save'] = array(
+  $form['filter']['actions']['save'] = array(
     '#type'     => 'submit',
     '#value'    => t('Save filter'),
-    '#suffix'   => '</div>',
     '#weight'   => 11,
     '#submit'   => array('privatemsg_filter_dropdown_submit'),
   );
@@ -417,14 +418,12 @@ function privatemsg_filter_dropdown_set_
     $form['filter']['search']['#default_value'] = $filter['search'];
   }
 
-  $form['filter']['reset'] = array(
+  $form['filter']['actions']['reset'] = array(
       '#type'     => 'submit',
       '#value'    => t('Reset'),
-      '#suffix'   => '</div>',
       '#weight'   => 12,
       '#submit'   => array('privatemsg_filter_dropdown_submit'),
   );
-  unset($form['filter']['save']['#suffix']);
 }
 
 function privatemsg_filter_dropdown_submit($form, &$form_state) {
@@ -506,49 +505,45 @@ function privatemsg_filter_create_get_qu
  */
 function privatemsg_filter_form_privatemsg_list_alter(&$form, $form_state) {
   global $user;
-  if (privatemsg_user_access('filter private messages') && !empty($form['list']['#options']) || privatemsg_filter_get_filter($user)) {
-    $form += privatemsg_filter_dropdown($form_state, $form['#account']);
+  if (privatemsg_user_access('filter private messages') && !empty($form['updated']['list']['#options']) || privatemsg_filter_get_filter($user)) {
+    $form += privatemsg_filter_dropdown($form_state, $form['account']['#value']);
   }
 
   $fields = array_filter(variable_get('privatemsg_display_fields', array('participants')));
-  if (privatemsg_user_access('tag private messages') && in_array('tags', $fields) && !empty($form['list']['#options'])) {
+  if (privatemsg_user_access('tag private messages') && in_array('tags', $fields) && !empty($form['updated']['list']['#options'])) {
     // Load thread id's of the current list.
-    $threads = array_keys($form['list']['#options']);
+    $threads = array_keys($form['updated']['list']['#options']);
 
     // Fetch all tags of those threads.
     $query = _privatemsg_assemble_query(array('tags', 'privatemsg_filter'), $user, $threads, 3);
 
     // Add them to tableselect options.
     foreach ($query->execute() as $tag) {
-      $form['list']['#options'][$tag->thread_id]['tags'][$tag->tag_id] = $tag->tag;
+      $form['updated']['list']['#options'][$tag->thread_id]['tags'][$tag->tag_id] = $tag->tag;
     }
     // Avoid notices for threads without tags.
-    foreach ($form['list']['#options'] as &$thread) {
+    foreach ($form['updated']['list']['#options'] as &$thread) {
       if (empty($thread['tags'])) {
         $thread['tags'] = array();
       }
     }
   }
 
-  if ($form['#list_argument'] == 'inbox' && !empty($form['list']['#options'])) {
-    $form['actions']['archive'] = array(
-      '#type'   => 'submit',
-      '#value'  => t('Archive'),
-      '#submit' => array('privatemsg_filter_archive_submit'),
-      '#weight' => -10,
+  if (privatemsg_user_access('tag private messages') && !empty( $form['updated']['list']['#options'])) {
+    $form['updated']['actions']['tag-add'] = array(
+       '#type'               => 'textfield',
+       '#size'               => 15,
+       '#autocomplete_path'  => 'messages/filter/tag-autocomplete',
     );
-  }
-
-  if (privatemsg_user_access('tag private messages') && !empty( $form['list']['#options'])) {
-    $form['actions']['tag-add'] = array(
-     '#type'               => 'textfield',
-     '#size'               => 15,
-     '#autocomplete_path'  => 'messages/filter/tag-autocomplete',
-    );
-    $form['actions']['tag-add-submit'] = array(
-        '#type'       => 'submit',
-        '#value'      => t('Apply Tag'),
-        '#submit'     => array('privatemsg_filter_add_tag_submit'),
+    $form['updated']['actions']['tag-add-submit'] = array(
+      '#type'       => 'submit',
+      '#value'      => t('Apply Tag'),
+      '#submit'     => array('privatemsg_filter_add_tag_submit'),
+      '#ajax' => array(
+        'callback' => 'privatemsg_list_js',
+        'wrapper' => 'privatemsg-list-form',
+        'effect' => 'fade',
+      ),
     );
     $tags = privatemsg_filter_get_tags_data($user);
     if (!empty($tags)) {
@@ -556,37 +551,49 @@ function privatemsg_filter_form_privatem
       foreach ($tags as $tag_id => $tag) {
         $options[$tag_id] = $tag;
       }
-      $form['actions']['tag-remove'] = array(
+      $form['updated']['actions']['tag-remove'] = array(
         '#type'          => 'select',
         '#options'       => $options,
         '#default_value' => 0,
+        '#ajax' => array(
+          'callback' => 'privatemsg_list_js',
+          'wrapper' => 'privatemsg-list-form',
+          'effect' => 'fade',
+        ),
+        '#submit'     => array('privatemsg_filter_remove_tag_submit'),
+        '#executes_submit_callback' => TRUE,
       );
-      $form['actions']['tag-remove-submit'] = array(
-        '#prefix'     => '<div class="privatemsg-tag-remove-submit">',
-        '#suffix'    => '</div>',
+      $form['updated']['actions']['tag-remove-submit'] = array(
         '#type'       => 'submit',
         '#value'      => t('Remove Tag'),
         '#submit'     => array('privatemsg_filter_remove_tag_submit'),
+        '#attributes' => array('class' => array('form-item')),
+        '#states' => array(
+          'visible' => array(
+            // This is never true, button is always hidden when JS is enabled.
+            ':input[name=operation]' => array('value' => 'fake'),
+          ),
+        ),
       );
     }
-
-    // JS for hiding the submit buttons.
-    drupal_add_js(drupal_get_path('module', 'privatemsg_filter') .'/privatemsg-filter-list.js');
   }
 }
 
 /**
  * Form callback for removing a tag to threads.
  */
-function privatemsg_filter_archive_submit($form, &$form_state) {
-  $operation = array(
-    'callback' => 'privatemsg_filter_remove_tags',
-    'callback arguments' => array('tag_id' => variable_get('privatemsg_filter_inbox_tag', '')),
-    'success message' => t('The messages have been archived.'),
-    'undo callback' => 'privatemsg_filter_add_tags',
-    'undo callback arguments' => array('tag_id' => variable_get('privatemsg_filter_inbox_tag', '')),
-  );
-  privatemsg_operation_execute($operation, $form_state['values']['list']);
+function privatemsg_filter_privatemsg_thread_operations($type) {
+  if ($type == 'inbox') {
+    $archive = array(
+      'label' => t('Archive'),
+      'callback' => 'privatemsg_filter_remove_tags',
+      'callback arguments' => array('tag_id' => variable_get('privatemsg_filter_inbox_tag', '')),
+      'success message' => t('The messages have been archived.'),
+      'undo callback' => 'privatemsg_filter_add_tags',
+      'undo callback arguments' => array('tag_id' => variable_get('privatemsg_filter_inbox_tag', '')),
+    );
+    return array('archive' => $archive);
+  }
 }
 
 /**
@@ -655,6 +662,8 @@ function privatemsg_filter_add_tag_submi
     'undo callback arguments' => array('tag_id' => $tag_ids),
   );
   privatemsg_operation_execute($operation, $form_state['values']['list']);
+  $form_state['rebuild'] = TRUE;
+  $form_state['input'] = array();
 }
 
 /**
@@ -669,6 +678,8 @@ function privatemsg_filter_remove_tag_su
     'undo callback arguments' => array('tag_id' => $form_state['values']['tag-remove']),
   );
   privatemsg_operation_execute($operation, $form_state['values']['list']);
+  $form_state['rebuild'] = TRUE;
+  $form_state['input'] = array();
 }
 
 /**
Index: privatemsg_filter/privatemsg_filter.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/privatemsg_filter/privatemsg_filter.test,v
retrieving revision 1.1.4.16
diff -u -p -r1.1.4.16 privatemsg_filter.test
--- privatemsg_filter/privatemsg_filter.test	24 Nov 2010 20:09:44 -0000	1.1.4.16
+++ privatemsg_filter/privatemsg_filter.test	9 Dec 2010 09:52:22 -0000
@@ -100,8 +100,9 @@ class PrivatemsgFilterTestCase extends D
     // Delete all messages for author.
     $archive = array(
         'list[1]' => 1,
+        'operation' => 'archive',
     );
-    $this->drupalPost(NULL, $archive, t('Archive'));
+    $this->drupalPost(NULL, $archive, t('Execute'));
     $this->assertText(t('The messages have been archived.'), t('Confirmation message displayed'));
     $this->assertNoText($edit['subject'], t('Thread has been removed from inbox.'));
 
Index: styles/privatemsg-list.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/privatemsg/styles/privatemsg-list.css,v
retrieving revision 1.1.2.2.2.2
diff -u -p -r1.1.2.2.2.2 privatemsg-list.css
--- styles/privatemsg-list.css	9 Jul 2010 20:19:05 -0000	1.1.2.2.2.2
+++ styles/privatemsg-list.css	9 Dec 2010 09:52:22 -0000
@@ -17,3 +17,7 @@
 .privatemsg-list-date {
   min-width: 20%;
 }
+
+form#privatemsg-list div.container-inline * {
+  margin: 0 2px;
+}
