From 22e87c1a7bfc53a4e117a0f3234afbe988f3583b Wed, 16 Nov 2011 09:36:19 -0300
From: Javier Castro <javier.alejandro.castro@gmail.com>
Date: Wed, 16 Nov 2011 09:33:09 -0300
Subject: [PATCH] Fix to correctly render numeric fields with value equal to 0

diff --git a/handlers/views_handler_field.inc b/handlers/views_handler_field.inc
index 7f2d397..a0087ce 100644
--- a/handlers/views_handler_field.inc
+++ b/handlers/views_handler_field.inc
@@ -383,7 +383,7 @@
     $options['empty'] = array('default' => '', 'translatable' => TRUE);
     $options['hide_empty'] = array('default' => FALSE);
     $options['empty_zero'] = array('default' => FALSE);
-    $options['hide_alter_empty'] = array('default' => FALSE);
+    $options['hide_alter_empty'] = array('default' => TRUE);
 
     return $options;
   }
diff --git a/handlers/views_handler_field_custom.inc b/handlers/views_handler_field_custom.inc
index 93925f4..053ecc1 100644
--- a/handlers/views_handler_field_custom.inc
+++ b/handlers/views_handler_field_custom.inc
@@ -31,8 +31,8 @@
   }
 
   function render($values) {
-    // Nothing to render.
-    return '';
+    // Return the text, so the code never thinks the value is empty.
+    return $this->options['alter']['text'];
   }
 }
 
diff --git a/handlers/views_handler_field_entity.inc b/handlers/views_handler_field_entity.inc
index 7b2bf02..259a45f 100644
--- a/handlers/views_handler_field_entity.inc
+++ b/handlers/views_handler_field_entity.inc
@@ -2,6 +2,12 @@
 /**
  * A handler to display data from entity objects.
  *
+ * Fields based upon this handler work with all query-backends if the tables
+ * used by the query backend have an 'entity type' specified. In order to
+ * make fields based upon this handler automatically available to all compatible
+ * query backends, the views field can be defined in the table
+ * @code views_entity_{ENTITY_TYPE} @endcode.
+ *
  * @ingroup views_field_handlers
  */
 class views_handler_field_entity extends views_handler_field {
@@ -22,6 +28,17 @@
   public $base_field;
 
   /**
+   * Initialize the entity type.
+   */
+  public function init(&$view, &$options) {
+    parent::init($view, $options);
+
+    // Initialize the entity-type used.
+    $table_data = views_fetch_data($this->table);
+    $this->entity_type = $table_data['table']['entity type'];
+  }
+
+  /**
    * Overriden to add the field for the entity id.
    */
   function query() {
@@ -35,7 +52,7 @@
           $this->table_alias = $relationship->alias;
 
           $table_data = views_fetch_data($base_table);
-          $this->base_field = $table_data['table']['base']['field'];
+          $this->base_field = empty($relationship->definition['base field']) ? $table_data['table']['base']['field'] : $relationship->definition['base field'];
         }
       }
     }
diff --git a/includes/admin.inc b/includes/admin.inc
index d9a407e..ee7555d 100644
--- a/includes/admin.inc
+++ b/includes/admin.inc
@@ -31,9 +31,26 @@
   $themes = list_themes();
   $theme_key = $GLOBALS['theme'];
   while ($theme_key) {
-    $list[$module_path . "/css/views-admin.$theme_key.css"] = array(
-      'group' => CSS_THEME,
-    );
+    // Try to find the admin css file for non-core themes.
+    if (!in_array($theme_key, array('garland', 'seven', 'bartik'))) {
+      $theme_path = drupal_get_path('theme', $theme_key);
+      // First search in the css directory, then in the root folder of the theme.
+      if (file_exists($theme_path . "/css/views-admin.$theme_key.css")) {
+        $list[$theme_path . "/css/views-admin.$theme_key.css"] = array(
+          'group' => CSS_THEME,
+        );
+      }
+      else if (file_exists($theme_path . "/views-admin.$theme_key.css")) {
+        $list[$theme_path . "/views-admin.$theme_key.css"] = array(
+          'group' => CSS_THEME,
+        );
+      }
+    }
+    else {
+      $list[$module_path . "/css/views-admin.$theme_key.css"] = array(
+        'group' => CSS_THEME,
+      );
+    }
     $theme_key = isset($themes[$theme_key]->base_theme) ? $themes[$theme_key]->base_theme : '';
   }
   // Views contains style overrides for the following modules
@@ -902,7 +919,7 @@
   if (!in_array($display_id, array(MENU_ACCESS_DENIED, MENU_NOT_FOUND))) {
     $build = array();
     $build['edit_form'] = drupal_get_form('views_ui_edit_form', $view, $display_id);
-    $build['preview'] = views_ui_build_preview($view, $display_id);
+    $build['preview'] = views_ui_build_preview($view, $display_id, FALSE);
   }
   else {
     $build = $display_id;
@@ -911,7 +928,7 @@
   return $build;
 }
 
-function views_ui_build_preview($view, $display_id) {
+function views_ui_build_preview($view, $display_id, $render = TRUE) {
   if (isset($_POST['ajax_html_ids'])) {
     unset($_POST['ajax_html_ids']);
   }
@@ -932,7 +949,7 @@
   $build['preview'] = array(
     '#theme_wrappers' => array('container'),
     '#attributes' => array('id' => 'views-live-preview'),
-    '#markup' => views_ui_preview($view->clone_view(), $display_id, $args),
+    '#markup' => $render ? views_ui_preview($view->clone_view(), $display_id, $args) : '',
   );
 
   return $build;
@@ -1196,6 +1213,7 @@
     //   we may need to split Preview into a separate form.
     '#process' => array_merge(array('views_ui_default_button'), element_info_property('submit', '#process', array())),
   );
+  $form['#action'] = url('admin/structure/views/view/' . $view->name .'/preview/' . $display_id);
 
   return $form;
 }
@@ -2464,7 +2482,7 @@
   // Determine whether the values the user entered are intended to apply to
   // the current display or the default display.
 
-  list($was_defaulted, $is_defaulted) = views_ui_standard_override_values($form, $form_state);
+  list($was_defaulted, $is_defaulted, $revert) = views_ui_standard_override_values($form, $form_state);
 
   // Mark the changed section of the view as changed.
   // TODO: Document why we are doing this, and see if we still need it.
@@ -2474,7 +2492,16 @@
 
   // Based on the user's choice in the display dropdown, determine which display
   // these changes apply to.
-  if ($was_defaulted === $is_defaulted) {
+  if ($revert) {
+    // If it's revert just change the override and return.
+    $display = &$form_state['view']->display[$form_state['display_id']];
+    $display->handler->options_override($form, $form_state);
+
+    // Don't execute the normal submit handling but still store the changed view into cache.
+    views_ui_cache_set($form_state['view']);
+    return;
+  }
+  elseif ($was_defaulted === $is_defaulted) {
     // We're not changing which display these form values apply to.
     // Run the regular submit handler for this form.
   }
@@ -2482,6 +2509,7 @@
     // We were using the default display's values, but we're now overriding
     // the default display and saving values specific to this display.
     $display = &$form_state['view']->display[$form_state['display_id']];
+    // options_override toggles the override of this section.
     $display->handler->options_override($form, $form_state);
     $display->handler->options_submit($form, $form_state);
   }
@@ -2491,6 +2519,7 @@
     // Overwrite the default display with the current form values, and make
     // the current display use the new default values.
     $display = &$form_state['view']->display[$form_state['display_id']];
+    // options_override toggles the override of this section.
     $display->handler->options_override($form, $form_state);
     $display->handler->options_submit($form, $form_state);
   }
@@ -2502,15 +2531,16 @@
 }
 
 /**
- * Return the was_defaulted and is_defaulted state of a form.
+ * Return the was_defaulted, is_defaulted and revert state of a form.
  */
 function views_ui_standard_override_values($form, $form_state) {
   // Make sure the dropdown exists in the first place.
   if (isset($form_state['values']['override']['dropdown'])) {
     // #default_value is used to determine whether it was the default value or not.
-    // So the availible options are: $display and 'default', not 'defaults'.
-    $was_defaulted = (bool) ($form['override']['dropdown']['#default_value'] === 'defaults');
-    $is_defaulted = (bool) ($form_state['values']['override']['dropdown'] === 'default');
+    // So the available options are: $display, 'default' and 'default_revert', not 'defaults'.
+    $was_defaulted = ($form['override']['dropdown']['#default_value'] === 'defaults');
+    $is_defaulted = ($form_state['values']['override']['dropdown'] === 'default');
+    $revert = ($form_state['values']['override']['dropdown'] === 'default_revert');
 
     if ($was_defaulted !== $is_defaulted && isset($form['#section'])) {
       // We're changing which display these values apply to.
@@ -2522,9 +2552,10 @@
     // The user didn't get the dropdown for overriding the default display.
     $was_defaulted = FALSE;
     $is_defaulted = FALSE;
+    $revert = FALSE;
   }
 
-  return array($was_defaulted, $is_defaulted);
+  return array($was_defaulted, $is_defaulted, $revert);
 }
 
 /**
@@ -2564,6 +2595,7 @@
 
   // Determine whether any other displays have overrides for this section.
   $section_overrides = FALSE;
+  $section_defaulted = $current_display->handler->is_defaulted($section);
   foreach ($displays as $id => $display) {
     if ($id === 'default' || $id === $display_id) {
       continue;
@@ -2575,6 +2607,10 @@
 
   $display_dropdown['default'] = ($section_overrides ? t('All displays (except overridden)') : t('All displays'));
   $display_dropdown[$display_id] = t('This @display_type (override)', array('@display_type' => $current_display->display_plugin));
+  // Only display the revert option if we are in a overridden section.
+  if (!$section_defaulted) {
+    $display_dropdown['default_revert'] = t('Revert to default');
+  }
 
   $form['override'] = array(
     '#prefix' => '<div class="views-override clearfix container-inline">',
@@ -4136,8 +4172,9 @@
     }
 
     views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_item_form', $name, t('Remove'), 'remove');
-    // Don't execute validations for the remove button.
-    $form['buttons']['remove']['#limit_validation_errors'] = array();
+    // Only validate the override values, because this values are required for
+    // the override selection.
+    $form['buttons']['remove']['#limit_validation_errors'] = array(array('override'));
   }
 
   return $form;
@@ -4328,6 +4365,12 @@
  */
 function views_ui_config_item_form_remove($form, &$form_state) {
   // Store the item back on the view
+  list($was_defaulted, $is_defaulted) = views_ui_standard_override_values($form, $form_state);
+  // If the display selection was changed toggle the override value.
+  if ($was_defaulted != $is_defaulted) {
+    $display =& $form_state['view']->display[$form_state['display_id']];
+    $display->handler->options_override($form, $form_state);
+  }
   $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], NULL);
 
   // Write to cache
diff --git a/includes/base.inc b/includes/base.inc
index 3223fab..2f69865 100644
--- a/includes/base.inc
+++ b/includes/base.inc
@@ -265,7 +265,7 @@
    * This function run's through all suboptions recursive.
    *
    * @param $translatable
-   *   Stores all availible translatable items.
+   *   Stores all available translatable items.
    * @param $storage
    * @param $option
    * @param $definition
diff --git a/includes/cache.inc b/includes/cache.inc
index aad8784..b2fe7d8 100644
--- a/includes/cache.inc
+++ b/includes/cache.inc
@@ -32,6 +32,7 @@
         $function = $module . '_views_data_alter';
         $function($cache);
       }
+      _views_data_process_entity_types($cache);
 
       views_cache_set('views_data', $cache, TRUE);
     }
@@ -63,6 +64,27 @@
 }
 
 /**
+ * Links tables having an 'entity type' specified to the respective generic entity-type tables.
+ */
+function _views_data_process_entity_types(&$data) {
+  foreach ($data as $table_name => $table_info) {
+    // Add in a join from the entity-table if an entity-type is given.
+    if (!empty($table_info['table']['entity type'])) {
+      $entity_table = 'views_entity_' . $table_info['table']['entity type'];
+
+      $data[$entity_table]['table']['join'][$table_name] = array(
+        'left_table' => $table_name,
+      );
+      $data[$entity_table]['table']['entity type'] = $table_info['table']['entity type'];
+      // Copy over the default table group if we have none yet.
+      if (!empty($table_info['table']['group']) && empty($data[$entity_table]['table']['group'])) {
+        $data[$entity_table]['table']['group'] = $table_info['table']['group'];
+      }
+    }
+  }
+}
+
+/**
  * Fetch the plugin data from cache.
  */
 function _views_fetch_plugin_data($type = NULL, $plugin = NULL, $reset = FALSE) {
diff --git a/includes/view.inc b/includes/view.inc
index 41ed056..d982c0b 100644
--- a/includes/view.inc
+++ b/includes/view.inc
@@ -1286,6 +1286,16 @@
   }
 
   /**
+   * Override the view's current title.
+   *
+   * The tokens in the title get's replaced before rendering.
+   */
+  function set_title($title) {
+     $this->build_info['title'] = $title;
+     return TRUE;
+   }
+
+  /**
    * Return the human readable name for a view.
    *
    * When a certain view doesn't have a human readable name return the machine readable name.
diff --git a/js/views-admin.js b/js/views-admin.js
index 321f612..104239a 100644
--- a/js/views-admin.js
+++ b/js/views-admin.js
@@ -391,6 +391,11 @@
   else {
     $('#preview-args').parent().hide();
   }
+
+  // Executes an initial preview.
+  if ($('#edit-displays-live-preview').once('edit-displays-live-preview').is(':checked')) {
+    $('#preview-submit').once('edit-displays-live-preview').click();
+  }
 };
 
 
@@ -861,6 +866,9 @@
       if ($(this).val() == 'default') {
         $submit.val(Drupal.t('Apply (all displays)'));
       }
+      else if ($(this).val() == 'default_revert') {
+        $submit.val(Drupal.t('Revert to default'));
+      }
       else {
         $submit.val(Drupal.t('Apply (this display)'));
       }
diff --git a/modules/field.views.inc b/modules/field.views.inc
index 2b3f47c..7dc5cb2 100644
--- a/modules/field.views.inc
+++ b/modules/field.views.inc
@@ -33,7 +33,7 @@
     drupal_alter('field_views_data', $result, $field, $module);
 
     if (is_array($result)) {
-      $data = array_merge($data, $result);
+      $data = drupal_array_merge_deep($result, $data);
     }
   }
 
diff --git a/modules/field/views_handler_field_field.inc b/modules/field/views_handler_field_field.inc
index d12dbd9..8e2b632 100644
--- a/modules/field/views_handler_field_field.inc
+++ b/modules/field/views_handler_field_field.inc
@@ -683,7 +683,7 @@
     }
 
     // The field we are trying to display doesn't exist on this entity.
-    if (empty($entity->{$this->definition['field_name']})) {
+    if (!isset($entity->{$this->definition['field_name']})) {
       return array();
     }
 
@@ -737,7 +737,7 @@
       return $entity;
     }
     else {
-      return $entity->{$this->definition['field_name']}[$langcode];
+      return !empty($entity->{$this->definition['field_name']}[$langcode]) ? $entity->{$this->definition['field_name']}[$langcode] : array();
     }
   }
 
diff --git a/modules/node.views.inc b/modules/node.views.inc
index 2518b91..8b79ccb 100644
--- a/modules/node.views.inc
+++ b/modules/node.views.inc
@@ -20,7 +20,7 @@
 
   // Define the base group of this table. Fields that don't
   // have a group defined will go into this field by default.
-  $data['node']['table']['group']  = t('Content');
+  $data['node']['table']['group'] = t('Content');
 
   // Advertise this table as a possible base table
   $data['node']['table']['base'] = array(
@@ -235,9 +235,12 @@
     ),
   );
 
-  // links to operate on the node
+  // Define some fields based upon views_handler_field_entity in the entity
+  // table so they can be re-used with other query backends.
+  // @see views_handler_field_entity
 
-  $data['node']['view_node'] = array(
+  $data['node']['view_node']['moved to'] = array('views_entity_node', 'view_node');
+  $data['views_entity_node']['view_node'] = array(
     'field' => array(
       'title' => t('Link'),
       'help' => t('Provide a simple link to the content.'),
@@ -245,7 +248,8 @@
     ),
   );
 
-  $data['node']['edit_node'] = array(
+  $data['node']['edit_node']['moved to'] = array('views_entity_node', 'edit_node');
+  $data['views_entity_node']['edit_node'] = array(
     'field' => array(
       'title' => t('Edit link'),
       'help' => t('Provide a simple link to edit the content.'),
@@ -253,7 +257,8 @@
     ),
   );
 
-  $data['node']['delete_node'] = array(
+  $data['node']['delete_node']['moved to'] = array('views_entity_node', 'delete_node');
+  $data['views_entity_node']['delete_node'] = array(
     'field' => array(
       'title' => t('Delete link'),
       'help' => t('Provide a simple link to delete the content.'),
diff --git a/modules/user/views_handler_field_user_picture.inc b/modules/user/views_handler_field_user_picture.inc
index 0b447ca..a603f4e 100644
--- a/modules/user/views_handler_field_user_picture.inc
+++ b/modules/user/views_handler_field_user_picture.inc
@@ -22,6 +22,7 @@
   function option_definition() {
     $options = parent::option_definition();
     $options['link_photo_to_profile'] = array('default' => TRUE);
+    $options['image_style'] = array('default' => '');
     return $options;
   }
 
@@ -33,20 +34,60 @@
       '#type' => 'checkbox',
       '#default_value' => $this->options['link_photo_to_profile'],
     );
+
+    if (module_exists('image')) {
+      $styles = image_styles();
+      $style_options = array('' => t('Default'));
+      foreach ($styles as $style) {
+        $style_options[$style['name']] = $style['name'];
+      }
+
+      $form['image_style'] = array(
+        '#title' => t('Image style'),
+        '#description' => t('Using <em>Default</em> will use the site-wide image style for user pictures set in the <a href="!account-settings">Account settings</a>.', array('!account-settings' => url('admin/config/people/accounts', array('fragment' => 'edit-personalization')))),
+        '#type' => 'select',
+        '#options' => $style_options,
+        '#default_value' => $this->options['image_style'],
+      );
+    }
   }
 
   function render($values) {
-    // Fake an account object.
-    $account = new stdClass();
-    if ($this->options['link_photo_to_profile']) {
-      // Prevent template_preprocess_user_picture from adding a link
-      // by not setting the uid.
-      $account->uid = $this->get_value($values, 'uid');
+    if ($this->options['image_style'] && module_exists('image')) {
+      // @todo: Switch to always using theme('user_picture') when it starts
+      // supporting image styles. See http://drupal.org/node/1021564
+      if ($picture_fid = $this->get_value($values)) {
+        $picture = file_load($picture_fid);
+        $picture_filepath = $picture->uri;
+      }
+      else {
+        $picture_filepath = variable_get('user_picture_default', '');
+      }
+      if (file_valid_uri($picture_filepath)) {
+        $output = theme('image_style', array('style_name' => $this->options['image_style'], 'path' => $picture_filepath));
+        if ($this->options['link_photo_to_profile'] && user_access('access user profiles')) {
+          $uid = $this->get_value($values, 'uid');
+          $output = l($output, "user/$uid", array('html' => TRUE));
+        }
+      }
+      else {
+        $output = '';
+      }
     }
-    $account->name = $this->get_value($values, 'name');
-    $account->mail = $this->get_value($values, 'mail');
-    $account->picture = $this->get_value($values);
+    else {
+      // Fake an account object.
+      $account = new stdClass();
+      if ($this->options['link_photo_to_profile']) {
+        // Prevent template_preprocess_user_picture from adding a link
+        // by not setting the uid.
+        $account->uid = $this->get_value($values, 'uid');
+      }
+      $account->name = $this->get_value($values, 'name');
+      $account->mail = $this->get_value($values, 'mail');
+      $account->picture = $this->get_value($values);
+      $output = theme('user_picture', array('account' => $account));
+    }
 
-    return theme('user_picture', array('account' => $account));
+    return $output;
   }
 }
diff --git a/plugins/views_plugin_display.inc b/plugins/views_plugin_display.inc
index f36323d..5d55d84 100644
--- a/plugins/views_plugin_display.inc
+++ b/plugins/views_plugin_display.inc
@@ -34,7 +34,7 @@
   var $handlers = array();
 
   /**
-   * Stores all availible display extenders.
+   * Stores all available display extenders.
    */
   var $extender = array();
 
@@ -342,7 +342,7 @@
       'group_by' => array('group_by'),
       'query' => array('query'),
       'use_more' => array('use_more', 'use_more_always', 'use_more_text'),
-      'link_display' => array('link_display'),
+      'link_display' => array('link_display', 'link_url'),
 
       // Force these to cascade properly.
       'style_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
@@ -409,6 +409,7 @@
           'exposed_form_options' => TRUE,
 
           'link_display' => TRUE,
+          'link_url' => '',
           'group_by' => TRUE,
 
           'style_plugin' => TRUE,
@@ -485,6 +486,9 @@
         'translatable' => TRUE,
       ),
       'link_display' => array(
+        'default' => '',
+      ),
+      'link_url' => array(
         'default' => '',
       ),
       'group_by' => array(
@@ -950,6 +954,33 @@
   }
 
   /**
+   * Returns to tokens for arguments.
+   *
+   * This function is similar to views_handler_field::get_render_tokens()
+   * but without fields tokens.
+   */
+  function get_arguments_tokens() {
+    $tokens = array();
+    if (!empty($this->view->build_info['substitutions'])) {
+      $tokens = $this->view->build_info['substitutions'];
+    }
+    $count = 0;
+    foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
+      $token = '%' . ++$count;
+      if (!isset($tokens[$token])) {
+        $tokens[$token] = '';
+      }
+
+      // Use strip tags as there should never be HTML in the path.
+      // However, we need to preserve special characters like " that
+      // were removed by check_plain().
+      $tokens['!' . $count] = isset($this->view->args[$count - 1]) ? strip_tags(html_entity_decode($this->view->args[$count - 1])) : '';
+    }
+
+    return $tokens;
+  }
+
+  /**
    * Provide the default summary for options in the views UI.
    *
    * This output is returned as an array.
@@ -1195,27 +1226,15 @@
     }
 
     if ($this->uses_link_display()) {
-      // Only show the 'link display' if there is more than one option.
-      $count = 0;
-      foreach ($this->view->display as $display_id => $display) {
-        if (is_object($display->handler) && $display->handler->has_path()) {
-          $count++;
-        }
-        if ($count > 1) {
-          break;
-        }
-      }
-
-      if ($count > 1) {
-        $display_id = $this->get_link_display();
-        $link_display = empty($this->view->display[$display_id]) ? t('None') : check_plain($this->view->display[$display_id]->display_title);
-        $options['link_display'] = array(
-          'category' => 'other',
-          'title' => t('Link display'),
-          'value' => $link_display,
-          'desc' => t('Specify which display this display will link to.'),
-        );
-      }
+      $display_id = $this->get_link_display();
+      $link_display = empty($this->view->display[$display_id]) ? t('None') : check_plain($this->view->display[$display_id]->display_title);
+      $link_display =  $this->get_option('link_display') == 'custom_url' ? t('Custom URL') : $link_display;
+      $options['link_display'] = array(
+        'category' => 'other',
+        'title' => t('Link display'),
+        'value' => $link_display,
+        'desc' => t('Specify which display or custom url this display will link to.'),
+      );
     }
 
     if ($this->uses_exposed_form_in_block()) {
@@ -1365,7 +1384,7 @@
         $form['use_more'] = array(
           '#type' => 'checkbox',
           '#title' => t('Create more link'),
-          '#description' => t("This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' above."),
+          '#description' => t("This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' above. You can override the url at the link display setting."),
           '#default_value' => $this->get_option('use_more'),
         );
         $form['use_more_always'] = array(
@@ -1621,11 +1640,48 @@
             $options[$display_id] = $display->display_title;
           }
         }
-        $form['link_display'] = array(
-          '#type' => 'radios',
-          '#options' => $options,
-          '#description' => t("Which display to use to get this display's path for things like summary links, rss feed links, more links, etc."),
-          '#default_value' => $this->get_link_display(),
+        $options['custom_url'] = t('Custom URL');
+        if (count($options)) {
+          $form['link_display'] = array(
+            '#type' => 'radios',
+            '#options' => $options,
+            '#description' => t("Which display to use to get this display's path for things like summary links, rss feed links, more links, etc."),
+            '#default_value' => $this->get_option('link_display'),
+          );
+        }
+
+        $options = array();
+        $count = 0; // This lets us prepare the key as we want it printed.
+        foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
+          $options[t('Arguments')]['%' . ++$count] = t('@argument title', array('@argument' => $handler->ui_name()));
+          $options[t('Arguments')]['!' . $count] = t('@argument input', array('@argument' => $handler->ui_name()));
+        }
+
+        // Default text.
+        // We have some options, so make a list.
+        if (!empty($options)) {
+          $output = t('<p>The following tokens are available for this link.</p>');
+          foreach (array_keys($options) as $type) {
+            if (!empty($options[$type])) {
+              $items = array();
+              foreach ($options[$type] as $key => $value) {
+                $items[] = $key . ' == ' . $value;
+              }
+              $output .= theme('item_list',
+                array(
+                  'items' => $items,
+                  'type' => $type
+                ));
+            }
+          }
+        }
+
+        $form['link_url'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Custom URL'),
+          '#default_value' => $this->get_option('link_url'),
+          '#description' => t('A Drupal path or external URL the more link will point to. Note that this will override the link display setting above.') . $output,
+          '#dependency' => array('radio:link_display' => array('custom_url')),
         );
         break;
       case 'analyze-theme':
@@ -2163,6 +2219,7 @@
       case 'link_display':
       case 'display_comment':
         $this->set_option($section, $form_state['values'][$section]);
+        $this->set_option('link_url', $form_state['values']['link_url']);
         break;
       case 'field_language':
         $this->set_option('field_language', $form_state['values']['field_language']);
@@ -2347,8 +2404,16 @@
   function render_more_link() {
     if ($this->use_more() && ($this->use_more_always() || (!empty($this->view->query->pager) && $this->view->query->pager->has_more_records()))) {
       $path = $this->get_path();
+
+      if ($this->get_option('link_display') == 'custom_url' && $override_path = $this->get_option('link_url')) {
+        $tokens = $this->get_arguments_tokens();
+        $path = strtr($override_path, $tokens);
+      }
+
       if ($path) {
-        $path = $this->view->get_url(NULL, $path);
+        if (empty($override_path)) {
+          $path = $this->view->get_url(NULL, $path);
+        }
         $url_options = array();
         if (!empty($this->view->exposed_raw_input)) {
           $url_options['query'] = $this->view->exposed_raw_input;
diff --git a/plugins/views_plugin_style.inc b/plugins/views_plugin_style.inc
index f8d6515..084e65d 100644
--- a/plugins/views_plugin_style.inc
+++ b/plugins/views_plugin_style.inc
@@ -19,7 +19,7 @@
  */
 class views_plugin_style extends views_plugin {
   /**
-   * Store all availible tokens row rows.
+   * Store all available tokens row rows.
    */
   var $row_tokens = array();
   /**
diff --git a/plugins/views_plugin_style_jump_menu.inc b/plugins/views_plugin_style_jump_menu.inc
index 1da3116..dd9e3cd 100644
--- a/plugins/views_plugin_style_jump_menu.inc
+++ b/plugins/views_plugin_style_jump_menu.inc
@@ -119,7 +119,7 @@
         else {
           $options[$key] = $field;
         }
-        $paths[$path] = $path;
+        $paths[$path] = $key;
         $this->view->row_index++;
       }
     }
@@ -127,7 +127,7 @@
 
     $default_value = '';
     if ($this->options['default_value'] && !empty($paths[url($_GET['q'])])) {
-      $default_value = url($_GET['q']);
+      $default_value = $paths[url($_GET['q'])];
     }
 
     ctools_include('jump-menu');
diff --git a/plugins/views_wizard/views_ui_base_views_wizard.class.php b/plugins/views_wizard/views_ui_base_views_wizard.class.php
index 01cbed6..c314bef 100644
--- a/plugins/views_wizard/views_ui_base_views_wizard.class.php
+++ b/plugins/views_wizard/views_ui_base_views_wizard.class.php
@@ -442,7 +442,7 @@
       $sorts += $this->plugin['available_sorts'];
     }
 
-    // If there is no sorts option availible continue.
+    // If there is no sorts option available continue.
     if (!empty($sorts)) {
       $form['displays']['show']['sort'] = array(
         '#type' => 'select',
diff --git a/tests/views_ui.test b/tests/views_ui.test
index 32f8074..003eb85 100644
--- a/tests/views_ui.test
+++ b/tests/views_ui.test
@@ -905,4 +905,31 @@
     $this->assertText($new_block_title);
     $this->assertNoText($view['block[title]']);
   }
+
+  /**
+   * Tests that the revert to all displays select-option works as expected.
+   */
+  function testRevertAllDisplays() {
+    // Create a basic view with a page, block.
+    // Because there is both a title on page and block we expect the title on
+    // the block be overriden.
+    $view['human_name'] = $this->randomName(16);
+    $view['name'] = strtolower($this->randomName(16));
+    $view['page[create]'] = 1;
+    $view['page[title]'] = $this->randomName(16);
+    $view['page[path]'] = $this->randomName(16);
+    $view['block[create]'] = 1;
+    $view['block[title]'] = $this->randomName(16);
+    $this->drupalPost('admin/structure/views/add', $view, t('Continue & edit'));
+
+    // Revert the title of the block back to the default ones, but submit some
+    // new values to be sure that the new value is not stored.
+    $edit = array();
+    $edit['title'] = $new_block_title = $this->randomName();
+    $edit['override[dropdown]'] = 'default_revert';
+
+    $this->drupalPost("admin/structure/views/nojs/display/{$view['name']}/block/title", $edit, t('Apply'));
+    $this->drupalPost("admin/structure/views/view/{$view['name']}/edit/block", array(), t('Save'));
+    $this->assertText($view['page[title]']);
+  }
 }
diff --git a/theme/theme.inc b/theme/theme.inc
index 3958b97..7b8f376 100644
--- a/theme/theme.inc
+++ b/theme/theme.inc
@@ -552,7 +552,7 @@
         }
 
         // Don't bother with separators and stuff if the field does not show up.
-        if (empty($field_output) && !empty($vars['rows'][$num][$column])) {
+        if (empty($field_output) && $renders[$num][$field] !== '0' && !empty($vars['rows'][$num][$column])) {
           continue;
         }
 
diff --git a/views.install b/views.install
index 64e2de7..7389639 100644
--- a/views.install
+++ b/views.install
@@ -593,3 +593,19 @@
     menu_rebuild();
   }
 }
+
+function views_schema_7300() {
+  return views_schema_6013();
+}
+/**
+ * Make sure the human_name field is added to the views_view table.
+ *
+ * If you updated from 6.x-2.x-dev to 7.x-3.x you had already schema
+ * version 6014, so the update 6013 isn't runned, and never was.
+ * As a result the human_name field is missing in the database.
+ *
+ * Add the human_name field if it doesn't exists before.
+ */
+function views_update_7300() {
+  views_update_6013();
+}
diff --git a/views_ui.module b/views_ui.module
index ce39c0d..a4480a9 100644
--- a/views_ui.module
+++ b/views_ui.module
@@ -89,6 +89,12 @@
     'theme callback' => 'ajax_base_page_theme',
     'type' => MENU_CALLBACK,
   ) + $base;
+  $items['admin/structure/views/view/%views_ui_cache/preview/%'] = array(
+    'page callback' => 'views_ui_build_preview',
+    'page arguments' => array(4, 6),
+    'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+  ) + $base;
   $items['admin/structure/views/view/%views_ui_cache/preview/%/ajax'] = array(
     'page callback' => 'views_ui_build_preview',
     'page arguments' => array(4, 6),