? tests
? views_diff.patch
? css/views-rtl.css
? handlers/views_handler_area.inc
? handlers/views_handler_area_text.inc
? handlers/views_handler_argument_group_by_numeric.inc
? handlers/views_handler_field_group_by_numeric.inc
? handlers/views_handler_field_math.inc
? handlers/views_handler_filter_group_by_numeric.inc
? handlers/views_handler_sort_group_by_numeric.inc
? help/api-example.html
? images/expanded-options.png
? modules/aggregator/views_handler_field_aggregator_item_description.inc
? modules/node/views_handler_field_node_path.inc
? modules/node/views_handler_field_node_revision.inc
? modules/search/views_handler_argument_search.inc
? modules/taxonomy/views_handler_field_term_link_edit.inc
? modules/taxonomy/views_handler_relationship_node_term_data.inc
? modules/taxonomy/views_plugin_argument_default_taxonomy_tid.inc
? modules/translation/views_handler_field_node_link_translate.inc
? plugins/views_plugin_argument_default_fixed.inc
? plugins/views_plugin_exposed_form.inc
? plugins/views_plugin_exposed_form_basic.inc
? plugins/views_plugin_exposed_form_input_required.inc
? plugins/views_plugin_pager.inc
? plugins/views_plugin_pager_full.inc
? plugins/views_plugin_pager_mini.inc
? plugins/views_plugin_pager_none.inc
? plugins/views_plugin_pager_some.inc
? plugins/views_plugin_query.inc
? plugins/views_plugin_query_default.inc
? plugins/views_plugin_style_jump_menu.inc
? plugins/views_plugin_style_summary_jump_menu.inc
Index: views.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/views.install,v
retrieving revision 1.49
diff -u -p -r1.49 views.install
--- views.install	2 Jun 2009 20:30:59 -0000	1.49
+++ views.install	11 Aug 2010 21:11:31 -0000
@@ -1,32 +1,100 @@
 <?php
-// $Id: views.install,v 1.49 2009/06/02 20:30:59 merlinofchaos Exp $
+// $Id: views.install,v 1.46.2.12 2010/07/27 22:26:24 merlinofchaos Exp $
 /**
  * @file views.install
  * Contains install and update functions for Views.
  */
 
+/**
+ * Implementation of hook_install().
+ */
 function views_install() {
+  if ($GLOBALS['db_type'] == 'pgsql') {
+    db_query('CREATE OR REPLACE FUNCTION first(anyelement, anyelement) RETURNS anyelement AS \'SELECT COALESCE($1, $2);\' LANGUAGE \'sql\';');
+    db_query("DROP AGGREGATE IF EXISTS first(anyelement)");
+    db_query("CREATE AGGREGATE first(sfunc = first, basetype = anyelement, stype = anyelement);");
+  }
   drupal_install_schema('views');
   db_query("UPDATE {system} SET weight = 10 WHERE name = 'views'");
 }
 
+/**
+ * Implementation of hook_uninstall().
+ */
 function views_uninstall() {
   drupal_uninstall_schema('views');
 }
 
 /**
- * Implementation of hook_schemea
+ * Implementation of hook_schema().
+ *
+ * Generate the current version of the database schema from
+ * the sequence of schema update functions. Uses a similar
+ * method to install.inc's drupal_get_schema_versions() to
+ * establish the update sequence.
+ *
+ * To change the schema, add a new views_schema_N()
+ * function to match the associated views_update_N()
+ *
+ * @param $caller_function
+ *   The name of the function that called us.
+ *   Used internally, if requesting a specific schema version.
  */
-function views_schema() {
-  // Currently, schema 1 is the only schema we have. As we make updates,
-  // we might either create a new schema 2 or make adjustments here.
-  return views_schema_1();
+function views_schema($caller_function = FALSE) {
+  static $get_current;
+  static $schemas = array();
+
+  // If called with no arguments, get the latest version of the schema.
+  if (!isset($get_current)) {
+    $get_current = $caller_function ? FALSE : TRUE;
+  }
+
+  // Generate a sorted list of available schema update functions.
+  if ($get_current || empty($schemas)) {
+    $get_current = FALSE;
+    $functions = get_defined_functions();
+    foreach ($functions['user'] as $function) {
+      if (strpos($function, 'views_schema_') === 0) {
+        $version = substr($function, strlen('views_schema_'));
+        if (is_numeric($version)) {
+          $schemas[] = $version;
+        }
+      }
+    }
+    if ($schemas) {
+      sort($schemas, SORT_NUMERIC);
+
+      // If a specific version was requested, drop any later
+      // updates from the sequence.
+      if ($caller_function) {
+        do {
+          $schema = array_pop($schemas);
+        } while ($schemas && $caller_function != 'views_schema_'. $schema);
+      }
+    }
+  }
+
+  // Call views_schema_<n>, for the highest available <n>.
+  if ($schema = array_pop($schemas)) {
+    $function = 'views_schema_'. $schema;
+    return $function();
+  }
+
+  return array();
 }
 
 /**
- * Views 2's initial schema; separated for the purposes of updates.
+ * Views 2's initial schema.
+ * Called directly by views_update_6000() for updates from Drupal 5.
+ *
+ * Important: Do not edit this schema!
+ *
+ * Updates to the views schema must be provided as views_schema_6xxx() functions,
+ * which views_schema() automatically sees and applies. See below for examples.
+ *
+ * Please do document updates with comments in this function, however.
  */
-function views_schema_1() {
+function views_schema_6000() {
   $schema['views_view'] = array(
     'description' => 'Stores the general data for a view.',
     'fields' => array(
@@ -62,7 +130,7 @@ function views_schema_1() {
       ),
       'base_table' => array(
         'type' => 'varchar',
-        'length' => '64',
+        'length' => '32', // Updated to '64' in views_schema_6005()
         'default' => '',
         'not null' => TRUE,
         'description' => 'What table this view is based on, such as node, user, comment, or term.',
@@ -75,7 +143,7 @@ function views_schema_1() {
       ),
     ),
     'primary key' => array('vid'),
-    'unique keys' => array('name' => array('name')),
+    'unique key' => array('name' => array('name')), // Updated to 'unique keys' in views_schema_6003()
   );
 
   $schema['views_display'] = array(
@@ -116,21 +184,18 @@ function views_schema_1() {
         'description' => 'The order in which this display is loaded.',
       ),
       'display_options' => array(
+        // Type corrected in update 6009
         'type' => 'blob',
         'description' => 'A serialized array of options for this display; it contains options that are generally only pertinent to that display plugin type.',
         'serialize' => TRUE,
         'serialized default' => 'a:0:{}',
       ),
     ),
+    // Added primary keys in views_schema_6008()
     'indexes' => array('vid' => array('vid', 'position')),
   );
 
   $schema['cache_views'] = drupal_get_schema_unprocessed('system', 'cache');
-  
-  $schema['cache_views_data'] = drupal_get_schema_unprocessed('system', 'cache');
-  $schema['cache_views_data']['description'] = 'Cache table for views to store pre-rendered queries, results, and display output.';
-  $schema['cache_views_data']['fields']['serialized']['default'] = 1;
-
 
   $schema['views_object_cache'] = array(
     'description' => 'A special cache used to store objects that are being edited; it serves to save state in an ordinarily stateless environment.',
@@ -158,8 +223,7 @@ function views_schema_1() {
         'description' => 'The time this cache was created or updated.',
       ),
       'data' => array(
-        'type' => 'text',
-        'size' => 'big',
+        'type' => 'blob', // Updated to 'text' (with size => 'big') in views_schema_6004()
         'description' => 'Serialized data being stored.',
         'serialize' => TRUE,
       ),
@@ -169,6 +233,9 @@ function views_schema_1() {
       'updated' => array('updated'),
     ),
   );
+
+  // $schema['cache_views_data'] added in views_schema_6006()
+
   return $schema;
 }
 
@@ -189,9 +256,9 @@ function views_update_6000() {
   }
 
   // This is mostly the same as drupal_install_schema, but it forces
-  // views_schema_1 rather than the default schema. This will be important
-  // if we have table updates.
-  $schema = views_schema_1();
+  // views_schema_6000() rather than the default views_schema().
+  // This is important for processing subsequent table updates.
+  $schema = views_schema_6000();
   _drupal_initialize_schema('views', $schema);
 
   foreach ($schema as $name => $table) {
@@ -200,6 +267,9 @@ function views_update_6000() {
   return $ret;
 }
 
+/**
+ * Remove '$' symbol in special blocks, as it is invalid for theming.
+ */
 function views_update_6001() {
   $ret = array();
   $result = db_query("SELECT * FROM {blocks} WHERE module = 'views' AND delta LIKE '\$exp%'");
@@ -207,20 +277,33 @@ function views_update_6001() {
     $new = strtr($block->delta, '$', '-');
     $ret[] = update_sql("UPDATE {blocks} SET delta = '" . db_escape_string($new) . "' WHERE module = 'views' AND delta = '" . db_escape_string($block->delta) . "'");
   }
-  $ret[] = update_sql("UPDATE {blocks} SET delta = CONCAT(delta, '-block_1') WHERE module = 'views'");
+  $result = db_query("SELECT * FROM {blocks} WHERE module = 'views'");
+  while ($block = db_fetch_object($result)) {
+    $new = $block->delta .= '-block_1';
+    if (strlen($new) >= 32) {
+      $new = md5($new);
+    }
+    $ret[] = update_sql("UPDATE {blocks} SET delta = '$new' WHERE bid = $block->bid");
+  }
 
   return $ret;
 }
 
 // NOTE: Update 6002 removed because it did not always work.
+// Update 6004 implements the change correctly.
+
 /**
  * Add missing unique key.
  */
+function views_schema_6003() {
+  $schema = views_schema(__FUNCTION__);
+  $schema['views_view']['unique keys'] = array('name' => array('name'));
+  unset($schema['views_view']['unique key']);
+  return $schema;
+}
 function views_update_6003() {
   $ret = array();
-
   db_add_unique_key($ret, 'views_view', 'name', array('name'));
-
   return $ret;
 }
 
@@ -228,6 +311,12 @@ function views_update_6003() {
  * Enlarge the views_object_cache.data column to prevent truncation and JS
  * errors.
  */
+function views_schema_6004() {
+  $schema = views_schema(__FUNCTION__);
+  $schema['views_object_cache']['fields']['data']['type'] = 'text';
+  $schema['views_object_cache']['fields']['data']['size'] = 'big';
+  return $schema;
+}
 function views_update_6004() {
   $ret = array();
 
@@ -249,9 +338,14 @@ function views_update_6004() {
 /**
  * Enlarge the base_table column
  */
+function views_schema_6005() {
+  $schema = views_schema(__FUNCTION__);
+  $schema['views_view']['fields']['base_table']['length'] = 64;
+  return $schema;
+}
 function views_update_6005() {
   $ret = array();
-  
+
   $new_field = array(
     'type' => 'varchar',
     'length' => '64',
@@ -266,9 +360,16 @@ function views_update_6005() {
 /**
  * Add the cache_views_data table to support standard caching.
  */
+function views_schema_6006() {
+  $schema = views_schema(__FUNCTION__);
+  $schema['cache_views_data'] = drupal_get_schema_unprocessed('system', 'cache');
+  $schema['cache_views_data']['description'] = 'Cache table for views to store pre-rendered queries, results, and display output.';
+  $schema['cache_views_data']['fields']['serialized']['default'] = 1;
+  return $schema;
+}
 function views_update_6006() {
   $ret = array();
-  
+
   $table = drupal_get_schema_unprocessed('system', 'cache');
   $table['description'] = 'Cache table for views to store pre-rendered queries, results, and display output.';
   $table['fields']['serialized']['default'] = 1;
@@ -277,3 +378,79 @@ function views_update_6006() {
 
   return $ret;
 }
+
+/**
+ * Add aggregate function to PostgreSQL so GROUP BY can be used to force only
+ * one result to be returned for each item.
+ */
+function views_update_6007() {
+  $ret = array();
+  if ($GLOBALS['db_type'] == 'pgsql') {
+    $ret[] = update_sql('CREATE OR REPLACE FUNCTION first(anyelement, anyelement) RETURNS anyelement AS \'SELECT COALESCE($1, $2);\' LANGUAGE \'sql\';');
+    $ret[] = update_sql("DROP AGGREGATE IF EXISTS first(anyelement)");
+    $ret[] = update_sql("CREATE AGGREGATE first(sfunc = first, basetype = anyelement, stype = anyelement);");
+  }
+  return $ret;
+}
+
+/**
+ * Add the primary key to views_display table.
+ */
+function views_schema_6008() {
+  $schema = views_schema(__FUNCTION__);
+  $schema['views_display']['primary key'] = array('vid', 'id');
+  return $schema;
+}
+
+/**
+ * Add the primary key to the views_display table.
+ */
+function views_update_6008() {
+  $ret = array();
+
+  db_add_primary_key($ret, 'views_display', array('vid', 'id'));
+
+  return $ret;
+}
+
+/**
+ * Enlarge the views_display.display_options field to accomodate a larger set
+ * of configurations (e. g. fields, filters, etc.) on a display.
+ */
+function views_schema_6009() {
+  $schema = views_schema(__FUNCTION__);
+  $schema['views_display']['fields']['display_options'] = array(
+    'type' => 'text',
+    'size' => 'big',
+    'description' => 'A serialized array of options for this display; it contains options that are generally only pertinent to that display plugin type.',
+    'serialize' => TRUE,
+    'serialized default' => 'a:0:{}',
+  );
+  return $schema;
+}
+
+function views_update_6009() {
+  $ret = array();
+
+  $schema = views_schema_6009();
+
+  if ($GLOBALS['db_type'] == 'pgsql') {
+    $ret[] = update_sql('ALTER TABLE {views_display} RENAME "display_options" TO "display_options_old"');
+    db_add_field($ret, 'views_display', 'display_options', $schema['views_display']['fields']['display_options']);
+
+    $sql = "SELECT vid, id, display_options_old FROM {views_display}";
+    $result = db_query($sql);
+    while ($row = db_fetch_array($result)) {
+      $row['display_options_old'] = db_decode_blob($row['display_options_old']);
+      $sql = "UPDATE {views_display} SET display_options = '%s' WHERE vid = %d AND id = '%s'";
+      db_query($sql, $row['display_options_old'], $row['vid'], $row['id']);
+    }
+
+    db_drop_field($ret, 'views_display', 'display_options_old');
+  }
+  else {
+    db_change_field($ret, 'views_display', 'display_options', 'display_options', $schema['views_display']['fields']['display_options']);
+  }
+
+  return $ret;
+}
Index: views.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/views.module,v
retrieving revision 1.338
diff -u -p -r1.338 views.module
--- views.module	3 Jun 2009 00:01:00 -0000	1.338
+++ views.module	11 Aug 2010 21:11:31 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views.module,v 1.338 2009/06/03 00:01:00 merlinofchaos Exp $
+// $Id: views.module,v 1.332.2.29 2010/04/29 18:26:02 merlinofchaos Exp $
 /**
  * @file
  * Primarily Drupal hooks and global API functions to manipulate views.
@@ -13,7 +13,21 @@
  * Advertise the current views api version
  */
 function views_api_version() {
-  return 2.0;
+  return '3.0-alpha1';
+}
+
+/**
+ * Views will not load plugins advertising a version older than this.
+ */
+function views_api_minimum_version() {
+  return '2';
+}
+
+/**
+ * Implementation of hook_init().
+ */
+function views_init() {
+  drupal_add_css(drupal_get_path('module', 'views') . '/css/views.css');
 }
 
 /**
@@ -157,8 +171,7 @@ function views_menu() {
   $items['views/ajax'] = array(
     'title' => 'Views',
     'page callback' => 'views_ajax',
-    'access callback' => 'user_access',
-    'access arguments' => array('access content'),
+    'access callback' => TRUE,
     'description' => 'Ajax callback for view loading.',
     'file' => 'includes/ajax.inc',
     'type' => MENU_CALLBACK,
@@ -183,7 +196,7 @@ function views_menu_alter(&$callbacks) {
   $views = views_get_applicable_views('uses hook menu');
   foreach ($views as $data) {
     list($view, $display_id) = $data;
-    $result = $view->execute_hook_menu($display_id);
+    $result = $view->execute_hook_menu($display_id, $callbacks);
     if (is_array($result)) {
       // The menu system doesn't support having two otherwise
       // identical paths with different placeholders.  So we
@@ -343,7 +356,11 @@ function views_block($op = 'list', $delt
         }
       }
 
-      variable_set('views_block_hashes', $hashes);
+      // Only save hashes if they have changed.
+      $old_hashes = variable_get('views_block_hashes', array());
+      if ($hashes != $old_hashes) {
+        variable_set('views_block_hashes', $hashes);
+      }
       // Save memory: Destroy those views.
       foreach ($views as $view) {
         $view->destroy();
@@ -351,7 +368,6 @@ function views_block($op = 'list', $delt
 
       return $items;
     case 'view':
-      $start = views_microtime();
       // if this is 32, this should be an md5 hash.
       if (strlen($delta) == 32) {
         $hashes = variable_get('views_block_hashes', array());
@@ -383,7 +399,6 @@ function views_block($op = 'list', $delt
       if ($view = views_get_view($name)) {
         if ($view->access($display_id)) {
           $output = $view->execute_display($display_id);
-          vpr("Block $view->name execute time: " . (views_microtime() - $start) * 1000 . "ms");
           $view->destroy();
           return $output;
         }
@@ -408,6 +423,16 @@ function views_invalidate_cache() {
 }
 
 /**
+ * Access callback to determine if the user can import Views.
+ *
+ * View imports require an additional access check because they are PHP
+ * code and PHP is more locked down than administer views.
+ */
+function views_import_access() {
+  return user_access('administer views') && user_access('use PHP for block visibility');
+}
+
+/**
  * Determine if the logged in user has access to a view.
  *
  * This function should only be called from a menu hook or some other
@@ -417,10 +442,6 @@ function views_invalidate_cache() {
  * is accessible, then the view is accessible.
  */
 function views_access() {
-  if (user_access('access all views')) {
-    return TRUE;
-  }
-
   $args = func_get_args();
   foreach ($args as $arg) {
     if ($arg === TRUE) {
@@ -441,17 +462,29 @@ function views_access() {
 }
 
 /**
- * Access callback to determine if the logged in user has any of the
- * requested roles.
+ * Access callback for the views_plugin_access_perm access plugin.
  *
- * This must be in views.module as it is called by menu access callback
- * and can be called often.
+ * Determine if the specified user has access to a view on the basis of
+ * permissions. If the $account argument is omitted, the current user
+ * is used.
  */
-function views_check_roles($rids) {
+function views_check_perm($perm, $account = NULL) {
+  return user_access($perm, $account) || user_access('access all views', $account);
+}
+
+/**
+ * Access callback for the views_plugin_access_role access plugin.
+
+ * Determine if the specified user has access to a view on the basis of any of
+ * the requested roles. If the $account argument is omitted, the current user
+ * is used.
+ */
+function views_check_roles($rids, $account = NULL) {
   global $user;
-  $roles = array_keys($user->roles);
-  $roles[] = $user->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID;
-  return array_intersect(array_filter($rids), $roles);
+  $account = isset($account) ? $account : $user;
+  $roles = array_keys($account->roles);
+  $roles[] = $account->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID;
+  return user_access('access all views', $account) || array_intersect(array_filter($rids), $roles);
 }
 // ------------------------------------------------------------------
 // Functions to help identify views that are running or ran
@@ -536,7 +569,8 @@ function views_get_module_apis() {
     foreach (module_implements('views_api') as $module) {
       $function = $module . '_views_api';
       $info = $function();
-      if (isset($info['api']) && $info['api'] == 2.000) {
+      if (version_compare($info['api'], views_api_minimum_version(), '>=') &&
+          version_compare($info['api'], views_api_version(), '<=')) {
         if (!isset($info['path'])) {
           $info['path'] = drupal_get_path('module', $module);
         }
@@ -625,19 +659,35 @@ function views_include_default_views() {
  *   The name of the field this handler is from.
  * @param $key
  *   The type of handler. i.e, sort, field, argument, filter, relationship
+ * @param $override
+ *   Override the actual handler object with this class. Used for
+ *   aggregation when the handler is redirected to the aggregation
+ *   handler.
  *
  * @return
  *   An instance of a handler object. May be views_handler_broken.
  */
-function views_get_handler($table, $field, $key) {
+function views_get_handler($table, $field, $key, $override = NULL) {
   $data = views_fetch_data($table);
+  $handler = NULL;
+
   if (isset($data[$field][$key])) {
     // Set up a default handler:
     if (empty($data[$field][$key]['handler'])) {
       $data[$field][$key]['handler'] = 'views_handler_' . $key;
     }
-    return _views_prepare_handler($data[$field][$key], $data, $field);
+
+    if ($override) {
+      $data[$field][$key]['override handler'] = $override;
+    }
+
+    $handler = _views_prepare_handler($data[$field][$key], $data, $field);
+  }
+
+  if ($handler) {
+    return $handler;
   }
+
   // DEBUG -- identify missing handlers
   vpr("Missing handler: $table $field $key");
   $broken = array(
@@ -692,10 +742,20 @@ function views_get_plugin($type, $plugin
  * @return
  *   A view object or NULL if it is not available.
  */
-function &views_get_default_view($view_name) {
+function &views_get_default_view($view_name, $reset = FALSE) {
   $null = NULL;
-  $cache = views_discover_default_views();
 
+  // Attempt to load individually cached view from cache.
+  views_include('cache');
+  if (!$reset) {
+    $data = views_cache_get("views_default:{$view_name}", TRUE);
+    if (isset($data->data) && is_object($data->data)) {
+      return $data->data;
+    }
+  }
+
+  // Otherwise, allow entire cache to be rebuilt.
+  $cache = views_discover_default_views($reset);
   if (isset($cache[$view_name])) {
     return $cache[$view_name];
   }
@@ -723,12 +783,12 @@ function views_new_view() {
  *
  * @return An associative array of all known default views.
  */
-function views_discover_default_views() {
+function views_discover_default_views($reset = FALSE) {
   static $cache = array();
 
-  if (empty($cache)) {
+  if (empty($cache) || $reset) {
     views_include('cache');
-    $cache = _views_discover_default_views();
+    $cache = _views_discover_default_views($reset);
   }
   return $cache;
 }
@@ -803,7 +863,7 @@ function views_get_all_views($reset = FA
     // Get all default views.
     $status = variable_get('views_defaults', array());
 
-    foreach (views_discover_default_views() as $view) {
+    foreach (views_discover_default_views($reset) as $view) {
       // Determine if default view is enabled or disabled.
       if (isset($status[$view->name])) {
         $view->disabled = $status[$view->name];
@@ -841,12 +901,16 @@ function views_get_all_views($reset = FA
 function views_get_view($name, $reset = FALSE) {
   views_include('view');
   $view = view::load($name, $reset);
-  $default_view = views_get_default_view($name);
+  $default_view = views_get_default_view($name, $reset);
 
   if (empty($view) && empty($default_view)) {
     return;
   }
   elseif (empty($view) && !empty($default_view)) {
+    $status = variable_get('views_defaults', array());
+    if (isset($status[$default_view->name])) {
+      $default_view->disabled = $status[$default_view->name];
+    }
     $default_view->type = t('Default');
     return $default_view->clone_view();
   }
@@ -857,7 +921,6 @@ function views_get_view($name, $reset = 
   return $view->clone_view();
 }
 
-
 // ------------------------------------------------------------------
 // Views debug helper functions
 
@@ -957,20 +1020,23 @@ function views_exposed_form(&$form_state
     );
   }
 
-  // Go through each filter and let it generate its info.
-  foreach ($view->filter as $id => $filter) {
-    $view->filter[$id]->exposed_form($form, $form_state);
-    if ($info = $view->filter[$id]->exposed_info()) {
-      $form['#info']['filter-' . $id] = $info;
+  // Go through each handler and let it generate its exposed widget.
+  foreach ($view->display_handler->handlers as $type => $value) {
+    foreach ($view->$type as $id => $handler) {
+      if ($handler->can_expose() && $handler->is_exposed()) {
+        $handler->exposed_form($form, $form_state);
+        if ($info = $handler->exposed_info()) {
+          $form['#info']["$type-$id"] = $info;
+        }
+      }
     }
   }
 
-  // @todo deal with exposed sorts
-
   $form['submit'] = array(
     '#name' => '', // prevent from showing up in $_GET.
     '#type' => 'submit',
     '#value' => t('Apply'),
+    '#id' => form_clean_id('edit-submit-' . $view->name),
   );
 
   $form['#action'] = url($view->get_url());
@@ -984,6 +1050,9 @@ function views_exposed_form(&$form_state
   }
   views_add_js('dependent');
 
+  $exposed_form_plugin = $form_state['exposed_form_plugin'];
+  $exposed_form_plugin->exposed_form_alter($form, $form_state);
+
   // Save the form
   views_exposed_form_cache($view->name, $view->current_display, $form);
 
@@ -1000,6 +1069,8 @@ function views_exposed_form_validate(&$f
       $handlers[$key]->exposed_validate($form, $form_state);
     }
   }
+  $exposed_form_plugin = $form_state['exposed_form_plugin'];
+  $exposed_form_plugin->exposed_form_validate($form, $form_state);
 }
 
 /**
@@ -1015,8 +1086,12 @@ function views_exposed_form_submit(&$for
   $form_state['view']->exposed_data = $form_state['values'];
   $form_state['view']->exposed_raw_input = array();
 
+  $exclude = array('q', 'submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', '');
+  $exposed_form_plugin = $form_state['exposed_form_plugin'];
+  $exposed_form_plugin->exposed_form_submit($form, $form_state, $exclude);
+  
   foreach ($form_state['values'] as $key => $value) {
-    if (!in_array($key, array('q', 'submit', 'form_build_id', 'form_id', 'form_token', ''))) {
+    if (!in_array($key, $exclude)) {
       $form_state['view']->exposed_raw_input[$key] = $value;
     }
   }
@@ -1117,7 +1192,7 @@ function views_embed_view($name, $displa
   }
 
   $view = views_get_view($name);
-  if (!$view) {
+  if (!$view || !$view->access($display_id)) {
     return;
   }
 
@@ -1125,6 +1200,51 @@ function views_embed_view($name, $displa
 }
 
 /**
+* Get the result of a view.
+*
+* @param string $name
+*      The name of the view to retrieve the data from.
+* @param string $display_id
+*      The display id. On the edit page for the view in question, you'll find
+*      a list of displays at the left side of the control area. "Defaults"
+*      will be at the top of that list. Hover your cursor over the name of the
+*      display you want to use. An URL will appear in the status bar of your
+*      browser. This is usually at the bottom of the window, in the chrome.
+*      Everything after #views-tab- is the display ID, e.g. page_1.
+ * @param ...
+ *   Any additional parameters will be passed as arguments.
+* @return
+*      array
+*          An array containing an object for each view item.
+*/
+function views_get_view_result($name, $display_id = NULL) {
+  $args = func_get_args();
+  array_shift($args); // remove $name
+  if (count($args)) {
+    array_shift($args); // remove $display_id
+  }
+
+  $view = views_get_view($name);
+  if (is_object($view)) {
+    if (is_array($args)) {
+      $view->set_arguments($args);
+    }
+    if (is_string($display_id)) {
+      $view->set_display($display_id);
+    }
+    else {
+      $view->init_display();
+    }
+    $view->pre_execute();
+    $view->execute();
+    return $view->result;
+  }
+  else {
+    return array();
+  }
+}
+
+/**
  * Export a field.
  */
 function views_var_export($var, $prefix = '', $init = TRUE) {
@@ -1218,3 +1338,43 @@ function views_microtime() {
   list($usec, $sec) = explode(' ', microtime());
   return (float)$sec + (float)$usec;
 }
+
+/**
+ * Trim the field down to the specified length.
+ *
+ * @param $alter
+ *   - max_length: Maximum lenght of the string, the rest gets truncated.
+ *   - word_boundary: Trim only on a word boundary.
+ *   - ellipsis: Trim only on a word boundary.
+ *   - html: Take sure that the html is correct.
+ */
+function views_trim_text($alter, $value) {
+  if (drupal_strlen($value) > $alter['max_length']) {
+    $value = drupal_substr($value, 0, $alter['max_length']);
+    // TODO: replace this with cleanstring of ctools
+    if (!empty($alter['word_boundary'])) {
+      $regex = "(.*)\b.+";
+      if (function_exists('mb_ereg')) {
+        mb_regex_encoding('UTF-8');
+        $found = mb_ereg($regex, $value, $matches);
+      }
+      else {
+        $found = preg_match("/$regex/us", $value, $matches);
+      }
+      if ($found) {
+        $value = $matches[1];
+      }
+    }
+    // Remove scraps of HTML entities from the end of a strings
+    $value = rtrim(preg_replace('/(?:<(?!.+>)|&(?!.+;)).*$/us', '', $value));
+
+    if (!empty($alter['ellipsis'])) {
+      $value .= '...';
+    }
+  }
+  if (!empty($alter['html'])) {
+    $value = _filter_htmlcorrector($value);
+  }
+
+  return $value;
+}
Index: views_ui.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/views_ui.module,v
retrieving revision 1.109
diff -u -p -r1.109 views_ui.module
--- views_ui.module	30 Jan 2009 00:56:01 -0000	1.109
+++ views_ui.module	11 Aug 2010 21:11:31 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_ui.module,v 1.109 2009/01/30 00:56:01 merlinofchaos Exp $
+// $Id: views_ui.module,v 1.109.2.4 2010/04/07 23:40:32 merlinofchaos Exp $
 /**
  * @file views_ui.module
  * Provide structure for the administrative interface to Views.
@@ -39,12 +39,13 @@ function views_ui_menu() {
     'page callback' => 'views_ui_add_page',
     'type' => MENU_LOCAL_TASK
   );
-  $items['admin/build/views/import'] = $base + array(
+  $items['admin/build/views/import'] = array(
     'title' => 'Import',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('views_ui_import_page'),
+    'access callback' => 'views_import_access',
     'type' => MENU_LOCAL_TASK
-  );
+  ) + $base;
   $items['admin/build/views/tools'] = $base + array(
     'title' => 'Tools',
     'page callback' => 'drupal_get_form',
@@ -120,6 +121,10 @@ function views_ui_menu() {
     'page callback' => 'views_ui_analyze_view',
     'page arguments' => array(3, 5),
   );
+  $items['admin/build/views/%views_ui_js/reorder-displays/%views_ui_cache'] = $callback + array(
+    'page callback' => 'views_ui_reorder_view',
+    'page arguments' => array(3, 5),
+  );
   $items['admin/build/views/%views_ui_js/details/%views_ui_cache'] = $callback + array(
     'page callback' => 'views_ui_edit_details',
     'page arguments' => array(3, 5),
@@ -188,6 +193,10 @@ function views_ui_theme() {
       'arguments' => array('form' => NULL),
       'file' => 'includes/admin.inc',
     ),
+    'views_ui_rearrange_filter_form' => array(
+      'arguments' => array('form' => NULL),
+      'file' => 'includes/admin.inc',
+    ),
 
     // list views
     'views_ui_list_views' => array(
@@ -208,6 +217,11 @@ function views_ui_theme() {
       'arguments' => array('body' => NULL),
       'file' => 'includes/tabs.inc',
     ),
+    'views_ui_reorder_displays_form' => array(
+      'arguments' => array('form' => NULL),
+      'file' => 'includes/admin.inc',
+    ),
+
 
     // On behalf of a plugin
     'views_ui_style_plugin_table' => array(
@@ -265,6 +279,7 @@ function views_ui_cache_set(&$view) {
   unset($view->display_handler);
   unset($view->current_display);
   unset($view->default_display);
+  $view->query = NULL;
   foreach (array_keys($view->display) as $id) {
     unset($view->display[$id]->handler);
     unset($view->display[$id]->default_display);
Index: css/views-admin.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/css/views-admin.css,v
retrieving revision 1.13
diff -u -p -r1.13 views-admin.css
--- css/views-admin.css	7 Apr 2009 19:34:35 -0000	1.13
+++ css/views-admin.css	11 Aug 2010 21:11:31 -0000
@@ -1,4 +1,4 @@
-/* $Id: views-admin.css,v 1.13 2009/04/07 19:34:35 merlinofchaos Exp $ */
+/* $Id: views-admin.css,v 1.13.2.4 2010/01/22 01:41:24 merlinofchaos Exp $ */
 
 /*
  * Summary pad
@@ -211,6 +211,7 @@ div.views-display-deleted div.tab-sectio
 
 #views-ajax-title {
   background: #f6f6f6;
+  color: #000;
   border-left: #D6DBDE 1px solid;
   border-right: #D6DBDE 1px solid;
   margin: 0 0 0 118px;
@@ -220,6 +221,7 @@ div.views-display-deleted div.tab-sectio
 
 #views-ajax-pad .message {
   background: #f6f6f6;
+  color: #000;
   margin-left: 118px;
   border: #D6DBDE 1px solid;
   border-top: 0;
@@ -230,6 +232,7 @@ div.views-display-deleted div.tab-sectio
 
 #views-ajax-pad form {
   background: #fff;
+  color: #000;
   margin-left: 118px;
   border: #D6DBDE 1px solid;
   padding-top: 3px;
@@ -386,6 +389,22 @@ html.js #views-ajax-pad {
   margin: 0;
 }
 
+#views-ajax-pad label.hidden-options {
+  background: transparent url(../images/arrow-active.png) no-repeat right;
+  height: 12px;
+  padding-right: 12px;
+}
+
+#views-ajax-pad label.expanded-options {
+  background: transparent url(../images/expanded-options.png) no-repeat right;
+  height: 12px;
+  padding-right: 16px;
+}
+
+#views-ajax-pad .dependent-options {
+  padding-left: 30px;
+}
+
 /*
  * Add, Rearrange and Configure buttons using sprites
  */
@@ -446,6 +465,20 @@ html.js #arrange thead {
   display: none;
 }
 
+html.js #ungroupable_arrange .views-hide-label {
+  color: #D4E7F3;
+}
+
+#ungroupable_arrange thead tr {
+  /* this CSS mirrors what is found in core for blocks admin. */
+  background-color: #D4E7F3;
+  border-bottom: 1px solid #B4D7F0;
+  border-top: 1.5em solid #FFFFFF;
+  color: #455067;
+  padding-top: 0;
+  padding-bottom: 0;
+}
+
 html.js .views-remove-checkbox {
   display: none;
 }
@@ -458,14 +491,14 @@ html.js a.views-button-remove {
   display: inline;
 }
 
-#arrange tr.even,
-#arrange tr.odd,
-#arrange td {
+.arrange tr.even,
+.arrange tr.odd,
+.arrange td {
   padding-top: 0;
   padding-bottom: 0;
 }
 
-#arrange .form-item {
+.arrange .form-item {
   padding: 0;
 }
 
@@ -530,6 +563,14 @@ div.changed div.view-changed {
   padding: .5em;
 }
 
+form#views-ui-reorder-displays-button {
+  margin-bottom: 0em;
+  border-bottom: 1px solid #ccc;
+}
+form#views-ui-reorder-displays-button input.form-submit{
+  margin-bottom: 2em;
+}
+
 form#views-add-display-form {
   margin-bottom: 0em;
   border-bottom: 1px solid #ccc;
@@ -638,3 +679,34 @@ html.js .views-hidden {
   margin: 0 1em;
   border: 1px solid;
 }
+
+.group-populated {
+  display: none;
+}
+
+td.group {
+  /* this CSS mirrors what is found in core for blocks admin. */
+  background-color: #D4E7F3;
+  border-bottom: 1px solid #B4D7F0;
+  border-top: 1.5em solid #FFFFFF;
+  color: #455067;
+}
+
+td.group-title {
+  font-weight: bold;
+}
+
+tr.group-message {
+  font-style: italic;
+  color:#999999;
+}
+
+.group-message .form-submit,
+#views-add-group {
+  float: right;
+  clear: both;
+}
+
+html.js .views-group-select {
+  display: none;
+}
Index: css/views-list.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/css/views-list.css,v
retrieving revision 1.12
diff -u -p -r1.12 views-list.css
--- css/views-list.css	25 Mar 2009 00:08:45 -0000	1.12
+++ css/views-list.css	11 Aug 2010 21:11:31 -0000
@@ -1,4 +1,4 @@
-/* $Id: views-list.css,v 1.12 2009/03/25 00:08:45 merlinofchaos Exp $ */
+/* $Id: views-list.css,v 1.12.2.1 2009/11/18 20:04:17 merlinofchaos Exp $ */
 
 table.views-entry {
   margin: 3px 0;
@@ -74,10 +74,6 @@ table.view-disabled td.view-ops {
   line-height: 1.6;
   padding-bottom: 0.3em;
 }
-table.views-entry td.view-name,
-table.views-entry td.view-ops {
-  background: #eee;
-}
 table.view-enabled td.view-name,
 table.view-enabled td.view-ops {
   background: #E4F0F8; 
Index: css/views.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/css/views.css,v
retrieving revision 1.11
diff -u -p -r1.11 views.css
--- css/views.css	6 Jun 2008 23:08:00 -0000	1.11
+++ css/views.css	11 Aug 2010 21:11:31 -0000
@@ -1,7 +1,7 @@
-/* $Id: views.css,v 1.11 2008/06/06 23:08:00 merlinofchaos Exp $ */
+/* $Id: views.css,v 1.11.2.3 2010/03/12 00:25:33 merlinofchaos Exp $ */
 .views-exposed-form .views-exposed-widget {
-  float: left;
-  padding: .5em 1em 0 0;
+  float: left; /* LTR */
+  padding: .5em 1em 0 0; /* LTR */
 }
 
 .views-exposed-form .views-exposed-widget .form-submit {
@@ -22,6 +22,17 @@
   margin-bottom: .5em;
 }
 
+/* table style column align */
+.views-align-left {
+  text-align: left;
+}
+.views-align-right {
+  text-align: right;
+}
+.views-align-center {
+  text-align: center;
+}
+
 html.js a.views-throbbing,
 html.js span.views-throbbing {
   background:url(../images/status-active.gif) no-repeat right center;
@@ -34,7 +45,7 @@ div.view div.views-admin-links {
   font-size: xx-small;
   margin-right: 1em;
   margin-top: 1em;
-  width: 95%;
+/*  width: 95%; */
 }
 
 .block div.view div.views-admin-links {
Index: docs/docs.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/docs/docs.php,v
retrieving revision 1.15
diff -u -p -r1.15 docs.php
--- docs/docs.php	1 Jun 2009 23:33:37 -0000	1.15
+++ docs/docs.php	11 Aug 2010 21:11:31 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: docs.php,v 1.15 2009/06/01 23:33:37 merlinofchaos Exp $
+// $Id: docs.php,v 1.13.2.5 2010/03/08 20:04:37 merlinofchaos Exp $
 /**
  * @file
  * This file contains no working PHP code; it exists to provide additional documentation
@@ -220,6 +220,14 @@ function hook_views_plugins() {
 }
 
 /**
+ * Alter existing plugins data, defined by modules.
+ */
+function hook_views_plugins_alter(&$plugins) {
+  // Add apachesolr to the base of the node row plugin.
+  $plugins['row']['node']['base'][] = 'apachesolr';
+}
+
+/**
  * Register handler, file and parent information so that handlers can be
  * loaded only on request.
  *
@@ -538,8 +546,8 @@ function hook_views_query_substitutions(
  * This hook is called at the very beginning of views processing,
  * before anything is done.
  *
- * Adding output to the view cam be accomplished by placing text on
- * $view->attachment_before and $view->attachment_after
+ * Adding output to the view can be accomplished by placing text on
+ * $view->attachment_before and $view->attachment_after.
  */
 function hook_views_pre_view(&$view, &$display_id, &$args) {
   // example code here
@@ -549,8 +557,8 @@ function hook_views_pre_view(&$view, &$d
  * This hook is called right before the build process, but after displays
  * are attached and the display performs its pre_execute phase.
  *
- * Adding output to the view cam be accomplished by placing text on
- * $view->attachment_before and $view->attachment_after
+ * Adding output to the view can be accomplished by placing text on
+ * $view->attachment_before and $view->attachment_after.
  */
 function hook_views_pre_build(&$view) {
   // example code here
@@ -560,8 +568,8 @@ function hook_views_pre_build(&$view) {
  * This hook is called right before the execute process. The query is
  * now fully built, but it has not yet been run through db_rewrite_sql.
  *
- * Adding output to the view cam be accomplished by placing text on
- * $view->attachment_before and $view->attachment_after
+ * Adding output to the view can be accomplished by placing text on
+ * $view->attachment_before and $view->attachment_after.
  */
 function hook_views_pre_execute(&$view) {
   // example code here
@@ -572,14 +580,43 @@ function hook_views_pre_execute(&$view) 
  * been executed, and the pre_render() phase has already happened for
  * handlers, so all data should be available.
  *
- * Adding output to the view cam be accomplished by placing text on
- * $view->attachment_before and $view->attachment_after
+ * Adding output to the view can be accomplished by placing text on
+ * $view->attachment_before and $view->attachment_after. Altering the
+ * content can be achieved by editing the items of $view->result.
+ *
+ * This hook can be utilized by themes.
  */
 function hook_views_pre_render(&$view) {
   // example code here
 }
 
 /**
+ * Post process any rendered data.
+ *
+ * This can be valuable to be able to cache a view and still have some level of
+ * dynamic output. In an ideal world, the actual output will include HTML
+ * comment based tokens, and then the post process can replace those tokens.
+ *
+ * Example usage. If it is known that the view is a node view and that the
+ * primary field will be a nid, you can do something like this:
+ *
+ * <!--post-FIELD-NID-->
+ *
+ * And then in the post render, create an array with the text that should
+ * go there:
+ *
+ * strtr($output, array('<!--post-FIELD-1-->', 'output for FIELD of nid 1');
+ *
+ * All of the cached result data will be available in $view->result, as well,
+ * so all ids used in the query should be discoverable.
+ *
+ * This hook can be utilized by themes.
+ */
+function hook_views_post_render(&$view, &$output, &$cache) {
+
+}
+
+/**
  * Stub hook documentation
  *
  * This hook should be placed in MODULENAME.views.inc and it will be auto-loaded.
Index: handlers/views_handler_argument.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_argument.inc,v
retrieving revision 1.8
diff -u -p -r1.8 views_handler_argument.inc
--- handlers/views_handler_argument.inc	2 Jun 2009 19:38:33 -0000	1.8
+++ handlers/views_handler_argument.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_argument.inc,v 1.8 2009/06/02 19:38:33 merlinofchaos Exp $
+// $Id: views_handler_argument.inc,v 1.7.2.12 2010/03/12 21:25:26 merlinofchaos Exp $
 
 /**
  * @defgroup views_argument_handlers Handlers for arguments
@@ -46,7 +46,7 @@ class views_handler_argument extends vie
     }
   }
 
-  function init(&$view, &$options) {
+  function init(&$view, $options) {
     parent::init($view, $options);
   }
 
@@ -96,15 +96,16 @@ class views_handler_argument extends vie
     $options = parent::option_definition();
 
     $options['default_action'] = array('default' => 'ignore');
-    $options['style_plugin'] = array('default' => 'default_summary');
-    $options['style_options'] = array('default' => array());
+    $options['style_plugin'] = array('default' => 'default_summary', 'export' => 'export_style');
+    $options['style_options'] = array('default' => array(), 'export' => FALSE);
     $options['wildcard'] = array('default' => 'all');
     $options['wildcard_substitution'] = array('default' => t('All'), 'translatable' => TRUE);
     $options['title'] = array('default' => '', 'translatable' => TRUE);
     $options['breadcrumb'] = array('default' => '', 'translatable' => TRUE);
-    $options['default_argument_type'] = array('default' => 'fixed');
-    $options['default_argument'] = array('default' => '');
-    $options['validate_type'] = array('default' => 'none');
+    $options['default_argument_type'] = array('default' => 'fixed', 'export' => 'export_plugin');
+    $options['default_argument_options'] = array('default' => array(), 'export' => FALSE);
+    $options['validate_type'] = array('default' => 'none', 'export' => 'export_plugin');
+    $options['validate_options'] = array('default' => array(), 'export' => FALSE);
     $options['validate_fail'] = array('default' => 'not found');
 
     return $options;
@@ -121,14 +122,14 @@ class views_handler_argument extends vie
       '#default_value' => $this->options['title'],
       '#description' => t('The title to use when this argument is present. It will override the title of the view and titles from previous arguments. You can use percent substitution here to replace with argument titles. Use "%1" for the first argument, "%2" for the second, etc.'),
     );
-    
+
     $form['breadcrumb'] = array(
       '#prefix' => '<div class="clear-block">',
       '#suffix' => '</div>',
       '#type' => 'textfield',
       '#title' => t('Breadcrumb'),
       '#default_value' => $this->options['breadcrumb'],
-      '#description' => t('The Breadcrumb title to use when this argument is present. If no breadcrumb is setted here, default Title values will be used, see "Title" for percent substitutions.'),
+      '#description' => t('The Breadcrumb title to use when this argument is present. If no breadcrumb is set here, default Title values will be used, see "Title" for percent substitutions.'),
     );
 
     $form['clear_start'] = array(
@@ -220,11 +221,18 @@ class views_handler_argument extends vie
 
       // If we decide this validator is ok, add it to the list.
       if ($valid) {
-        $plugin = views_get_plugin('argument validator', $id);
+        $plugin = $this->get_plugin('argument validator', $id);
         if ($plugin) {
-          $plugin->init($this->view, $this, $id);
           if ($plugin->access() || $this->options['validate_type'] == $id) {
-            $plugin->validate_form($form, $form_state, $id);
+            $form['argument_validate'][$id] = array(
+              '#type' => 'item',
+              '#input' => TRUE, // trick it into checking input to make #process run
+              '#process' => array('views_process_dependency'),
+              '#dependency' => array(
+                'edit-options-validate-type' => array($id)
+              ),
+            );
+            $plugin->options_form($form['argument_validate'][$id], $form_state);
             $validate_types[$id] = $info['title'];
           }
         }
@@ -246,6 +254,51 @@ class views_handler_argument extends vie
     );
   }
 
+  function options_validate(&$form, &$form_state) {
+    if (empty($form_state['values']['options'])) {
+      return;
+    }
+
+    // Let the plugins do validation.
+    $default_id = $form_state['values']['options']['default_argument_type'];
+    $plugin = $this->get_plugin('argument default', $default_id);
+    if ($plugin) {
+      $plugin->options_validate($form['argument_default'][$default_id], $form_state, $form_state['values']['options']['argument_default'][$default_id]);
+    }
+
+    $validate_id = $form_state['values']['options']['validate_type'];
+    $plugin = $this->get_plugin('argument validator', $validate_id);
+    if ($plugin) {
+      $plugin->options_validate($form['argument_validate'][$default_id], $form_state, $form_state['values']['options']['argument_validate'][$validate_id]);
+    }
+
+  }
+
+  function options_submit($form, &$form_state) {
+    if (empty($form_state['values']['options'])) {
+      return;
+    }
+
+    // Let the plugins make submit modifications if necessary.
+    $default_id = $form_state['values']['options']['default_argument_type'];
+    $plugin = $this->get_plugin('argument default', $default_id);
+    if ($plugin) {
+      $options = &$form_state['values']['options']['argument_default'][$default_id];
+      $plugin->options_submit($form['argument_default'][$default_id], $form_state, $options);
+      // Copy the now submitted options to their final resting place so they get saved.
+      $form_state['values']['options']['default_argument_options'] = $options;
+    }
+
+    $validate_id = $form_state['values']['options']['validate_type'];
+    $plugin = $this->get_plugin('argument validator', $validate_id);
+    if ($plugin) {
+      $options = &$form_state['values']['options']['argument_validate'][$validate_id];
+      $plugin->options_submit($form['argument_validate'][$validate_id], $form_state, $options);
+      // Copy the now submitted options to their final resting place so they get saved.
+      $form_state['values']['options']['validate_options'] = $options;
+    }
+  }
+
   /**
    * Provide a list of default behaviors for this argument if the argument
    * is not present.
@@ -283,6 +336,20 @@ class views_handler_argument extends vie
         'style plugin' => TRUE,
         'breadcrumb' => TRUE, // generate a breadcrumb to here
       ),
+      'summary asc by count' => array(
+        'title' => t('Summary, sorted by number of records ascending'),
+        'method' => 'default_summary',
+        'method args' => array('asc', 'num_records'),
+        'style plugin' => TRUE,
+        'breadcrumb' => TRUE, // generate a breadcrumb to here
+      ),
+      'summary desc by count' => array(
+        'title' => t('Summary, sorted by number of records descending'),
+        'method' => 'default_summary',
+        'method args' => array('desc', 'num_records'),
+        'style plugin' => TRUE,
+        'breadcrumb' => TRUE, // generate a breadcrumb to here
+      ),
       'default' => array(
         'title' => t('Provide default argument'),
         'method' => 'default_default',
@@ -329,18 +396,28 @@ class views_handler_argument extends vie
       '#id' => 'edit-options-default-argument-type',
       '#title' => t('Default argument type'),
       '#default_value' => $this->options['default_argument_type'],
-      '#process' => array('expand_radios', 'views_process_dependency'),
-      '#dependency' => array('radio:options[default_action]' => array('default')),
     );
 
     foreach ($plugins as $id => $info) {
-      $plugin = views_get_plugin('argument default', $id);
-      if ($plugin) {
-        $plugin->init($this->view, $this, $id);
+      if (!empty($info['no ui'])) {
+        continue;
+      }
 
+      $plugin = $this->get_plugin('argument default', $id);
+      if ($plugin) {
         if ($plugin->access() || $this->options['default_argument_type'] == $id) {
+          $form['argument_default'][$id] = array(
+            '#type' => 'item',
+            '#input' => TRUE, // trick it into checking input to make #process run
+            '#process' => array('views_process_dependency'),
+            '#dependency' => array(
+              'radio:options[default_action]' => array('default'),
+              'radio:options[default_argument_type]' => array($id)
+            ),
+            '#dependency_count' => 2,
+          );
           $options[$id] = $info['title'];
-          $plugin->argument_form($form, $form_state);
+          $plugin->options_form($form['argument_default'][$id], $form_state);
         }
       }
     }
@@ -442,9 +519,8 @@ class views_handler_argument extends vie
    * Get a default argument, if available.
    */
   function get_default_argument() {
-    $plugin = views_get_plugin('argument default', $this->options['default_argument_type']);
+    $plugin = $this->get_plugin('argument default');
     if ($plugin) {
-      $plugin->init($this->view, $this);
       return $plugin->get_argument();
     }
   }
@@ -455,7 +531,7 @@ class views_handler_argument extends vie
    * If an argument was expected and was not given, in this case, display
    * a summary query.
    */
-  function default_summary($order) {
+  function default_summary($order, $by = NULL) {
     $this->view->build_info['summary'] = TRUE;
     $this->view->build_info['summary_level'] = $this->options['id'];
 
@@ -469,7 +545,7 @@ class views_handler_argument extends vie
     $this->query->clear_fields();
     $this->summary_query();
 
-    $this->summary_sort($order);
+    $this->summary_sort($order, $by);
 
     // Summaries have their own sorting and fields, so tell the View not
     // to build these.
@@ -560,8 +636,8 @@ class views_handler_argument extends vie
    * @param $order
    *   The order selected in the UI.
    */
-  function summary_sort($order) {
-    $this->query->add_orderby(NULL, NULL, $order, $this->name_alias);
+  function summary_sort($order, $by = NULL) {
+    $this->query->add_orderby(NULL, NULL, $order, (!empty($by) ? $by : $this->name_alias));
   }
 
   /**
@@ -642,9 +718,8 @@ class views_handler_argument extends vie
       return $this->argument_validated = $this->validate_argument_basic($arg);
     }
 
-    $plugin = views_get_plugin('argument validator', $this->options['validate_type']);
+    $plugin = $this->get_plugin('argument validator');
     if ($plugin) {
-      $plugin->init($this->view, $this, $this->options['validate_type']);
       return $this->argument_validated = $plugin->validate_argument($arg);
     }
 
@@ -689,7 +764,7 @@ class views_handler_argument extends vie
       return FALSE;
     }
 
-    if (isset($this->definition['numeric']) && !isset($this->options['break_phrase']) && !is_numeric($arg)) {
+    if (!empty($this->definition['numeric']) && !isset($this->options['break_phrase']) && !is_numeric($arg)) {
       return FALSE;
     }
 
@@ -714,7 +789,7 @@ class views_handler_argument extends vie
     if (isset($this->argument)) {
       return $this->argument;
     }
-    
+
     // Otherwise, we have to pretend to process ourself to find the value.
     $value = NULL;
     // Find the position of this argument within the view.
@@ -742,6 +817,92 @@ class views_handler_argument extends vie
     unset($argument);
     return $value;
   }
+
+  /**
+   * Special handling for the style export.
+   *
+   * Arguments can have styles for the summary view. This special export
+   * handler makes sure this works properly.
+   */
+  function export_style($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+    $name = $storage[$option];
+    $options = $storage['style_options'];
+
+    $plugin = views_get_plugin('style', $name);
+    if ($plugin) {
+      $plugin->init($this->view, $this->display, $options);
+      // Write which plugin to use.
+      $output .= $indent . $prefix . "['$option'] = '$name';\n";
+
+      // Pass off to the plugin to export itself.
+      $output .= $plugin->export_options($indent, $prefix . "['style_options']");
+    }
+
+    return $output;
+  }
+
+  /**
+   * Special handling for the style export.
+   *
+   * Arguments can have styles for the summary view. This special export
+   * handler makes sure this works properly.
+   */
+  function export_plugin($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+    if ($option == 'default_argument_type') {
+      $type = 'argument default';
+      $option_name = 'default_argument_options';
+    }
+    else {
+      $type = 'argument validator';
+      $option_name = 'validate_options';
+    }
+    $plugin = $this->get_plugin($type);
+    $name = $this->options[$option];
+
+    if ($plugin) {
+      // Write which plugin to use.
+      $output .= $indent . $prefix . "['$option'] = '$name';\n";
+
+      // Pass off to the plugin to export itself.
+      $output .= $plugin->export_options($indent, $prefix . "['$option_name']");
+    }
+
+    return $output;
+  }
+
+  /**
+   * Get the display or row plugin, if it exists.
+   */
+  function get_plugin($type = 'argument default', $name = NULL) {
+    $options = array();
+    switch ($type) {
+      case 'argument default':
+        $plugin_name = 'default_argument_type';
+        $options_name = 'default_argument_options';
+        break;
+      case 'argument validator':
+        $plugin_name = 'validate_type';
+        $options_name = 'validate_options';
+    }
+
+    if (!$name) {
+      $name = $this->options[$plugin_name];
+    }
+
+    // we only fetch the options if we're fetching the plugin actually
+    // in use.
+    if ($name == $this->options[$plugin_name]) {
+      $options = $this->options[$options_name];
+    }
+
+    $plugin = views_get_plugin($type, $name);
+    if ($plugin) {
+      $plugin->init($this->view, $this, $options);
+      return $plugin;
+    }
+  }
 }
 
 /**
@@ -750,7 +911,7 @@ class views_handler_argument extends vie
  * @ingroup views_argument_handlers
  */
 class views_handler_argument_broken extends views_handler_argument {
-  function ui_name() {
+  function ui_name($short = FALSE) {
     return t('Broken/missing handler');
   }
 
Index: handlers/views_handler_argument_date.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_argument_date.inc,v
retrieving revision 1.3
diff -u -p -r1.3 views_handler_argument_date.inc
--- handlers/views_handler_argument_date.inc	24 Mar 2009 22:28:26 -0000	1.3
+++ handlers/views_handler_argument_date.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_argument_date.inc,v 1.3 2009/03/24 22:28:26 merlinofchaos Exp $
+// $Id: views_handler_argument_date.inc,v 1.3.2.2 2010/03/11 00:49:50 merlinofchaos Exp $
 /**
  * Abstract argument handler for dates.
  *
@@ -38,7 +38,7 @@ class views_handler_argument_date extend
     if (!$raw && $this->options['default_argument_type'] == 'date') {
       return date($this->arg_format, time());
     }
-    else if (!$raw) {
+    else if (!$raw && in_array($this->options['default_argument_type'], array('node_created', 'node_changed'))) {
       foreach (range(1, 3) as $i) {
         $node = menu_get_object('node', $i);
         if (!empty($node)) {
@@ -60,8 +60,8 @@ class views_handler_argument_date extend
         return date($this->arg_format, $node->changed);
       }
     }
-    else {
-      return parent::get_default_argument($raw);
-    }
+
+    return parent::get_default_argument($raw);
+
   }
 }
Index: handlers/views_handler_argument_many_to_one.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_argument_many_to_one.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_argument_many_to_one.inc
--- handlers/views_handler_argument_many_to_one.inc	3 Sep 2008 19:21:28 -0000	1.1
+++ handlers/views_handler_argument_many_to_one.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_argument_many_to_one.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos Exp $
+// $Id: views_handler_argument_many_to_one.inc,v 1.1.2.3 2010/03/22 20:40:35 merlinofchaos Exp $
 /**
  * An argument handler for use in fields that have a many to one relationship
  * with the table(s) to the left. This adds a bunch of options that are
@@ -8,11 +8,13 @@
  * - numeric: If true, the field will be considered numeric. Probably should
  *   always be set TRUE as views_handler_argument_string has many to one
  *   capabilities.
+ * - zero is null: If true, a 0 will be handled as empty, so for example 
+ *   a default argument can be provided or a summary can be shown.
  *
  * @ingroup views_argument_handlers
  */
 class views_handler_argument_many_to_one extends views_handler_argument {
-  function init(&$view, &$options) {
+  function init(&$view, $options) {
     parent::init($view, $options);
     $this->helper = new views_many_to_one_helper($this);
 
@@ -73,7 +75,18 @@ class views_handler_argument_many_to_one
   }
 
   function query() {
-    if (empty($this->argument)) {
+    $empty = FALSE;
+    if (isset($this->definition['zero is null']) && $this->definition['zero is null']) {
+      if (empty($this->argument)) {
+        $empty = TRUE;
+      }
+    }
+    else {
+      if (!isset($this->argument)) {
+        $empty = TRUE;
+      }
+    }
+    if ($empty) {
       parent::ensure_my_table();
       $this->query->add_where(0, "$this->table_alias.$this->real_field IS NULL");
       return;
Index: handlers/views_handler_argument_string.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_argument_string.inc,v
retrieving revision 1.4
diff -u -p -r1.4 views_handler_argument_string.inc
--- handlers/views_handler_argument_string.inc	7 Jan 2009 21:30:31 -0000	1.4
+++ handlers/views_handler_argument_string.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_argument_string.inc,v 1.4 2009/01/07 21:30:31 merlinofchaos Exp $
+// $Id: views_handler_argument_string.inc,v 1.4.2.3 2010/07/27 22:23:00 merlinofchaos Exp $
 
 /**
  * Basic argument handler to implement string arguments that may have length
@@ -8,7 +8,7 @@
  * @ingroup views_argument_handlers
  */
 class views_handler_argument_string extends views_handler_argument {
-  function init(&$view, &$options) {
+  function init(&$view, $options) {
     parent::init($view, $options);
     if (!empty($this->definition['many to one'])) {
       $this->helper = new views_many_to_one_helper($this);
@@ -23,6 +23,7 @@ class views_handler_argument_string exte
     $options = parent::option_definition();
 
     $options['glossary'] = array('default' => FALSE);
+    $options['ignorecase'] = array('default' => FALSE);
     $options['limit'] = array('default' => 0);
     $options['case'] = array('default' => 'none');
     $options['path_case'] = array('default' => 'none');
@@ -46,6 +47,13 @@ class views_handler_argument_string exte
       '#default_value' => $this->options['glossary'],
     );
 
+    $form['ignorecase'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Ignore case'),
+      '#description' => t('Ignore case allows for doing database searches without case sensitivity. MySQL already works in lower-case mode, so MySQL users should leave this unchecked to improve performance.'),
+      '#default_value' => $this->options['ignorecase'],
+    );
+
     $form['limit'] = array(
       '#type' => 'textfield',
       '#title' => t('Character limit'),
@@ -72,7 +80,7 @@ class views_handler_argument_string exte
     $form['path_case'] = array(
       '#type' => 'select',
       '#title' => t('Case in path'),
-      '#description' => t('When printing url paths, how to transform the of the argument. Do not use this unless with Postgres as it uses case sensitive comparisons.'),
+      '#description' => t('When printing url paths, how to transform the case of the argument. Do not use this unless with Postgres as it uses case sensitive comparisons.'),
       '#options' => array(
         'none' => t('No transform'),
         'upper' => t('Upper case'),
@@ -118,14 +126,26 @@ class views_handler_argument_string exte
 
     if (empty($this->options['glossary'])) {
       // Add the field.
-      $this->base_alias = $this->name_alias = $this->query->add_field($this->table_alias, $this->real_field);
-      $this->query->set_count_field($this->table_alias, $this->real_field);
+      if (empty($this->options['ignorecase'])){
+        $this->base_alias = $this->name_alias = $this->query->add_field($this->table_alias, $this->real_field);
+        $this->query->set_count_field($this->table_alias, $this->real_field);
+      }
+      else {
+        $this->base_alias = $this->name_alias = $this->query->add_field($this->table_alias, 'LOWER(' . $this->real_field . ')');
+        $this->query->set_count_field($this->table_alias, 'LOWER(' . $this->real_field . ')');
+      }
     }
     else {
       // Add the field.
       $formula = $this->get_formula();
-      $this->base_alias = $this->name_alias = $this->query->add_field(NULL, $formula, $this->field . '_truncated');
-      $this->query->set_count_field(NULL, $formula, $this->field, $this->field . '_truncated');
+      if (empty($this->options['ignorecase'])){
+        $this->base_alias = $this->name_alias = $this->query->add_field(NULL, $formula, $this->field . '_truncated');
+        $this->query->set_count_field(NULL, $formula, $this->field, $this->field . '_truncated');
+      }
+      else {
+        $this->base_alias = $this->name_alias = $this->query->add_field(NULL, 'LOWER(' . $formula . ')', $this->field . '_truncated');
+        $this->query->set_count_field(NULL, $formula, $this->field, $this->field . '_truncated');
+      }
     }
 
     return $this->summary_basics(FALSE);
@@ -167,7 +187,12 @@ class views_handler_argument_string exte
       $field = $this->get_formula();
     }
 
-    $this->query->add_where(0, "$field = '%s'", $argument);
+    if (empty($this->options['ignorecase'])){
+      $this->query->add_where(0, "$field = '%s'", $argument);
+    }
+    else {
+      $this->query->add_where(0, "LOWER($field) = LOWER('%s')", $argument);
+    }
   }
 
   function summary_argument($data) {
Index: handlers/views_handler_field.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_field.inc,v
retrieving revision 1.19
diff -u -p -r1.19 views_handler_field.inc
--- handlers/views_handler_field.inc	3 Jun 2009 19:55:52 -0000	1.19
+++ handlers/views_handler_field.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field.inc,v 1.19 2009/06/03 19:55:52 merlinofchaos Exp $
+// $Id: views_handler_field.inc,v 1.14.2.38 2010/07/27 21:50:26 merlinofchaos Exp $
 /**
  * @defgroup views_field_handlers Views' field handlers
  * @{
@@ -94,7 +94,19 @@ class views_handler_field extends views_
           else {
             $table_alias = $this->table_alias;
           }
-          $this->aliases[$identifier] = $this->query->add_field($table_alias, $info['field']);
+
+          if (empty($table_alias)) {
+            vpr(t('Handler @handler tried to add additional_field @identifier but @table could not be added!', array('@handler' => $this->definition['handler'], '@identifier' => $identifier, '@table' => $info['table'])));
+            $this->aliases[$identifier] = 'broken';
+            continue;
+          }
+
+          $params = array();
+          if (!empty($info['params'])) {
+            $params = $info['params'];
+          }
+
+          $this->aliases[$identifier] = $this->query->add_field($table_alias, $info['field'], NULL, $params);
         }
         else {
           $this->aliases[$info] = $this->query->add_field($this->table_alias, $info);
@@ -142,16 +154,19 @@ class views_handler_field extends views_
     $options = parent::option_definition();
 
     $options['label'] = array('default' => $this->definition['title'], 'translatable' => TRUE);
+    $options['exclude'] = array('default' => FALSE, 'bool' => TRUE);
     $options['alter'] = array(
       'contains' => array(
         'alter_text' => array('default' => FALSE),
         'text' => array('default' => '', 'translatable' => TRUE),
         'make_link' => array('default' => FALSE),
         'path' => array('default' => '', 'translatable' => TRUE),
+        'absolute' => array('default' => '', 'translatable' => FALSE),
         'alt' => array('default' => '', 'translatable' => TRUE),
         'link_class' => array('default' => ''),
         'prefix' => array('default' => '', 'translatable' => TRUE),
         'suffix' => array('default' => '', 'translatable' => TRUE),
+        'target' => array('default' => '', 'translatable' => TRUE),
         'trim' => array('default' => FALSE),
         'max_length' => array('default' => ''),
         'word_boundary' => array('default' => TRUE),
@@ -160,6 +175,9 @@ class views_handler_field extends views_
         'html' => array('default' => FALSE),
       ),
     );
+    $options['empty'] = array('default' => '', 'translatable' => TRUE);
+    $options['hide_empty'] = array('default' => FALSE);
+    $options['empty_zero'] = array('default' => FALSE);
 
     return $options;
   }
@@ -169,6 +187,8 @@ class views_handler_field extends views_
    * should have.
    */
   function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
     $form['label'] = array(
       '#type' => 'textfield',
       '#title' => t('Label'),
@@ -217,7 +237,18 @@ class views_handler_field extends views_
         '#dependency' => array(
           'edit-options-alter-make-link' => array(1)
         ),
+        '#maxlength' => 255,
       );
+       $form['alter']['absolute'] = array(
+         '#type' => 'checkbox',
+         '#title' => t('Use absolute path'),
+         '#default_value' => $this->options['alter']['absolute'],
+         '#process' => array('views_process_dependency'),
+         '#dependency' => array(
+           'edit-options-alter-make-link' => array(1)
+         ),
+       );
+
       $form['alter']['link_class'] = array(
         '#title' => t('Link class'),
         '#type' => 'textfield',
@@ -258,6 +289,17 @@ class views_handler_field extends views_
           'edit-options-alter-make-link' => array(1)
         ),
       );
+      $form['alter']['target'] = array(
+        '#title' => t('Target'),
+        '#type' => 'textfield',
+        '#default_value' => $this->options['alter']['target'],
+        '#description' => t("Target of the link, such as _blank, _parent or an iframe's name. This field is rarely used."),
+        '#process' => array('views_process_dependency'),
+        '#dependency' => array(
+          'edit-options-alter-make-link' => array(1)
+        ),
+      );
+
 
       // Get a list of the available fields and arguments for token replacement.
       $options = array();
@@ -270,22 +312,24 @@ class views_handler_field extends views_
       }
       $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] = $handler->ui_name();
+        $options[t('Arguments')]['%' . ++$count] = t('@argument title', array('@argument' => $handler->ui_name()));
+        $options[t('Arguments')]['!' . $count] = t('@argument input', array('@argument' => $handler->ui_name()));
       }
 
+      $this->document_self_tokens($options[t('Fields')]);
+
       // Default text.
       $output = t('<p>You must add some additional fields to this display before using this field. These fields may be marked as <em>Exclude from display</em> if you prefer. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.</p>');
       // We have some options, so make a list.
       if (!empty($options)) {
-        $output = t('<p>The following substitution patterns are available for this display. Use the pattern shown on the left to display the value indicated on the right. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.</p>');
+        $output = t('<p>The following tokens are available for this field. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.</p>');
         foreach (array_keys($options) as $type) {
           if (!empty($options[$type])) {
             $items = array();
-            $title = t(ucwords($type));
             foreach ($options[$type] as $key => $value) {
-              $items[] = $key .' == '. $value;
+              $items[] = $key . ' == ' . $value;
             }
-            $output .= theme('item_list', $items, $title);
+            $output .= theme('item_list', $items, $type);
           }
         }
       }
@@ -315,7 +359,7 @@ class views_handler_field extends views_
         '#title' => t('Maximum length'),
         '#type' => 'textfield',
         '#default_value' => $this->options['alter']['max_length'],
-        '#description' => t('The maximum number of characters his field can be.'),
+        '#description' => t('The maximum number of characters this field can be.'),
         '#process' => array('views_process_dependency'),
         '#dependency' => array(
           'edit-options-alter-trim' => array(1)
@@ -344,17 +388,6 @@ class views_handler_field extends views_
         ),
       );
 
-      $form['alter']['strip_tags'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Strip HTML tags'),
-        '#description' => t('If checked, all HTML tags will be stripped.'),
-        '#default_value' => $this->options['alter']['strip_tags'],
-        '#process' => array('views_process_dependency'),
-        '#dependency' => array(
-          'edit-options-alter-trim' => array(1)
-        ),
-      );
-
       $form['alter']['html'] = array(
         '#type' => 'checkbox',
         '#title' => t('Field can contain HTML'),
@@ -365,7 +398,36 @@ class views_handler_field extends views_
           'edit-options-alter-trim' => array(1)
         ),
       );
+
+      $form['alter']['strip_tags'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Strip HTML tags'),
+        '#description' => t('If checked, all HTML tags will be stripped.'),
+        '#default_value' => $this->options['alter']['strip_tags'],
+        '#process' => array('views_process_dependency'),
+      );
     }
+
+    $form['empty'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Empty text'),
+      '#default_value' => $this->options['empty'],
+      '#description' => t('If the field is empty, display this text instead.'),
+    );
+
+    $form['empty_zero'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Count the number 0 as empty'),
+      '#default_value' => $this->options['empty_zero'],
+      '#description' => t('If the field contains the number zero, display the empty text instead'),
+    );
+
+    $form['hide_empty'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Hide if empty'),
+      '#default_value' => $this->options['hide_empty'],
+      '#description' => t('Do not display anything for this field if it is empty. Note that the field label may still be displayed. Check style or row style settings to hide labels for empty fields.'),
+    );
   }
 
   /**
@@ -404,25 +466,30 @@ class views_handler_field extends views_
    * text-replacement rendering is necessary.
    */
   function advanced_render($values) {
-    $this->last_render = $value = $this->render($values);
-    $this->original_value = $value;
+    if ($this->allow_advanced_render() && method_exists($this, 'render_item')) {
+      $raw_items = $this->get_items($values);
+    }
+    else {
+      $this->last_render = $value = $this->render($values);
+      $this->original_value = $value;
+    }
 
     if ($this->allow_advanced_render()) {
       $tokens = NULL;
-      if (!empty($this->options['alter']['alter_text']) && !empty($this->options['alter']['text'])) {
-        $tokens = $this->get_render_tokens();
-        $value = $this->render_altered($tokens);
-      }
-
-      if (!empty($this->options['alter']['trim']) && !empty($this->options['alter']['max_length'])) {
-        $value = $this->render_trim_text($value);
-      }
+      if (method_exists($this, 'render_item')) {
+        $items = array();
+        foreach ($raw_items as $count => $item) {
+          $this->last_render = $this->render_item($count, $item);
+          $this->original_value = $this->last_render;
 
-      if (!empty($this->options['alter']['make_link']) && !empty($this->options['alter']['path'])) {
-        if (!isset($tokens)) {
-         $tokens = $this->get_render_tokens();
+          $alter = $item + $this->options['alter'];
+          $items[] = $this->render_text($alter);
         }
-        $value = $this->render_as_link($value, $tokens);
+
+        $value = $this->render_items($items);
+      }
+      else {
+        $value = $this->render_text($this->options['alter']);
       }
 
       // This happens here so that render_as_link can get the unaltered value of
@@ -430,15 +497,58 @@ class views_handler_field extends views_
       $this->last_render = $value;
     }
 
+    if (empty($this->last_render)) {
+      if (($this->last_render !== 0 && $this->last_render !== '0') || !empty($this->options['empty_zero'])) {
+        $this->options['alter']['alter_text'] = 1;
+        $this->options['alter']['text'] = $this->options['empty'];
+        $this->last_render = $this->render_text($this->options['alter']);
+      }
+    }
+
     return $this->last_render;
   }
 
   /**
+   * Perform an advanced text render for the item.
+   *
+   * This is separated out as some fields may render lists, and this allows
+   * each item to be handled individually.
+   */
+  function render_text($alter) {
+    $value = trim($this->last_render);
+    if ($this->options['hide_empty'] && empty($value) && ($value !== 0 || $this->options['empty_zero'])) {
+      return '';
+    }
+
+    if (!empty($alter['alter_text']) && $alter['text'] !== '') {
+      $tokens = $this->get_render_tokens($alter);
+      $value = $this->render_altered($alter, $tokens);
+    }
+
+    if (!empty($alter['strip_tags'])) {
+      $value = strip_tags($value);
+    }
+
+    if (!empty($alter['trim']) && !empty($alter['max_length'])) {
+      $value = $this->render_trim_text($alter, $value);
+    }
+
+    if (!empty($alter['make_link']) && !empty($alter['path'])) {
+      if (!isset($tokens)) {
+       $tokens = $this->get_render_tokens($alter);
+      }
+      $value = $this->render_as_link($alter, $value, $tokens);
+    }
+
+    return $value;
+  }
+
+  /**
    * Render this field as altered text, from a fieldset set by the user.
    */
-  function render_altered($tokens) {
+  function render_altered($alter, $tokens) {
     // Filter this right away as our substitutions are already sanitized.
-    $value = filter_xss_admin($this->options['alter']['text']);
+    $value = filter_xss_admin($alter['text']);
     $value = strtr($value, $tokens);
 
     return $value;
@@ -447,61 +557,49 @@ class views_handler_field extends views_
   /**
    * Trim the field down to the specified length.
    */
-  function render_trim_text($value) {
-    if (!empty($this->options['alter']['strip_tags'])) {
-      $value = strip_tags($value);
+  function render_trim_text($alter, $value) {
+    if (!empty($alter['strip_tags'])) {
       // NOTE: It's possible that some external fields might override the
       // element type so if someone from, say, CCK runs into a bug here,
       // this may be why =)
       $this->definition['element type'] = 'span';
     }
-
-    if (drupal_strlen($value) <= $this->options['alter']['max_length']) {
-      return $value;
-    }
-
-    $value = drupal_substr($value, 0, $this->options['alter']['max_length']);
-
-    if (!empty($this->options['alter']['word_boundary'])) {
-      if (preg_match("/(.*)\b.+/us", $value, $matches)) {
-        $value = $matches[1];
-      }
-    }
-    // Remove scraps of HTML entities from the end of a strings
-    $value = rtrim(preg_replace('/(?:<(?!.+>)|&(?!.+;)).*$/us', '', $value));
-
-    if (!empty($this->options['alter']['ellipsis'])) {
-      $value .= '...';
-    }
-
-    if (!empty($this->options['alter']['html'])) {
-      $value = _filter_htmlcorrector($value);
-    }
-
-    return $value;
+    return views_trim_text($alter, $value);
   }
 
   /**
    * Render this field as a link, with the info from a fieldset set by
    * the user.
    */
-  function render_as_link($text, $tokens) {
+  function render_as_link($alter, $text, $tokens) {
     $value = '';
 
-    if (!empty($this->options['alter']['prefix'])) {
-      $value .= filter_xss_admin($this->options['alter']['prefix']);
+    if (!empty($alter['prefix'])) {
+      $value .= filter_xss_admin(strtr($alter['prefix'], $tokens));
     }
 
     $options = array(
-      'html' => 'true',
+      'html' => TRUE,
+      'absolute' => !empty($alter['absolute']) ? TRUE : FALSE,
     );
 
     // $path will be run through check_url() by l() so we do not need to
     // sanitize it ourselves.
-    $path = $this->options['alter']['path'];
+    $path = $alter['path'];
+
+    // html_entity_decode removes <front>, so check whether its different to front.
+    if ($path != '<front>') {
+      // 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().
+      $path = strip_tags(html_entity_decode(strtr($path, $tokens)));
+    }
 
-    // Use strip tags as there should never be HTML in the path.
-    $path = strip_tags(strtr($path, $tokens));
+    // If the path is empty do not build a link around the given text and return
+    // it as is.
+    if (empty($path)) {
+      return $text;
+    }
 
     // Parse the URL and move any query and fragment parameters out of the path.
     $url = parse_url($path);
@@ -514,31 +612,42 @@ class views_handler_field extends views_
       $options['fragment'] = $url['fragment'];
     }
 
-    $alt = $this->options['alter']['alt'];
-    $alt = strtr($alt, $tokens);
-    if ($alt) {
+    $alt = strtr($alter['alt'], $tokens);
+    // Set the title attribute of the link only if it improves accessibility
+    if ($alt && $alt != $text) {
       $options['attributes']['title'] = $alt;
-      $options['attributes']['alt'] = $alt;
     }
 
-    $class = $this->options['alter']['link_class'];
+    $class = strtr($alter['link_class'], $tokens);
     if ($class) {
       $options['attributes']['class'] = $class;
     }
 
+    $target = check_plain(trim(strtr($alter['target'],$tokens)));
+    if (!empty($target)) {
+      $options['attributes']['target'] = $target;
+    }
+
     // If the query and fragment were programatically assigned overwrite any
     // parsed values.
-    if (isset($this->options['alter']['query'])) {
-      $options['query'] = $this->options['alter']['query'];
+    if (isset($alter['query'])) {
+      $options['query'] = strtr($alter['query'], $tokens);
     }
-    if (isset($this->options['alter']['fragment'])) {
-      $options['fragment'] = $this->options['alter']['fragment'];
+    if (isset($alter['alias'])) {
+      // Alias is a boolean field, so no token.
+      $options['alias'] = $alter['alias'];
+    }
+    if (isset($alter['fragment'])) {
+      $options['fragment'] = strtr($alter['fragment'], $tokens);
+    }
+    if (isset($this->options['alter']['language'])) {
+      $options['language'] = $this->options['alter']['language'];
     }
 
     $value .= l($text, $path, $options);
 
-    if (!empty($this->options['alter']['suffix'])) {
-      $value .= filter_xss_admin($this->options['alter']['suffix']);
+    if (!empty($alter['suffix'])) {
+      $value .= filter_xss_admin(strtr($alter['suffix'], $tokens));
     }
 
     return $value;
@@ -551,7 +660,7 @@ class views_handler_field extends views_
    * are available and gets their values. This will then be
    * used in one giant str_replace().
    */
-  function get_render_tokens() {
+  function get_render_tokens($item) {
     $tokens = array();
     if (!empty($this->view->build_info['substitutions'])) {
       $tokens = $this->view->build_info['substitutions'];
@@ -562,10 +671,11 @@ class views_handler_field extends views_
       if (!isset($tokens[$token])) {
         $tokens[$token] = '';
       }
+
+      $tokens['!' . $count] = isset($this->view->args[$count - 1]) ? check_plain($this->view->args[$count - 1]) : '';
     }
 
     // Now add replacements for our fields.
-    $options = array();
     foreach ($this->view->display_handler->get_handlers('field') as $field => $handler) {
       if (isset($handler->last_render)) {
         $tokens["[$field]"] = $handler->last_render;
@@ -573,6 +683,8 @@ class views_handler_field extends views_
       else {
         $tokens["[$field]"] = '';
       }
+      $this->add_self_tokens($tokens, $item);
+
       // We only use fields up to (and including) this one.
       if ($field == $this->options['id']) {
         break;
@@ -583,6 +695,26 @@ class views_handler_field extends views_
   }
 
   /**
+   * Add any special tokens this field might use for itself.
+   *
+   * This method is intended to be overridden by items that generate
+   * fields as a list. For example, the field that displays all terms
+   * on a node might have tokens for the tid and the term.
+   *
+   * By convention, tokens should follow the format of [token-subtoken]
+   * where token is the field ID and subtoken is the field. If the
+   * field ID is terms, then the tokens might be [terms-tid] and [terms-name].
+   */
+  function add_self_tokens(&$tokens, $item) { }
+
+  /**
+   * Document any special tokens this field might use for itself.
+   *
+   * @see add_self_tokens() for details.
+   */
+  function document_self_tokens(&$tokens) { }
+
+  /**
    * Call out to the theme() function, which probably just calls render() but
    * allows sites to override output fairly easily.
    */
@@ -621,7 +753,7 @@ class views_handler_field extends views_
  * A special handler to take the place of missing or broken handlers.
  */
 class views_handler_field_broken extends views_handler_field {
-  function ui_name() {
+  function ui_name($short = FALSE) {
     return t('Broken/missing handler');
   }
 
Index: handlers/views_handler_field_boolean.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_field_boolean.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_handler_field_boolean.inc
--- handlers/views_handler_field_boolean.inc	30 Jan 2009 00:01:41 -0000	1.2
+++ handlers/views_handler_field_boolean.inc	11 Aug 2010 21:11:32 -0000
@@ -1,33 +1,53 @@
 <?php
-// $Id: views_handler_field_boolean.inc,v 1.2 2009/01/30 00:01:41 merlinofchaos Exp $
+// $Id: views_handler_field_boolean.inc,v 1.2.2.2 2010/03/25 01:14:18 merlinofchaos Exp $
 
 /**
- * A handler to provide proper displays for dates.
+ * A handler to provide proper displays for booleans.
  *
  * Allows for display of true/false, yes/no, on/off.
  *
+ * Definition terms:
+ *   - output formats: An array where the first entry is displayed on boolean false
+ *      and the second is displayed on boolean true. An example for sticky is:
+ *      @code
+ *      'output formats' => array(
+ *        'sticky' => array('', t('Sticky')),
+ *      ),
+ *      @endcode
+ *
  * @ingroup views_field_handlers
  */
 class views_handler_field_boolean extends views_handler_field {
   function option_definition() {
     $options = parent::option_definition();
-
     $options['type'] = array('default' => 'yes-no');
     $options['not'] = array('definition bool' => 'reverse');
 
     return $options;
   }
 
+  function init(&$view, $options) {
+    parent::init($view, $options);
+
+    $default_formats = array(
+      'yes-no' => array(t('Yes'), t('No')),
+      'true-false' => array(t('True'), t('False')),
+      'on-off' => array(t('On'), t('Off')),
+    );
+    $output_formats = isset($this->definition['output formats']) ? $this->definition['output formats'] : array();
+    $this->formats = array_merge($default_formats, $output_formats);
+  }
+
   function options_form(&$form, &$form_state) {
     parent::options_form($form, $form_state);
+    foreach ($this->formats as $key => $item) {
+      $options[$key] = implode('/', $item);
+    }
+
     $form['type'] = array(
       '#type' => 'select',
       '#title' => t('Output format'),
-      '#options' => array(
-        'yes-no' => t('Yes/No'),
-        'true-false' => t('True/False'),
-        'on-off' => t('On/Off'),
-      ),
+      '#options' => $options,
       '#default_value' => $this->options['type'],
     );
     $form['not'] = array(
@@ -44,14 +64,11 @@ class views_handler_field_boolean extend
       $value = !$value;
     }
 
-    switch ($this->options['type']) {
-      case 'yes-no':
-      default:
-        return $value ? t('Yes') : t('No');
-      case 'true-false':
-        return $value ? t('True') : t('False');
-      case 'on-off':
-        return $value ? t('On') : t('Off');
+    if (isset($this->formats[$this->options['type']])) {
+      return $value ? $this->formats[$this->options['type']][0] : $this->formats[$this->options['type']][1];
+    }
+    else {
+      return $value ? $this->formats['yes-no'][0] : $this->formats['yes-no'][1];
     }
   }
 }
Index: handlers/views_handler_field_counter.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_field_counter.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_field_counter.inc
--- handlers/views_handler_field_counter.inc	2 Jun 2009 20:18:26 -0000	1.1
+++ handlers/views_handler_field_counter.inc	11 Aug 2010 21:11:32 -0000
@@ -1,21 +1,42 @@
 <?php
-// $Id: views_handler_field_counter.inc,v 1.1 2009/06/02 20:18:26 merlinofchaos Exp $
+// $Id: views_handler_field_counter.inc,v 1.1.2.7 2009/12/03 01:47:31 merlinofchaos Exp $
 
 class views_handler_field_counter extends views_handler_field {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['counter_start'] = array('default' => 1);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['counter_start'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Starting value'),
+      '#default_value' => $this->options['counter_start'],
+      '#description' => t('Specify the number the counter should start at.'),
+      //'#process' => array('views_process_dependency'),
+      '#size' => 2,
+    );
+  }
+
   function query() {
     // do nothing -- to override the parent query.
   }
 
   function render($values) {
-    $pager = $this->view->pager;
+    // Note:  1 is subtracted from the counter start value below because the
+    // counter value is incremented by 1 at the end of this function.
+    $count = is_numeric($this->options['counter_start']) ? $this->options['counter_start'] - 1 : 0;
+    $pager = $this->view->query->pager;
     // Get the base count of the pager.
-    if ($pager['use_pager']) {
-      $count = ($pager['items_per_page'] * $pager['current_page']);
-      $count += $pager['offset'];
+    if ($pager->use_pager()) {
+      $count += ($pager->get_items_per_page() * $pager->get_current_page() + $pager->get_offset());
     }
     // Add the counter for the current site.
-    $count += array_search($values, $this->view->result) + 1;
+    $count += $this->view->row_index + 1;
 
-     return $count;
+    return $count;
   }
 }
Index: handlers/views_handler_field_date.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_field_date.inc,v
retrieving revision 1.3
diff -u -p -r1.3 views_handler_field_date.inc
--- handlers/views_handler_field_date.inc	2 Jun 2009 18:20:18 -0000	1.3
+++ handlers/views_handler_field_date.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_date.inc,v 1.3 2009/06/02 18:20:18 merlinofchaos Exp $
+// $Id: views_handler_field_date.inc,v 1.2.2.1 2009/06/02 18:20:12 merlinofchaos Exp $
 /**
  * A handler to provide proper displays for dates.
  *
Index: handlers/views_handler_field_markup.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_field_markup.inc,v
retrieving revision 1.3
diff -u -p -r1.3 views_handler_field_markup.inc
--- handlers/views_handler_field_markup.inc	8 Jan 2009 20:01:00 -0000	1.3
+++ handlers/views_handler_field_markup.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_markup.inc,v 1.3 2009/01/08 20:01:00 merlinofchaos Exp $
+// $Id: views_handler_field_markup.inc,v 1.3.2.1 2009/11/18 20:52:20 merlinofchaos Exp $
 
 /**
  * A handler to run a field through check_markup, using a companion
@@ -29,7 +29,9 @@ class views_handler_field_markup extends
   function render($values) {
     $value = $values->{$this->field_alias};
     $format = is_numeric($this->format) ? $this->format : $values->{$this->aliases['format']};
-    return check_markup($value, $format, FALSE);
+    if ($value) {
+      return check_markup($value, $format, FALSE);
+    }
   }
 
   function element_type() {
Index: handlers/views_handler_field_numeric.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_field_numeric.inc,v
retrieving revision 1.5
diff -u -p -r1.5 views_handler_field_numeric.inc
--- handlers/views_handler_field_numeric.inc	7 Apr 2009 22:59:14 -0000	1.5
+++ handlers/views_handler_field_numeric.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_numeric.inc,v 1.5 2009/04/07 22:59:14 merlinofchaos Exp $
+// $Id: views_handler_field_numeric.inc,v 1.5.2.2 2010/07/27 21:59:03 merlinofchaos Exp $
 /**
  * Render a field as a numeric value
  *
@@ -17,6 +17,9 @@ class views_handler_field_numeric extend
     $options['precision'] = array('default' => 0);
     $options['decimal'] = array('default' => '.', 'translatable' => TRUE);
     $options['separator'] = array('default' => ',', 'translatable' => TRUE);
+    $options['format_plural'] = array('default' => FALSE);
+    $options['format_plural_singular'] = array('default' => '1');
+    $options['format_plural_plural'] = array('default' => '@count');
     $options['prefix'] = array('default' => '', 'translatable' => TRUE);
     $options['suffix'] = array('default' => '', 'translatable' => TRUE);
 
@@ -57,6 +60,28 @@ class views_handler_field_numeric extend
       '#description' => t('What single character to use as the thousands separator.'),
       '#size' => 2,
     );
+    $form['format_plural'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Format plural'),
+      '#description' => t('If checked, special handling will be used for plurality.'),
+      '#default_value' => $this->options['format_plural'],
+    );
+    $form['format_plural_singular'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Singular form'),
+      '#default_value' => $this->options['format_plural_singular'],
+      '#description' => t('Text to use for the singular form.'),
+      '#process' => array('views_process_dependency'),
+      '#dependency' => array('edit-options-format-plural' => array(TRUE)),
+    );
+    $form['format_plural_plural'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Plural form'),
+      '#default_value' => $this->options['format_plural_plural'],
+      '#description' => t('Text to use for the plural form, @count will be replaced with the value.'),
+      '#process' => array('views_process_dependency'),
+      '#dependency' => array('edit-options-format-plural' => array(TRUE)),
+    );
     $form['prefix'] = array(
       '#type' => 'textfield',
       '#title' => t('Prefix'),
@@ -85,6 +110,17 @@ class views_handler_field_numeric extend
         $value .= $this->options['decimal'] . substr($remainder, 2);
       }
     }
+
+    // Check to see if hiding should happen before adding prefix and suffix.
+    if ($this->options['hide_empty'] && empty($value) && ($value !== 0 || $this->options['empty_zero'])) {
+      return '';
+    }
+
+    // Should we format as a plural.
+    if (!empty($this->options['format_plural'])) {
+      $value = format_plural($value, $this->options['format_plural_singular'], $this->options['format_plural_plural']);
+    }
+
     return check_plain($this->options['prefix'] . $value . $this->options['suffix']);
   }
 }
Index: handlers/views_handler_field_prerender_list.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_field_prerender_list.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_field_prerender_list.inc
--- handlers/views_handler_field_prerender_list.inc	3 Sep 2008 19:21:28 -0000	1.1
+++ handlers/views_handler_field_prerender_list.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_prerender_list.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos Exp $
+// $Id: views_handler_field_prerender_list.inc,v 1.1.2.2 2009/07/02 00:13:06 merlinofchaos Exp $
 
 /**
  * Field handler to provide a list of items.
@@ -17,7 +17,6 @@ class views_handler_field_prerender_list
 
     $options['type'] = array('default' => 'separator');
     $options['separator'] = array('default' => ', ');
-    $options['empty'] = array('default' => '', 'translatable' => TRUE);
 
     return $options;
   }
@@ -42,15 +41,15 @@ class views_handler_field_prerender_list
       '#process' => array('views_process_dependency'),
       '#dependency' => array('radio:options[type]' => array('separator')),
     );
-
-    $form['empty'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Empty list text'),
-      '#default_value' => $this->options['empty'],
-      '#description' => t('If the list is empty, you may enter text here that will be displayed.'),
-    );
   }
 
+  /**
+   * Render the field.
+   *
+   * This function is deprecated, but left in for older systems that have not
+   * yet or won't update their prerender list fields. If a render_item method
+   * exists, this will not get used by advanced_render.
+   */
   function render($values) {
     $field = $values->{$this->field_alias};
     if (!empty($this->items[$field])) {
@@ -61,8 +60,53 @@ class views_handler_field_prerender_list
         return theme('item_list', $this->items[$field], NULL, $this->options['type']);
       }
     }
-    else if (!empty($this->options['empty'])) {
-      return $this->options['empty'];
+  }
+
+  /**
+   * Render all items in this field together.
+   *
+   * When using advanced render, each possible item in the list is rendered
+   * individually. Then the items are all pasted together.
+   */
+  function render_items($items) {
+    if (!empty($items)) {
+      if ($this->options['type'] == 'separator') {
+        return implode(check_plain($this->options['separator']), $items);
+      }
+      else {
+        return theme('item_list', $items, NULL, $this->options['type']);
+      }
+    }
+  }
+
+  /**
+   * Return an array of items for the field.
+   *
+   * Items should be stored in the result array, if possible, as an array 
+   * with 'value' as the actual displayable value of the item, plus
+   * any items that might be found in the 'alter' options array for
+   * creating links, such as 'path', 'fragment', 'query' etc, such a thing
+   * is to be made. Additionally, items that might be turned into tokens
+   * should also be in this array.
+   */
+  function get_items($values) {
+    $field = $values->{$this->field_alias};
+    if (!empty($this->items[$field])) {
+      return $this->items[$field];
     }
+    
+    return array();
+  }
+
+  /**
+   * Determine if advanced rendering is allowed.
+   *
+   * By default, advanced rendering will NOT be allowed if the class
+   * inheriting from this does not implement a 'render_items' method.
+   */
+  function allow_advanced_render() {
+    // Note that the advanced render bits also use the presence of
+    // this method to determine if it needs to render items as a list.
+    return method_exists($this, 'render_item');
   }
 }
Index: handlers/views_handler_field_url.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_field_url.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_field_url.inc
--- handlers/views_handler_field_url.inc	3 Sep 2008 19:21:28 -0000	1.1
+++ handlers/views_handler_field_url.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_url.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos Exp $
+// $Id: views_handler_field_url.inc,v 1.1.2.1 2010/06/17 02:47:02 merlinofchaos Exp $
 
 /**
  * Field handler to provide simple renderer that turns a URL into a clickable link.
@@ -33,7 +33,7 @@ class views_handler_field_url extends vi
       return l(check_plain($value), $value, array('html' => TRUE));
     }
     else {
-      return $value;
+      return check_url($value);
     }
   }
 }
Index: handlers/views_handler_filter.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_filter.inc,v
retrieving revision 1.9
diff -u -p -r1.9 views_handler_filter.inc
--- handlers/views_handler_filter.inc	3 Jun 2009 00:05:05 -0000	1.9
+++ handlers/views_handler_filter.inc	11 Aug 2010 21:11:32 -0000
@@ -1,614 +1,546 @@
-<?php
-// $Id: views_handler_filter.inc,v 1.9 2009/06/03 00:05:05 merlinofchaos Exp $
-/**
- * @defgroup views_filter_handlers Views' filter handlers
- * @{
- * Handlers to tell Views how to filter queries.
- *
- * Definition items:
- * - allow empty: If true, the 'IS NULL' and 'IS NOT NULL' operators become
- *   available as standard operators.
- * -
- */
-
-/**
- * Base class for filters.
- */
-class views_handler_filter extends views_handler {
-  /**
-   * Provide some extra help to get the operator/value easier to use.
-   *
-   * This likely has to be overridden by filters which are more complex
-   * than simple operator/value.
-   */
-  function init(&$view, $options) {
-    parent::init($view, $options);
-
-    $this->operator = $this->options['operator'];
-    $this->value = $this->options['value'];
-
-    // Compatibility: Set use_operator to true if the old way of using
-    // the operator is set and use_operator is NULL (was never set).
-    if (!empty($options['exposed']) && !empty($options['expose']['operator']) && !isset($options['expose']['use_operator'])) {
-      $this->options['expose']['use_operator'] = TRUE;
-    }
-
-    // If there are relationships in the view, allow empty should be true
-    // so that we can do IS NULL checks on items. Not all filters respect
-    // allow empty, but string and numeric do and that covers enough.
-    if ($this->view->display_handler->get_option('relationships')) {
-      $this->definition['allow empty'] = TRUE;
-    }
-  }
-
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['operator'] = array('default' => '=');
-    $options['value'] = array('default' => '');
-    $options['group'] = array('default' => '0');
-    $options['exposed'] = array('default' => FALSE);
-    $options['expose'] = array(
-      'contains' => array(
-        'operator' => array('default' => FALSE),
-        'label' => array('default' => '', 'translatable' => TRUE),
-      ),
-    );
-
-    return $options;
-  }
-
-  /**
-   * Display the filter on the administrative summary
-   */
-  function admin_summary() {
-    return check_plain((string) $this->operator) . ' ' . check_plain((string) $this->value);
-  }
-
-  /**
-   * Determine if a filter can be exposed.
-   */
-  function can_expose() { return TRUE; }
-
-  /**
-   * Provide the basic form which calls through to subforms.
-   * If overridden, it is best to call through to the parent,
-   * or to at least make sure all of the functions in this form
-   * are called.
-   */
-  function options_form(&$form, &$form_state) {
-    if ($this->can_expose()) {
-      $this->show_expose_button($form, $form_state);
-    }
-    $form['op_val_start'] = array('#value' => '<div class="clear-block">');
-    $this->show_operator_form($form, $form_state);
-    $this->show_value_form($form, $form_state);
-    $form['op_val_end'] = array('#value' => '</div>');
-    if ($this->can_expose()) {
-      $this->show_expose_form($form, $form_state);
-    }
-  }
-
-  /**
-   * Simple validate handler
-   */
-  function options_validate(&$form, &$form_state) {
-    $this->operator_validate($form, $form_state);
-    $this->value_validate($form, $form_state);
-    if (!empty($this->options['exposed'])) {
-      $this->expose_validate($form, $form_state);
-    }
-
-  }
-
-  /**
-   * Simple submit handler
-   */
-  function options_submit(&$form, &$form_state) {
-    unset($form_state['values']['expose_button']); // don't store this.
-    $this->operator_submit($form, $form_state);
-    $this->value_submit($form, $form_state);
-    if (!empty($this->options['exposed'])) {
-      $this->expose_submit($form, $form_state);
-    }
-  }
-
-  /**
-   * Shortcut to display the operator form.
-   */
-  function show_operator_form(&$form, &$form_state) {
-    $this->operator_form($form, $form_state);
-    $form['operator']['#prefix'] = '<div class="views-left-30">';
-    $form['operator']['#suffix'] = '</div>';
-  }
-
-  /**
-   * Provide a form for setting the operator.
-   *
-   * This may be overridden by child classes, and it must
-   * define $form['operator'];
-   */
-  function operator_form(&$form, &$form_state) {
-    $options = $this->operator_options();
-    if (!empty($options)) {
-      $form['operator'] = array(
-        '#type' => count($options) < 10 ? 'radios' : 'select',
-        '#title' => t('Operator'),
-        '#default_value' => $this->operator,
-        '#options' => $options,
-      );
-    }
-  }
-
-  /**
-   * Provide a list of options for the default operator form.
-   * Should be overridden by classes that don't override operator_form
-   */
-  function operator_options() { return array(); }
-
-  /**
-   * Validate the operator form.
-   */
-  function operator_validate($form, &$form_state) { }
-
-  /**
-   * Perform any necessary changes to the form values prior to storage.
-   * There is no need for this function to actually store the data.
-   */
-  function operator_submit($form, &$form_state) { }
-
-  /**
-   * Shortcut to display the value form.
-   */
-  function show_value_form(&$form, &$form_state) {
-    $this->value_form($form, $form_state);
-    if (empty($this->no_operator)) {
-      $form['value']['#prefix'] = '<div class="views-right-70">' . (isset($form['value']['#prefix']) ? $form['value']['#prefix'] : '');
-      $form['value']['#suffix'] = (isset($form['value']['#suffix']) ? $form['value']['#suffix'] : '') . '</div>';
-    }
-  }
-
-  /**
-   * Provide a form for setting options.
-   *
-   * This should be overridden by all child classes and it must
-   * define $form['value']
-   */
-  function value_form(&$form, &$form_state) { $form['value'] = array(); }
-
-  /**
-   * Validate the options form.
-   */
-  function value_validate($form, &$form_state) { }
-
-  /**
-   * Perform any necessary changes to the form values prior to storage.
-   * There is no need for this function to actually store the data.
-   */
-  function value_submit($form, &$form_state) { }
-
-  /**
-   * Shortcut to display the expose/hide button.
-   */
-  function show_expose_button(&$form, &$form_state) {
-    $form['expose_button'] = array(
-      '#prefix' => '<div class="views-expose clear-block">',
-      '#suffix' => '</div>',
-    );
-    if (empty($this->options['exposed'])) {
-      $form['expose_button']['button'] = array(
-        '#type' => 'submit',
-        '#value' => t('Expose'),
-        '#submit' => array('views_ui_config_item_form_expose'),
-      );
-      $form['expose_button']['markup'] = array(
-        '#prefix' => '<div class="description">',
-        '#value' => t('This item is currently not exposed. If you <strong>expose</strong> it, users will be able to change the filter as they view it.'),
-        '#suffix' => '</div>',
-      );
-    }
-    else {
-      $form['expose_button']['button'] = array(
-        '#type' => 'submit',
-        '#value' => t('Hide'),
-        '#submit' => array('views_ui_config_item_form_expose'),
-      );
-      $form['expose_button']['markup'] = array(
-        '#prefix' => '<div class="description">',
-        '#value' => t('This item is currently exposed. If you <strong>hide</strong> it, users will not be able to change the filter as they view it.'),
-        '#suffix' => '</div>',
-      );
-    }
-  }
-
-  /**
-   * Shortcut to display the exposed options form.
-   */
-  function show_expose_form(&$form, &$form_state) {
-    if (empty($this->options['exposed'])) {
-      return;
-    }
-
-    $form['expose'] = array(
-      '#prefix' => '<div class="views-expose-options clear-block">',
-      '#suffix' => '</div>',
-    );
-    $this->expose_form($form, $form_state);
-
-    // When we click the expose button, we add new gadgets to the form but they
-    // have no data in $_POST so their defaults get wiped out. This prevents
-    // these defaults from getting wiped out. This setting will only be TRUE
-    // during a 2nd pass rerender.
-    if (!empty($form_state['force_expose_options'])) {
-      foreach (element_children($form['expose']) as $id) {
-        if (isset($form['expose'][$id]['#default_value']) && !isset($form['expose'][$id]['#value'])) {
-          $form['expose'][$id]['#value'] = $form['expose'][$id]['#default_value'];
-        }
-      }
-    }
-  }
-
-  /**
-   * Overridable form for exposed filter options.
-   *
-   * If overridden, it is best to call the parent or re-implement
-   * the stuff here.
-   *
-   * Many filters will need to override this in order to provide options
-   * that are nicely tailored to the given filter.
-   */
-  function expose_form(&$form, &$form_state) {
-    $form['expose']['start_left'] = array(
-      '#value' => '<div class="views-left-50">',
-    );
-
-    $this->expose_form_left($form, $form_state);
-
-    $form['expose']['end_left'] = array(
-      '#value' => '</div>',
-    );
-
-    $form['expose']['start_checkboxes'] = array(
-      '#value' => '<div class="form-checkboxes views-left-40 clear-block">',
-    );
-
-    $this->expose_form_right($form, $form_state);
-
-    $form['expose']['end_checkboxes'] = array(
-      '#value' => '</div>',
-    );
-  }
-
-  /**
-   * Handle the 'left' side fo the exposed options form.
-   */
-  function expose_form_left(&$form, &$form_state) {
-    if (!empty($form['operator']['#type'])) {
-      $form['expose']['use_operator'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Unlock operator'),
-        '#description' => t('When checked, the operator will be exposed to the user'),
-        '#default_value' => !empty($this->options['expose']['use_operator']),
-      );
-      $form['expose']['operator'] = array(
-        '#type' => 'textfield',
-        '#default_value' => $this->options['expose']['operator'],
-        '#title' => t('Operator identifier'),
-        '#size' => 40,
-        '#description' => t('This will appear in the URL after the ? to identify this operator.'),
-        '#process' => array('views_process_dependency'),
-        '#dependency' => array(
-          'edit-options-expose-use-operator' => array(1)
-        ),
-      );
-    }
-    else {
-      $form['expose']['operator'] = array(
-        '#type' => 'value',
-        '#value' => '',
-      );
-    }
-
-    $form['expose']['identifier'] = array(
-      '#type' => 'textfield',
-      '#default_value' => $this->options['expose']['identifier'],
-      '#title' => t('Filter identifier'),
-      '#size' => 40,
-      '#description' => t('This will appear in the URL after the ? to identify this filter. Cannot be blank.'),
-    );
-    $form['expose']['label'] = array(
-      '#type' => 'textfield',
-      '#default_value' => $this->options['expose']['label'],
-      '#title' => t('Label'),
-      '#size' => 40,
-    );
-  }
-
-  /**
-   * Handle the 'right' side fo the exposed options form.
-   */
-  function expose_form_right(&$form, &$form_state) {
-    $form['expose']['optional'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Optional'),
-      '#description' => t('This exposed filter is optional and will have added options to allow it not to be set.'),
-      '#default_value' => $this->options['expose']['optional'],
-    );
-    if (empty($this->no_single)) {
-      $form['expose']['single'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Force single'),
-        '#description' => t('Force this exposed filter to accept only one option.'),
-        '#default_value' => $this->options['expose']['single'],
-      );
-    }
-    $form['expose']['remember'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Remember'),
-      '#description' => t('Remember the last setting the user gave this filter.'),
-      '#default_value' => $this->options['expose']['remember'],
-    );
-  }
-
-  /**
-   * Validate the options form.
-   */
-  function expose_validate($form, &$form_state) {
-    if (empty($this->options['expose']['identifier'])) {
-      if (empty($form_state['values']['options']['expose']['identifier'])) {
-        form_error($form['expose']['identifier'], t('The identifier is required if the filter is exposed.'));
-      }
-    }
-
-    if (!empty($form_state['values']['options']['expose']['identifier']) && $form_state['values']['options']['expose']['identifier'] == 'value') {
-      form_error($form['expose']['identifier'], t('This identifier is not allowed.'));
-    }
-  }
-
-  /**
-   * Perform any necessary changes to the form exposes prior to storage.
-   * There is no need for this function to actually store the data.
-   */
-  function expose_submit($form, &$form_state) { }
-
-  /**
-   * Provide default options for exposed filters.
-   */
-  function expose_options() {
-    $this->options['expose'] = array(
-      'use_operator' => FALSE,
-      'operator' => $this->options['id'] . '_op',
-      'identifier' => $this->options['id'],
-      'label' => $this->ui_name(),
-      'remember' => FALSE,
-      'single' => TRUE,
-      'optional' => TRUE,
-    );
-  }
-
-  /**
-   * Render our chunk of the exposed filter form when selecting
-   *
-   * You can override this if it doesn't do what you expect.
-   */
-  function exposed_form(&$form, &$form_state) {
-    if (empty($this->options['exposed'])) {
-      return;
-    }
-
-    if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator'])) {
-      $operator = $this->options['expose']['operator'];
-      $this->operator_form($form, $form_state);
-      $form[$operator] = $form['operator'];
-
-      if (isset($form[$operator]['#title'])) {
-        unset($form[$operator]['#title']);
-      }
-
-      $this->exposed_translate($form[$operator], 'operator');
-
-      unset($form['operator']);
-    }
-
-    if (!empty($this->options['expose']['identifier'])) {
-      $value = $this->options['expose']['identifier'];
-      $this->value_form($form, $form_state);
-      $form[$value] = $form['value'];
-
-      if (isset($form[$value]['#title']) && !empty($form[$value]['#type']) && $form[$value]['#type'] != 'checkbox') {
-        unset($form[$value]['#title']);
-      }
-
-      $this->exposed_translate($form[$value], 'value');
-
-      if (!empty($form['#type']) && ($form['#type'] == 'checkboxes' || ($form['#type'] == 'select' && !empty($form['#multiple'])))) {
-        unset($form[$value]['#default_value']);
-      }
-
-      if (!empty($form['#type']) && $form['#type'] == 'select' && empty($form['#multiple'])) {
-        $form[$value]['#default_value'] = 'All';
-      }
-
-      if ($value != 'value') {
-        unset($form['value']);
-      }
-    }
-  }
-
-  /**
-   * Make some translations to a form item to make it more suitable to
-   * exposing.
-   */
-  function exposed_translate(&$form, $type) {
-    if (!isset($form['#type'])) {
-      return;
-    }
-
-    if ($form['#type'] == 'radios') {
-      $form['#type'] = 'select';
-    }
-    // Checkboxes don't work so well in exposed forms due to GET conversions.
-    if ($form['#type'] == 'checkboxes') {
-      if (empty($form['#no_convert']) || !empty($this->options['expose']['single'])) {
-        $form['#type'] = 'select';
-      }
-      if (empty($this->options['expose']['single'])) {
-        $form['#multiple'] = TRUE;
-      }
-    }
-    if (!empty($this->options['expose']['single']) && isset($form['#multiple'])) {
-      unset($form['#multiple']);
-      $form['#size'] = NULL;
-    }
-
-    if ($type == 'value' && !empty($this->options['expose']['optional']) && $form['#type'] == 'select' && empty($form['#multiple'])) {
-      $any_label = variable_get('views_exposed_filter_any_label', 'old_any') == 'old_any' ? t('<Any>') : t('- Any -');
-      $form['#options'] = array('All' => $any_label) + $form['#options'];
-      $form['#default_value'] = 'All';
-    }
-  }
-
-  /**
-   * Tell the renderer about our exposed form. This only needs to be
-   * overridden for particularly complex forms. And maybe not even then.
-   */
-  function exposed_info() {
-    if (empty($this->options['exposed'])) {
-      return;
-    }
-
-    return array(
-      'operator' => $this->options['expose']['operator'],
-      'value' => $this->options['expose']['identifier'],
-      'label' => $this->options['expose']['label'],
-    );
-  }
-
-  /**
-   * Check to see if input from the exposed filters should change
-   * the behavior of this filter.
-   */
-  function accept_exposed_input($input) {
-    if (empty($this->options['exposed'])) {
-      return TRUE;
-    }
-
-
-    if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator']) && isset($input[$this->options['expose']['operator']])) {
-      $this->operator = $input[$this->options['expose']['operator']];
-    }
-
-    if (!empty($this->options['expose']['identifier'])) {
-      $value = $input[$this->options['expose']['identifier']];
-
-      // Various ways to check for the absence of optional input.
-      if (!empty($this->options['expose']['optional'])) {
-        if ($value == 'All' || $value === array()) {
-          return FALSE;
-        }
-
-        if (!empty($this->no_single) && $value === '') {
-          return FALSE;
-        }
-      }
-
-
-      if (isset($value)) {
-        $this->value = $value;
-        if (!empty($this->options['expose']['single'])) {
-          $this->value = array($value);
-        }
-      }
-      else {
-        return FALSE;
-      }
-    }
-
-    return TRUE;
-  }
-
-  function store_exposed_input($input, $status) {
-    if (empty($this->options['exposed']) || empty($this->options['expose']['identifier'])) {
-      return TRUE;
-    }
-
-    if (empty($this->options['expose']['remember'])) {
-      return;
-    }
-
-    // Figure out which display id is responsible for the filters, so we
-    // know where to look for session stored values.
-    $display_id = ($this->view->display_handler->is_defaulted('filters')) ? 'default' : $this->view->current_display;
-
-    // shortcut test.
-    $operator = !empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator']);
-
-    // false means that we got a setting that means to recuse ourselves,
-    // so we should erase whatever happened to be there.
-    if (!$status && isset($_SESSION['views'][$this->view->name][$display_id])) {
-      $session = &$_SESSION['views'][$this->view->name][$display_id];
-      if ($operator && isset($session[$this->options['expose']['operator']])) {
-        unset($session[$this->options['expose']['operator']]);
-      }
-
-      if (isset($session[$this->options['expose']['identifier']])) {
-        unset($session[$this->options['expose']['identifier']]);
-      }
-    }
-
-    if ($status) {
-      if (!isset($_SESSION['views'][$this->view->name][$display_id])) {
-        $_SESSION['views'][$this->view->name][$display_id] = array();
-      }
-
-      $session = &$_SESSION['views'][$this->view->name][$display_id];
-
-      if ($operator && isset($input[$this->options['expose']['operator']])) {
-        $session[$this->options['expose']['operator']] = $input[$this->options['expose']['operator']];
-      }
-
-      $session[$this->options['expose']['identifier']] = $input[$this->options['expose']['identifier']];
-    }
-  }
-
-  /**
-   * Add this filter to the query.
-   *
-   * Due to the nature of fapi, the value and the operator have an unintended
-   * level of indirection. You will find them in $this->operator
-   * and $this->value respectively.
-   */
-  function query() {
-    $this->ensure_my_table();
-    $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field " . $this->operator . " '%s'", $this->value);
-  }
-}
-
-
-/**
- * A special handler to take the place of missing or broken handlers.
- */
-class views_handler_filter_broken extends views_handler_filter {
-  function ui_name() {
-    return t('Broken/missing handler');
-  }
-
-  function ensure_my_table() { /* No table to ensure! */ }
-  function query() { /* No query to run */ }
-  function options_form(&$form, &$form_state) {
-    $form['markup'] = array(
-      '#prefix' => '<div class="form-item description">',
-      '#value' => t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.'),
-    );
-  }
-
-  /**
-   * Determine if the handler is considered 'broken'
-   */
-  function broken() { return TRUE; }
-}
-
-
-/**
- * @}
- */
+<?php
+// $Id: views_handler_filter.inc,v 1.6.2.15 2010/03/22 20:44:52 merlinofchaos Exp $
+/**
+ * @defgroup views_filter_handlers Views' filter handlers
+ * @{
+ * Handlers to tell Views how to filter queries.
+ *
+ * Definition items:
+ * - allow empty: If true, the 'IS NULL' and 'IS NOT NULL' operators become
+ *   available as standard operators.
+ * -
+ */
+
+/**
+ * Base class for filters.
+ */
+class views_handler_filter extends views_handler {
+  /**
+   * Provide some extra help to get the operator/value easier to use.
+   *
+   * This likely has to be overridden by filters which are more complex
+   * than simple operator/value.
+   */
+  function init(&$view, $options) {
+    parent::init($view, $options);
+
+    $this->operator = $this->options['operator'];
+    $this->value = $this->options['value'];
+
+    // Compatibility: Set use_operator to true if the old way of using
+    // the operator is set and use_operator is NULL (was never set).
+    if (!empty($options['exposed']) && !empty($options['expose']['operator']) && !isset($options['expose']['use_operator'])) {
+      $this->options['expose']['use_operator'] = TRUE;
+    }
+
+    // If there are relationships in the view, allow empty should be true
+    // so that we can do IS NULL checks on items. Not all filters respect
+    // allow empty, but string and numeric do and that covers enough.
+    if ($this->view->display_handler->get_option('relationships')) {
+      $this->definition['allow empty'] = TRUE;
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['operator'] = array('default' => '=');
+    $options['value'] = array('default' => '');
+    $options['group'] = array('default' => '0');
+    $options['exposed'] = array('default' => FALSE);
+    $options['expose'] = array(
+      'contains' => array(
+        'operator' => array('default' => FALSE),
+        'label' => array('default' => '', 'translatable' => TRUE),
+        'use_operator' => array('deafult' => 0),
+        'operator' => array('default' => ''),
+        'identifier' => array('default' => ''),
+        'optional' => array('default' => 1),
+        'remember' => array('default' => 0),
+        'single' => array('default' => 1),
+      ),
+    );
+
+    return $options;
+  }
+
+  /**
+   * Display the filter on the administrative summary
+   */
+  function admin_summary() {
+    return check_plain((string) $this->operator) . ' ' . check_plain((string) $this->value);
+  }
+
+  /**
+   * Determine if a filter can be exposed.
+   */
+  function can_expose() { return TRUE; }
+
+  /**
+   * Provide the basic form which calls through to subforms.
+   * If overridden, it is best to call through to the parent,
+   * or to at least make sure all of the functions in this form
+   * are called.
+   */
+  function options_form(&$form, &$form_state) {
+    if ($this->can_expose()) {
+      $this->show_expose_button($form, $form_state);
+    }
+    $form['op_val_start'] = array('#value' => '<div class="clear-block">');
+    $this->show_operator_form($form, $form_state);
+    $this->show_value_form($form, $form_state);
+    $form['op_val_end'] = array('#value' => '</div>');
+    if ($this->can_expose()) {
+      $this->show_expose_form($form, $form_state);
+    }
+  }
+
+  /**
+   * Simple validate handler
+   */
+  function options_validate(&$form, &$form_state) {
+    $this->operator_validate($form, $form_state);
+    $this->value_validate($form, $form_state);
+    if (!empty($this->options['exposed'])) {
+      $this->expose_validate($form, $form_state);
+    }
+
+  }
+
+  /**
+   * Simple submit handler
+   */
+  function options_submit($form, &$form_state) {
+    unset($form_state['values']['expose_button']); // don't store this.
+    $this->operator_submit($form, $form_state);
+    $this->value_submit($form, $form_state);
+    if (!empty($this->options['exposed'])) {
+      $this->expose_submit($form, $form_state);
+    }
+  }
+
+  /**
+   * Shortcut to display the operator form.
+   */
+  function show_operator_form(&$form, &$form_state) {
+    $this->operator_form($form, $form_state);
+    $form['operator']['#prefix'] = '<div class="views-left-30">';
+    $form['operator']['#suffix'] = '</div>';
+  }
+
+  /**
+   * Provide a form for setting the operator.
+   *
+   * This may be overridden by child classes, and it must
+   * define $form['operator'];
+   */
+  function operator_form(&$form, &$form_state) {
+    $options = $this->operator_options();
+    if (!empty($options)) {
+      $form['operator'] = array(
+        '#type' => count($options) < 10 ? 'radios' : 'select',
+        '#title' => t('Operator'),
+        '#default_value' => $this->operator,
+        '#options' => $options,
+      );
+    }
+  }
+
+  /**
+   * Provide a list of options for the default operator form.
+   * Should be overridden by classes that don't override operator_form
+   */
+  function operator_options() { return array(); }
+
+  /**
+   * Validate the operator form.
+   */
+  function operator_validate($form, &$form_state) { }
+
+  /**
+   * Perform any necessary changes to the form values prior to storage.
+   * There is no need for this function to actually store the data.
+   */
+  function operator_submit($form, &$form_state) { }
+
+  /**
+   * Shortcut to display the value form.
+   */
+  function show_value_form(&$form, &$form_state) {
+    $this->value_form($form, $form_state);
+    if (empty($this->no_operator)) {
+      $form['value']['#prefix'] = '<div class="views-right-70">' . (isset($form['value']['#prefix']) ? $form['value']['#prefix'] : '');
+      $form['value']['#suffix'] = (isset($form['value']['#suffix']) ? $form['value']['#suffix'] : '') . '</div>';
+    }
+  }
+
+  /**
+   * Provide a form for setting options.
+   *
+   * This should be overridden by all child classes and it must
+   * define $form['value']
+   */
+  function value_form(&$form, &$form_state) { $form['value'] = array(); }
+
+  /**
+   * Validate the options form.
+   */
+  function value_validate($form, &$form_state) { }
+
+  /**
+   * Perform any necessary changes to the form values prior to storage.
+   * There is no need for this function to actually store the data.
+   */
+  function value_submit($form, &$form_state) { }
+
+  /**
+   * Handle the 'left' side fo the exposed options form.
+   */
+  function expose_form_left(&$form, &$form_state) {
+    if (!empty($form['operator']['#type'])) {
+      $form['expose']['use_operator'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Unlock operator'),
+        '#description' => t('When checked, the operator will be exposed to the user'),
+        '#default_value' => !empty($this->options['expose']['use_operator']),
+      );
+      $form['expose']['operator'] = array(
+        '#type' => 'textfield',
+        '#default_value' => $this->options['expose']['operator'],
+        '#title' => t('Operator identifier'),
+        '#size' => 40,
+        '#description' => t('This will appear in the URL after the ? to identify this operator.'),
+        '#process' => array('views_process_dependency'),
+        '#dependency' => array(
+          'edit-options-expose-use-operator' => array(1)
+        ),
+      );
+    }
+    else {
+      $form['expose']['operator'] = array(
+        '#type' => 'value',
+        '#value' => '',
+      );
+    }
+
+    $form['expose']['identifier'] = array(
+      '#type' => 'textfield',
+      '#default_value' => $this->options['expose']['identifier'],
+      '#title' => t('Filter identifier'),
+      '#size' => 40,
+      '#description' => t('This will appear in the URL after the ? to identify this filter. Cannot be blank.'),
+    );
+    $form['expose']['label'] = array(
+      '#type' => 'textfield',
+      '#default_value' => $this->options['expose']['label'],
+      '#title' => t('Label'),
+      '#size' => 40,
+    );
+  }
+
+  /**
+   * Handle the 'right' side fo the exposed options form.
+   */
+  function expose_form_right(&$form, &$form_state) {
+    $form['expose']['optional'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Optional'),
+      '#description' => t('This exposed filter is optional and will have added options to allow it not to be set.'),
+      '#default_value' => $this->options['expose']['optional'],
+    );
+    if (empty($this->no_single)) {
+      $form['expose']['single'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Force single'),
+        '#description' => t('Force this exposed filter to accept only one option.'),
+        '#default_value' => $this->options['expose']['single'],
+      );
+    }
+    $form['expose']['remember'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Remember'),
+      '#description' => t('Remember the last setting the user gave this filter.'),
+      '#default_value' => $this->options['expose']['remember'],
+    );
+  }
+
+  /**
+   * Validate the options form.
+   */
+  function expose_validate($form, &$form_state) {
+    if (empty($this->options['expose']['identifier'])) {
+      if (empty($form_state['values']['options']['expose']['identifier'])) {
+        form_error($form['expose']['identifier'], t('The identifier is required if the filter is exposed.'));
+      }
+    }
+
+    if (!empty($form_state['values']['options']['expose']['identifier']) && $form_state['values']['options']['expose']['identifier'] == 'value') {
+      form_error($form['expose']['identifier'], t('This identifier is not allowed.'));
+    }
+
+    if (!$this->view->display_handler->is_identifier_unique($form_state['id'], $form_state['values']['options']['expose']['identifier'])) {
+      form_error($form['expose']['identifier'], t('This identifier is used by another handler.'));
+    }
+  }
+
+  /**
+   * Provide default options for exposed filters.
+   */
+  function expose_options() {
+    $this->options['expose'] = array(
+      'use_operator' => FALSE,
+      'operator' => $this->options['id'] . '_op',
+      'identifier' => $this->options['id'],
+      'label' => $this->ui_name(),
+      'remember' => FALSE,
+      'single' => TRUE,
+      'optional' => TRUE,
+    );
+  }
+
+  /**
+   * Render our chunk of the exposed filter form when selecting
+   *
+   * You can override this if it doesn't do what you expect.
+   */
+  function exposed_form(&$form, &$form_state) {
+    if (empty($this->options['exposed'])) {
+      return;
+    }
+
+    // Build the exposed form, when its based on an operator.
+    if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator'])) {
+      $operator = $this->options['expose']['operator'];
+      $this->operator_form($form, $form_state);
+      $form[$operator] = $form['operator'];
+
+      if (isset($form[$operator]['#title'])) {
+        unset($form[$operator]['#title']);
+      }
+
+      $this->exposed_translate($form[$operator], 'operator');
+
+      unset($form['operator']);
+    }
+
+    // Build the form and set the value based on the identifier.
+    if (!empty($this->options['expose']['identifier'])) {
+      $value = $this->options['expose']['identifier'];
+      $this->value_form($form, $form_state);
+      $form[$value] = $form['value'];
+
+      if (isset($form[$value]['#title']) && !empty($form[$value]['#type']) && $form[$value]['#type'] != 'checkbox') {
+        unset($form[$value]['#title']);
+      }
+
+      $this->exposed_translate($form[$value], 'value');
+
+      if (!empty($form['#type']) && ($form['#type'] == 'checkboxes' || ($form['#type'] == 'select' && !empty($form['#multiple'])))) {
+        unset($form[$value]['#default_value']);
+      }
+
+      if (!empty($form['#type']) && $form['#type'] == 'select' && empty($form['#multiple'])) {
+        $form[$value]['#default_value'] = 'All';
+      }
+
+      if ($value != 'value') {
+        unset($form['value']);
+      }
+    }
+  }
+
+  /**
+   * Make some translations to a form item to make it more suitable to
+   * exposing.
+   */
+  function exposed_translate(&$form, $type) {
+    if (!isset($form['#type'])) {
+      return;
+    }
+
+    if ($form['#type'] == 'radios') {
+      $form['#type'] = 'select';
+    }
+    // Checkboxes don't work so well in exposed forms due to GET conversions.
+    if ($form['#type'] == 'checkboxes') {
+      if (empty($form['#no_convert']) || !empty($this->options['expose']['single'])) {
+        $form['#type'] = 'select';
+      }
+      if (empty($this->options['expose']['single'])) {
+        $form['#multiple'] = TRUE;
+      }
+    }
+    if (!empty($this->options['expose']['single']) && isset($form['#multiple'])) {
+      unset($form['#multiple']);
+      $form['#size'] = NULL;
+    }
+
+    if ($type == 'value' && !empty($this->options['expose']['optional']) && $form['#type'] == 'select' && empty($form['#multiple'])) {
+      $any_label = variable_get('views_exposed_filter_any_label', 'old_any') == 'old_any' ? '<Any>' : t('- Any -');
+      $form['#options'] = array('All' => $any_label) + $form['#options'];
+      $form['#default_value'] = 'All';
+    }
+  }
+
+  /**
+   * Tell the renderer about our exposed form. This only needs to be
+   * overridden for particularly complex forms. And maybe not even then.
+   *
+   * @return
+   *   An array with the following keys:
+   *   - operator: The $form key of the operator. Set to NULL if no operator.
+   *   - value: The $form key of the value. Set to NULL if no value.
+   *   - label: The label to use for this piece.
+   */
+  function exposed_info() {
+    if (empty($this->options['exposed'])) {
+      return;
+    }
+
+    return array(
+      'operator' => $this->options['expose']['operator'],
+      'value' => $this->options['expose']['identifier'],
+      'label' => $this->options['expose']['label'],
+    );
+  }
+
+  /**
+   * Check to see if input from the exposed filters should change
+   * the behavior of this filter.
+   */
+  function accept_exposed_input($input) {
+    if (empty($this->options['exposed'])) {
+      return TRUE;
+    }
+
+
+    if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator']) && isset($input[$this->options['expose']['operator']])) {
+      $this->operator = $input[$this->options['expose']['operator']];
+    }
+
+    if (!empty($this->options['expose']['identifier'])) {
+      $value = $input[$this->options['expose']['identifier']];
+
+      // Various ways to check for the absence of optional input.
+      if (!empty($this->options['expose']['optional'])) {
+        if ($value == 'All' || $value === array()) {
+          return FALSE;
+        }
+
+        if (!empty($this->no_single) && $value === '') {
+          return FALSE;
+        }
+      }
+
+
+      if (isset($value)) {
+        $this->value = $value;
+        if (empty($this->no_single) && !empty($this->options['expose']['single'])) {
+          $this->value = array($value);
+        }
+      }
+      else {
+        return FALSE;
+      }
+    }
+
+    return TRUE;
+  }
+
+  function store_exposed_input($input, $status) {
+    if (empty($this->options['exposed']) || empty($this->options['expose']['identifier'])) {
+      return TRUE;
+    }
+
+    if (empty($this->options['expose']['remember'])) {
+      return;
+    }
+
+    // Figure out which display id is responsible for the filters, so we
+    // know where to look for session stored values.
+    $display_id = ($this->view->display_handler->is_defaulted('filters')) ? 'default' : $this->view->current_display;
+
+    // shortcut test.
+    $operator = !empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator']);
+
+    // false means that we got a setting that means to recuse ourselves,
+    // so we should erase whatever happened to be there.
+    if (!$status && isset($_SESSION['views'][$this->view->name][$display_id])) {
+      $session = &$_SESSION['views'][$this->view->name][$display_id];
+      if ($operator && isset($session[$this->options['expose']['operator']])) {
+        unset($session[$this->options['expose']['operator']]);
+      }
+
+      if (isset($session[$this->options['expose']['identifier']])) {
+        unset($session[$this->options['expose']['identifier']]);
+      }
+    }
+
+    if ($status) {
+      if (!isset($_SESSION['views'][$this->view->name][$display_id])) {
+        $_SESSION['views'][$this->view->name][$display_id] = array();
+      }
+
+      $session = &$_SESSION['views'][$this->view->name][$display_id];
+
+      if ($operator && isset($input[$this->options['expose']['operator']])) {
+        $session[$this->options['expose']['operator']] = $input[$this->options['expose']['operator']];
+      }
+
+      $session[$this->options['expose']['identifier']] = $input[$this->options['expose']['identifier']];
+    }
+  }
+
+  /**
+   * Add this filter to the query.
+   *
+   * Due to the nature of fapi, the value and the operator have an unintended
+   * level of indirection. You will find them in $this->operator
+   * and $this->value respectively.
+   */
+  function query() {
+    $this->ensure_my_table();
+    $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field " . $this->operator . " '%s'", $this->value);
+  }
+
+  /**
+   * Can this filter be used in OR groups?
+   *
+   * Some filters have complicated where clauses that cannot be easily used
+   * with OR groups. Some filters must also use HAVING which also makes
+   * them not groupable. These filters will end up in a special group
+   * if OR grouping is in use.
+   */
+   function can_group() {
+     return TRUE;
+   }
+}
+
+
+/**
+ * A special handler to take the place of missing or broken handlers.
+ */
+class views_handler_filter_broken extends views_handler_filter {
+  function ui_name($short = FALSE) {
+    return t('Broken/missing handler');
+  }
+
+  function ensure_my_table() { /* No table to ensure! */ }
+  function query() { /* No query to run */ }
+  function options_form(&$form, &$form_state) {
+    $form['markup'] = array(
+      '#prefix' => '<div class="form-item description">',
+      '#value' => t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.'),
+    );
+  }
+
+  /**
+   * Determine if the handler is considered 'broken'
+   */
+  function broken() { return TRUE; }
+}
+
+
+/**
+ * @}
+ */
Index: handlers/views_handler_filter_boolean_operator.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_filter_boolean_operator.inc,v
retrieving revision 1.4
diff -u -p -r1.4 views_handler_filter_boolean_operator.inc
--- handlers/views_handler_filter_boolean_operator.inc	1 Jun 2009 21:41:31 -0000	1.4
+++ handlers/views_handler_filter_boolean_operator.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_boolean_operator.inc,v 1.4 2009/06/01 21:41:31 merlinofchaos Exp $
+// $Id: views_handler_filter_boolean_operator.inc,v 1.3.2.7 2010/03/13 00:50:55 merlinofchaos Exp $
 /**
  * Simple filter to handle matching of boolean values
  *
@@ -15,12 +15,17 @@ class views_handler_filter_boolean_opera
   var $no_single = TRUE;
   // Don't display empty space where the operator would be.
   var $no_operator = TRUE;
+  // Whether to accept NULL as a false value or not
+  var $accept_null = FALSE;
 
   function construct() {
     $this->value_value = t('True');
     if (isset($this->definition['label'])) {
       $this->value_value = $this->definition['label'];
     }
+    if (isset($this->definition['accept_null'])) {
+      $this->accept_null = (bool) $this->definition['accept_null'];
+    }
     $this->value_options = NULL;
     parent::construct();
   }
@@ -90,11 +95,15 @@ class views_handler_filter_boolean_opera
         $form_state['input'][$identifier] = $this->value;
       }
       // If we're configuring an exposed filter, add an <Any> option.
-      $form['value']['#options'] += array('All' => check_plain(t('<Any>')));
+      $any_label = variable_get('views_exposed_filter_any_label', 'old_any') == 'old_any' ? '<Any>' : t('- Any -');
+      if ($form['value']['#type'] != 'select') {
+        $any_label = check_plain($any_label);
+      }
+      $form['value']['#options'] = array('All' => $any_label) + $form['value']['#options'];
     }
   }
 
-  function value_validate(&$form, &$form_state) {
+  function value_validate($form, &$form_state) {
     if ($form_state['values']['options']['value'] == 'All' && empty($form_state['values']['options']['expose']['optional'])) {
       form_set_error('value', t('You must select a value unless this is an optional exposed filter.'));
     }
@@ -123,6 +132,18 @@ class views_handler_filter_boolean_opera
 
   function query() {
     $this->ensure_my_table();
-    $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field " . (empty($this->value) ? '=' : '<>') . " 0");
+
+    $where = "$this->table_alias.$this->real_field ";
+
+    if (empty($this->value)) {
+      $where .= '= 0';
+      if ($this->accept_null) {
+        $where = '(' . $where . " OR $this->table_alias.$this->real_field IS NULL)";
+      }
+    }
+    else {
+      $where .= '<> 0';
+    }
+    $this->query->add_where($this->options['group'], $where);
   }
 }
Index: handlers/views_handler_filter_boolean_operator_string.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_filter_boolean_operator_string.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_filter_boolean_operator_string.inc
--- handlers/views_handler_filter_boolean_operator_string.inc	16 Dec 2008 19:12:27 -0000	1.1
+++ handlers/views_handler_filter_boolean_operator_string.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_boolean_operator_string.inc,v 1.1 2008/12/16 19:12:27 merlinofchaos Exp $
+// $Id: views_handler_filter_boolean_operator_string.inc,v 1.1.2.1 2009/09/15 16:18:35 merlinofchaos Exp $
 /**
  * Simple filter to handle matching of boolean values.
  *
@@ -12,6 +12,17 @@
 class views_handler_filter_boolean_operator_string extends views_handler_filter_boolean_operator {
   function query() {
     $this->ensure_my_table();
-    $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field " . (empty($this->value) ? '=' : '<>') . " ''");
+    $where = "$this->table_alias.$this->real_field ";
+
+    if (empty($this->value)) {
+      $where .= "= ''";
+      if ($this->accept_null) {
+        $where = '(' . $where . " OR $this->table_alias.$this->real_field IS NULL)";
+      }
+    }
+    else {
+      $where .= "<> ''";
+    }
+    $this->query->add_where($this->options['group'], $where);
   }
 }
Index: handlers/views_handler_filter_date.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_filter_date.inc,v
retrieving revision 1.3
diff -u -p -r1.3 views_handler_filter_date.inc
--- handlers/views_handler_filter_date.inc	26 Nov 2008 19:01:44 -0000	1.3
+++ handlers/views_handler_filter_date.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_date.inc,v 1.3 2008/11/26 19:01:44 merlinofchaos Exp $
+// $Id: views_handler_filter_date.inc,v 1.3.2.2 2010/03/10 20:28:10 merlinofchaos Exp $
 
 /**
  * Filter to handle dates stored as a timestamp.
@@ -9,7 +9,7 @@ class views_handler_filter_date extends 
     $options = parent::option_definition();
 
     // value is already set up properly, we're just adding our new field to it.
-    $options['value']['type']['default'] = 'date';
+    $options['value']['contains']['type']['default'] = 'date';
 
     return $options;
   }
@@ -24,7 +24,7 @@ class views_handler_filter_date extends 
         '#title' => t('Value type'),
         '#options' => array(
           'date' => t('A date in any machine readable format. CCYY-MM-DD HH:MM:SS is preferred.'),
-          'offset' => t('An offset from the current time such as "+1 day" or "-2 hours and 30 minutes"'),
+          'offset' => t('An offset from the current time such as "+1 day" or "-2 hours -30 minutes"'),
         ),
         '#default_value' => !empty($this->value['type']) ? $this->value['type'] : 'date',
       );
Index: handlers/views_handler_filter_in_operator.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_filter_in_operator.inc,v
retrieving revision 1.10
diff -u -p -r1.10 views_handler_filter_in_operator.inc
--- handlers/views_handler_filter_in_operator.inc	10 Jun 2009 22:04:57 -0000	1.10
+++ handlers/views_handler_filter_in_operator.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_in_operator.inc,v 1.10 2009/06/10 22:04:57 merlinofchaos Exp $
+// $Id: views_handler_filter_in_operator.inc,v 1.6.2.12 2010/04/07 19:14:49 merlinofchaos Exp $
 /**
  * Simple filter to handle matching of multiple options selectable via checkboxes
  *
@@ -57,6 +57,7 @@ class views_handler_filter_in_operator e
 
     $options['operator']['default'] = 'in';
     $options['value']['default'] = array();
+    $options['expose']['contains']['reduce'] = array('default' => FALSE);
 
     return $options;
   }
@@ -93,7 +94,7 @@ class views_handler_filter_in_operator e
           'values' => 0,
         ),
         'not empty' => array(
-          'title' => t('Is not empty (NULL)'),
+          'title' => t('Is not empty (NOT NULL)'),
           'method' => 'op_empty',
           'short' => t('not empty'),
           'values' => 0,
@@ -173,11 +174,6 @@ class views_handler_filter_in_operator e
     }
 
     if ($which == 'all' || $which == 'value') {
-      if ($this->value_form_type == 'checkboxes') {
-        foreach ($options as $key => $option) {
-          $options[$key] = check_plain($option);
-        }
-      }
       $form['value'] = array(
         '#type' => $this->value_form_type,
         '#title' => $this->value_title,
@@ -191,18 +187,27 @@ class views_handler_filter_in_operator e
         $form_state['input'][$identifier] = $default_value;
       }
 
+      $process = array();
+      if ($this->value_form_type == 'checkboxes') {
+        // If this form element will use checkboxes in the UI, we need to
+        // check_plain() all the options ourselves since FAPI is inconsistent
+        // about this. However, instead of directly doing that to the #options
+        // right now, we define a #process callback since we might change our
+        // mind later and convert this into a 'select' form element, which
+        // would lead to double-escaping the options.
+        $process[] = 'views_process_check_options';
+      }
       if ($which == 'all') {
-        $process = array();
-        if ($this->value_form_type == 'checkboxes' || $this->value_form_type == 'radios') {
+        if (empty($form_state['exposed']) && ($this->value_form_type == 'checkboxes' || $this->value_form_type == 'radios')) {
           $process[] = "expand_$this->value_form_type";
           $form['value']['#prefix'] = '<div id="edit-options-value-wrapper">';
           $form['value']['#suffix'] = '</div>';
         }
         $process[] = 'views_process_dependency';
-        $form['value'] += array(
-          '#process' => $process,
-          '#dependency' => array($source => $this->operator_values(1)),
-        );
+        $form['value']['#dependency'] = array($source => $this->operator_values(1));
+      }
+      if (!empty($process)) {
+        $form['value']['#process'] = $process;
       }
     }
   }
@@ -268,7 +273,6 @@ class views_handler_filter_in_operator e
     // instead.
 
     $form_state['values']['options']['value'] = $form['value']['#value'];
-//    $form_state['values']['options']['value'] = array_filter($form_state['values']['options']['value']);
   }
 
   function admin_summary() {
@@ -286,20 +290,25 @@ class views_handler_filter_in_operator e
     $operator = check_plain($info[$this->operator]['short']);
     $values = '';
     if (in_array($this->operator, $this->operator_values(1))) {
-      if (count($this->value) == 1) {
+      // Remove every element which is not known.
+      foreach ($this->value as $value) {
+        if (!isset($this->value_options[$value])) {
+          unset($this->value[$value]);
+        }
+      }
+      // Choose different kind of ouput for 0, a single and multiple values.
+      if (count($this->value) == 0) {
+        $values = t('Unknown');
+      }
+      else if (count($this->value) == 1) {
         // If any, use the 'single' short name of the operator instead.
         if (isset($info[$this->operator]['short_single'])) {
           $operator = check_plain($info[$this->operator]['short_single']);
         }
 
         $keys = $this->value;
-        $key = array_shift($keys);
-        if (isset($this->value_options[$key])) {
-          $values = check_plain($this->value_options[$key]);
-        }
-        else {
-          $values = t('Unknown');
-        }
+        $value = array_shift($keys);
+        $values = check_plain($this->value_options[$value]);
       }
       else {
         foreach ($this->value as $value) {
Index: handlers/views_handler_filter_many_to_one.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_filter_many_to_one.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_handler_filter_many_to_one.inc
--- handlers/views_handler_filter_many_to_one.inc	1 Jun 2009 21:29:11 -0000	1.2
+++ handlers/views_handler_filter_many_to_one.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_many_to_one.inc,v 1.2 2009/06/01 21:29:11 merlinofchaos Exp $
+// $Id: views_handler_filter_many_to_one.inc,v 1.1.2.3 2010/03/08 19:53:47 merlinofchaos Exp $
 
 /**
  * Complex filter to handle filtering for many to one relationships,
@@ -10,7 +10,7 @@
  * to provide something that isn't just a select list.
  */
 class views_handler_filter_many_to_one extends views_handler_filter_in_operator {
-  function init(&$view, &$options) {
+  function init(&$view, $options) {
     parent::init($view, $options);
     $this->helper = new views_many_to_one_helper($this);
   }
@@ -61,7 +61,7 @@ class views_handler_filter_many_to_one e
           'values' => 0,
         ),
         'not empty' => array(
-          'title' => t('Is not empty (NULL)'),
+          'title' => t('Is not empty (NOT NULL)'),
           'method' => 'op_empty',
           'short' => t('not empty'),
           'values' => 0,
Index: handlers/views_handler_filter_numeric.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_filter_numeric.inc,v
retrieving revision 1.7
diff -u -p -r1.7 views_handler_filter_numeric.inc
--- handlers/views_handler_filter_numeric.inc	25 Mar 2009 17:29:33 -0000	1.7
+++ handlers/views_handler_filter_numeric.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_numeric.inc,v 1.7 2009/03/25 17:29:33 merlinofchaos Exp $
+// $Id: views_handler_filter_numeric.inc,v 1.7.2.1 2010/03/08 19:53:47 merlinofchaos Exp $
 
 /**
  * Simple filter to handle greater than/less than filters
@@ -82,7 +82,7 @@ class views_handler_filter_numeric exten
           'values' => 0,
         ),
         'not empty' => array(
-          'title' => t('Is not empty (NULL)'),
+          'title' => t('Is not empty (NOT NULL)'),
           'method' => 'op_empty',
           'short' => t('not empty'),
           'values' => 0,
Index: handlers/views_handler_filter_string.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_filter_string.inc,v
retrieving revision 1.7
diff -u -p -r1.7 views_handler_filter_string.inc
--- handlers/views_handler_filter_string.inc	27 Jan 2009 20:40:29 -0000	1.7
+++ handlers/views_handler_filter_string.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_string.inc,v 1.7 2009/01/27 20:40:29 merlinofchaos Exp $
+// $Id: views_handler_filter_string.inc,v 1.7.2.5 2010/04/29 19:29:15 merlinofchaos Exp $
 
 /**
  * Basic textfield filter to handle string filtering commands
@@ -60,18 +60,42 @@ class views_handler_filter_string extend
         'method' => 'op_starts',
         'values' => 1,
       ),
+      'not_starts' => array(
+        'title' => t('Does not start with'),
+        'short' => t('not_begins'),
+        'method' => 'op_not_starts',
+        'values' => 1,
+      ),
       'ends' => array(
         'title' => t('Ends with'),
         'short' => t('ends'),
         'method' => 'op_ends',
         'values' => 1,
       ),
+      'not_ends' => array(
+        'title' => t('Does not end with'),
+        'short' => t('not_ends'),
+        'method' => 'op_not_ends',
+        'values' => 1,
+      ),
       'not' => array(
         'title' => t('Does not contain'),
         'short' => t('!has'),
         'method' => 'op_not',
         'values' => 1,
       ),
+      'shorterthan' => array(
+        'title' => t('Length is shorter than'),
+        'short' => t('shorter than'),
+        'method' => 'op_shorter',
+        'values' => 1,
+      ),
+      'longerthan' => array(
+        'title' => t('Length is longer than'),
+        'short' => t('longer than'),
+        'method' => 'op_longer',
+        'values' => 1,
+      ),
     );
     // if the definition allows for the empty operator, add it.
     if (!empty($this->definition['allow empty'])) {
@@ -83,7 +107,7 @@ class views_handler_filter_string extend
           'values' => 0,
         ),
         'not empty' => array(
-          'title' => t('Is not empty (NULL)'),
+          'title' => t('Is not empty (NOT NULL)'),
           'method' => 'op_empty',
           'short' => t('not empty'),
           'values' => 0,
@@ -216,11 +240,11 @@ class views_handler_filter_string extend
 
   function op_equal($field, $upper) {
     // operator is either = or !=
-    $this->query->add_where($this->options['group'], "$upper(%s) $this->operator $upper('%s')", $field, $this->value);
+    $this->query->add_where($this->options['group'], "$upper($field) $this->operator $upper('%s')", $this->value);
   }
 
   function op_contains($field, $upper) {
-    $this->query->add_where($this->options['group'], "$upper(%s) LIKE $upper('%%%s%%')", $field, $this->value);
+    $this->query->add_where($this->options['group'], "$upper($field) LIKE $upper('%%%s%%')", $this->value);
   }
 
   function op_word($field, $upper) {
@@ -236,8 +260,7 @@ class views_handler_filter_string extend
       $words = trim($match[2], ',?!();:-');
       $words = $phrase ? array($words) : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY);
       foreach ($words as $word) {
-        $where[] = "$upper(%s) LIKE $upper('%%%s%%')";
-        $values[] = $field;
+        $where[] = "$upper($field) LIKE $upper('%%%s%%')";
         $values[] = trim($word, " ,!?");
       }
     }
@@ -258,15 +281,31 @@ class views_handler_filter_string extend
   }
 
   function op_starts($field, $upper) {
-    $this->query->add_where($this->options['group'], "$upper(%s) LIKE $upper('%s%%')", $field, $this->value);
+    $this->query->add_where($this->options['group'], "$upper($field) LIKE $upper('%s%%')", $this->value);
+  }
+
+  function op_not_starts($field, $upper) {
+    $this->query->add_where($this->options['group'], "$upper($field) NOT LIKE $upper('%s%%')", $this->value);
   }
 
   function op_ends($field, $upper) {
-    $this->query->add_where($this->options['group'], "$upper(%s) LIKE $upper('%%%s')", $field, $this->value);
+    $this->query->add_where($this->options['group'], "$upper($field) LIKE $upper('%%%s')", $this->value);
+  }
+
+  function op_not_ends($field, $upper) {
+    $this->query->add_where($this->options['group'], "$upper($field) NOT LIKE $upper('%%%s')", $this->value);
   }
 
   function op_not($field, $upper) {
-    $this->query->add_where($this->options['group'], "$upper(%s) NOT LIKE $upper('%%%s%%')", $field, $this->value);
+    $this->query->add_where($this->options['group'], "$upper($field) NOT LIKE $upper('%%%s%%')", $this->value);
+  }
+
+  function op_shorter($field, $upper) {
+    $this->query->add_where($this->options['group'], "LENGTH($upper($field)) < %d", $this->value);
+  }
+
+  function op_longer($field, $upper) {
+    $this->query->add_where($this->options['group'], "LENGTH($upper($field)) > %d", $this->value);
   }
 
   function op_empty($field) {
Index: handlers/views_handler_relationship.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_relationship.inc,v
retrieving revision 1.3
diff -u -p -r1.3 views_handler_relationship.inc
--- handlers/views_handler_relationship.inc	4 Jun 2009 20:09:26 -0000	1.3
+++ handlers/views_handler_relationship.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_relationship.inc,v 1.3 2009/06/04 20:09:26 merlinofchaos Exp $
+// $Id: views_handler_relationship.inc,v 1.1.2.2 2009/11/02 23:25:10 merlinofchaos Exp $
 /**
  * @file
  * Views' relationship handlers.
@@ -23,11 +23,11 @@
  * - base: The new base table this relationship will be adding. This does not
  *   have to be a declared base table, but if there are no tables that
  *   utilize this base table, it won't be very effective.
- * - base field: The field to use in the relationship; if left out this iwll be
+ * - base field: The field to use in the relationship; if left out this will be
  *   assumed to be the primary field.
  * - relationship table: The actual table this relationship operates against.
  *   This is analogous to using a 'table' override.
- * - relationship field: The actual field this relationsihp operates against.
+ * - relationship field: The actual field this relationship operates against.
  *   This is analogous to using a 'real field' override.
  * - label: The default label to provide for this relationship, which is
  *   shown in parentheses next to any field/sort/filter/argument that uses
@@ -129,7 +129,7 @@ class views_handler_relationship extends
  * A special handler to take the place of missing or broken handlers.
  */
 class views_handler_relationship_broken extends views_handler_relationship {
-  function ui_name() {
+  function ui_name($short = FALSE) {
     return t('Broken/missing handler');
   }
 
Index: handlers/views_handler_sort.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_sort.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_sort.inc
--- handlers/views_handler_sort.inc	3 Sep 2008 19:21:28 -0000	1.1
+++ handlers/views_handler_sort.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_sort.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos Exp $
+// $Id: views_handler_sort.inc,v 1.1.2.2 2009/12/23 20:29:00 merlinofchaos Exp $
 /**
  * @defgroup views_sort_handlers Views' sort handlers
  * @{
@@ -10,6 +10,12 @@
  * Base sort handler that has no options and performs a simple sort
  */
 class views_handler_sort extends views_handler {
+
+  /**
+   * Determine if a sort can be exposed.
+   */
+  function can_expose() { return TRUE; }
+
   /**
    * Called to add the sort to a query.
    */
@@ -23,7 +29,12 @@ class views_handler_sort extends views_h
     $options = parent::option_definition();
 
     $options['order'] = array('default' => 'ASC');
-
+    $options['exposed'] = array('default' => FALSE);
+    $options['expose'] = array(
+      'contains' => array(
+        'label' => array('default' => '', 'translatable' => TRUE),
+      ),
+    );
     return $options;
   }
 
@@ -31,29 +42,124 @@ class views_handler_sort extends views_h
    * Display whether or not the sort order is ascending or descending
    */
   function admin_summary() {
+    if (!empty($this->options['exposed'])) {
+      return t('Exposed');
+    }
     switch ($this->options['order']) {
       case 'ASC':
       case 'asc':
       default:
-        $type = t('asc');
+        return t('asc');
         break;
       case 'DESC';
       case 'desc';
-        $type = t('desc');
+        return t('desc');
         break;
     }
-    return '<span class="views-ascending"><span>' . $type . '</span></span>';
   }
 
   /**
    * Basic options for all sort criteria
    */
   function options_form(&$form, &$form_state) {
-    $form['order'] = array(
-      '#type' => 'radios',
-      '#title' => t('Sort order'),
-      '#options' => array('ASC' => t('Ascending'), 'DESC' => t('Descending')),
-      '#default_value' => $this->options['order'],
+    if ($this->can_expose()) {
+      $this->show_expose_button($form, $form_state);
+    }
+    $form['op_val_start'] = array('#value' => '<div class="clear-block">');
+    $this->show_sort_form($form, $form_state);
+    $form['op_val_end'] = array('#value' => '</div>');
+    if ($this->can_expose()) {
+      $this->show_expose_form($form, $form_state);
+    }
+  }
+
+  /**
+   * Simple validate handler
+   */
+  function options_validate(&$form, &$form_state) {
+    $this->sort_validate($form, $form_state);
+    if (!empty($this->options['exposed'])) {
+      $this->expose_validate($form, $form_state);
+    }
+
+  }
+
+  /**
+   * Simple submit handler
+   */
+  function options_submit(&$form, &$form_state) {
+    unset($form_state['values']['expose_button']); // don't store this.
+    $this->sort_submit($form, $form_state);
+    if (!empty($this->options['exposed'])) {
+      $this->expose_submit($form, $form_state);
+    }
+  }
+
+  /**
+   * Shortcut to display the value form.
+   */
+  function show_sort_form(&$form, &$form_state) {
+    $options = $this->sort_options();
+    if (!empty($options)) {
+      $form['order'] = array(
+        '#type' => 'radios',
+        '#options' => $options,
+        '#default_value' => $this->options['order'],
+      );
+    }
+  }
+
+  function sort_validate(&$form, &$form_state) { }
+
+  function sort_submit(&$form, &$form_state) { }
+
+  /**
+   * Provide a list of options for the default sort form.
+   * Should be overridden by classes that don't override sort_form
+   */
+  function sort_options() { 
+    return array(
+      'ASC' => t('Sort ascending'), 
+      'DESC' => t('Sort descending'),
+    ); 
+  }
+
+  /**
+   * Since all exposed sorts are grouped into one select box.
+   * We don't return nothing when views call to exposed_form()
+   */ 
+  function exposed_form(&$form, &$form_state) { }
+
+  /**
+   * Handle the 'left' side fo the exposed options form.
+   */
+ function expose_form_left(&$form, &$form_state) {
+    $form['expose']['label'] = array(
+      '#type' => 'textfield',
+      '#default_value' => $this->options['expose']['label'],
+      '#title' => t('Label'),
+      '#required' => TRUE,
+      '#size' => 40,
+   );
+  }
+  
+  /**
+   * Handle the 'right' side fo the exposed options form.
+   */
+  function expose_form_right(&$form, &$form_state) {
+    $form['expose']['order'] = array(
+      '#type' => 'value',
+      '#value' => 'ASC',
+     );
+  }
+
+  /**
+   * Provide default options for exposed sorts.
+   */
+  function expose_options() {
+    $this->options['expose'] = array(
+      'order' => $this->options['order'],
+      'label' => $this->ui_name(),
     );
   }
 }
@@ -62,7 +168,7 @@ class views_handler_sort extends views_h
  * A special handler to take the place of missing or broken handlers.
  */
 class views_handler_sort_broken extends views_handler_sort {
-  function ui_name() {
+  function ui_name($short = FALSE) {
     return t('Broken/missing handler');
   }
 
Index: help/api-default-views.html
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/help/api-default-views.html,v
retrieving revision 1.3
diff -u -p -r1.3 api-default-views.html
--- help/api-default-views.html	31 Jan 2009 18:16:26 -0000	1.3
+++ help/api-default-views.html	11 Aug 2010 21:11:32 -0000
@@ -1,4 +1,4 @@
-<!-- $Id: api-default-views.html,v 1.3 2009/01/31 18:16:26 merlinofchaos Exp $ -->
+<!-- $Id: api-default-views.html,v 1.3.2.1 2009/12/23 19:17:12 merlinofchaos Exp $ -->
 Views can be stored in the database, which is typical of smaller sites and hobby sites. However, Views may also be stored directly in the code as "default" views, (which simply means they're available by default). Modules often come with views that are specific to the module data, but it's also possible -- and <b>highly</b> recommended -- that sites which have separate "development" and "production" sites export their views into default views in a site-specific module. This makes it very easy to transfer views from dev to production without making database changes.
 
 <h3>Creating a module</h3>
@@ -48,10 +48,11 @@ You can theme these views in the module 
 To do this, you need to implement <em>hook_theme()</em> in your module:
 <pre>function mymodule_theme($existing) {
   return array(
-    'views_view__viewname_displayid' => array (
+    'views_view__viewname__displayid' => array (
       'arguments' => array('view' => NULL),
       'template' => 'views-view--viewname--displayid',
       'original hook' => 'views_view',
+      'path' => drupal_get_path('module', 'mymodule'),
     ),
   );
 }
@@ -60,7 +61,7 @@ To do this, you need to implement <em>ho
 There are a small number of gotchas in doing this that you must be aware of.
 
 <ol>
-<li>When referring to a template filename, you always use dashes in the name. i.e, <em>views-view--viewname--displayid.tpl.php</em>. However, when referring to the hook or function names, you use underscores instead of dashes. i.e, <em>views_view</em> and <em>views_view__viewname_displayid</em></li>
+<li>When referring to a template filename, you always use dashes in the name. i.e, <em>views-view--viewname--displayid.tpl.php</em>. However, when referring to the hook or function names, you use underscores instead of dashes. i.e, <em>views_view</em> and <em>views_view__viewname__displayid</em></li>
 
 <li>The 'arguments' change based upon which of the 3 types you're overriding. There's the 'display', the 'style' and the 'row' style. The above code is assuming the display, which is usually just <em>views_view</em>. Here are the possibilities:
 
@@ -98,5 +99,8 @@ Be sure to use the right arguments line 
   </li>
 </ol>
 </li>
+<li>
+  If you leave the path blank the template file will be searched for in "./" which is the Drupal install base path.
+</li>
 </ol>
 
Index: help/api-plugins.html
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/help/api-plugins.html,v
retrieving revision 1.7
diff -u -p -r1.7 api-plugins.html
--- help/api-plugins.html	9 Jan 2009 16:47:07 -0000	1.7
+++ help/api-plugins.html	11 Aug 2010 21:11:32 -0000
@@ -1,4 +1,4 @@
-<!-- $Id: api-plugins.html,v 1.7 2009/01/09 16:47:07 merlinofchaos Exp $ -->
+<!-- $Id: api-plugins.html,v 1.7.2.1 2010/07/27 22:34:07 merlinofchaos Exp $ -->
 In Views, a plugin is a bit like a handler, but plugins are not directly responsible for building the query. Instead, they are objects that are used to display the view or make other modifications.
 
 There are 6 types of plugins in Views:
@@ -20,60 +20,60 @@ There are 6 types of plugins in Views:
 Plugins are registered by implementing <strong>hook_views_plugins()</strong> in your modulename.views.inc file and returning an array of data.
 
 The array will look something like this:
-<code>
+<pre>
   return array(
-    'display' => array(
+    'display' =&gt; array(
       // ... list of display plugins,
      ),
-    'style' => array(
+    'style' =&gt; array(
       // ... list of style plugins,
      ),
-    'row' => array(
+    'row' =&gt; array(
       // ... list of row style plugins,
      ),
-    'argument default' => array(
+    'argument default' =&gt; array(
       // ... list of argument default plugins,
      ),
-    'argument validator' => array(
+    'argument validator' =&gt; array(
       // ... list of argument validator plugins,
      ),
-     'access' => array(
+     'access' =&gt; array(
       // ... list of access plugins,
      ),
   );
-</code>
+</pre>
 
 Each plugin will be registered with an identifier for the plugin, plus a fairly lengthy list of items that can define how and where the plugin is used. Here is an example from Views core:
 
-<code>
-      'node' => array(
-        'title' => t('Node'),
-        'help' => t('Display the node with standard node view.'),
-        'handler' => 'views_plugin_row_node_view',
-        'path' => drupal_get_path('module', 'views') . '/modules/node', // not necessary for most modules
-        'theme' => 'views_view_row_node',
-        'base' => array('node'), // only works with 'node' as base.
-        'uses options' => TRUE,
-        'type' => 'normal',
+<pre>
+      'node' =&gt; array(
+        'title' =&gt; t('Node'),
+        'help' =&gt; t('Display the node with standard node view.'),
+        'handler' =&gt; 'views_plugin_row_node_view',
+        'path' =&gt; drupal_get_path('module', 'views') . '/modules/node', // not necessary for most modules
+        'theme' =&gt; 'views_view_row_node',
+        'base' =&gt; array('node'), // only works with 'node' as base.
+        'uses options' =&gt; TRUE,
+        'type' =&gt; 'normal',
       ),
-</code>
+</pre>
 
 Of particular interest is the <em>path</em> directive, which works a little differently from handler registration; each plugin must define its own path, rather than relying on a global info for the paths. Also, there is an optional <em>parent</em> directive which is automatically filled in to be the base parent for the plugin type. Usually this is enough, but if your plugin derives from something other than the base, it must be filled in. For example:
 
-<code>
-      'feed' => array(
-        'title' => t('Feed'),
-        'help' => t('Display the view as a feed, such as an RSS feed.'),
-        'handler' => 'views_plugin_display_feed',
-        'parent' => 'page', // so it knows to load the page plugin .inc file
-        'uses hook menu' => TRUE,
-        'use ajax' => FALSE,
-        'use pager' => FALSE,
-        'accept attachments' => FALSE,
-        'admin' => t('Feed'),
-        'help topic' => 'display-feed',
+<pre>
+      'feed' =&gt; array(
+        'title' =&gt; t('Feed'),
+        'help' =&gt; t('Display the view as a feed, such as an RSS feed.'),
+        'handler' =&gt; 'views_plugin_display_feed',
+        'parent' =&gt; 'page', // so it knows to load the page plugin .inc file
+        'uses hook menu' =&gt; TRUE,
+        'use ajax' =&gt; FALSE,
+        'use pager' =&gt; FALSE,
+        'accept attachments' =&gt; FALSE,
+        'admin' =&gt; t('Feed'),
+        'help topic' =&gt; 'display-feed',
       ),
-</code>
+</pre>
 
 Note that unlike handler registration, where parentage is referred to by object name, with plugins it is referred to by the unique plugin identifier. Please be sure to prefix your plugin identifiers with your module name to ensure namespace safety; after all, two different modules could try to implement the 'grid2' plugin, and that would cause one plugin to completely fail.
 
Index: help/api-tables.html
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/help/api-tables.html,v
retrieving revision 1.7
diff -u -p -r1.7 api-tables.html
--- help/api-tables.html	2 Jun 2009 20:44:13 -0000	1.7
+++ help/api-tables.html	11 Aug 2010 21:11:32 -0000
@@ -1,4 +1,4 @@
-<!-- $Id: api-tables.html,v 1.7 2009/06/02 20:44:13 merlinofchaos Exp $ -->
+<!-- $Id: api-tables.html,v 1.6.2.2 2009/08/22 09:22:35 dww Exp $ -->
 Tables are described to Views via hook_views_data(), which returns an array of table information, keyed by the name of the table. For example, if your module is describing three tables, 'foo', 'bar' and 'baz', your array will look like this:
 <pre>$data = array(
   'foo' =&gt; array(
@@ -67,7 +67,7 @@ For example:
 The following tags are available in the 
 <dl>
 <dt>field</dt>
-<dd>The primary key field for this table. For Views to treat any table as a base table, it <b>must</b> have a primary field. For node this is the 'nid', for users this is the 'uid', etc. <strong>Without a single primary key field, Views will not be able to utilize the table as a base table.</strong> If your table does not have a primary key field, it is not too difficult to just add a serial field to it, usually.</dd>
+<dd>The primary key field for this table. For Views to treat any table as a base table, it <b>must</b> have a primary field. For node this is the 'nid', for users this is the 'uid', etc. <strong>Without a single primary key field (i.e. not a composite key), Views will not be able to utilize the table as a base table.</strong> If your table does not have a primary key field, it is not too difficult to just add a serial field to it, usually.</dd>
 <dt>title</dt>
 <dd>The title of this table in the UI. It should be singular and describe the object that this table contains from the perspective of the user.</dd>
 <dt>help</dt>
Index: help/argument.html
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/help/argument.html,v
retrieving revision 1.8
diff -u -p -r1.8 argument.html
--- help/argument.html	20 Feb 2009 20:46:48 -0000	1.8
+++ help/argument.html	11 Aug 2010 21:11:32 -0000
@@ -1,4 +1,4 @@
-<!-- $Id: argument.html,v 1.8 2009/02/20 20:46:48 merlinofchaos Exp $ -->
+<!-- $Id: argument.html,v 1.8.2.1 2010/03/19 23:03:20 merlinofchaos Exp $ -->
 Arguments are input. While they often come from the URL, <strong>they don't always</strong> so please don't be shocked when they don't. Each display type may have its own source for arguments. Block displays have no source of arguments at all; they cannot pull arguments from the URL, and often require use of the default argument PHP code in order to get arguments. The argument default plugins can be used to get arguments into a block view. See "Provide default", below.
 
 In general, arguments are used to filter the view, and in that sense they have a very close relationship to filters, but that isn't necessarily true for every argument. Arguments can be used for any purpose, really; the extent of what the argument does is up to the developer of the argument, but the arguments that come with Views are almost entirely filters.
@@ -11,7 +11,7 @@ A typical use of an argument might be to
 <dd>The argument is removed from the view as though it weren't there and all results will be displayed.</dd>
 
 <dt>Hide view / Page not found</dt>
-<dd>The view will remove itself entirely if the argument is not present; for a block this means it simply won't a appear. For page views the View will return a 404 and present a "Page not found" error. </dd>
+<dd>The view will remove itself entirely if the argument is not present; for a block this means it simply won't appear. For page views the View will return a 404 and present a "Page not found" error. </dd>
 
 <dt>Display empty text</dt>
 <dd>The value of the <a href=topic:views/empty-text>empty text</a> will be displayed.</dd>
@@ -38,7 +38,7 @@ Default argument selection is available 
 <dd>You can use this to easily default a menu item to the logged in user. For example, if you created the path 'blogs' and gave it a User: ID argument with this default, 'blogs' would go to the user's own blogs, and blogs/1 would go to User ID 1's blogs.</dd>
 </dl>
 
-Please bear in mind that the selection of default argument happens only if an argument is not provided. If using a display that has no argument source, such as a block, this will be the case 100% of the time. However, if using a display that reads arguments from the URL, this will happen only if the URL did not contain an argument.
+Please bear in mind that the selection of default argument happens only if an argument is not provided. If using a display that has no argument source, such as a block, this will always be used. However, if using a display that reads arguments from the URL, this will happen only if the URL did not contain an argument.
 <h3>Argument validation</h3>
 Arguments can also have validators, which are pluggable systems used to ensure that arguments fit within certain parameters. When a validator is chosen, it may provide some settings for the validator, including the action to take if an argument is presented, but it fails to validate. These actions are generally the same as the default actions above, excluding the ability to provide another default.
 
Index: help/display-page.html
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/help/display-page.html,v
retrieving revision 1.3
diff -u -p -r1.3 display-page.html
--- help/display-page.html	8 Oct 2008 22:58:13 -0000	1.3
+++ help/display-page.html	11 Aug 2010 21:11:32 -0000
@@ -1,4 +1,6 @@
-<!-- $Id: display-page.html,v 1.3 2008/10/08 22:58:13 merlinofchaos Exp $ -->
+<!-- $Id: display-page.html,v 1.3.2.1 2010/03/25 20:31:17 merlinofchaos Exp $ -->
 Page displays have a <a href="topic:views/path">path</a> and an optional <a href="topic:views/menu">menu</a> component. Page displays will be the primary content for the page, meaning they will be displayed in the main content area when you visit the URL that corresponds to the path.
 
-Page displays take their arguments from the URL. You can embed arguments into the URL using %; in previous versions of Views, this was '$arg'. For example, 'node/%/foo' will accept URLs such as 'node/1/foo'.
\ No newline at end of file
+Page displays take their arguments from the URL. You can embed arguments into the URL using %; in previous versions of Views, this was '$arg'. For example, 'node/%/foo' will accept URLs such as 'node/1/foo'.
+
+Please remember that using a % placeholder makes the argument required. If you wish to have an optional argument, simply omit the % from the path. I.e. using "page/%" as the path requires an argument and visiting 'http://www.example.com/page' will not trigger the view.
\ No newline at end of file
Index: help/display.html
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/help/display.html,v
retrieving revision 1.2
diff -u -p -r1.2 display.html
--- help/display.html	29 Apr 2008 00:35:07 -0000	1.2
+++ help/display.html	11 Aug 2010 21:11:32 -0000
@@ -1,7 +1,7 @@
-<!-- $Id: display.html,v 1.2 2008/04/29 00:35:07 merlinofchaos Exp $ -->
+<!-- $Id: display.html,v 1.2.2.1 2010/03/19 23:03:20 merlinofchaos Exp $ -->
 Displays tell Views where the output should go. By adding a display to a View, you can have your view appear as a page, or as a block, or even as an attachment to a different display on the view.
 
-Each display can have its own settings, but when it's created, a display will take all of its <em>basic settings</em> from the <strong>default display</strong> which all Views must have. For most settings, there is an <strong>override</strong> button that will override that single setting for the current display. Overridden settings will have a mark in the summary for that display.
+Each display can have its own settings, but when it's created, a display will take all of its <em>basic settings</em> from the <strong>default display</strong> which all Views must have. For most settings, there is an <strong>override</strong> button that will override that single setting for the current display. Overridden settings will have a mark in the summary for that display. All 'default display settings' are shown in the other displays '<i>italic</i>'. When you override a setting, than it is shown 'normal'.
 
 Please keep in mind that when you are editing a setting on a display that is not overridden, then by default you are editing that for all displays.
 
Index: help/getting-started.html
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/help/getting-started.html,v
retrieving revision 1.8
diff -u -p -r1.8 getting-started.html
--- help/getting-started.html	14 Oct 2008 18:20:25 -0000	1.8
+++ help/getting-started.html	11 Aug 2010 21:11:32 -0000
@@ -1,4 +1,8 @@
-<!-- $Id: getting-started.html,v 1.8 2008/10/14 18:20:25 merlinofchaos Exp $ -->
+<!-- $Id: getting-started.html,v 1.8.2.1 2010/03/11 23:54:14 merlinofchaos Exp $ -->
+Module Developers:
+The Views' API help pages can be found <a href="topic:views/api">here</a>.
+
+New Users:
 For those new to Views, it can be a complex system that appears totally overwhelming. The good news is that the UI is designed to compartmentalize everything; this means that for the most part, you can ignore the parts you're not interested in. Start small and build your way up.
 
 Because of this, the edit UI can seem overwhelming at first, but there are really just a few things you <strong>have</strong> to know. The rest you can find through exploration. The Views Edit UI image, below, gives an overview of what you'll find on the edit UI.
Index: help/overrides.html
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/help/overrides.html,v
retrieving revision 1.2
diff -u -p -r1.2 overrides.html
--- help/overrides.html	10 Sep 2008 18:42:44 -0000	1.2
+++ help/overrides.html	11 Aug 2010 21:11:32 -0000
@@ -1,7 +1,7 @@
-<!-- $Id: overrides.html,v 1.2 2008/09/10 18:42:44 merlinofchaos Exp $ -->
+<!-- $Id: overrides.html,v 1.2.2.1 2010/03/10 20:00:34 merlinofchaos Exp $ -->
 
 If an item is <strong>using defaults</strong> then it is using values from the <strong>default display</strong>. <em>IMPORTANT NOTE:</em> If you modify this value, you are modifying the <strong>default display</strong> and thus modifying for all displays that are using default values.
 
 If that is not what you intend, you must click the <strong>override</strong> button. Once overridden, that display now has its own version of the value; modifying it will not modify it for other displays.
 
-For <strong>Relationships</strong>, <strong>arguments</strong>, <strong>fields</strong>, <strong>sort criteria</strong>, and <strong>filters</strong>, each of these must be overridden as a group! In other words, you cannot override a single filter, but instead must override allr filters. A message will appear on the item to let you know what its status is, but you can only change the status by clicking on the header or the rearrange button for that item.
\ No newline at end of file
+For <strong>Relationships</strong>, <strong>arguments</strong>, <strong>fields</strong>, <strong>sort criteria</strong>, and <strong>filters</strong>, each of these must be overridden as a group! In other words, you cannot override a single filter, but instead must override all filters. A message will appear on the item to let you know what its status is, but you can only change the status by clicking on the header or the rearrange button for that item.
Index: help/style.html
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/help/style.html,v
retrieving revision 1.4
diff -u -p -r1.4 style.html
--- help/style.html	14 Oct 2008 18:20:25 -0000	1.4
+++ help/style.html	11 Aug 2010 21:11:32 -0000
@@ -1,4 +1,4 @@
-<!-- $Id: style.html,v 1.4 2008/10/14 18:20:25 merlinofchaos Exp $ -->
+<!-- $Id: style.html,v 1.4.2.1 2010/03/16 22:27:23 merlinofchaos Exp $ -->
 The Views' <strong>style</strong> system is how you customize the output produced by your view. A view style is basically a smart theme template that processes the view data and then outputs it. All styles in Views can be <a href="topic:views/using-theme">overridden</a> by placing copies of the templates in your theme directory and then modifying them. See the <a href="topic:views/analyze-theme">theme: information</a> link available on all views to get hints for which templates a given view is using.
 
 <div class="help-box" style="text-align:center">
@@ -10,5 +10,6 @@ By default, the style is <em>unformatted
 Some styles use a separate <a href="topic:views/style-row">row style</a> to determine how each row of the View looks. This is useful for mixing and matching styles to more readily produce exactly the kind of output you need.
 
 Many styles can be <strong>grouped</strong>. For styles that can, there will be a 'grouping field' option; pick one of the fields to group by. This grouping field will be displayed as a header, and all rows will be displayed beneath it.
+With the Theme Developer module enabled, the field grouping in Views does not work. Disable the Theme Developer module before grouping by fields.
 
-Each style is its own entity.
\ No newline at end of file
+Each style is its own entity.
Index: help/views.help.ini
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/help/views.help.ini,v
retrieving revision 1.17
diff -u -p -r1.17 views.help.ini
--- help/views.help.ini	22 Apr 2009 07:03:35 -0000	1.17
+++ help/views.help.ini	11 Aug 2010 21:11:32 -0000
@@ -1,4 +1,4 @@
-; $Id: views.help.ini,v 1.17 2009/04/22 07:03:35 merlinofchaos Exp $
+; $Id: views.help.ini,v 1.17.2.3 2009/11/30 19:37:02 merlinofchaos Exp $
 [advanced help settings]
 line break = TRUE
 
@@ -157,17 +157,17 @@ title = "Using CSS with Views"
 parent = analyze-theme
 
 [overrides]
-title = What are overrides?
+title = "What are overrides?"
 
 [embed]
-title = Embedding a view into other parts of your site
+title = "Embedding a view into other parts of your site"
 
 [new]
-title = What's new in Views 2
+title = "What's new in Views 2"
 weight = -42
 
 [updating]
-title = Updating your views from Views 1 to Views 2
+title = "Updating your views from Views 1 to Views 2"
 
 ; API related
 [api]
@@ -197,3 +197,8 @@ parent = api
 [api-upgrading]
 title = "Upgrading your module Views 1 to Views 2"
 parent = api
+
+[api-example]
+title = "Integrating the Node Example module"
+parent = api
+weight = 100
Index: includes/admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/admin.inc,v
retrieving revision 1.160
diff -u -p -r1.160 admin.inc
--- includes/admin.inc	10 Jun 2009 22:01:31 -0000	1.160
+++ includes/admin.inc	11 Aug 2010 21:11:32 -0000
@@ -1,3073 +1,3903 @@
-<?php
-// $Id: admin.inc,v 1.160 2009/06/10 22:01:31 merlinofchaos Exp $
-/**
- * @file admin.inc
- * Provides the Views' administrative interface.
- */
-
-/**
- * Page callback to list views in the system.
- */
-function views_ui_list_views($arg = NULL) {
-  if ($arg != NULL) {
-    return drupal_not_found();
-  }
-
-  $output = theme('views_ui_list_views');
-  views_ui_check_advanced_help();
-  return $output;
-}
-
-/**
- * Check to see if the advanced help module is installed, and if not put up
- * a message.
- *
- * Only call this function if the user is already in a position for this to
- * be useful.
- */
-function views_ui_check_advanced_help() {
-  if (variable_get('views_hide_help_message', FALSE)) {
-    return;
-  }
-
-  if (!module_exists('advanced_help')) {
-    $filename = db_result(db_query("SELECT filename FROM {system} WHERE type = 'module' AND name = 'advanced_help'"));
-    if ($filename && file_exists($filename)) {
-      drupal_set_message(t('If you <a href="@modules">enable the advanced help module</a>, Views will provide more and better help. <a href="@hide">Hide this message.</a>', array('@modules' => url('admin/build/modules'),'@hide' => url('admin/build/views/tools'))));
-    }
-    else {
-      drupal_set_message(t('If you install the advanced help module from !href, Views will provide more and better help. <a href="@hide">Hide this message.</a>', array('!href' => l('http://drupal.org/project/advanced_help', 'http://drupal.org/project/advanced_help'), '@hide' => url('admin/build/views/tools'))));
-    }
-  }
-}
-
-/**
- * Preprocess the list views theme
- */
-function template_preprocess_views_ui_list_views(&$vars) {
-  $items = array();
-  $sorts = array();
-
-  $views = views_get_all_views();
-
-  // Respond to a reset command by clearing session and doing a drupal goto
-  // back to the base URL.
-  if (isset($_GET['op']) && $_GET['op'] == t('Reset')) {
-    unset($_SESSION['views']['#admin']);
-    drupal_goto('admin/build/views');
-  }
-  if (count($_GET) <= 1) {
-    if (isset($_SESSION['views']['#admin']) && is_array($_SESSION['views']['#admin'])) {
-      $_GET += $_SESSION['views']['#admin'];
-    }
-  }
-  else {
-    $_SESSION['views']['#admin'] = $_GET;
-    unset($_SESSION['views']['#admin']['q']);
-  }
-
-  $form_state = array(
-    'views' => $views,
-    'input' => $_GET,
-    'method' => 'get',
-    'rerender' => TRUE,
-    'no_redirect' => TRUE,
-  );
-
-  $vars['widgets'] = drupal_build_form('views_ui_list_views_form', $form_state);
-
-  $vars['help_type_icon'] = theme('advanced_help_topic', 'views', 'view-type');
-
-  $base_tables = views_fetch_base_tables();
-
-  foreach ($views as $view) {
-    if ($form_state['values']['tag'] != 'all') {
-      if ($form_state['values']['tag'] == 'none') {
-        if (!empty($view->tag)) {
-          continue;
-        }
-      }
-      else if ($form_state['values']['tag'] != $view->tag) {
-        continue;
-      }
-    }
-    if ($form_state['values']['type'] != 'all' && $form_state['values']['type'] != $view->type) {
-      continue;
-    }
-
-    if ($form_state['values']['base'] != 'all' && $form_state['values']['base'] != $view->base_table) {
-      continue;
-    }
-
-    if ($form_state['values']['display'] != 'all' && empty($view->display[$form_state['values']['display']])) {
-      continue;
-    }
-
-    $item = new stdClass();
-    $item->ops = array();
-    if (empty($view->disabled)) {
-      $item->ops[] = l(t('Edit'), "admin/build/views/edit/$view->name");
-      $item->ops[] = l(t('Export'), "admin/build/views/export/$view->name");
-      $item->ops[] = l(t('Clone'), "admin/build/views/clone/$view->name");
-    }
-    if ($view->type != t('Default')) {
-      $text = $view->type == t('Overridden') ? t('Revert') : t('Delete');
-      $item->ops[] = l($text, "admin/build/views/delete/$view->name");
-    }
-    else {
-      if (empty($view->disabled)) {
-        $item->ops[] = l(t('Disable'), "admin/build/views/disable/$view->name", array('query' => drupal_get_destination()));
-      }
-      else {
-        $item->ops[] = l(t('Enable'), "admin/build/views/enable/$view->name", array('query' => drupal_get_destination()));
-      }
-    }
-
-    $item->ops = implode(' | ', $item->ops);
-    if (empty($view->display)) {
-      $item->path = t('Warning! Broken view!');
-    }
-    else {
-      $item->path = $raw_path = $view->get_path();
-      $item->path = $item->path && empty($view->disabled) && strpos($item->path, '%') === FALSE ? l($item->path, $item->path) : check_plain($item->path);
-    }
-
-    $item->type = $view->type;
-    $item->name = $view->name;
-
-    if (!empty($view->tag)) {
-      $item->tag = $view->tag;
-    }
-
-    $item->title = $view->get_title();
-    $item->base = !empty($base_tables[$view->base_table]['title']) ? $base_tables[$view->base_table]['title'] : t('Broken');
-
-    $item->displays = array();
-    foreach ($view->display as $display) {
-      if (!empty($display->handler->definition['admin'])) {
-        $item->displays[$display->handler->definition['admin']] = TRUE;
-      }
-    }
-
-    if ($item->displays) {
-      ksort($item->displays);
-      $item->displays = implode(', ', array_keys($item->displays));
-    }
-
-    $item->description = check_plain($view->description);
-    $item->classes = empty($view->disabled) ? 'view-enabled' : 'view-disabled';
-    $items[] = $item;
-
-    $sort = intval(empty($view->disabled) xor $form_state['values']['sort'] == 'asc');
-
-    switch ($form_state['values']['order']) {
-      case 'name':
-      default:
-        $sort .= strtolower($view->name);
-        break;
-      case 'title':
-        $sort .= strtolower($item->title);
-        break;
-      case 'path':
-        $sort .= strtolower($raw_path); // $path;
-        break;
-      case 'type':
-        $sort .= $view->type . $view->name;
-        break;
-      case 'tag':
-        $sort .= strtolower($view->tag);
-        break;
-      case 'desc':
-        $sort .= strtolower($view->description);
-        break;
-    }
-
-    $sorts[] = $sort;
-  }
-
-  if ($form_state['values']['sort'] == 'desc') {
-    arsort($sorts);
-  }
-  else {
-    asort($sorts);
-  }
-
-  $i = array();
-  foreach ($sorts as $id => $title) {
-    $i[] = $items[$id];
-  }
-
-  views_add_css('views-list');
-  $vars['views'] = $i;
-
-  $getting_started = theme('advanced_help_topic', 'views', 'getting-started', 'title');
-  if (!$getting_started) {
-    $getting_started = t('Install the advanced help module for the getting started');
-  }
-
-  $vars['help'] = t('Not sure what to do? Try the "!getting-started" page.', array('!getting-started' => $getting_started));
-}
-
-/**
- * Provide a form for sorting and filtering the list of views.
- */
-function views_ui_list_views_form(&$form_state) {
-  if (!variable_get('clean_url', FALSE)) {
-    $form['q'] = array(
-      '#type' => 'hidden',
-      '#value' => $_GET['q'],
-    );
-  }
-
-  $all = array('all' => t('<All>'));
-  $none = array('none' => t('<None>'));
-
-  $form['type'] = array(
-    '#type' => 'select',
-    '#title' => t('Storage'),
-    '#options' => array(
-      'all' => t('<All>'),
-      t('Normal') => t('Normal'),
-      t('Default') => t('Default'),
-      t('Overridden') => t('Overridden'),
-    ),
-    '#default_value' => 'all',
-  );
-
-  $bases = array();
-  foreach (views_fetch_base_tables() as $table => $info) {
-    $bases[$table] = $info['title'];
-  }
-
-  $form['base'] = array(
-    '#type' => 'select',
-    '#title' => t('Type'),
-    '#options' => array_merge($all, $bases),
-    '#default_value' => 'all',
-  );
-
-  $tags = array();
-
-  $extras = array();
-  foreach ($form_state['views'] as $name => $view) {
-    if (!empty($view->tag)) {
-      $tags[$view->tag] = $view->tag;
-    }
-  }
-
-  asort($tags);
-
-  $form['tag'] = array(
-    '#type' => 'select',
-    '#title' => t('Tag'),
-    '#options' => array_merge($all, $none, $tags),
-    '#default_value' => 'all',
-  );
-
-  $displays = array();
-  foreach (views_fetch_plugin_data('display') as $id => $info) {
-    if (!empty($info['admin'])) {
-      $displays[$id] = $info['admin'];
-    }
-  }
-
-  asort($displays);
-
-  $form['display'] = array(
-    '#type' => 'select',
-    '#title' => t('Displays'),
-    '#options' => array_merge($all, $displays),
-    '#default_value' => 'all',
-  );
-
-  $form['order'] = array(
-    '#type' => 'select',
-    '#title' => t('Sort by'),
-    '#options' => array(
-      'name' => t('Name'),
-      'title' => t('Title'),
-      'tag' => t('Tag'),
-      'path' => t('Path'),
-      'type' => t('Type'),
-      'desc' => t('Description'),
-    ),
-    '#default_value' => 'name',
-  );
-
-  $form['sort'] = array(
-    '#type' => 'select',
-    '#title' => t('Order'),
-    '#options' => array(
-      'asc' => t('Up'),
-      'desc' => t('Down'),
-    ),
-    '#default_value' => 'asc',
-  );
-
-  $form['submit'] = array(
-    '#name' => '', // so it won't in the $_GET args
-    '#type' => 'submit',
-    '#id' => 'edit-views-apply',
-    '#value' => t('Apply'),
-  );
-
-  if (!empty($_SESSION['views']['#admin'])) {
-    $form['reset'] = array(
-      '#type' => 'submit',
-      '#id' => 'edit-views-reset',
-      '#value' => t('Reset'),
-    );
-  }
-
-  $form['#theme'] = array('views_ui_list_views_form');
-  return $form;
-}
-
-function theme_views_ui_list_views_form($form) {
-  // Don't render these:
-  unset($form['form_id']);
-  unset($form['form_build_id']);
-  unset($form['form_token']);
-  return drupal_render($form);
-}
-
-/**
- * Page callback for the live preview.
- *
- * @todo make this use a template
- */
-function views_ui_preview($js, $view) {
-  // Take off the items we know so that we can have just the args passed
-  // in for later use.
-  $func_args = func_get_args();
-  array_shift($func_args); // $js
-  array_shift($func_args); // $view
-  $display_id = (count($func_args)) ? array_shift($func_args) : 'default';
-
-  $form_state = array(
-    'display_id' => $display_id,
-    'view_args' => $func_args ? implode('/', $func_args) : '',
-    'rerender' => TRUE,
-    'no_redirect' => TRUE,
-    'view' => &$view,
-    'ajax' => $js
-  );
-
-  $output = drupal_build_form('views_ui_preview_form', $form_state);
-  $args = array();
-  if (isset($form_state['view_args']) && $form_state['view_args'] !== '') {
-    $args = explode('/', $form_state['view_args']);
-  }
-
-  $errors = $view->validate();
-  if ($errors === TRUE) {
-    $view->ajax = $js;
-    $view->live_preview = TRUE;
-
-    // Store the current view URL for later use:
-    $view->set_display($form_state['display_id']);
-    $view->set_arguments($args);
-
-    if ($view->display_handler->get_option('path')) {
-      $path = $view->get_url();
-    }
-
-    // Make view links come back to preview.
-    $view->override_path = 'admin/build/views/nojs/preview/' . $view->name . '/' . $form_state['display_id'];
-
-    // also override $_GET['q'] so we get the pager
-    $_GET['q'] = $view->override_path;
-    if ($form_state['view_args']) {
-      $_GET['q'] .= '/' . $form_state['view_args'];
-    }
-
-    $preview = $view->preview($form_state['display_id'], $args);
-
-    // Get information from the preview for display.
-    if (!empty($view->build_info['query'])) {
-      $rows = array();
-      $query = db_prefix_tables($view->build_info['query']);
-      if ($view->build_info['query_args']) {
-        _db_query_callback($view->build_info['query_args'], TRUE);
-        $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
-      }
-      $rows[] = array('<strong>' . t('Query') . '</strong>', '<pre>' . check_plain($query) . '</pre>');
-      if (!empty($view->additional_queries)) {
-        $queries = '<strong>' . t('These queries were run during view rendering:') . '</strong>';
-        foreach ($view->additional_queries as $query) {
-          if ($queries) {
-            $queries .= "\n";
-          }
-          $queries .= t('[@time ms]', array('@time' => intval($query[1] * 100000) / 100)) . ' ' . $query[0];
-        }
-
-        $rows[] = array('<strong>' . t('Other queries') . '</strong>', '<pre>' . $queries . '</pre>');
-      }
-
-      $rows[] = array('<strong>' . t('Title') . '</strong>', filter_xss_admin($view->get_title()));
-      if (isset($path)) {
-        $path = l($path, $path);
-      }
-      else {
-        $path = t('This display has no path.');
-      }
-
-      $rows[] = array('<strong>' . t('Path') . '</strong>', $path);
-
-      $rows[] = array('<strong>' . t('Query build time') . '</strong>', t('@time ms', array('@time' => intval($view->build_time * 100000) / 100)));
-      $rows[] = array('<strong>' . t('Query execute time') . '</strong>', t('@time ms', array('@time' => intval($view->execute_time * 100000) / 100)));
-      $rows[] = array('<strong>' . t('View render time') . '</strong>', t('@time ms', array('@time' => intval($view->render_time * 100000) / 100)));
-      drupal_alter('views_preview_info', $rows, $view);
-
-      $info = theme('table', array(), $rows);
-    }
-    else {
-      $info = theme('table', array(), array(array('<strong>' . t('Query') . '</strong>', t('No query was run'))));
-    }
-  }
-  else {
-    foreach ($errors as $error) {
-      drupal_set_message($error, 'error');
-    }
-    $preview = t('Unable to preview due to validation errors.');
-    $info = '';
-  }
-
-  $info = '<div class="views-query-info">' . $info . '</div>';
-
-  if (variable_get('views_ui_query_on_top', FALSE)) {
-    $output .= $info . $preview;
-  }
-  else {
-    $output .= $preview . $info;
-  }
-
-  if (!$js) {
-    views_add_css('views-admin');
-    drupal_set_title($view->get_title());
-    return $output;
-  }
-  else {
-    views_include('ajax');
-    $object = new stdClass();
-    if (!empty($view->js_settings)) {
-      $object->js = $view->js_settings;
-    }
-    $object->display = '';
-    if ($messages = theme('status_messages')) {
-      $object->display = '<div class="views-messages">' . $messages . '</div>';
-    }
-    $object->display .= $output;
-    $object->title = $view->get_title();
-    views_ajax_render($object);
-  }
-}
-
-/**
- * Form for generating argument information for the live preview.
- */
-function views_ui_preview_form(&$form_state) {
-  $view = &$form_state['view'];
-  $view->init_display();
-  $options = array();
-  foreach ($view->display as $id => $display) {
-    $options[$id] = $display->display_title;
-  }
-
-  $form['#attributes'] = array(
-    'class' => 'clear-block',
-  );
-
-  $form['display_id'] = array(
-    '#type' => 'select',
-    '#title' => t('Display'),
-    '#options' => $options,
-    '#default_value' => $form_state['display_id'],
-    '#id' => 'preview-display-id',
-  );
-
-  $form['args'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Arguments'),
-    '#default_value' => $form_state['view_args'],
-    '#description' => t('Separate arguments with a / as though they were a URL path.'),
-    '#id' => 'preview-args',
-  );
-
-  $form['preview'] = array(
-    '#type' => 'submit',
-    '#value' => t('Preview'),
-    '#id' => 'preview-submit',
-  );
-
-  $form['#action'] = url("admin/build/views/nojs/preview/$view->name");
-  return $form;
-}
-
-/**
- * Submit the preview form.
- *
- * This just takes the data and stores it on the form state in a
- * known location. The caller will be responsible for using it.
- */
-function views_ui_preview_form_submit(&$form, &$form_state) {
-  $form_state['display_id'] = $form_state['values']['display_id'];
-  $form_state['view_args'] = $form_state['values']['args'];
-}
-
-/**
- * Page callback to add a new view.
- */
-function views_ui_add_page() {
-  $form_state = array(
-    'view' => NULL
-  );
-
-  return drupal_build_form('views_ui_add_form', $form_state);
-}
-
-/**
- * Page callback to add a new view.
- */
-function views_ui_clone_page($view) {
-  $form_state = array(
-    'view' => $view->copy(),
-  );
-
-  drupal_set_title(t('Clone view %view', array('%view' => $view->name)));
-  return drupal_build_form('views_ui_add_form', $form_state);
-}
-
-/**
- * Form constructor callback to create the views Add Form, phase 1.
- */
-function views_ui_add_form(&$form_state) {
-  $view = $form_state['view'];
-  $form = array();
-
-  $form['name'] = array(
-    '#type' => 'textfield',
-    '#title' => t('View name'),
-    '#description' => t('This is the unique name of the view. It must contain only alphanumeric characters and underscores; it is used to identify the view internally and to generate unique theming template names for this view. If overriding a module provided view, the name must not be changed or instead a new view will be created.'),
-    '#required' => TRUE,
-    '#maxlength' => 32,
-    '#default_value' => $view ? $view->name : '',
-    '#attributes' => array('dir'=>'ltr'),
-  );
-
-  $form['description'] = array(
-    '#type' => 'textfield',
-    '#title' => t('View description'),
-    '#description' => t('This description will appear on the Views administrative UI to tell you what the view is about.'),
-    '#default_value' => $view ? $view->description : '',
-  );
-
-  $form['tag'] = array(
-    '#type' => 'textfield',
-    '#title' => t('View tag'),
-    '#description' => t('Enter an optional tag for this view; it is used only to help sort views on the administrative page.'),
-    '#default_value' => $view ? $view->tag : '',
-    '#autocomplete_path' => 'admin/views/ajax/autocomplete/tag',
-  );
-
-  $base_tables = array();
-  foreach (views_fetch_base_tables() as $table => $info) {
-    $base_tables[$table] = $info['title'] . '<div class="description">' . $info['description'] . '</div>';
-  }
-
-  $form['base_table'] = array(
-    '#type' => 'radios',
-    '#title' => t('View type'),
-    '#description' => t('The view type is the primary table for which information is being retrieved. The view type controls what arguments, fields, sort criteria and filters are available, so once this is set it <strong>cannot be changed</strong>.'),
-    '#default_value' => $view ? $view->base_table : 'node',
-    '#options' => $base_tables,
-  );
-
-  if ($view) {
-    $form['base_table']['#disabled'] = TRUE;
-  }
-
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Next'),
-    '#validate' => array('views_ui_add_form_validate'),
-    '#submit' => array('views_ui_add_form_submit'),
-  );
-
-  return $form;
-}
-
-/**
- * Validate the add view form.
- */
-function views_ui_add_form_validate($form, &$form_state) {
-  $name = $form_state['values']['name'];
-
-  // View name must be alphanumeric or underscores, no other punctuation.
-  if (preg_match('/[^a-zA-Z0-9_]/', $name)) {
-    form_error($form['name'], t('View name must be alphanumeric or underscores only.'));
-  }
-
-  // View name must already exist.
-  $view = views_get_view($form_state['values']['name']);
-  if ($view && $view->type != t('Default')) {
-    form_error($form['name'], t('You must use a unique name for this view.'));
-  }
-}
-
-/**
- * Process the add view form
- */
-function views_ui_add_form_submit($form, &$form_state) {
-  $view = $form_state['view'] ? $form_state['view'] : views_new_view();
-  $view->name = $form_state['values']['name'];
-  $view->description = $form_state['values']['description'];
-  $view->tag = $form_state['values']['tag'];
-  if (empty($form['base_table']['#disabled'])) {
-    $view->base_table = $form_state['values']['base_table'];
-  }
-
-  views_ui_cache_set($view);
-  $form_state['redirect'] ='admin/build/views/edit/' . $view->name;
-}
-
-/**
- * Page to delete a view.
- */
-function views_ui_delete_confirm(&$form_state, $view) {
-  $form_state['view'] = &$view;
-  $form = array();
-
-  $cancel = 'admin/build/views';
-  if (!empty($_REQUEST['cancel'])) {
-    $cancel = $_REQUEST['cancel'];
-  }
-
-  if ($view->type == t('Overridden')) {
-    $title = t('Are you sure you want to revert the view %name?', array('%name' => $view->name));
-    $desc = t('Reverting the view will delete the view that is in the database, reverting it to the original default view. Any changes you have made will be lost and cannot be recovered.');
-    $button = t('Revert');
-  }
-  else {
-    $title = t('Are you sure you want to delete the view %name?', array('%name' => $view->name));
-    $desc = t('Deleting a view cannot be undone.');
-    $button = t('Delete');
-  }
-
-  return confirm_form($form,
-                  $title,
-                  $cancel,
-                  $desc,
-                  $button,
-                  t('Cancel'));
-}
-
-/**
- * Submit handler to delete a view.
- */
-function views_ui_delete_confirm_submit(&$form, &$form_state) {
-  $form_state['view']->delete();
-  views_object_cache_clear('view', $form_state['view']->name);
-  drupal_set_message(t('The view has been deleted.'));
-  $form_state['redirect'] = 'admin/build/views';
-}
-
-/**
- * Page to delete a view.
- */
-function views_ui_break_lock_confirm(&$form_state, $view) {
-  $form_state['view'] = &$view;
-  $form = array();
-
-  if (empty($view->locked)) {
-    return t('There is no lock on view %view to break.', array('%name' => $view->name));
-  }
-
-  $cancel = 'admin/build/views/edit/' . $view->name;
-  if (!empty($_REQUEST['cancel'])) {
-    $cancel = $_REQUEST['cancel'];
-  }
-
-  $account = user_load($view->locked->uid);
-  return confirm_form($form,
-                  t('Are you sure you want to break the lock on view %name?',
-                  array('%name' => $view->name)),
-                  $cancel,
-                  t('By breaking this lock, any unsaved changes made by !user will be lost!', array('!user' => theme('username', $account))),
-                  t('Break lock'),
-                  t('Cancel'));
-}
-
-/**
- * Submit handler to break_lock a view.
- */
-function views_ui_break_lock_confirm_submit(&$form, &$form_state) {
-  db_query("DELETE FROM {views_object_cache} WHERE obj = 'view' AND name = '%s'", $form_state['view']->name);
-  $form_state['redirect'] = 'admin/build/views/edit/' . $form_state['view']->name;
-  drupal_set_message(t('The lock has been broken and you may now edit this view.'));
-}
-
-/**
- * The main view edit page
- */
-function views_ui_edit_page($view) {
-  drupal_set_title(t('Edit view %view', array('%view' => $view->name)));
-  $output = theme('views_ui_edit_view', $view);
-  views_ui_check_advanced_help();
-  return $output;
-}
-
-/**
- * Export a view for cut & paste.
- */
-function views_ui_export_page(&$form_state, $view) {
-  $code = $view->export();
-  $lines = substr_count($code, "\n");
-  $form['code'] = array(
-    '#type' => 'textarea',
-    '#title' => $view->name,
-    '#default_value' => $code,
-    '#rows' => $lines,
-  );
-  return $form;
-}
-
-/**
- * Import a view from cut & paste
- */
-function views_ui_import_page(&$form_state) {
-  $form['name'] = array(
-    '#type' => 'textfield',
-    '#title' => t('View name'),
-    '#description' => t('Enter the name to use for this view if it is different from the source view. Leave blank to use the name of the view.'),
-  );
-
-  $form['view'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Paste view code here'),
-    '#required' => TRUE,
-  );
-
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Import'),
-    '#submit' => array('views_ui_import_submit'),
-    '#validate' => array('views_ui_import_validate'),
-  );
-  return $form;
-}
-
-/**
- * Validate handler to import a view
- */
-function views_ui_import_validate($form, &$form_state) {
-  $view = '';
-  views_include('view');
-  ob_start();
-  eval($form_state['values']['view']);
-  ob_end_clean();
-
-  if (!is_object($view)) {
-    return form_error($form['view'], t('Unable to interpret view code.'));
-  }
-
-  if (empty($view->api_version) || $view->api_version < 2) {
-    // Check for some value that would only exist on a Views 1 view.
-    if (isset($view->url) || isset($view->page) || isset($view->block)) {
-      views_include('convert');
-      $view = views1_import($view);
-      drupal_set_message(t('You are importing a view created in Views version 1. You may need to adjust some parameters to work correctly in version 2.'), 'warning');
-    }
-    else {
-      form_error($form['view'], t('That view is not compatible with this version of Views.'));
-    }
-  }
-
-  // View name must be alphanumeric or underscores, no other punctuation.
-  if (!empty($form_state['values']['name']) && preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['name'])) {
-    form_error($form['name'], t('View name must be alphanumeric or underscores only.'));
-  }
-
-  if ($form_state['values']['name']) {
-    $view->name = $form_state['values']['name'];
-  }
-
-  $test = views_get_view($view->name);
-  if ($test && $test->type != t('Default')) {
-    form_set_error('', t('A view by that name already exists; please choose a different name'));
-  }
-
-  $view->init_display();
-
-  $broken = FALSE;
-  // Make sure that all plugins and handlers needed by this view actually exist.
-  foreach ($view->display as $id => $display) {
-    if (empty($display->handler) || !empty($display->handler->broken)) {
-      drupal_set_message(t('Display plugin @plugin is not available.', array('@plugin' => $display->display_plugin)), 'error');
-      $broken = TRUE;
-      continue;
-    }
-
-    $plugin = views_get_plugin('style', $display->handler->get_option('style_plugin'));
-    if (!$plugin) {
-      drupal_set_message(t('Style plugin @plugin is not available.', array('@plugin' => $display->handler->get_option('style_plugin'))), 'error');
-      $broken = TRUE;
-    }
-    else if ($plugin->uses_row_plugin()) {
-      $plugin = views_get_plugin('row', $display->handler->get_option('row_plugin'));
-      if (!$plugin) {
-        drupal_set_message(t('Row plugin @plugin is not available.', array('@plugin' => $display->handler->get_option('row_plugin'))), 'error');
-        $broken = TRUE;
-      }
-    }
-
-    foreach (views_object_types() as $type => $info) {
-      $handlers = $display->handler->get_handlers($type);
-      if ($handlers) {
-        foreach ($handlers as $id => $handler) {
-          if ($handler->broken()) {
-            drupal_set_message(t('@type handler @table.@field is not available.', array(
-              '@type' => $info['stitle'],
-              '@table' => $handler->table,
-              '@field' => $handler->field,
-            )), 'error');
-            $broken = TRUE;
-          }
-        }
-      }
-    }
-  }
-
-  if ($broken) {
-    form_set_error('', t('Unable to import view.'));
-  }
-
-  $form_state['view'] = &$view;
-}
-
-/**
- * Submit handler for view import
- */
-function views_ui_import_submit($form, &$form_state) {
-  // Store in cache and then go to edit.
-  views_ui_cache_set($form_state['view']);
-  $form_state['redirect'] = 'admin/build/views/edit/' . $form_state['view']->name;
-}
-
-/**
- * The main edit view form, which is really just a save/cancel/delete button.
- */
-function views_ui_edit_view_form(&$form_state, $view) {
-  $form['buttons']['save'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
-    '#validate' => array('views_ui_edit_view_form_validate'),
-    '#submit' => array('views_ui_edit_view_form_submit'),
-  );
-
-  $form['buttons']['cancel'] = array(
-    '#type' => 'submit',
-    '#value' => t('Cancel'),
-    '#submit' => array('views_ui_edit_view_form_cancel'),
-  );
-
-  if (is_numeric($view->vid)) {
-    $form['buttons']['delete'] = array(
-      '#type' => 'submit',
-      '#value' => t('Delete'),
-      '#submit' => array('views_ui_edit_view_form_delete'),
-    );
-  }
-
-  $form_state['view'] = &$view;
-  return $form;
-}
-
-/**
- * Validate that a view is complete and whole.
- */
-function views_ui_edit_view_form_validate($form, &$form_state) {
-  // Do not validate cancel or delete.
-  if (empty($form_state['clicked_button']['#value']) || $form_state['clicked_button']['#value'] != t('Save')) {
-    return;
-  }
-
-  $errors = $form_state['view']->validate();
-  if ($errors !== TRUE) {
-    foreach ($errors as $error) {
-      form_set_error('', $error);
-    }
-  }
-}
-
-/**
- * Submit handler for the edit view form.
- */
-function views_ui_edit_view_form_submit($form, &$form_state) {
-  // Go through and remove displayed scheduled for removal.
-  foreach ($form_state['view']->display as $id => $display) {
-    if (!empty($display->deleted)) {
-      unset($form_state['view']->display[$id]);
-    }
-  }
-
-  $form_state['view']->save();
-  drupal_set_message(t('The view has been saved.'));
-
-  // Make sure menu items get rebuilt as neces
-  menu_rebuild();
-
-  // Clear the views cache.
-  cache_clear_all('*', 'cache_views');
-
-  // Clear the page cache.
-  cache_clear_all();
-
-  // Remove this view from cache so we can edit it properly.
-  views_object_cache_clear('view', $form_state['view']->name);
-}
-
-/**
- * Submit handler for the edit view form.
- */
-function views_ui_edit_view_form_cancel($form, &$form_state) {
-  // Remove this view from cache so edits will be lost.
-  views_object_cache_clear('view', $form_state['view']->name);
-  if (empty($form['view']->vid)) {
-    // I seem to have to drupal_goto here because I can't get fapi to
-    // honor the redirect target. Not sure what I screwed up here.
-    drupal_goto('admin/build/views');
-  }
-}
-
-function views_ui_edit_view_form_delete($form, &$form_state) {
-  unset($_REQUEST['destination']);
-  // Redirect to the delete confirm page
-  $form_state['redirect'] = array('admin/build/views/delete/' . $form_state['view']->name, 'cancel=admin/build/views/edit/' . $form_state['view']->name);
-}
-
-/**
- * Preprocess the view edit page.
- */
-function template_preprocess_views_ui_edit_view(&$vars) {
-  $view = &$vars['view'];
-
-  $vars['save_button'] = drupal_get_form('views_ui_edit_view_form', $view);
-
-  $table = views_fetch_data($view->base_table);
-  $vars['base_table'] = !empty($table['table']['base']['title']) ?
-    $table['table']['base']['title'] : t('Unknown or missing table name');
-
-  views_include('tabs');
-  $tabs = new views_tabset;
-
-  $vars['message'] = '<div class="message">' . t("Click on an item to edit that item's details.") . '</div>';
-
-  if (!$view->set_display('default')) {
-    drupal_set_message(t('This view has a broken default display and cannot be used.'), 'error');
-  }
-
-  foreach ($view->display as $display) {
-    list($title, $body) = views_ui_display_tab($view, $display);
-    // The first display is the default.
-    $tabs->set($display->id, $title, $body);
-  }
-
-  // This is the area that will render beneath the links
-  $form_state = array(
-    'view' => &$view,
-    'ajax' => FALSE,
-  );
-
-  $display_button = drupal_build_form('views_ui_add_display_form', $form_state);
-  $analyze_button = drupal_get_form('views_ui_analyze_view_button', $view);
-  $tabs->add_extra($display_button . $analyze_button);
-
-  $vars['tabs'] = $tabs->render();
-
-  $form_state = array(
-    'display_id' => 'default',
-    'view_args' => '',
-    'rerender' => FALSE,
-    'no_redirect' => TRUE,
-    'view' => &$view,
-    'input' => array(),
-  );
-  $vars['preview'] = drupal_build_form('views_ui_preview_form', $form_state);
-
-  $vars['locked'] = NULL;
-  if (isset($view->locked) && is_object($view->locked)) {
-    $account = user_load($view->locked->uid);
-    $vars['locked'] = theme('username', $account);
-    $vars['lock_age'] = format_interval(time() - $view->locked->updated);
-    $vars['break'] = url('admin/build/views/break-lock/' . $view->name);
-  }
-
-  $vars['quick_links_raw'] = array(
-    array(
-      'title' => t('Export'),
-      'alt' => t("Export this view"),
-      'href' => "admin/build/views/export/$view->name",
-    ),
-    array(
-      'title' => t('Clone'),
-      'alt' => t("Create a copy of this view"),
-      'href' => "admin/build/views/clone/$view->name",
-    ),
-  );
-
-  $paths = array();
-  foreach ($view->display as $id => $display) {
-    if (!empty($display->handler) && $display->handler->has_path()) {
-      $path = $display->handler->get_path();
-      if (strpos($path, '%') === FALSE && !isset($paths[$path])) {
-        $vars['quick_links_raw'][] = array(
-          'title' => t('View "@display"', array('@display' => $display->display_title)),
-          'alt' => t("Go to the real page for this display"),
-          'href' => $path,
-        );
-        // Displays can have the same path; no point in showing more than one link.
-        $paths[$path] = TRUE;
-      }
-    }
-  }
-
-  $vars['quick_links'] = theme('links', $vars['quick_links_raw']);
-  views_add_css('views-admin');
-  views_add_css('views');
-  views_add_js('ajax');
-  drupal_add_js('misc/jquery.form.js');
-
-  // Also add any js files required by plugins:
-  $plugins = views_fetch_plugin_data();
-  foreach ($plugins as $type => $type_plugins) {
-    foreach ($type_plugins as $name => $plugin) {
-      if (!empty($plugin['js'])) {
-        foreach ($plugin['js'] as $file) {
-          drupal_add_js($file);
-        }
-      }
-    }
-  }
-
-  $settings = array('views' => array('ajax' => array(
-    'id' => '#views-ajax-pad',
-    'title' => '#views-ajax-title',
-    'defaultForm' => $vars['message'],
-  )));
-
-  drupal_add_js($settings, 'setting');
-}
-
-function template_preprocess_views_ui_edit_tab(&$vars) {
-  $view = $vars['view'];
-  $display = $vars['display'];
-  $plugin = $display->handler->definition;
-
-  $top = $left = $middle = $right = '';
-
-  // If this form was submitted it was already handled, so force it not to
-  // submit again.
-
-  $vars['remove'] = '';
-  if (empty($plugin['no remove'])) {
-    if (!empty($_POST['form_id']) && $_POST['form_id'] == 'views_ui_remove_display_form') {
-      unset($_POST['form_id']);
-    }
-    $form_state = array('view' => &$view, 'display_id' => $display->id, 'ajax' => FALSE);
-    $vars['remove'] = drupal_build_form('views_ui_remove_display_form', $form_state);
-  }
-
-  // basic fields
-  $vars['title'] = check_plain($display->display_title);
-  $vars['description'] = check_plain($plugin['help']);
-
-  // Special fields if tihs is the default display.
-  $vars['default'] = ($display->id == 'default');
-  $vars['details_class'] = views_ui_item_css('details');
-  if (!empty($view->changed_sections['details'])) {
-    $vars['details_changed'] = TRUE;
-  }
-
-  $tag = empty($view->tag) ? t('None') : $view->tag;
-  $vars['details'] = t('Tag') . ': ' . l($tag, "admin/build/views/nojs/details/$view->name", array('attributes' => array('class' => 'views-ajax-link')));
-
-  // Calculate options from display plugin.
-  $options = $categories = array();
-  $display->handler->options_summary($categories, $options);
-
-  // Build all of the options we were returned and put them into the
-  // category data fields.
-  foreach ($options as $id => $option) {
-    if (empty($categories[$option['category']]['data'])) {
-      $categories[$option['category']]['data'] = array();
-    }
-    $categories[$option['category']]['data'][$id] = array();
-    $data = &$categories[$option['category']]['data'][$id];
-    $data['content'] = '';
-    $data['links'] = '';
-    $data['overridden'] = FALSE;
-    $data['defaulted'] = FALSE;
-
-    // If there are optional links, build them first so they float properly.
-    if (!empty($option['links'])) {
-      foreach ($option['links'] as $link_id => $link_value) {
-        $data['links'] .= $display->handler->option_link($link_value, $link_id, 'views-button-configure');
-      }
-    }
-    if (!empty($option['title'])) {
-      $data['content'] .= $option['title'] . ': ';
-    }
-
-    $data['content'] .= $display->handler->option_link($option['value'], $id, '', empty($option['desc']) ? '' : $option['desc']);
-    if (!empty($display->handler->options['defaults'][$id])) {
-      $display_id = 'default';
-      $data['defaulted'] = TRUE;
-    }
-    else {
-      $display_id = $display->id;
-      if (!$display->handler->is_default_display()) {
-        if ($display->handler->defaultable_sections($id)) {
-          $data['overridden'] = TRUE;
-        }
-      }
-    }
-    $data['class'] = views_ui_item_css($display_id . '-' . $id);
-    if (!empty($view->changed_sections[$display_id . '-' . $id])) {
-      $data['changed'] = TRUE;
-    }
-  }
-
-  $vars['categories'] = $categories;
-
-  // Add a help icon
-  if (isset($plugin['help topic'])) {
-    $vars['display_help_icon'] = theme('advanced_help_topic', $plugin['module'], $plugin['help topic']);
-  }
-  else {
-    $vars['display_help_icon'] = '';
-  }
-
-  // Fetch style plugin info because it has some effect on how/what we render.
-  $style_plugin = $display->handler->get_plugin();
-
-  $vars['fields'] = '';
-  $vars['fields'] = theme('views_ui_edit_item', 'field', $view, $display, !($style_plugin && $style_plugin->uses_fields()));
-  $vars['relationships'] = theme('views_ui_edit_item', 'relationship', $view, $display);
-  $vars['arguments'] = theme('views_ui_edit_item', 'argument', $view, $display);
-  $vars['filters'] = theme('views_ui_edit_item', 'filter', $view, $display);
-  $vars['sorts'] = theme('views_ui_edit_item', 'sort', $view, $display);
-}
-
-/**
- * Generate the summary output for a single display to render in a tab.
- */
-function views_ui_display_tab($view, $display) {
-  if (isset($display->handler)) {
-    $plugin = $display->handler->definition;
-  }
-  if (empty($plugin)) {
-    $title = isset($display->display_title) ? $display->display_title : t('Invalid');
-    return array($title, t("Error: Display @display refers to a plugin named '@plugin', but that plugin doesn't exist!", array('@display' => $display->id, '@plugin' => $display->display_plugin)));
-
-    // @todo We can do a better 'plugin does not exist' tab.
-  }
-
-  // The display should always be initialized prior to this call.
-  if (empty($display->handler)) {
-    return FALSE;
-  }
-
-  $body = theme('views_ui_edit_tab', $view, $display);
-  return array($display->display_title, $body);
-}
-
-/**
- * Add information about a section to a display.
- */
-function template_preprocess_views_ui_edit_item(&$vars) {
-  $type = $vars['type'];
-  $view = $vars['view'];
-  $display = $vars['display'];
-
-  $types = views_object_types();
-
-  $vars['overridden'] = FALSE;
-  $vars['defaulted'] = FALSE;
-
-  if ($vars['no_fields']) {
-    $vars['title'] = $types[$type]['title'];
-    $vars['item_help_icon'] = theme('advanced_help_topic', 'views', $type);
-    $vars['rearrange'] = NULL;
-    $vars['add'] = NULL;
-    return;
-  }
-
-  $vars['rearrange'] = l('<span>' . t('Rearrange') . '</span>', "admin/build/views/nojs/rearrange/$view->name/$display->id/$type", array('attributes' => array('class' => 'views-button-rearrange views-ajax-link', 'title' => t('Rearrange')), 'html' => true));
-
-  $vars['add'] = l('<span>' . t('Add') . '</span>', "admin/build/views/nojs/add-item/$view->name/$display->id/$type", array('attributes' => array('class' => 'views-button-add views-ajax-link', 'title' => t('Add')), 'html' => true));
-
-  if (!$display->handler->is_default_display()) {
-    if (!$display->handler->is_defaulted($types[$type]['plural'])) {
-      $vars['overridden'] = TRUE;
-    }
-    else {
-      $vars['defaulted'] = TRUE;
-    }
-  }
-
-  $vars['title'] = l($types[$type]['title'], "admin/build/views/nojs/config-type/$view->name/$display->id/$type", array('attributes' => array('class' => 'views-ajax-link')));
-//  $vars['title'] = l($types[$type]['title'], "admin/build/views/nojs/config-type/$view->name/$display->id/$type", array('attributes' => array('class' => 'views-ajax-link')));
-
-  $fields = array();
-
-  static $relationships = NULL;
-  if (!isset($relationships)) {
-    // Get relationship labels
-    $relationships = array();
-    // @todo: get_handlers()
-    foreach ($display->handler->get_option('relationships') as $id => $relationship) {
-      $handler = views_get_handler($relationship['table'], $relationship['field'], 'relationship');
-      if (empty($handler)) {
-        continue;
-      }
-      $handler->init($view, $relationship);
-      $relationships[$id] = $handler->label();
-    }
-  }
-
-  // @todo: get_handlers()
-  foreach ($display->handler->get_option($types[$type]['plural']) as $id => $field) {
-    $fields[$id] = array();
-
-    $handler = views_get_handler($field['table'], $field['field'], $type);
-    if (empty($handler)) {
-      $fields[$id]['class'] = 'broken';
-      $fields[$id]['title'] = t("Error: handler for @table > @field doesn't exist!", array('@table' => $field['table'], '@field' => $field['field']));
-      $fields[$id]['info'] = '';
-      continue;
-    }
-    $handler->init($view, $field);
-
-    $field_name = $handler->ui_name(TRUE);
-    if (!empty($field['relationship']) && !empty($relationships[$field['relationship']])) {
-      $field_name = '(' . $relationships[$field['relationship']] . ') ' . $field_name;
-    }
-
-    $fields[$id]['title'] = l($field_name, "admin/build/views/nojs/config-item/$view->name/$display->id/$type/$id", array('attributes' => array('class' => 'views-ajax-link'), 'html' => TRUE));
-    $fields[$id]['class'] = views_ui_item_css($display->id . '-' . $type . '-' . $id);
-    if (!empty($view->changed_sections[$display->id . '-' . $type . '-' . $id])) {
-      $fields[$id]['changed'] = TRUE;
-    }
-    $fields[$id]['info'] = $handler->admin_summary();
-
-    if ($handler->has_extra_options()) {
-      $fields[$id]['links'] = l('<span>' . t('Settings') . '</span>', "admin/build/views/nojs/config-item-extra/$view->name/$display->id/$type/$id", array('attributes' => array('class' => 'views-button-configure views-ajax-link', 'title' => t('Settings')), 'html' => true));
-    }
-
-    if ($handler->needs_style_plugin()) {
-      $style_plugin = views_fetch_plugin_data('style', $handler->options['style_plugin']);
-      $style_title = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin['title'];
-      $pid = $id . '-style-plugin';
-
-      if (!empty($style_plugin['uses options'])) {
-        $fields[$pid]['links'] = l('<span>' . t('Change settings for this style') . '</span>', "admin/build/views/nojs/config-style/$view->name/$display->id/$type/$id", array('attributes' => array('class' => 'views-button-configure views-ajax-link', 'title' => t('Settings')), 'html' => true));
-      }
-
-      $fields[$pid]['title'] = ' ' . t('&nbsp; Style: !style', array('!style' => l($style_title, "admin/build/views/nojs/change-style/$view->name/$display->id/$type/$id", array('attributes' => array('class' => 'views-ajax-link')))));
-      $fields[$pid]['class'] = views_ui_item_css($display->id . '-' . $type . '-' . $pid);
-      if (!empty($view->changed_sections[$display->id . '-' . $type . '-' . $pid])) {
-        $fields[$pid]['changed'] = TRUE;
-      }
-      $fields[$pid]['info'] = '';
-    }
-  }
-
-  $vars['fields'] = $fields;
-  $vars['item_help_icon'] = theme('advanced_help_topic', 'views', $type);
-}
-
-/**
- * Regenerate the tabs for AJAX updates.
- */
-function views_ui_regenerate_tabs(&$view, $display_id = NULL, $object = NULL) {
-  if (empty($display_id)) {
-    $displays = array_keys($view->display);
-  }
-  elseif (!is_array($display_id)) {
-    $displays = array($display_id);
-    if ($display_id != 'default') {
-      $displays[] = 'default';
-    }
-  }
-  else {
-    $displays = $display_id;
-  }
-
-  if (!$view->set_display('default')) {
-    views_ajax_render(t('Invalid display id found while regenerating tabs'));
-  }
-
-  if (!is_object($object)) {
-    $object = new stdClass();
-  }
-
-  $object->replace = array();
-  foreach ($displays as $id) {
-    list($title, $body) = views_ui_display_tab($view, $view->display[$id]);
-    $object->replace['#views-tab-' . $id] = $body;
-    $object->replace['#views-tab-title-' . $id] = check_plain($title);
-  }
-
-  if (!empty($view->changed)) {
-    $object->changed = TRUE;
-  }
-
-  views_ajax_render($object);
-}
-
-/**
- * Provide standard buttons for the forms to make it easy. Also provide
- * a hidden op operator because the forms plugin doesn't seem to properly
- * provide which button was clicked.
- */
-function views_ui_standard_form_buttons(&$form, &$form_state, $form_id, $name = NULL, $third = NULL, $submit = NULL) {
-  $form['buttons'] = array(
-    '#prefix' => '<div class="clear-block"><div class="form-buttons">',
-    '#suffix' => '</div></div>',
-  );
-
-  if (empty($name)) {
-    $name = t('Update');
-  }
-  // remove default validate handler
-  $form['#validate'] = array();
-
-  if (empty($form_state['ok_button'])) {
-    // but be sure submit button validates!
-    $form['buttons']['submit'] = array(
-      '#type' => 'submit',
-      '#value' => $name,
-      '#submit' => array($form_id . '_submit'),
-      '#validate' => array('views_ui_standard_submit', $form_id . '_validate'),
-    );
-  }
-
-  $cancel_submit = function_exists($form_id . '_cancel') ? $form_id . '_cancel' : 'views_ui_standard_cancel';
-  $form['buttons']['cancel'] = array(
-    '#type' => 'submit',
-    '#value' => empty($form_state['ok_button']) ? t('Cancel') : t('Ok'),
-    '#submit' => array($cancel_submit),
-    '#validate' => array(),
-  );
-
-  if ($third) {
-    if (empty($submit)) {
-      $submit = 'third';
-    }
-    $third_submit = function_exists($form_id . '_' . $submit) ? $form_id . '_' . $submit : 'views_ui_standard_cancel';
-
-    $form['buttons'][$submit] = array(
-      '#type' => 'submit',
-      '#value' => $third,
-      '#validate' => array(),
-      '#submit' => array($third_submit),
-    );
-  }
-
-  // Compatibility, to be removed later:
-  // We used to set these items on the form, but now we want them on the $form_state:
-  if (isset($form['#title'])) {
-    $form_state['title'] = $form['#title'];
-  }
-  if (isset($form['#help_topic'])) {
-    $form_state['help_topic'] = $form['#help_topic'];
-  }
-  if (isset($form['#help_module'])) {
-    $form_state['help_module'] = $form['#help_module'];
-  }
-  if (isset($form['#url'])) {
-    $form_state['url'] = $form['#url'];
-  }
-  if (isset($form['#js'])) {
-    if (!empty($form_state['js settings']) && is_array($form_state['js settings'])) {
-      $form_state['js settings'] = array_merge($form_state['js settings'], $form['#js']);
-    }
-    else {
-      $form_state['js settings'] = $form['#js'];
-    }
-  }
-  if (isset($form['#section'])) {
-    $form_state['#section'] = $form['#section'];
-  }
-  // Finally, we never want these cached -- our object cache does that for us.
-  $form['#no_cache'] = TRUE;
-
-  // If this isn't an ajaxy form, then we want to set the title.
-  if (!empty($form['#title'])) {
-    drupal_set_title($form['#title']);
-  }
-  views_add_css('views-admin');
-}
-
-/**
- * Basic submit handler applicable to all 'standard' forms
- */
-function views_ui_standard_submit($form, &$form_state) {
-  if (!empty($form['#section'])) {
-    $form_state['view']->changed_sections[$form['#section']] = TRUE;
-  }
-}
-
-/**
- * Submit handler for cancel button
- */
-function views_ui_standard_cancel($form, &$form_state) {
-  $form_state['redirect'] = 'admin/build/views/edit/' . $form_state['view']->name;
-}
-
-// --------------------------------------------------------------------------
-// Various subforms for editing the pieces of a view.
-
-function views_ui_ajax_forms($key = NULL) {
-  $forms = array(
-    'display' => array(
-      'form_id' => 'views_ui_edit_display_form',
-      'args' => array('section'),
-    ),
-    'remove-display' => array(
-      'form_id' => 'views_ui_remove_display_form',
-      'args' => array(),
-    ),
-    'config-type' => array(
-      'form_id' => 'views_ui_config_type_form',
-      'args' => array('type'),
-    ),
-    'rearrange' => array(
-      'form_id' => 'views_ui_rearrange_form',
-      'args' => array('type'),
-    ),
-    'add-item' => array(
-      'form_id' => 'views_ui_add_item_form',
-      'args' => array('type'),
-    ),
-    'config-item' => array(
-      'form_id' => 'views_ui_config_item_form',
-      'args' => array('type', 'id'),
-    ),
-    'config-item-extra' => array(
-      'form_id' => 'views_ui_config_item_extra_form',
-      'args' => array('type', 'id'),
-    ),
-    'change-style' => array(
-      'form_id' => 'views_ui_change_style_form',
-      'args' => array('type', 'id'),
-    ),
-    'config-style' => array(
-      'form_id' => 'views_ui_config_style_form',
-      'args' => array('type', 'id'),
-    ),
-  );
-
-  if ($key) {
-    return !empty($forms[$key]) ? $forms[$key] : NULL;
-  }
-
-  return $forms;
-}
-
-/**
- * Build a form identifier that we can use to see if one form
- * is the same as another. Since the arguments differ slightly
- * we do a lot of spiffy concenation here.
- */
-function views_ui_build_identifier($key, $view, $display_id, $args) {
-  $form = views_ui_ajax_forms($key);
-  $identifier = implode('-', array($key, $view->name, $display_id));
-
-  foreach ($form['args'] as $id) {
-    $arg = (!empty($args)) ? array_shift($args) : NULL;
-    $identifier .= '-' . $arg;
-  }
-  return $identifier;
-}
-
-/**
- * Build up a $form_state object suitable for use with drupal_build_form
- * based on known information about a form.
- */
-function views_ui_build_form_state($js, $key, &$view, $display_id, $args) {
-  $form = views_ui_ajax_forms($key);
-  // Build up form state
-  $form_state = array(
-    'form_key' => $key,
-    'form_id' => $form['form_id'],
-    'view' => &$view,
-    'ajax' => $js,
-    'display_id' => $display_id,
-    'no_redirect' => TRUE,
-  );
-
-  foreach ($form['args'] as $id) {
-    $form_state[$id] = (!empty($args)) ? array_shift($args) : NULL;
-  }
-
-  return $form_state;
-}
-
-/**
- * Create the URL for one of our standard AJAX forms based upon known
- * information about the form.
- */
-function views_ui_build_form_url($form_state) {
-  $form = views_ui_ajax_forms($form_state['form_key']);
-  $ajax = empty($form_state['ajax']) ? 'nojs' : 'ajax';
-  $name = $form_state['view']->name;
-  $url = "admin/build/views/$ajax/$form_state[form_key]/$name/$form_state[display_id]";
-  foreach ($form['args'] as $arg) {
-    $url .= '/' . $form_state[$arg];
-  }
-  return $url;
-}
-
-/**
- * Add another form to the stack; clicking 'update' will go to this form
- * rather than closing the ajax pad.
- */
-function views_ui_add_form_to_stack($key, &$view, $display_id, $args, $top = FALSE) {
-  if (empty($view->stack)) {
-    $view->stack = array();
-  }
-
-  $stack = array(views_ui_build_identifier($key, $view, $display_id, $args), $key, &$view, $display_id, $args);
-  if ($top) {
-    array_unshift($view->stack, $stack);
-  }
-  else {
-    $view->stack[] = $stack;
-  }
-}
-
-/**
- * Generic entry point to handle forms.
- *
- * We do this for consistency and to make it easy to chain forms
- * together. This only works for forms that use both $view
- * and $display_id, so we have a couple of ajax forms that we don't
- * use with this system.
- */
-function views_ui_ajax_form($js, $key, &$view, $display_id) {
-  $form = views_ui_ajax_forms($key);
-  if (empty($form)) {
-    return drupal_not_found();
-  }
-
-  views_include('ajax');
-  $args = func_get_args();
-  // Remove the known args
-  array_splice($args, 0, 4);
-
-  $form_state = views_ui_build_form_state($js, $key, $view, $display_id, $args);
-  // check to see if this is the top form of the stack. If it is, pop
-  // it off; if it isn't, the user clicked somewhere else and the stack is
-  // now irrelevant.
-  if (!empty($view->stack)) {
-    $identifier = views_ui_build_identifier($key, $view, $display_id, $args);
-    $top = array_shift($view->stack);
-    if (array_shift($top) != $identifier) {
-      $view->stack = array();
-    }
-  }
-
-  $output = views_ajax_form_wrapper($form_state['form_id'], $form_state);
-
-  if (!$output) {
-    // Sometimes we need to re-generate the form for multi-step type operations.
-    $object = NULL;
-    if (!empty($view->stack)) {
-      $stack = $view->stack; // copy so the next shift doesn't break the array
-      $top = array_shift($stack);
-      $top[0] = $js; // change identifier into $js setting
-      $form_state = call_user_func_array('views_ui_build_form_state', $top);
-      $form_state['input'] = array(); // this is a new form, make sure it
-      // doesn't try to inherit $_POST info.
-      if (!$js) {
-        return drupal_goto(views_ui_build_form_url($form_state));
-      }
-      $object = views_ajax_form_wrapper($form_state['form_id'], $form_state);
-      $object->url = url(views_ui_build_form_url($form_state));
-    }
-    else if (!$js) {
-      // if nothing on the stack, non-js forms just go back to the main view editor.
-      return drupal_goto("admin/build/views/edit/$view->name");
-    }
-    // regenerate all tabs because changes to the default tab could ripple.
-    return views_ui_regenerate_tabs($view, NULL, $object);
-  }
-
-  return ($js) ? views_ajax_render($output) : $output;
-}
-
-/**
- * AJAX callback to add a display.
- */
-function views_ui_add_display($js, $view) {
-  views_include('ajax');
-  $form_state = array(
-    'view' => &$view,
-    'ajax' => $js,
-  );
-
-  $output = views_ajax_form_wrapper('views_ui_add_display_form', $form_state);
-
-  if ($js) {
-    // If we don't have an output object, it was submitted. Set up the submission.
-    if (empty($output)) {
-      $id = $form_state['id'];
-
-      // Make sure the new display is active
-      if (!$view->set_display('default')) {
-        views_ajax_render(t('Unable to initialize default display'));
-      }
-
-      // Render the new display
-      list($title, $body) = views_ui_display_tab($view, $view->display[$id]);
-
-      // Instruct the javascript on the browser to render the new tab.
-      $output = new stdClass;
-      $output->tab = array('#views-tab-' . $id => array('title' => $title, 'body' => $body));
-    }
-    // Render the command object. This automatically exits.
-    views_ajax_render($output);
-  }
-
-  // But the non-js variant will return output if it didn't redirect us.
-  return $output;
-}
-
-/**
- * Form to add a display to a view.
- */
-function views_ui_add_display_form(&$form_state) {
-  $view = &$form_state['view'];
-
-  $form['display']['display'] = array(
-    '#type' => 'select',
-    '#options' => views_fetch_plugin_names('display'),
-    '#default_value' => 'page',
-  );
-
-  $form['display']['add_display'] = array(
-    '#type' => 'submit',
-    '#value' => t('Add display'),
-    '#submit' => array('views_ui_add_display_form_submit'),
-  );
-
-  $form['#id'] = 'views-add-display-form';
-  $form['#attributes'] = array('class' => 'views-ajax-form');
-  $form['#action'] = url("admin/build/views/nojs/add-display/$view->name");
-
-  return $form;
-}
-
-/**
- * Submit handler to add a display to a view.
- */
-function views_ui_add_display_form_submit($form, &$form_state) {
-  // Create the new display
-  $plugin = $form_state['values']['display'];
-  $form_state['id'] = $form_state['view']->add_display($plugin);
-
-  // Store in cache
-  views_ui_cache_set($form_state['view']);
-
-  // Send it back
-  $form_state['redirect'] = array('admin/build/views/edit/' . $form_state['view']->name, NULL, 'views-tab-' . $form_state['id']);
-}
-
-/**
- * Form to remove a display from a view.
- */
-function views_ui_remove_display_form(&$form_state) {
-  $view = &$form_state['view'];
-  $display_id = $form_state['display_id'];
-
-  if (empty($view->display[$display_id]->deleted)) {
-    $form['display'] = array(
-      '#prefix' => '<div class="display-button remove-display">',
-      '#suffix' => '</div>',
-    );
-    $form['remove_display'] = array(
-      '#type' => 'submit',
-      '#value' => t('Remove display'),
-      '#submit' => array('views_ui_remove_display_form_submit'),
-    );
-  }
-  else {
-    $form['display'] = array(
-      '#prefix' => '<div class="display-button restore-display">',
-      '#suffix' => '</div>',
-    );
-    $form['restore_display'] = array(
-      '#type' => 'submit',
-      '#value' => t('Restore display'),
-      '#submit' => array('views_ui_remove_display_form_restore'),
-    );
-  }
-  $form['#action'] = url("admin/build/views/nojs/remove-display/$view->name/$display_id");
-  $form['#attributes'] = array('class' => 'views-ajax-form');
-
-  return $form;
-}
-
-/**
- * Submit handler to add a remove to a display from a view.
- */
-function views_ui_remove_display_form_submit($form, &$form_state) {
-  // Create the new display
-  $plugin = views_fetch_plugin_data('display', $form_state['view']->display[$form_state['display_id']]->display_plugin);
-  if (empty($plugin['no remove'])) {
-    $id = $form_state['display_id'];
-    $form_state['view']->display[$id]->deleted = TRUE;
-
-    // Store in cache
-    views_ui_cache_set($form_state['view']);
-  }
-}
-
-/**
- * Submit handler to add a restore a removed display to a view.
- */
-function views_ui_remove_display_form_restore($form, &$form_state) {
-  // Create the new display
-  $id = $form_state['display_id'];
-  $form_state['view']->display[$id]->deleted = FALSE;
-
-  // Store in cache
-  views_ui_cache_set($form_state['view']);
-}
-
-/**
- * Page callback to display analysis information on a view.
- */
-function views_ui_analyze_view($js, $view) {
-  views_include('ajax');
-  $form_state = array(
-    'view' => &$view,
-    'ajax' => $js,
-  );
-
-  $output = views_ajax_form_wrapper('views_ui_analyze_view_form', $form_state);
-
-  if ($js) {
-    // If we don't have an output object, it was submitted. Set up the submission.
-    if (empty($output)) {
-      return views_ui_regenerate_tabs($view);
-    }
-    return views_ajax_render($output);
-
-  }
-  return $output;
-}
-
-/**
- * This form doesn't particularly do much; it's really just providing a link
- * but a button seems like it would be nicer here.
- *
- * It has no submit or anything, as we will never actually submit this form
- * where the form is placed.
- */
-function views_ui_analyze_view_button(&$form_state, $view) {
-  $form['#action'] = url("admin/build/views/nojs/analyze/$view->name");
-  $form['#attributes'] = array('class' => 'views-ajax-form');
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Analyze'),
-  );
-
-  return $form;
-}
-
-/**
- * Form constructor callback to display analysis information on a view
- */
-function views_ui_analyze_view_form(&$form_state) {
-  $view = &$form_state['view'];
-
-  $form['#title'] = t('View analysis');
-  $form['#section'] = 'analyze';
-
-  views_include('analyze');
-  $messages = views_analyze_view($view);
-
-  $form['analysis'] = array(
-    '#prefix' => '<div class="form-item">',
-    '#suffix' => '</div>',
-    '#value' => views_analyze_format_result($view, $messages),
-  );
-
-  // Inform the standard button function that we want an OK button.
-  $form_state['ok_button'] = TRUE;
-  views_ui_standard_form_buttons($form, $form_state, 'views_ui_analyze_view_form');
-  return $form;
-}
-
-/**
- * Submit handler for views_ui_analyze_view_form
- */
-function views_ui_analyze_view_form_submit($form, &$form_state) {
-  $form_state['redirect'] = 'admin/build/views/edit/' . $form_state['view']->name;
-}
-
-/**
- * Page callback to edit details of a view.
- */
-function views_ui_edit_details($js, $view) {
-  views_include('ajax');
-  $form_state = array(
-    'view' => &$view,
-    'ajax' => $js,
-  );
-
-  $output = views_ajax_form_wrapper('views_ui_edit_details_form', $form_state);
-
-  if ($js) {
-    // If we don't have an output object, it was submitted. Set up the submission.
-    if (empty($output)) {
-      return views_ui_regenerate_tabs($view);
-    }
-    return views_ajax_render($output);
-
-  }
-  return $output;
-}
-
-/**
- * Form constructor callback to edit details of a view
- */
-function views_ui_edit_details_form(&$form_state) {
-  $view = &$form_state['view'];
-
-  $form['#title'] = t('View details');
-  $form['#section'] = 'details';
-
-  $form['description'] = array(
-    '#type' => 'textfield',
-    '#title' => t('View description'),
-    '#description' => t('This description will appear on the Views administrative UI to tell you what the view is about.'),
-    '#default_value' => $view->description,
-  );
-
-  $form['tag'] = array(
-    '#type' => 'textfield',
-    '#title' => t('View tag'),
-    '#description' => t('Enter an optional tag for this view; it is used only to help sort views on the administrative page.'),
-    '#default_value' => $view->tag,
-    '#autocomplete_path' => 'admin/views/ajax/autocomplete/tag',
-  );
-
-  views_ui_standard_form_buttons($form, $form_state, 'views_ui_edit_details_form');
-  return $form;
-}
-
-/**
- * Submit handler for views_ui_edit_details_form
- */
-function views_ui_edit_details_form_submit($form, &$form_state) {
-  $form_state['view']->description = $form_state['values']['description'];
-  $form_state['view']->tag = $form_state['values']['tag'];
-  views_ui_cache_set($form_state['view']);
-  $form_state['redirect'] = 'admin/build/views/edit/' . $form_state['view']->name;
-}
-
-/**
- * Form constructor callback to edit display of a view
- */
-function views_ui_edit_display_form(&$form_state) {
-  $view = &$form_state['view'];
-  $display_id = $form_state['display_id'];
-  $section = $form_state['section'];
-
-  if (!$view->set_display($display_id)) {
-    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
-  }
-  $display = &$view->display[$display_id];
-
-  // Get form from the handler.
-  $display->handler->options_form($form, $form_state);
-  $name = NULL;
-  if (isset($form_state['update_name'])) {
-    $name = $form_state['update_name'];
-  }
-
-  views_ui_standard_form_buttons($form, $form_state, 'views_ui_edit_display_form', $name);
-  return $form;
-}
-
-/**
- * Validate handler for views_ui_edit_display_form
- */
-function views_ui_edit_display_form_validate($form, &$form_state) {
-  $display = &$form_state['view']->display[$form_state['display_id']];
-  $display->handler->options_validate($form, $form_state);
-}
-
-/**
- * Submit handler for views_ui_edit_display_form
- */
-function views_ui_edit_display_form_submit($form, &$form_state) {
-  $display = &$form_state['view']->display[$form_state['display_id']];
-  $display->handler->options_submit($form, $form_state);
-
-  views_ui_cache_set($form_state['view']);
-}
-
-/**
- * Override handler for views_ui_edit_display_form
- */
-function views_ui_edit_display_form_override($form, &$form_state) {
-  $display = &$form_state['view']->display[$form_state['display_id']];
-  $display->handler->options_override($form, $form_state);
-
-  views_ui_cache_set($form_state['view']);
-  $form_state['rerender'] = TRUE;
-  $form_state['rebuild'] = TRUE;
-}
-/**
- * Form to config items in the views UI.
- */
-function views_ui_config_type_form(&$form_state) {
-  $view = &$form_state['view'];
-  $display_id = $form_state['display_id'];
-  $type = $form_state['type'];
-
-  $types = views_object_types();
-  if (!$view->set_display($display_id)) {
-    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
-  }
-  $display = &$view->display[$display_id];
-  $form['#title'] = check_plain($display->display_title) . ': ';
-  $form['#title'] .= t('Configure @type', array('@type' => $types[$type]['ltitle']));
-  $form['#section'] = $display_id . 'config-item';
-
-  if ($display->handler->defaultable_sections($types[$type]['plural'])) {
-    $form_state['section'] = $types[$type]['plural'];
-    $display->handler->add_override_button($form, $form_state, $form_state['section']);
-  }
-
-  if (!empty($types[$type]['options']) && function_exists($types[$type]['options'])) {
-    $options = $type . '_options';
-    $form[$options] = array('#tree' => TRUE);
-    $types[$type]['options']($form, $form_state);
-  }
-
-  $name = NULL;
-  if (isset($form_state['update_name'])) {
-    $name = $form_state['update_name'];
-  }
-
-  views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_type_form', $name);
-  return $form;
-}
-
-/**
- * Submit handler for type configuration form
- */
-function views_ui_config_type_form_submit($form, &$form_state) {
-  $types = views_object_types();
-  $display = &$form_state['view']->display[$form_state['display_id']];
-
-  // Store in cache
-  views_ui_cache_set($form_state['view']);
-}
-
-/**
- * Configure settings particular to filters.
- */
-function views_ui_config_filters_form(&$form, &$form_state) {
-
-}
-
-/**
- * Form to rearrange items in the views UI.
- */
-function views_ui_rearrange_form(&$form_state) {
-  $view = &$form_state['view'];
-  $display_id = $form_state['display_id'];
-  $type = $form_state['type'];
-
-  $types = views_object_types();
-  if (!$view->set_display($display_id)) {
-    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
-  }
-  $display = &$view->display[$display_id];
-  $form['#title'] = check_plain($display->display_title) . ': ';
-  $form['#title'] .= t('Rearrange @type', array('@type' => $types[$type]['ltitle']));
-  $form['#section'] = $display_id . 'rearrange-item';
-
-  if ($display->handler->defaultable_sections($types[$type]['plural'])) {
-    $form_state['section'] = $types[$type]['plural'];
-    $display->handler->add_override_button($form, $form_state, $form_state['section']);
-  }
-
-  $count = 0;
-
-  // Get relationship labels
-  $relationships = array();
-  // @todo: get_handlers()
-  foreach ($display->handler->get_option('relationships') as $id => $relationship) {
-    $handler = views_get_handler($relationship['table'], $relationship['field'], 'relationship');
-    if (empty($handler)) {
-      continue;
-    }
-    $handler->init($view, $relationship);
-    $relationships[$id] = $handler->label();
-  }
-
-  // @todo: get_handlers()
-  foreach ($display->handler->get_option($types[$type]['plural']) as $id => $field) {
-    $form[$id] = array('#tree' => TRUE);
-    $form[$id]['weight'] = array(
-      '#type' => 'weight',
-      '#delta' => 25,
-      '#default_value' => ++$count,
-    );
-    $handler = views_get_handler($field['table'], $field['field'], $type);
-    if ($handler) {
-      $handler->init($view, $field);
-      $name = $handler->ui_name() . ' ' . $handler->admin_summary();
-      if (!empty($field['relationship']) && !empty($relationships[$field['relationship']])) {
-        $name = '(' . $relationships[$field['relationship']] . ') ' . $name;
-      }
-
-      $form[$id]['name'] = array(
-        '#value' => $name,
-      );
-    }
-    else {
-      $form[$id]['name'] = array('#value' => t('Broken field @id', array('@id' => $id)));
-    }
-    $form[$id]['removed'] = array(
-      '#type' => 'checkbox',
-      '#id' => 'views-removed-' . $id,
-      '#attributes' => array('class' => 'views-remove-checkbox'),
-      '#default_value' => 0,
-    );
-  }
-
-  // Add javascript settings that will be added via $.extend for tabledragging
-  $form['#js']['tableDrag']['arrange']['weight'][0] = array(
-    'target' => 'weight',
-    'source' => NULL,
-    'relationship' => 'sibling',
-    'action' => 'order',
-    'hidden' => TRUE,
-    'limit' => 0,
-  );
-
-  $name = NULL;
-  if (isset($form_state['update_name'])) {
-    $name = $form_state['update_name'];
-  }
-
-  views_ui_standard_form_buttons($form, $form_state, 'views_ui_rearrange_form');
-  return $form;
-}
-
-/**
- * Turn the rearrange form into a proper table
- */
-function theme_views_ui_rearrange_form($form) {
-  $rows = array();
-  foreach (element_children($form) as $id) {
-    if (isset($form[$id]['name'])) {
-      $row = array();
-      $row[] = drupal_render($form[$id]['name']);
-      $form[$id]['weight']['#attributes']['class'] = 'weight';
-      $row[] = drupal_render($form[$id]['weight']);
-      $row[] = drupal_render($form[$id]['removed']) . l('<span>' . t('Remove') . '</span>', 'javascript:void()', array('attributes' => array('id' => 'views-remove-link-' . $id, 'class' => 'views-button-remove views-remove-link', 'alt' => t('Remove this item'), 'title' => t('Remove this item')), 'html' => true));
-
-      $rows[] = array('data' => $row, 'class' => 'draggable', 'id' => 'views-row-' . $id);
-    }
-  }
-  if (empty($rows)) {
-    $rows[] = array(array('data' => t('No fields available.'), 'colspan' => '2'));
-  }
-
-  $header = array('', t('Weight'), t('Remove'));
-  drupal_add_tabledrag('arrange', 'order', 'sibling', 'weight');
-  $output = drupal_render($form['override']);
-  $output .= theme('table', $header, $rows, array('id' => 'arrange'));
-  $output .= drupal_render($form);
-  return $output;
-
-}
-
-/**
- * Submit handler for rearranging form
- */
-function views_ui_rearrange_form_submit($form, &$form_state) {
-  $types = views_object_types();
-  $display = &$form_state['view']->display[$form_state['display_id']];
-
-  $old_fields = $display->handler->get_option($types[$form_state['type']]['plural']);
-  $new_fields = $order = array();
-
-  // Make an array with the weights
-  foreach ($form_state['values'] as $field => $info) {
-    // add each value that is a field with a weight to our list, but only if
-    // it has had its 'removed' checkbox checked.
-    if (is_array($info) && isset($info['weight']) && empty($info['removed'])) {
-      $order[$field] = $info['weight'];
-    }
-  }
-
-  // Sort the array
-  asort($order);
-
-  // Create a new list of fields in the new order.
-  foreach (array_keys($order) as $field) {
-    $new_fields[$field] = $old_fields[$field];
-  }
-  $display->handler->set_option($types[$form_state['type']]['plural'], $new_fields);
-
-  // Store in cache
-  views_ui_cache_set($form_state['view']);
-}
-
-/**
- * Form to add_item items in the views UI.
- */
-function views_ui_add_item_form(&$form_state) {
-  $view = &$form_state['view'];
-  $display_id = $form_state['display_id'];
-  $type = $form_state['type'];
-
-  if (!$view->set_display($display_id)) {
-    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
-  }
-  $display = &$view->display[$display_id];
-
-  $types = views_object_types();
-  $form['#title'] = check_plain($display->display_title) . ': ';
-  $form['#title'] .= t('Add @type', array('@type' => $types[$type]['ltitle']));
-  $form['#section'] = $display_id . 'add-item';
-
-  // Figure out all the base tables allowed based upon what the relationships provide.
-  $base_tables = $view->get_base_tables();
-  $options = views_fetch_fields(array_keys($base_tables), $type);
-
-  if (!empty($options)) {
-    $groups = array('all' => t('<All>'));
-    $form['group'] = array(
-      '#type' => 'select',
-      '#title' => t('Groups'),
-      '#options' => array(),
-      '#attributes' => array('class' => 'views-master-dependent'),
-    );
-
-    $form['name'] = array(
-      '#prefix' => '<div class="views-radio-box form-checkboxes">',
-      '#suffix' => '</div>',
-      '#tree' => TRUE,
-      '#default_value' => 'all',
-    );
-
-    // Group options first to simplify the DOM objects that Views
-    // dependent JS will act upon.
-    $grouped_options = array();
-    foreach ($options as $key => $option) {
-      $group = preg_replace('/[^a-z0-9]/', '-', strtolower($option['group']));
-      $groups[$group] = $option['group'];
-      $grouped_options[$group][$key] = $option;
-    }
-
-    foreach ($grouped_options as $group => $group_options) {
-      $form['name'][$group . '_start'] = array('#type' => 'markup', '#value' => '<div class="views-dependent-all views-dependent-' . $group . '">');
-      foreach ($group_options as $key => $option) {
-        $form['name'][$key] = array(
-          '#type' => 'checkbox',
-          '#title' => t('!group: !field', array('!group' => $option['group'], '!field' => $option['title'])),
-          '#description' => $option['help'],
-          '#return_value' => $key,
-        );
-      }
-      $form['name'][$group . '_end'] = array('#type' => 'markup', '#value' => '</div>');
-    }
-
-    $form['group']['#options'] = $groups;
-  }
-  else {
-    $form['markup'] = array(
-      '#value' => '<div class="form-item">' . t('There are no @types available to add.', array('@types' =>  $types[$type]['ltitle'])) . '</div>',
-    );
-  }
-  views_ui_standard_form_buttons($form, $form_state, 'views_ui_add_item_form', t('Add'));
-
-  return $form;
-}
-
-/**
- * Submit handler for adding new item(s) to a view.
- */
-function views_ui_add_item_form_submit($form, &$form_state) {
-  $type = $form_state['type'];
-  $types = views_object_types();
-
-  if (!empty($form_state['values']['name']) && is_array($form_state['values']['name'])) {
-    // Loop through each of the items that were checked and add them to the view.
-    foreach (array_keys(array_filter($form_state['values']['name'])) as $field) {
-      list($table, $field) = explode('.', $field, 2);
-      $id = $form_state['view']->add_item($form_state['display_id'], $type, $table, $field);
-
-      // check to see if this type has settings, if so add the settings form first
-      $handler = views_get_handler($table, $field, $type);
-      if ($handler && $handler->has_extra_options()) {
-        views_ui_add_form_to_stack('config-item-extra', $form_state['view'], $form_state['display_id'], array($type, $id));
-      }
-      // Then add the form to the stack
-      views_ui_add_form_to_stack('config-item', $form_state['view'], $form_state['display_id'], array($type, $id));
-    }
-  }
-
-  // Store in cache
-  views_ui_cache_set($form_state['view']);
-}
-
-
-/**
- * Form to config_item items in the views UI.
- */
-function views_ui_config_item_form(&$form_state) {
-  $view = &$form_state['view'];
-  $display_id = $form_state['display_id'];
-  $type = $form_state['type'];
-  $id = $form_state['id'];
-
-  $form = array('options' => array('#tree' => TRUE));
-  if (!$view->set_display($display_id)) {
-    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
-  }
-  $item = $view->get_item($display_id, $type, $id);
-
-  if ($item) {
-    $handler = views_get_handler($item['table'], $item['field'], $type);
-    if (empty($handler)) {
-      $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field'])));
-    }
-    else {
-      $handler->init($view, $item);
-      $types = views_object_types();
-
-      if ($view->display_handler->defaultable_sections($types[$type]['plural'])) {
-        $form_state['section'] = $types[$type]['plural'];
-        $view->display_handler->add_override_button($form['options'], $form_state, $form_state['section']);
-      }
-
-      // A whole bunch of code to figure out what relationships are valid for
-      // this item.
-      $relationships = $view->display_handler->get_option('relationships');
-      $relationship_options = array();
-
-      foreach ($relationships as $relationship) {
-        // relationships can't link back to self. But also, due to ordering,
-        // relationships can only link to prior relationships.
-        if ($type == 'relationship' && $id == $relationship['id']) {
-          break;
-        }
-        $relationship_handler = views_get_handler($relationship['table'], $relationship['field'], 'relationship');
-        // ignore invalid/broken relationships.
-        if (empty($relationship_handler)) {
-          continue;
-        }
-
-        // If this relationship is valid for this type, add it to the list.
-        $data = views_fetch_data($relationship['table']);
-        $base = $data[$relationship['field']]['relationship']['base'];
-        $base_fields = views_fetch_fields($base, $form_state['type']);
-        if (isset($base_fields[$item['table'] . '.' . $item['field']])) {
-          $relationship_handler->init($view, $relationship);
-          $relationship_options[$relationship['id']] = $relationship_handler->label();
-        }
-      }
-
-      if (!empty($relationship_options)) {
-        // Make sure the existing relationship is even valid. If not, force
-        // it to none.
-        $base_fields = views_fetch_fields($view->base_table, $form_state['type']);
-        if (isset($base_fields[$item['table'] . '.' . $item['field']])) {
-          $relationship_options = array_merge(array('none' => t('Do not use a relationship')), $relationship_options);
-        }
-        $rel = empty($item['relationship']) ? 'none' : $item['relationship'];
-        if (empty($relationship_options[$rel])) {
-          // Pick the first relationship.
-          $rel = key($relationship_options);
-          // We want this relationship option to get saved even if the user
-          // skips submitting the form.
-          $view->set_item_option($display_id, $type, $id, 'relationship', $rel);
-          $temp_view = $view->clone_view();
-          views_ui_cache_set($temp_view);
-        }
-
-        $form['options']['relationship'] = array(
-          '#type' => 'select',
-          '#title' => t('Relationship'),
-          '#options' => $relationship_options,
-          '#default_value' => $rel,
-        );
-      }
-      else {
-        $form['options']['relationship'] = array(
-          '#type' => 'value',
-          '#value' => 'none',
-        );
-      }
-
-      $form['#title'] = check_plain($view->display[$display_id]->display_title) . ': ';
-      $form['#title'] .= t('Configure @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->ui_name()));
-
-      $form['#section'] = $display_id . '-' . $type . '-' . $id;
-
-      // Get form from the handler.
-      $handler->options_form($form['options'], $form_state);
-      $form_state['handler'] = &$handler;
-    }
-
-    $name = NULL;
-    if (isset($form_state['update_name'])) {
-      $name = $form_state['update_name'];
-    }
-
-    views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_item_form', $name, t('Remove'), 'remove');
-  }
-  return $form;
-}
-
-/**
- * Submit handler for configing new item(s) to a view.
- */
-function views_ui_config_item_form_validate($form, &$form_state) {
-  $form_state['handler']->options_validate($form['options'], $form_state);
-}
-
-/**
- * Submit handler for configing new item(s) to a view.
- */
-function views_ui_config_item_form_submit($form, &$form_state) {
-  // Run it through the handler's submit function.
-  $form_state['handler']->options_submit($form['options'], $form_state);
-  $item = $form_state['handler']->options;
-
-  // Unset a button
-  unset($form_state['values']['options']['expose_button']);
-
-  // Store the data we're given.
-  foreach ($form_state['values']['options'] as $key => $value) {
-    $item[$key] = $value;
-  }
-
-  // Store the item back on the view
-  $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
-
-  $handler = views_get_handler($item['table'], $item['field'], $form_state['type']);
-  $handler->init($form_state['view'], $item);
-  if ($handler && $handler->needs_style_plugin()) {
-    views_ui_add_form_to_stack('change-style', $form_state['view'], $form_state['display_id'], array($form_state['type'], $form_state['id']), TRUE);
-  }
-
-  // Write to cache
-  views_ui_cache_set($form_state['view']);
-}
-
-/**
- * Submit handler for removing an item from a view
- */
-function views_ui_config_item_form_remove($form, &$form_state) {
-  // Store the item back on the view
-  $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], NULL);
-
-  // Write to cache
-  views_ui_cache_set($form_state['view']);
-}
-
-/**
- * Override handler for views_ui_edit_display_form
- */
-function views_ui_config_item_form_expose($form, &$form_state) {
-  $item = &$form_state['handler']->options;
-  // flip
-  $item['exposed'] = empty($item['exposed']);
-
-  // If necessary, set new defaults:
-  if ($item['exposed']) {
-    $form_state['handler']->expose_options();
-  }
-
-  $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
-
-  views_ui_cache_set($form_state['view']);
-  $form_state['rerender'] = TRUE;
-  $form_state['rebuild'] = TRUE;
-  $form_state['force_expose_options'] = TRUE;
-}
-
-/**
- * Form to config_item items in the views UI.
- */
-function views_ui_config_item_extra_form(&$form_state) {
-  $view = &$form_state['view'];
-  $display_id = $form_state['display_id'];
-  $type = $form_state['type'];
-  $id = $form_state['id'];
-
-  $form = array('options' => array('#tree' => TRUE));
-  if (!$view->set_display($display_id)) {
-    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
-  }
-  $item = $view->get_item($display_id, $type, $id);
-
-  if ($item) {
-    $handler = views_get_handler($item['table'], $item['field'], $type);
-    if (empty($handler)) {
-      $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field'])));
-      break;
-    }
-    else {
-      $handler->init($view, $item);
-      $types = views_object_types();
-
-      $form['#title'] = check_plain($view->display[$display_id]->display_title) . ': ';
-      $form['#title'] .= t('Configure extra settings for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->ui_name()));
-
-      $form['#section'] = $display_id . '-' . $type . '-' . $id;
-
-      // Get form from the handler.
-      $handler->extra_options_form($form['options'], $form_state);
-        $form_state['handler'] = &$handler;
-
-    }
-
-    views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_item_extra_form');
-  }
-  return $form;
-}
-
-/**
- * Submit handler for configing new item(s) to a view.
- */
-function views_ui_config_item_extra_form_validate($form, &$form_state) {
-  $form_state['handler']->extra_options_validate($form['options'], $form_state);
-}
-
-/**
- * Submit handler for configing new item(s) to a view.
- */
-function views_ui_config_item_extra_form_submit($form, &$form_state) {
-  // Run it through the handler's submit function.
-  $form_state['handler']->extra_options_submit($form['options'], $form_state);
-  $item = $form_state['handler']->options;
-
-  // Store the data we're given.
-  foreach ($form_state['values']['options'] as $key => $value) {
-    $item[$key] = $value;
-  }
-
-  // Store the item back on the view
-  $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
-
-  // Write to cache
-  views_ui_cache_set($form_state['view']);
-}
-
-/**
- * Form to change_style items in the views UI.
- */
-function views_ui_change_style_form(&$form_state) {
-  $view = &$form_state['view'];
-  $display_id = $form_state['display_id'];
-  $type = $form_state['type'];
-  $id = $form_state['id'];
-
-  $form = array('options' => array('#tree' => TRUE));
-  if (!$view->set_display($display_id)) {
-    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
-  }
-  $item = $view->get_item($display_id, $type, $id);
-
-  if ($item) {
-    $handler = views_get_handler($item['table'], $item['field'], $type);
-    if (empty($handler)) {
-      $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field'])));
-      break;
-    }
-    $handler->init($view, $item);
-    $types = views_object_types();
-    $form['#title'] = t('Change summary style for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->ui_name()));
-
-    $form['#section'] = $display_id . '-' . $type . '-' . $id . '-style-plugin';
-
-    $form['style_plugin'] =  array(
-      '#type' => 'radios',
-      '#options' => views_fetch_plugin_names('style', 'summary'),
-      '#default_value' => $item['style_plugin'],
-    );
-
-    $form_state['handler'] = &$handler;
-
-    views_ui_standard_form_buttons($form, $form_state, 'views_ui_change_style_form');
-  }
-  return $form;
-}
-
-function views_ui_change_style_form_validate($form, &$form_state) {
-  // Run it through the handler's submit function.
-  $form_state['handler']->options_validate($form['options'], $form_state);
-
-  $plugin = views_get_plugin('style', $form_state['values']['style_plugin']);
-  if (!$plugin) {
-    form_error($form['style_plugin'], t('Internal error: broken plugin.'));
-  }
-}
-
-/**
- * Submit handler for configing new item(s) to a view.
- */
-function views_ui_change_style_form_submit($form, &$form_state) {
-  // Run it through the handler's submit function.
-  $form_state['handler']->options_submit($form['options'], $form_state);
-  $item = $form_state['handler']->options;
-
-  $plugin = views_get_plugin('style', $form_state['values']['style_plugin']);
-  if (!$plugin) {
-    drupal_set_message(t('Internal error: broken plugin.'), 'error');
-    return;
-  }
-
-  $plugin->init($form_state['view'], $form_state['view']->display[$form_state['display_id']]);
-
-  // If changing style plugin, reset options to defaults.
-  if (empty($item['style_plugin']) || $item['style_plugin'] != $form_state['values']['style_plugin']) {
-    $item['style_options'] = $plugin->options;
-  }
-
-  // Store the data we're given.
-  $item['style_plugin'] = $form_state['values']['style_plugin'];
-
-  // Store the item back on the view
-  $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
-
-  if (!empty($plugin->definition['uses options'])) {
-    views_ui_add_form_to_stack('config-style', $form_state['view'], $form_state['display_id'], array($form_state['type'], $form_state['id']), TRUE);
-  }
-
-  // Write to cache
-  views_ui_cache_set($form_state['view']);
-}
-
-/**
- * Form to config_style items in the views UI.
- */
-function views_ui_config_style_form(&$form_state) {
-  $view = &$form_state['view'];
-  $display_id = $form_state['display_id'];
-  $type = $form_state['type'];
-  $id = $form_state['id'];
-
-  $form = array('options' => array('#tree' => TRUE));
-  if (!$view->set_display($display_id)) {
-    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
-  }
-  $item = $view->get_item($display_id, $type, $id);
-
-  if ($item) {
-    $handler = views_get_handler($item['table'], $item['field'], $type);
-    if (empty($handler)) {
-      $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field'])));
-      break;
-    }
-    $handler->init($view, $item);
-    $types = views_object_types();
-
-    $form['#title'] = check_plain($view->display[$display_id]->display_title) . ': ';
-    $form['#title'] .= t('Configure summary style for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->ui_name()));
-
-    $form['#section'] = $display_id . '-' . $type . '-style-options';
-
-    $plugin = views_get_plugin('style', $item['style_plugin']);
-    if ($plugin) {
-      $form['style_options'] = array(
-        '#tree' => TRUE,
-      );
-      $plugin->init($view, $view->display[$display_id], $item['style_options']);
-
-      $plugin->options_form($form['style_options'], $form_state);
-    }
-
-    $form_state['handler'] = &$handler;
-
-    views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_style_form');
-  }
-  return $form;
-}
-
-/**
- * Submit handler for configing new item(s) to a view.
- */
-function views_ui_config_style_form_submit($form, &$form_state) {
-  // Run it through the handler's submit function.
-  $form_state['handler']->options_submit($form['style_options'], $form_state);
-  $item = $form_state['handler']->options;
-
-  // Store the data we're given.
-  $item['style_options'] = $form_state['values']['style_options'];
-
-  // Store the item back on the view
-  $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
-
-  // Write to cache
-  views_ui_cache_set($form_state['view']);
-}
-
-/**
- * Get a list of roles in the system.
- */
-function views_ui_get_roles() {
-  static $roles = NULL;
-  if (!isset($roles)) {
-    $roles = array();
-    $result = db_query("SELECT r.rid, r.name FROM {role} r ORDER BY r.name");
-    while ($obj = db_fetch_object($result)) {
-      $roles[$obj->rid] = $obj->name;
-    }
-  }
-
-  return $roles;
-}
-
-/**
- * Get a css safe id for a particular section.
- */
-function views_ui_item_css($item) {
-  return views_css_safe('views-item-' . $item);
-}
-
-/**
- * Page callback for the Views enable page.
- */
-function views_ui_enable_page($view) {
-  $views_status = variable_get('views_defaults', array());
-  $views_status[$view->name] = FALSE; // false is enabled
-  variable_set('views_defaults', $views_status);
-  views_invalidate_cache();
-  menu_rebuild();
-  drupal_goto('admin/build/views');
-}
-
-/**
- * Page callback for the Views enable page
- */
-function views_ui_disable_page($view) {
-  $views_status = variable_get('views_defaults', array());
-  $views_status[$view->name] = TRUE; // True is disabled
-  variable_set('views_defaults', $views_status);
-  views_invalidate_cache();
-  menu_rebuild();
-  drupal_goto('admin/build/views');
-}
-
-/**
- * Page callback for the tools - other page
- */
-function views_ui_admin_tools() {
-  $form['clear_cache'] = array(
-    '#type' => 'submit',
-    '#value' => t("Clear Views' cache"),
-    '#submit' => array('views_ui_tools_clear_cache'),
-  );
-
-  $form['views_sql_signature'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Add Views signature to all SQL queries'),
-    '#description' => t("All Views-generated queries will include a special 'VIEWS' = 'VIEWS' string in the WHERE clause. This makes identifying Views queries in database server logs simpler, but should only be used when troubleshooting."),
-    '#default_value' => variable_get('views_sql_signature', FALSE),
-  );
-
-  $form['views_skip_cache'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Disable views data caching'),
-    '#description' => t("Views caches data about tables, modules and views available, to increase performance. By checking this box, Views will skip this cache and always rebuild this data when needed. This can have a serious performance impact on your site."),
-    '#default_value' => variable_get('views_skip_cache', FALSE),
-  );
-
-  $form['views_hide_help_message'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Ignore missing advanced help module'),
-    '#description' => t("Views uses the advanced help module to provide help text; if this module is not present Views will complain, unless this setting is checked."),
-    '#default_value' => variable_get('views_hide_help_message', FALSE),
-  );
-
-  $form['views_ui_query_on_top'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Show query above live preview'),
-    '#description' => t("The live preview feature will show you the output of the view you're creating, as well as the view. Check here to show the query and other information above the view; leave this unchecked to show that information below the view."),
-    '#default_value' => variable_get('views_ui_query_on_top', FALSE),
-  );
-
-  $form['views_show_additional_queries'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Show other queries run during render during live preview'),
-    '#description' => t("Drupal has the potential to run many queries while a view is being rendered. Checking this box will display every query run during view render as part of the live preview."),
-    '#default_value' => variable_get('views_show_additional_queries', FALSE),
-  );
-
-  $form['views_no_hover_links'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Do not show hover links over views'),
-    '#description' => t("To make it easier to administrate your views, Views provides 'hover' links to take you to the edit and export screen of a view whenever the view is used. This can be distracting on some themes, though; if it is problematic, you can turn it off here."),
-    '#default_value' => variable_get('views_no_hover_links', FALSE),
-  );
-
-  $form['views_devel_output'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Enable views performance statistics via the Devel module'),
-    '#description' => t("Check this to enable some Views query and performance statistics <em>if Devel is installed</em>."),
-    '#default_value' => variable_get('views_devel_output', FALSE),
-  );
-
-  $form['views_no_javascript'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Disable javascript with Views'),
-    '#description' => t("If you are having problems with the javascript, you can disable it here; the Views UI should degrade and still be usable without javascript, it just not as good."),
-    '#default_value' => variable_get('views_no_javascript', FALSE),
-  );
-
-  $regions = system_region_list(variable_get('theme_default', 'garland'));
-  $regions['watchdog'] = t('Watchdog');
-
-  $form['views_devel_region'] = array(
-    '#type' => 'select',
-    '#title' => t('Page region to output performance statistics'),
-    '#default_value' => variable_get('views_devel_region', 'footer'),
-    '#options' => $regions,
-  );
-
-  $form['views_exposed_filter_any_label'] = array(
-    '#type' => 'select',
-    '#title' => t('Label for "Any" value on optional single-select exposed filters'),
-    '#options' => array('old_any' => t('<Any>'), 'new_any' => t('- Any -')),
-    '#default_value' => variable_get('views_exposed_filter_any_label', 'old_any'),
-  );
-
-  return system_settings_form($form);
-}
-
-/**
- * Submit hook to clear the views cache.
- */
-function views_ui_tools_clear_cache() {
-  views_invalidate_cache();
-  drupal_set_message(t('The cache has been cleared.'));
-}
-
-/**
- * Submit hook to clear Drupal's theme registry (thereby triggering
- * a templates rescan).
- */
-function views_ui_config_item_form_rescan($form, &$form_state) {
-  drupal_rebuild_theme_registry();
-
-  // The 'Theme: Information' page is about to be shown again. That page
-  // analyzes the output of theme_get_registry(). However, this latter
-  // function uses an internal cache (which was initialized before we
-  // called drupal_rebuild_theme_registry()) so it won't reflect the
-  // current state of our theme registry. The only way to clear that cache
-  // is to re-initialize the theme system:
-  unset($GLOBALS['theme']);
-  init_theme();
-
-  $form_state['rerender'] = TRUE;
-  $form_state['rebuild'] = TRUE;
-}
-
-/**
- * Override handler for views_ui_edit_display_form
- */
-function views_ui_edit_display_form_change_theme($form, &$form_state) {
-  // This is just a temporary variable.
-  $form_state['view']->theme = $form_state['values']['theme'];
-
-  views_ui_cache_set($form_state['view']);
-  $form_state['rerender'] = TRUE;
-  $form_state['rebuild'] = TRUE;
-}
-
-/**
- * Page callback for views tag autocomplete
- */
-function views_ui_autocomplete_tag($string = '') {
-  $matches = array();
-  // get matches from default views:
-  views_include('view');
-  $views = views_discover_default_views();
-  foreach ($views as $view) {
-    if (!empty($view->tag) && strpos($view->tag, $string) === 0) {
-      $matches[$view->tag] = $view->tag;
-    }
-  }
-
-  if ($string) {
-    $result = db_query_range("SELECT DISTINCT tag FROM {views_view} WHERE LOWER(tag) LIKE LOWER('%s%%')", $string, 0, 10 - count($matches));
-    while ($view = db_fetch_object($result)) {
-      $matches[$view->tag] = check_plain($view->tag);
-    }
-  }
-
-  drupal_json($matches);
-}
-
-// ------------------------------------------------------------------
-// Get information from the Views data
-
-function _views_weight_sort($a, $b) {
-  if ($a['weight'] != $b['weight']) {
-    return $a['weight'] < $b['weight'] ? -1 : 1;
-  }
-  if ($a['title'] != $b['title']) {
-    return $a['title'] < $b['title'] ? -1 : 1;
-  }
-
-  return 0;
-}
-
-/**
- * Fetch a list of all base tables available
- *
- * @return
- *   A keyed array of in the form of 'base_table' => 'Description'.
- */
-function views_fetch_base_tables() {
-  static $base_tables = array();
-  if (empty($base_tables)) {
-    $weights = array();
-    $tables = array();
-    $data = views_fetch_data();
-    foreach ($data as $table => $info) {
-      if (!empty($info['table']['base'])) {
-        $tables[$table] = array(
-          'title' => $info['table']['base']['title'],
-          'description' => $info['table']['base']['help'],
-          'weight' => !empty($info['table']['base']['weight']) ? $info['table']['base']['weight'] : 0,
-        );
-      }
-    }
-    uasort($tables, '_views_weight_sort');
-    $base_tables = $tables;
-  }
-
-  return $base_tables;
-}
-
-function _views_sort_types($a, $b) {
-  if ($a['group'] != $b['group']) {
-    return $a['group'] < $b['group'] ? -1 : 1;
-  }
-
-  if ($a['title'] != $b['title']) {
-    return $a['title'] < $b['title'] ? -1 : 1;
-  }
-
-  return 0;
-}
-
-/**
- * Fetch a list of all fields available for a given base type.
- *
- * @return
- *   A keyed array of in the form of 'base_table' => 'Description'.
- */
-function views_fetch_fields($base, $type) {
-  static $fields = array();
-  if (empty($fields)) {
-    $data = views_fetch_data();
-    $start = views_microtime();
-    // This constructs this ginormous multi dimensional array to
-    // collect the important data about fields. In the end,
-    // the structure looks a bit like this (using nid as an example)
-    // $strings['nid']['filter']['title'] = 'string'.
-    //
-    // This is constructed this way because the above referenced strings
-    // can appear in different places in the actual data structure so that
-    // the data doesn't have to be repeated a lot. This essentially lets
-    // each field have a cheap kind of inheritance.
-
-    foreach ($data as $table => $table_data) {
-      $bases = array();
-      $strings = array();
-      $skip_bases = array();
-      foreach ($table_data as $field => $info) {
-        // Collect table data from this table
-        if ($field == 'table') {
-          // calculate what tables this table can join to.
-          if (!empty($info['join'])) {
-            $bases = array_keys($info['join']);
-          }
-          // And it obviously joins to itself.
-          $bases[] = $table;
-          continue;
-        }
-        foreach (array('field', 'sort', 'filter', 'argument', 'relationship') as $key) {
-          if (!empty($info[$key])) {
-            if (!empty($info[$key]['skip base'])) {
-              foreach ((array) $info[$key]['skip base'] as $base_name) {
-                $skip_bases[$field][$key][$base_name] = TRUE;
-              }
-            }
-            elseif (!empty($info['skip base'])) {
-              foreach ((array) $info['skip base'] as $base_name) {
-                $skip_bases[$field][$key][$base_name] = TRUE;
-              }
-            }
-            foreach (array('title', 'group', 'help', 'base') as $string) {
-              // First, try the lowest possible level
-              if (!empty($info[$key][$string])) {
-                $strings[$field][$key][$string] = $info[$key][$string];
-              }
-              // Then try the field level
-              elseif (!empty($info[$string])) {
-                $strings[$field][$key][$string] = $info[$string];
-              }
-              // Finally, try the table level
-              elseif (!empty($table_data['table'][$string])) {
-                $strings[$field][$key][$string] = $table_data['table'][$string];
-              }
-              else {
-                if ($string != 'base') {
-                  $strings[$field][$key][$string] = t("Error: missing @component", array('@component' => $string));
-                }
-              }
-            }
-          }
-        }
-      }
-      foreach ($bases as $base_name) {
-        foreach ($strings as $field => $field_strings) {
-          foreach ($field_strings as $type_name => $type_strings) {
-            if (empty($skip_bases[$field][$type_name][$base_name])) {
-              $fields[$base_name][$type_name]["$table.$field"] = $type_strings;
-            }
-          }
-        }
-      }
-    }
-//    vsm('Views UI data build time: ' . (views_microtime() - $start) * 1000 . ' ms');
-  }
-
-  // If we have an array of base tables available, go through them
-  // all and add them together. Duplicate keys will be lost and that's
-  // Just Fine.
-  if (is_array($base)) {
-    $strings = array();
-    foreach ($base as $base_table) {
-      if (isset($fields[$base_table][$type])) {
-        $strings += $fields[$base_table][$type];
-      }
-    }
-    uasort($strings, '_views_sort_types');
-    return $strings;
-  }
-
-  if (isset($fields[$base][$type])) {
-    uasort($fields[$base][$type], '_views_sort_types');
-    return $fields[$base][$type];
-  }
-  return array();
-}
-
-/**
- * Fetch a list of all base tables available
- *
- * @param $type
- *   Either 'display', 'style' or 'row'
- * @param $key
- *   For style plugins, this is an optional type to restrict to. May be 'normal',
- *   'summary', 'feed' or others based on the neds of the display.
- * @param $base
- *   An array of possible base tables.
- *
- * @return
- *   A keyed array of in the form of 'base_table' => 'Description'.
- */
-function views_fetch_plugin_names($type, $key = NULL, $base = array()) {
-  $data = views_fetch_plugin_data();
-
-  $plugins[$type] = array();
-
-  foreach ($data[$type] as $id => $plugin) {
-    // Skip plugins that don't conform to our key.
-    if ($key && (empty($plugin['type']) || $plugin['type'] != $key)) {
-      continue;
-    }
-    if (empty($plugin['no ui']) && (empty($base) || empty($plugin['base']) || array_intersect($base, $plugin['base']))) {
-      $plugins[$type][$id] = $plugin['title'];
-    }
-  }
-
-  if (!empty($plugins[$type])) {
-    asort($plugins[$type]);
-    return $plugins[$type];
-  }
-  // fall-through
-  return array();
-}
-
-
-/**
- * Theme the form for the table style plugin
- */
-function theme_views_ui_style_plugin_table($form) {
-  $output = drupal_render($form['description_markup']);
-
-  $header = array(
-    t('Field'),
-    t('Column'),
-    t('Separator'),
-    array(
-      'data' => t('Sortable'),
-      'align' => 'center',
-    ),
-    array(
-      'data' => t('Default sort'),
-      'align' => 'center',
-    ),
-  );
-  $rows = array();
-  foreach (element_children($form['columns']) as $id) {
-    $row = array();
-    $row[] = drupal_render($form['info'][$id]['name']);
-    $row[] = drupal_render($form['columns'][$id]);
-    $row[] = drupal_render($form['info'][$id]['separator']);
-    if (!empty($form['info'][$id]['sortable'])) {
-      $row[] = array(
-        'data' => drupal_render($form['info'][$id]['sortable']),
-        'align' => 'center',
-      );
-      $row[] = array(
-        'data' => drupal_render($form['default'][$id]),
-        'align' => 'center',
-      );
-    }
-    else {
-      $row[] = '';
-      $row[] = '';
-    }
-    $rows[] = $row;
-  }
-
-  // Add the special 'None' row.
-  $rows[] = array(t('None'), '', '', '', array('align' => 'center', 'data' => drupal_render($form['default'][-1])));
-
-  $output .= theme('table', $header, $rows);
-  $output .= drupal_render($form);
-  return $output;
-}
-
+<?php
+// $Id: admin.inc,v 1.154.2.33 2010/07/27 22:38:05 merlinofchaos Exp $
+/**
+ * @file admin.inc
+ * Provides the Views' administrative interface.
+ */
+
+/**
+ * Page callback to list views in the system.
+ */
+function views_ui_list_views($arg = NULL) {
+  if ($arg != NULL) {
+    return drupal_not_found();
+  }
+
+  $output = theme('views_ui_list_views');
+  views_ui_check_advanced_help();
+  return $output;
+}
+
+/**
+ * Check to see if the advanced help module is installed, and if not put up
+ * a message.
+ *
+ * Only call this function if the user is already in a position for this to
+ * be useful.
+ */
+function views_ui_check_advanced_help() {
+  if (variable_get('views_hide_help_message', FALSE)) {
+    return;
+  }
+
+  if (!module_exists('advanced_help')) {
+    $filename = db_result(db_query("SELECT filename FROM {system} WHERE type = 'module' AND name = 'advanced_help'"));
+    if ($filename && file_exists($filename)) {
+      drupal_set_message(t('If you <a href="@modules">enable the advanced help module</a>, Views will provide more and better help. <a href="@hide">Hide this message.</a>', array('@modules' => url('admin/build/modules'),'@hide' => url('admin/build/views/tools'))));
+    }
+    else {
+      drupal_set_message(t('If you install the advanced help module from !href, Views will provide more and better help. <a href="@hide">Hide this message.</a>', array('!href' => l('http://drupal.org/project/advanced_help', 'http://drupal.org/project/advanced_help'), '@hide' => url('admin/build/views/tools'))));
+    }
+  }
+}
+
+/**
+ * Preprocess the list views theme
+ */
+function template_preprocess_views_ui_list_views(&$vars) {
+  $items = array();
+  $sorts = array();
+
+  $views = views_get_all_views();
+
+  $token_enable = drupal_get_token('views-enable');
+  $token_disable = drupal_get_token('views-disable');
+
+  // Respond to a reset command by clearing session and doing a drupal goto
+  // back to the base URL.
+  if (isset($_GET['op']) && $_GET['op'] == t('Reset')) {
+    unset($_SESSION['views']['#admin']);
+    drupal_goto('admin/build/views');
+  }
+  if (count($_GET) <= 1) {
+    if (isset($_SESSION['views']['#admin']) && is_array($_SESSION['views']['#admin'])) {
+      $_GET += $_SESSION['views']['#admin'];
+    }
+  }
+  else {
+    $_SESSION['views']['#admin'] = $_GET;
+    unset($_SESSION['views']['#admin']['q']);
+  }
+
+  $form_state = array(
+    'views' => $views,
+    'input' => $_GET,
+    'method' => 'get',
+    'rerender' => TRUE,
+    'no_redirect' => TRUE,
+  );
+
+  $vars['widgets'] = drupal_build_form('views_ui_list_views_form', $form_state);
+
+  $vars['help_type_icon'] = theme('advanced_help_topic', 'views', 'view-type');
+
+  $base_tables = views_fetch_base_tables();
+
+  foreach ($views as $view) {
+    if ($form_state['values']['tag'] != 'all') {
+      if ($form_state['values']['tag'] == 'none') {
+        if (!empty($view->tag)) {
+          continue;
+        }
+      }
+      else if ($form_state['values']['tag'] != $view->tag) {
+        continue;
+      }
+    }
+    if ($form_state['values']['type'] != 'all' && $form_state['values']['type'] != $view->type) {
+      continue;
+    }
+
+    if ($form_state['values']['base'] != 'all' && $form_state['values']['base'] != $view->base_table) {
+      continue;
+    }
+
+    if ($form_state['values']['display'] != 'all' && empty($view->display[$form_state['values']['display']])) {
+      continue;
+    }
+
+    if ($form_state['values']['status'] != 'all' && (!empty($view->disabled) == $form_state['values']['status'])) {
+      continue;
+    }
+
+    $item = new stdClass();
+    $item->ops = array();
+
+    if (empty($view->disabled)) {
+      $item->ops[] = l(t('Edit'), "admin/build/views/edit/$view->name");
+      $item->ops[] = l(t('Export'), "admin/build/views/export/$view->name");
+      $item->ops[] = l(t('Clone'), "admin/build/views/clone/$view->name");
+    }
+    if ($view->type != t('Default')) {
+      $text = $view->type == t('Overridden') ? t('Revert') : t('Delete');
+      $item->ops[] = l($text, "admin/build/views/delete/$view->name");
+    }
+    else {
+      if (empty($view->disabled)) {
+        $item->ops[] = l(t('Disable'), "admin/build/views/disable/$view->name", array('query' => drupal_get_destination() . '&token=' . $token_disable));
+      }
+      else {
+        $item->ops[] = l(t('Enable'), "admin/build/views/enable/$view->name", array('query' => drupal_get_destination() . '&token=' . $token_enable));
+      }
+    }
+
+    $item->ops = implode(' | ', $item->ops);
+    if (empty($view->display)) {
+      $item->path = t('Warning! Broken view!');
+    }
+    else {
+      $view->init_display();   // Make sure all the handlers are set up
+      $all_paths = array();
+      foreach ($view->display as $display) {
+        if (!empty($display->handler) && $display->handler->has_path()) {
+          $one_path = $display->handler->get_option('path');
+          if (empty($path_sort)) {
+            $path_sort = strtolower($one_path);
+          }
+          if (empty($view->disabled) && strpos($one_path, '%') === FALSE) {
+            $all_paths[] = l($one_path, $one_path);
+          }
+          else {
+            $all_paths[] = check_plain($one_path);
+          }
+        }
+      }
+      if (!empty($all_paths)) {
+        $item->path = implode(', ', array_unique($all_paths));
+      }
+    }
+
+    $item->type = $view->type;
+    $item->name = $view->name;
+
+    if (!empty($view->tag)) {
+      $item->tag = $view->tag;
+    }
+
+    $item->title = $view->get_title();
+    $item->base = !empty($base_tables[$view->base_table]['title']) ? $base_tables[$view->base_table]['title'] : t('Broken');
+
+    $item->displays = array();
+    foreach ($view->display as $display) {
+      if (!empty($display->handler->definition['admin'])) {
+        $item->displays[$display->handler->definition['admin']] = TRUE;
+      }
+    }
+
+    if ($item->displays) {
+      ksort($item->displays);
+      $item->displays = implode(', ', array_keys($item->displays));
+    }
+
+    $item->description = check_plain($view->description);
+    $item->classes = empty($view->disabled) ? 'view-enabled' : 'view-disabled';
+    $items[] = $item;
+
+    $sort = intval(empty($view->disabled) xor $form_state['values']['sort'] == 'asc');
+
+    switch ($form_state['values']['order']) {
+      case 'name':
+      default:
+        $sort .= strtolower($view->name);
+        break;
+      case 'title':
+        $sort .= strtolower($item->title);
+        break;
+      case 'path':
+        $sort .= strtolower($raw_path); // $path;
+        break;
+      case 'type':
+        $sort .= $view->type . $view->name;
+        break;
+      case 'tag':
+        $sort .= strtolower($view->tag);
+        break;
+      case 'desc':
+        $sort .= strtolower($view->description);
+        break;
+    }
+
+    $sorts[] = $sort;
+  }
+
+  if ($form_state['values']['sort'] == 'desc') {
+    arsort($sorts);
+  }
+  else {
+    asort($sorts);
+  }
+
+  $i = array();
+  foreach ($sorts as $id => $title) {
+    $i[] = $items[$id];
+  }
+
+  views_add_css('views-list');
+  $vars['views'] = $i;
+
+  $getting_started = theme('advanced_help_topic', 'views', 'getting-started', 'title');
+  if (!$getting_started) {
+    $getting_started = t('Install the advanced help module for the getting started');
+  }
+
+  $vars['help'] = t('Not sure what to do? Try the "!getting-started" page.', array('!getting-started' => $getting_started));
+}
+
+/**
+ * Provide a form for sorting and filtering the list of views.
+ */
+function views_ui_list_views_form(&$form_state) {
+  if (!variable_get('clean_url', FALSE)) {
+    $form['q'] = array(
+      '#type' => 'hidden',
+      '#value' => $_GET['q'],
+    );
+  }
+
+  $all = array('all' => t('<All>'));
+  $none = array('none' => t('<None>'));
+
+  $form['type'] = array(
+    '#type' => 'select',
+    '#title' => t('Storage'),
+    '#options' => array(
+      'all' => t('<All>'),
+      t('Normal') => t('Normal'),
+      t('Default') => t('Default'),
+      t('Overridden') => t('Overridden'),
+    ),
+    '#default_value' => 'all',
+  );
+
+  $status = array(
+    '0' => t('Disabled'),
+    '1' => t('Enabled'),
+  );
+  $form['status'] = array(
+    '#type' => 'select',
+    '#title' => t('Status'),
+    '#options' => array_merge($all, $status),
+    '#default_value' => 'all',
+  );
+
+  $bases = array();
+  foreach (views_fetch_base_tables() as $table => $info) {
+    $bases[$table] = $info['title'];
+  }
+
+  $form['base'] = array(
+    '#type' => 'select',
+    '#title' => t('Type'),
+    '#options' => array_merge($all, $bases),
+    '#default_value' => 'all',
+  );
+
+  $tags = array();
+
+  $extras = array();
+  foreach ($form_state['views'] as $name => $view) {
+    if (!empty($view->tag)) {
+      $tags[$view->tag] = $view->tag;
+    }
+  }
+
+  asort($tags);
+
+  $form['tag'] = array(
+    '#type' => 'select',
+    '#title' => t('Tag'),
+    '#options' => array_merge($all, $none, $tags),
+    '#default_value' => 'all',
+  );
+
+  $displays = array();
+  foreach (views_fetch_plugin_data('display') as $id => $info) {
+    if (!empty($info['admin'])) {
+      $displays[$id] = $info['admin'];
+    }
+  }
+
+  asort($displays);
+
+  $form['display'] = array(
+    '#type' => 'select',
+    '#title' => t('Displays'),
+    '#options' => array_merge($all, $displays),
+    '#default_value' => 'all',
+  );
+
+  $form['order'] = array(
+    '#type' => 'select',
+    '#title' => t('Sort by'),
+    '#options' => array(
+      'name' => t('Name'),
+      'title' => t('Title'),
+      'tag' => t('Tag'),
+      'path' => t('Path'),
+      'type' => t('Type'),
+      'desc' => t('Description'),
+    ),
+    '#default_value' => 'name',
+  );
+
+  $form['sort'] = array(
+    '#type' => 'select',
+    '#title' => t('Order'),
+    '#options' => array(
+      'asc' => t('Up'),
+      'desc' => t('Down'),
+    ),
+    '#default_value' => 'asc',
+  );
+
+  $form['submit'] = array(
+    '#name' => '', // so it won't in the $_GET args
+    '#type' => 'submit',
+    '#id' => 'edit-views-apply',
+    '#value' => t('Apply'),
+  );
+
+  if (!empty($_SESSION['views']['#admin'])) {
+    $form['reset'] = array(
+      '#type' => 'submit',
+      '#id' => 'edit-views-reset',
+      '#value' => t('Reset'),
+    );
+  }
+
+  $form['#theme'] = array('views_ui_list_views_form');
+  return $form;
+}
+
+function theme_views_ui_list_views_form($form) {
+  // Don't render these:
+  unset($form['form_id']);
+  unset($form['form_build_id']);
+  unset($form['form_token']);
+  return drupal_render($form);
+}
+
+/**
+ * Page callback for the live preview.
+ *
+ * @todo make this use a template
+ */
+function views_ui_preview($js, $view) {
+  // Take off the items we know so that we can have just the args passed
+  // in for later use.
+  $func_args = func_get_args();
+  array_shift($func_args); // $js
+  array_shift($func_args); // $view
+  $display_id = (count($func_args)) ? array_shift($func_args) : 'default';
+
+  $form_state = array(
+    'display_id' => $display_id,
+    'view_args' => $func_args ? implode('/', $func_args) : '',
+    'rerender' => TRUE,
+    'no_redirect' => TRUE,
+    'view' => &$view,
+    'ajax' => $js
+  );
+
+  $output = drupal_build_form('views_ui_preview_form', $form_state);
+  $args = array();
+  if (isset($form_state['view_args']) && $form_state['view_args'] !== '') {
+    $args = explode('/', $form_state['view_args']);
+  }
+
+  $errors = $view->validate();
+  if ($errors === TRUE) {
+    $view->ajax = $js;
+    $view->live_preview = TRUE;
+
+    // Store the current view URL for later use:
+    $view->set_display($form_state['display_id']);
+    $view->set_arguments($args);
+
+    if ($view->display_handler->get_option('path')) {
+      $path = $view->get_url();
+    }
+
+    // Make view links come back to preview.
+    $ajax = $js ? 'ajax' : 'nojs';
+    $view->override_path = "admin/build/views/$ajax/preview/" . $view->name . '/' . $form_state['display_id'];
+
+    // also override $_GET['q'] so we get the pager
+    $_GET['q'] = $view->override_path;
+    if ($form_state['view_args']) {
+      $_GET['q'] .= '/' . $form_state['view_args'];
+    }
+
+    $preview = $view->preview($form_state['display_id'], $args);
+
+    // Get information from the preview for display.
+    if (!empty($view->build_info['query'])) {
+      $rows = array();
+      $query = db_prefix_tables($view->build_info['query']);
+      if ($view->build_info['query_args']) {
+        _db_query_callback($view->build_info['query_args'], TRUE);
+        $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
+      }
+      $rows[] = array('<strong>' . t('Query') . '</strong>', '<pre>' . check_plain($query) . '</pre>');
+      if (!empty($view->additional_queries)) {
+        $queries = '<strong>' . t('These queries were run during view rendering:') . '</strong>';
+        foreach ($view->additional_queries as $query) {
+          if ($queries) {
+            $queries .= "\n";
+          }
+          $queries .= t('[@time ms]', array('@time' => intval($query[1] * 100000) / 100)) . ' ' . check_plain($query[0]);
+        }
+
+        $rows[] = array('<strong>' . t('Other queries') . '</strong>', '<pre>' . $queries . '</pre>');
+      }
+
+      $rows[] = array('<strong>' . t('Title') . '</strong>', filter_xss_admin($view->get_title()));
+      if (isset($path)) {
+        $path = l($path, $path);
+      }
+      else {
+        $path = t('This display has no path.');
+      }
+
+      $rows[] = array('<strong>' . t('Path') . '</strong>', $path);
+
+      $rows[] = array('<strong>' . t('Query build time') . '</strong>', t('@time ms', array('@time' => intval($view->build_time * 100000) / 100)));
+      $rows[] = array('<strong>' . t('Query execute time') . '</strong>', t('@time ms', array('@time' => intval($view->execute_time * 100000) / 100)));
+      $rows[] = array('<strong>' . t('View render time') . '</strong>', t('@time ms', array('@time' => intval($view->render_time * 100000) / 100)));
+      drupal_alter('views_preview_info', $rows, $view);
+
+      $info = theme('table', array(), $rows);
+    }
+    else {
+      $info = theme('table', array(), array(array('<strong>' . t('Query') . '</strong>', t('No query was run'))));
+    }
+  }
+  else {
+    foreach ($errors as $error) {
+      drupal_set_message($error, 'error');
+    }
+    $preview = t('Unable to preview due to validation errors.');
+    $info = '';
+  }
+
+  $info = '<div class="views-query-info">' . $info . '</div>';
+
+  if (variable_get('views_ui_query_on_top', FALSE)) {
+    $output .= $info . $preview;
+  }
+  else {
+    $output .= $preview . $info;
+  }
+
+  if (!$js) {
+    views_add_css('views-admin');
+    drupal_set_title($view->get_title());
+    return $output;
+  }
+  else {
+    views_include('ajax');
+    $object = new stdClass();
+    if (!empty($view->js_settings)) {
+      $object->js = $view->js_settings;
+    }
+    $object->display = '';
+    if ($messages = theme('status_messages')) {
+      $object->display = '<div class="views-messages">' . $messages . '</div>';
+    }
+    $object->display .= $output;
+    $object->title = $view->get_title();
+    views_ajax_render($object);
+  }
+}
+
+/**
+ * Form for generating argument information for the live preview.
+ */
+function views_ui_preview_form(&$form_state) {
+  $view = &$form_state['view'];
+  $view->init_display();
+  $options = array();
+  foreach ($view->display as $id => $display) {
+    $options[$id] = $display->display_title;
+  }
+
+  $form['#attributes'] = array(
+    'class' => 'clear-block',
+  );
+
+  $form['display_id'] = array(
+    '#type' => 'select',
+    '#title' => t('Display'),
+    '#options' => $options,
+    '#default_value' => $form_state['display_id'],
+    '#id' => 'preview-display-id',
+  );
+
+  $form['args'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Arguments'),
+    '#default_value' => $form_state['view_args'],
+    '#description' => t('Separate arguments with a / as though they were a URL path.'),
+    '#id' => 'preview-args',
+  );
+
+  $form['preview'] = array(
+    '#type' => 'submit',
+    '#value' => t('Preview'),
+    '#id' => 'preview-submit',
+  );
+
+
+  $form['live_preview'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Automatic live preview'),
+    '#default_value' => !variable_get('views_ui_disable_live_preview', 0),
+  );
+
+  $form['#action'] = url("admin/build/views/nojs/preview/$view->name");
+  return $form;
+}
+
+/**
+ * Submit the preview form.
+ *
+ * This just takes the data and stores it on the form state in a
+ * known location. The caller will be responsible for using it.
+ */
+function views_ui_preview_form_submit(&$form, &$form_state) {
+  $form_state['display_id'] = $form_state['values']['display_id'];
+  $form_state['view_args'] = $form_state['values']['args'];
+}
+
+/**
+ * Page callback to add a new view.
+ */
+function views_ui_add_page() {
+  $form_state = array(
+    'view' => NULL
+  );
+
+  return drupal_build_form('views_ui_add_form', $form_state);
+}
+
+/**
+ * Page callback to add a new view.
+ */
+function views_ui_clone_page($view) {
+  $form_state = array(
+    'view' => $view->copy(),
+  );
+
+  drupal_set_title(t('Clone view %view', array('%view' => $view->name)));
+  return drupal_build_form('views_ui_add_form', $form_state);
+}
+
+/**
+ * Form constructor callback to create the views Add Form, phase 1.
+ */
+function views_ui_add_form(&$form_state) {
+  $view = $form_state['view'];
+  $form = array();
+
+  $form['name'] = array(
+    '#type' => 'textfield',
+    '#title' => t('View name'),
+    '#description' => t('This is the unique name of the view. It must contain only alphanumeric characters and underscores; it is used to identify the view internally and to generate unique theming template names for this view. If overriding a module provided view, the name must not be changed or instead a new view will be created.'),
+    '#required' => TRUE,
+    '#maxlength' => 32,
+    '#default_value' => $view ? $view->name : '',
+    '#attributes' => array('dir'=>'ltr'),
+  );
+
+  $form['description'] = array(
+    '#type' => 'textfield',
+    '#title' => t('View description'),
+    '#description' => t('This description will appear on the Views administrative UI to tell you what the view is about.'),
+    '#default_value' => $view ? $view->description : '',
+  );
+
+  $form['tag'] = array(
+    '#type' => 'textfield',
+    '#title' => t('View tag'),
+    '#description' => t('Enter an optional tag for this view; it is used only to help sort views on the administrative page.'),
+    '#default_value' => $view ? $view->tag : '',
+    '#autocomplete_path' => 'admin/views/ajax/autocomplete/tag',
+  );
+
+  $base_tables = array();
+  foreach (views_fetch_base_tables() as $table => $info) {
+    $base_tables[$table] = $info['title'] . '<div class="description">' . $info['description'] . '</div>';
+  }
+
+  $form['base_table'] = array(
+    '#type' => 'radios',
+    '#title' => t('View type'),
+    '#description' => t('The view type is the primary table for which information is being retrieved. The view type controls what arguments, fields, sort criteria and filters are available, so once this is set it <strong>cannot be changed</strong>.'),
+    '#default_value' => $view ? $view->base_table : 'node',
+    '#options' => $base_tables,
+  );
+
+  if ($view) {
+    $form['base_table']['#disabled'] = TRUE;
+  }
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Next'),
+    '#validate' => array('views_ui_add_form_validate'),
+    '#submit' => array('views_ui_add_form_submit'),
+  );
+
+  return $form;
+}
+
+/**
+ * Validate the add view form.
+ */
+function views_ui_add_form_validate($form, &$form_state) {
+  $name = $form_state['values']['name'];
+
+  // View name must be alphanumeric or underscores, no other punctuation.
+  if (preg_match('/[^a-zA-Z0-9_]/', $name) || is_numeric($name)) {
+    form_error($form['name'], t('View name must be alphanumeric or underscores only, but cannot be numeric.'));
+  }
+
+  // View name must already exist.
+  $view = views_get_view($form_state['values']['name']);
+  if ($view && $view->type != t('Default')) {
+    form_error($form['name'], t('You must use a unique name for this view.'));
+  }
+}
+
+/**
+ * Process the add view form
+ */
+function views_ui_add_form_submit($form, &$form_state) {
+  $view = $form_state['view'] ? $form_state['view'] : views_new_view();
+  $view->name = $form_state['values']['name'];
+  $view->description = $form_state['values']['description'];
+  $view->tag = $form_state['values']['tag'];
+  if (empty($form['base_table']['#disabled'])) {
+    $view->base_table = $form_state['values']['base_table'];
+  }
+
+  views_ui_cache_set($view);
+  $form_state['redirect'] ='admin/build/views/edit/' . $view->name;
+}
+
+/**
+ * Page to delete a view.
+ */
+function views_ui_delete_confirm(&$form_state, $view) {
+  $form_state['view'] = &$view;
+  $form = array();
+
+  $cancel = 'admin/build/views';
+  if (!empty($_REQUEST['cancel'])) {
+    $cancel = $_REQUEST['cancel'];
+  }
+
+  if ($view->type == t('Overridden')) {
+    $title = t('Are you sure you want to revert the view %name?', array('%name' => $view->name));
+    $desc = t('Reverting the view will delete the view that is in the database, reverting it to the original default view. Any changes you have made will be lost and cannot be recovered.');
+    $button = t('Revert');
+  }
+  else {
+    $title = t('Are you sure you want to delete the view %name?', array('%name' => $view->name));
+    $desc = t('Deleting a view cannot be undone.');
+    $button = t('Delete');
+  }
+
+  return confirm_form($form,
+                  $title,
+                  $cancel,
+                  $desc,
+                  $button,
+                  t('Cancel'));
+}
+
+/**
+ * Submit handler to delete a view.
+ */
+function views_ui_delete_confirm_submit(&$form, &$form_state) {
+  $form_state['view']->delete();
+  views_object_cache_clear('view', $form_state['view']->name);
+  drupal_set_message(t('The view has been deleted.'));
+  $form_state['redirect'] = 'admin/build/views';
+}
+
+/**
+ * Page to delete a view.
+ */
+function views_ui_break_lock_confirm(&$form_state, $view) {
+  $form_state['view'] = &$view;
+  $form = array();
+
+  if (empty($view->locked)) {
+    return t('There is no lock on view %view to break.', array('%name' => $view->name));
+  }
+
+  $cancel = 'admin/build/views/edit/' . $view->name;
+  if (!empty($_REQUEST['cancel'])) {
+    $cancel = $_REQUEST['cancel'];
+  }
+
+  $account = user_load($view->locked->uid);
+  return confirm_form($form,
+                  t('Are you sure you want to break the lock on view %name?',
+                  array('%name' => $view->name)),
+                  $cancel,
+                  t('By breaking this lock, any unsaved changes made by !user will be lost!', array('!user' => theme('username', $account))),
+                  t('Break lock'),
+                  t('Cancel'));
+}
+
+/**
+ * Submit handler to break_lock a view.
+ */
+function views_ui_break_lock_confirm_submit(&$form, &$form_state) {
+  db_query("DELETE FROM {views_object_cache} WHERE obj = 'view' AND name = '%s'", $form_state['view']->name);
+  $form_state['redirect'] = 'admin/build/views/edit/' . $form_state['view']->name;
+  drupal_set_message(t('The lock has been broken and you may now edit this view.'));
+}
+
+/**
+ * The main view edit page
+ */
+function views_ui_edit_page($view) {
+  drupal_set_title(t('Edit view %view', array('%view' => $view->name)));
+  $output = theme('views_ui_edit_view', $view);
+  views_ui_check_advanced_help();
+  return $output;
+}
+
+/**
+ * Export a view for cut & paste.
+ */
+function views_ui_export_page(&$form_state, $view) {
+  $code = $view->export();
+  $lines = substr_count($code, "\n");
+  $form['code'] = array(
+    '#type' => 'textarea',
+    '#title' => $view->name,
+    '#default_value' => $code,
+    '#rows' => $lines,
+  );
+  return $form;
+}
+
+/**
+ * Import a view from cut & paste
+ */
+function views_ui_import_page(&$form_state) {
+  $form['name'] = array(
+    '#type' => 'textfield',
+    '#title' => t('View name'),
+    '#description' => t('Enter the name to use for this view if it is different from the source view. Leave blank to use the name of the view.'),
+  );
+
+  $form['view'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Paste view code here'),
+    '#required' => TRUE,
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Import'),
+    '#submit' => array('views_ui_import_submit'),
+    '#validate' => array('views_ui_import_validate'),
+  );
+  return $form;
+}
+
+/**
+ * Validate handler to import a view
+ */
+function views_ui_import_validate($form, &$form_state) {
+  $view = '';
+  views_include('view');
+  ob_start();
+  eval($form_state['values']['view']);
+  ob_end_clean();
+
+  if (!is_object($view)) {
+    return form_error($form['view'], t('Unable to interpret view code.'));
+  }
+
+  if (empty($view->api_version) || $view->api_version < 2) {
+    // Check for some value that would only exist on a Views 1 view.
+    if (isset($view->url) || isset($view->page) || isset($view->block)) {
+      views_include('convert');
+      $view = views1_import($view);
+      drupal_set_message(t('You are importing a view created in Views version 1. You may need to adjust some parameters to work correctly in version 2.'), 'warning');
+    }
+    else {
+      form_error($form['view'], t('That view is not compatible with this version of Views.'));
+    }
+  }
+  elseif ($view->api_version > views_api_version()) {
+    form_error($form['view'], t('That view is created for the version @import_version of views, but you only have @api_version', array(
+      '@import_version' => $view->api_version,
+      '@api_version' => views_api_version())));
+  }
+
+  // View name must be alphanumeric or underscores, no other punctuation.
+  if (!empty($form_state['values']['name']) && preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['name'])) {
+    form_error($form['name'], t('View name must be alphanumeric or underscores only.'));
+  }
+
+  if ($form_state['values']['name']) {
+    $view->name = $form_state['values']['name'];
+  }
+
+  $test = views_get_view($view->name);
+  if ($test && $test->type != t('Default')) {
+    form_set_error('', t('A view by that name already exists; please choose a different name'));
+  }
+
+  $view->init_display();
+
+  $broken = FALSE;
+  // Make sure that all plugins and handlers needed by this view actually exist.
+  foreach ($view->display as $id => $display) {
+    if (empty($display->handler) || !empty($display->handler->broken)) {
+      drupal_set_message(t('Display plugin @plugin is not available.', array('@plugin' => $display->display_plugin)), 'error');
+      $broken = TRUE;
+      continue;
+    }
+
+    $plugin = views_get_plugin('style', $display->handler->get_option('style_plugin'));
+    if (!$plugin) {
+      drupal_set_message(t('Style plugin @plugin is not available.', array('@plugin' => $display->handler->get_option('style_plugin'))), 'error');
+      $broken = TRUE;
+    }
+    else if ($plugin->uses_row_plugin()) {
+      $plugin = views_get_plugin('row', $display->handler->get_option('row_plugin'));
+      if (!$plugin) {
+        drupal_set_message(t('Row plugin @plugin is not available.', array('@plugin' => $display->handler->get_option('row_plugin'))), 'error');
+        $broken = TRUE;
+      }
+    }
+
+    foreach (views_object_types() as $type => $info) {
+      $handlers = $display->handler->get_handlers($type);
+      if ($handlers) {
+        foreach ($handlers as $id => $handler) {
+          if ($handler->broken()) {
+            drupal_set_message(t('@type handler @table.@field is not available.', array(
+              '@type' => $info['stitle'],
+              '@table' => $handler->table,
+              '@field' => $handler->field,
+            )), 'error');
+            $broken = TRUE;
+          }
+        }
+      }
+    }
+  }
+
+  if ($broken) {
+    form_set_error('', t('Unable to import view.'));
+  }
+
+  $form_state['view'] = &$view;
+}
+
+/**
+ * Submit handler for view import
+ */
+function views_ui_import_submit($form, &$form_state) {
+  // Store in cache and then go to edit.
+  views_ui_cache_set($form_state['view']);
+  $form_state['redirect'] = 'admin/build/views/edit/' . $form_state['view']->name;
+}
+
+/**
+ * The main edit view form, which is really just a save/cancel/delete button.
+ */
+function views_ui_edit_view_form(&$form_state, $view) {
+  $form['buttons']['save'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save'),
+    '#validate' => array('views_ui_edit_view_form_validate'),
+    '#submit' => array('views_ui_edit_view_form_submit'),
+  );
+
+  $form['buttons']['cancel'] = array(
+    '#type' => 'submit',
+    '#value' => t('Cancel'),
+    '#submit' => array('views_ui_edit_view_form_cancel'),
+  );
+
+  if (is_numeric($view->vid)) {
+    $form['buttons']['delete'] = array(
+      '#type' => 'submit',
+      '#value' => $view->type == t('Overridden') ? t('Revert') : t('Delete'),
+      '#submit' => array('views_ui_edit_view_form_delete'),
+    );
+  }
+
+  $form_state['view'] = &$view;
+  return $form;
+}
+
+/**
+ * Validate that a view is complete and whole.
+ */
+function views_ui_edit_view_form_validate($form, &$form_state) {
+  // Do not validate cancel or delete or revert.
+  if (empty($form_state['clicked_button']['#value']) || $form_state['clicked_button']['#value'] != t('Save')) {
+    return;
+  }
+
+  $errors = $form_state['view']->validate();
+  if ($errors !== TRUE) {
+    foreach ($errors as $error) {
+      form_set_error('', $error);
+    }
+  }
+}
+
+/**
+ * Submit handler for the edit view form.
+ */
+function views_ui_edit_view_form_submit($form, &$form_state) {
+  // Go through and remove displayed scheduled for removal.
+  foreach ($form_state['view']->display as $id => $display) {
+    if (!empty($display->deleted)) {
+      unset($form_state['view']->display[$id]);
+    }
+  }
+  // Rename display ids if needed.
+  foreach ($form_state['view']->display as $id => $display) {
+    if (!empty($display->new_id)) {
+      $form_state['view']->display[$id]->id = $display->new_id;
+    }
+  }
+
+  $form_state['view']->save();
+  drupal_set_message(t('The view %name has been saved.', array('%name' => $form_state['view']->name)));
+
+  // Make sure menu items get rebuilt as neces
+  menu_rebuild();
+
+  // Clear the views cache.
+  cache_clear_all('*', 'cache_views');
+
+  // Clear the page cache.
+  cache_clear_all();
+
+  // Remove this view from cache so we can edit it properly.
+  views_object_cache_clear('view', $form_state['view']->name);
+}
+
+/**
+ * Submit handler for the edit view form.
+ */
+function views_ui_edit_view_form_cancel($form, &$form_state) {
+  // Remove this view from cache so edits will be lost.
+  views_object_cache_clear('view', $form_state['view']->name);
+  if (empty($form['view']->vid)) {
+    // I seem to have to drupal_goto here because I can't get fapi to
+    // honor the redirect target. Not sure what I screwed up here.
+    drupal_goto('admin/build/views');
+  }
+}
+
+function views_ui_edit_view_form_delete($form, &$form_state) {
+  unset($_REQUEST['destination']);
+  // Redirect to the delete confirm page
+  $form_state['redirect'] = array('admin/build/views/delete/' . $form_state['view']->name, 'cancel=admin/build/views/edit/' . $form_state['view']->name);
+}
+
+/**
+ * Preprocess the view edit page.
+ */
+function template_preprocess_views_ui_edit_view(&$vars) {
+  $view = &$vars['view'];
+
+  $vars['save_button'] = drupal_get_form('views_ui_edit_view_form', $view);
+
+  $table = views_fetch_data($view->base_table);
+  $vars['base_table'] = !empty($table['table']['base']['title']) ?
+    $table['table']['base']['title'] : t('Unknown or missing table name');
+
+  views_include('tabs');
+  $tabs = new views_tabset;
+
+  $vars['message'] = '<div class="message">' . t("Click on an item to edit that item's details.") . '</div>';
+
+  if (!$view->set_display('default')) {
+    drupal_set_message(t('This view has a broken default display and cannot be used.'), 'error');
+  }
+
+  foreach ($view->display as $display) {
+    list($title, $body) = views_ui_display_tab($view, $display);
+    // The first display is the default.
+    $tabs->set($display->id, $title, $body);
+  }
+
+  // This is the area that will render beneath the links
+  $form_state = array(
+    'view' => &$view,
+    'ajax' => FALSE,
+  );
+
+  $display_button = drupal_build_form('views_ui_add_display_form', $form_state);
+  $analyze_button = drupal_get_form('views_ui_analyze_view_button', $view);
+  $reorder_button = drupal_get_form('views_ui_reorder_displays_button', $view);
+  $tabs->add_extra($display_button . $reorder_button . $analyze_button);
+
+  $vars['tabs'] = $tabs->render();
+
+  $form_state = array(
+    'display_id' => 'default',
+    'view_args' => '',
+    'rerender' => FALSE,
+    'no_redirect' => TRUE,
+    'view' => &$view,
+    'input' => array(),
+  );
+  $vars['preview'] = drupal_build_form('views_ui_preview_form', $form_state);
+
+  $vars['locked'] = NULL;
+  if (isset($view->locked) && is_object($view->locked)) {
+    $account = user_load($view->locked->uid);
+    $vars['locked'] = theme('username', $account);
+    $vars['lock_age'] = format_interval(time() - $view->locked->updated);
+    $vars['break'] = url('admin/build/views/break-lock/' . $view->name);
+  }
+
+  $vars['quick_links_raw'] = array(
+    array(
+      'title' => t('Export'),
+      'alt' => t("Export this view"),
+      'href' => "admin/build/views/export/$view->name",
+    ),
+    array(
+      'title' => t('Clone'),
+      'alt' => t("Create a copy of this view"),
+      'href' => "admin/build/views/clone/$view->name",
+    ),
+  );
+
+  $paths = array();
+  foreach ($view->display as $id => $display) {
+    if (!empty($display->handler) && $display->handler->has_path()) {
+      $path = $display->handler->get_path();
+      if (strpos($path, '%') === FALSE && !isset($paths[$path])) {
+        $vars['quick_links_raw'][] = array(
+          'title' => t('View "@display"', array('@display' => $display->display_title)),
+          'alt' => t("Go to the real page for this display"),
+          'href' => $path,
+        );
+        // Displays can have the same path; no point in showing more than one link.
+        $paths[$path] = TRUE;
+      }
+    }
+  }
+
+  $vars['quick_links'] = theme('links', $vars['quick_links_raw']);
+  views_add_css('views-admin');
+  drupal_add_js('misc/tabledrag.js', 'core');
+  views_add_js('ajax');
+  drupal_add_js('misc/jquery.form.js', 'core');
+
+  // Also add any js files required by plugins:
+  $plugins = views_fetch_plugin_data();
+  foreach ($plugins as $type => $type_plugins) {
+    foreach ($type_plugins as $name => $plugin) {
+      if (!empty($plugin['js'])) {
+        foreach ($plugin['js'] as $file) {
+          drupal_add_js($file);
+        }
+      }
+    }
+  }
+
+  $settings = array('views' => array('ajax' => array(
+    'id' => '#views-ajax-pad',
+    'title' => '#views-ajax-title',
+    'defaultForm' => $vars['message'],
+  )));
+
+  drupal_add_js($settings, 'setting');
+}
+
+function template_preprocess_views_ui_edit_tab(&$vars) {
+  $view = $vars['view'];
+  $display = $vars['display'];
+  $plugin = $display->handler->definition;
+
+  $top = $left = $middle = $right = '';
+
+  // If this form was submitted it was already handled, so force it not to
+  // submit again.
+
+  $vars['remove'] = '';
+  if (empty($plugin['no remove'])) {
+    if (!empty($_POST['form_id']) && $_POST['form_id'] == 'views_ui_remove_display_form') {
+      unset($_POST['form_id']);
+    }
+    $form_state = array('view' => &$view, 'display_id' => $display->id, 'ajax' => FALSE);
+    $vars['remove'] = drupal_build_form('views_ui_remove_display_form', $form_state);
+  }
+
+  // basic fields
+  $vars['title'] = check_plain($display->display_title);
+  $vars['description'] = check_plain($plugin['help']);
+
+  // Special fields if tihs is the default display.
+  $vars['default'] = ($display->id == 'default');
+  $vars['details_class'] = views_ui_item_css('details');
+  if (!empty($view->changed_sections['details'])) {
+    $vars['details_changed'] = TRUE;
+  }
+
+  $tag = empty($view->tag) ? t('None') : $view->tag;
+  $vars['details'] = t('Description') . '/' . t('Tag') . ': ' . l($tag, "admin/build/views/nojs/details/$view->name", array('attributes' => array('class' => 'views-ajax-link')));
+
+  // Calculate options from display plugin.
+  $options = $categories = array();
+  $display->handler->options_summary($categories, $options);
+
+  // Build all of the options we were returned and put them into the
+  // category data fields.
+  foreach ($options as $id => $option) {
+    if (empty($categories[$option['category']]['data'])) {
+      $categories[$option['category']]['data'] = array();
+    }
+    $categories[$option['category']]['data'][$id] = array();
+    $data = &$categories[$option['category']]['data'][$id];
+    $data['content'] = '';
+    $data['links'] = '';
+    $data['overridden'] = FALSE;
+    $data['defaulted'] = FALSE;
+
+    // If there are optional links, build them first so they float properly.
+    if (!empty($option['links'])) {
+      foreach ($option['links'] as $link_id => $link_value) {
+        $data['links'] .= $display->handler->option_link($link_value, $link_id, 'views-button-configure');
+      }
+    }
+    if (!empty($option['title'])) {
+      $data['content'] .= $option['title'] . ': ';
+    }
+
+    $data['content'] .= $display->handler->option_link($option['value'], $id, '', empty($option['desc']) ? '' : $option['desc']);
+    if (!empty($display->handler->options['defaults'][$id])) {
+      $display_id = 'default';
+      $data['defaulted'] = TRUE;
+    }
+    else {
+      $display_id = $display->id;
+      if (!$display->handler->is_default_display()) {
+        if ($display->handler->defaultable_sections($id)) {
+          $data['overridden'] = TRUE;
+        }
+      }
+    }
+    $data['class'] = views_ui_item_css($display_id . '-' . $id);
+    if (!empty($view->changed_sections[$display_id . '-' . $id])) {
+      $data['changed'] = TRUE;
+    }
+  }
+
+  $vars['categories'] = $categories;
+
+  // Add a help icon
+  if (isset($plugin['help topic'])) {
+    $vars['display_help_icon'] = theme('advanced_help_topic', $plugin['module'], $plugin['help topic']);
+  }
+  else {
+    $vars['display_help_icon'] = '';
+  }
+
+  // Fetch style plugin info because it has some effect on how/what we render.
+  $style_plugin = $display->handler->get_plugin();
+
+  $vars['fields'] = '';
+  $vars['areas'] = array();
+  foreach (array('header', 'footer', 'empty') as $area) {
+    $vars['areas'][$area] = theme('views_ui_edit_item', $area, $view, $display);
+  }
+  $vars['fields'] = theme('views_ui_edit_item', 'field', $view, $display, !($style_plugin && $style_plugin->uses_fields()));
+  $vars['relationships'] = theme('views_ui_edit_item', 'relationship', $view, $display);
+  $vars['arguments'] = theme('views_ui_edit_item', 'argument', $view, $display);
+  $vars['filters'] = theme('views_ui_edit_item', 'filter', $view, $display);
+  $vars['sorts'] = theme('views_ui_edit_item', 'sort', $view, $display);
+}
+
+/**
+ * Generate the summary output for a single display to render in a tab.
+ */
+function views_ui_display_tab($view, $display) {
+  if (isset($display->handler)) {
+    $plugin = $display->handler->definition;
+  }
+  if (empty($plugin)) {
+    $title = isset($display->display_title) ? $display->display_title : t('Invalid');
+    return array($title, t("Error: Display @display refers to a plugin named '@plugin', but that plugin doesn't exist!", array('@display' => $display->id, '@plugin' => $display->display_plugin)));
+
+    // @todo We can do a better 'plugin does not exist' tab.
+  }
+
+  // The display should always be initialized prior to this call.
+  if (empty($display->handler)) {
+    return FALSE;
+  }
+
+  $body = theme('views_ui_edit_tab', $view, $display);
+  return array($display->display_title, $body);
+}
+
+/**
+ * Add information about a section to a display.
+ */
+function template_preprocess_views_ui_edit_item(&$vars) {
+  $type = $vars['type'];
+  $view = $vars['view'];
+  $display = $vars['display'];
+
+  $types = views_object_types();
+
+  $vars['overridden'] = FALSE;
+  $vars['defaulted'] = FALSE;
+
+  if ($vars['no_fields']) {
+    $vars['title'] = $types[$type]['title'];
+    $vars['item_help_icon'] = theme('advanced_help_topic', 'views', $type);
+    $vars['rearrange'] = NULL;
+    $vars['add'] = NULL;
+    return;
+  }
+
+  // Different types now have different rearrange forms, so we use this switch
+  // to get the right one.
+  switch ($type) {
+    case 'filter':
+      $rearrange_url = "admin/build/views/nojs/rearrange-$type/$view->name/$display->id/$type";
+      break;
+    default:
+      $rearrange_url = "admin/build/views/nojs/rearrange/$view->name/$display->id/$type";
+  }
+
+  $vars['rearrange'] = l('<span>' . t('Rearrange') . '</span>', $rearrange_url, array('attributes' => array('class' => 'views-button-rearrange views-ajax-link', 'title' => t('Rearrange')), 'html' => true));
+
+  $vars['add'] = l('<span>' . t('Add') . '</span>', "admin/build/views/nojs/add-item/$view->name/$display->id/$type", array('attributes' => array('class' => 'views-button-add views-ajax-link', 'title' => t('Add')), 'html' => true));
+
+  if (!$display->handler->is_default_display()) {
+    if (!$display->handler->is_defaulted($types[$type]['plural'])) {
+      $vars['overridden'] = TRUE;
+    }
+    else {
+      $vars['defaulted'] = TRUE;
+    }
+  }
+
+  $vars['title'] = l($types[$type]['title'], "admin/build/views/nojs/config-type/$view->name/$display->id/$type", array('attributes' => array('class' => 'views-ajax-link')));
+//  $vars['title'] = l($types[$type]['title'], "admin/build/views/nojs/config-type/$view->name/$display->id/$type", array('attributes' => array('class' => 'views-ajax-link')));
+
+  $fields = array();
+
+  static $relationships = NULL;
+  if (!isset($relationships)) {
+    // Get relationship labels
+    $relationships = array();
+    // @todo: get_handlers()
+    foreach ($display->handler->get_handlers('relationship') as $id => $handler) {
+      $relationships[$id] = $handler->label();
+    }
+  }
+
+  // Filters can now be grouped so we do a little bit extra:
+  $groups = array();
+  $grouping = FALSE;
+  if ($type == 'filter') {
+    $group_info = $view->display_handler->get_option('filter_groups');
+    if (!empty($group_info['groups']) && count($group_info['groups']) > 1) {
+      $grouping = TRUE;
+      $groups = array(0 => array());
+    }
+  }
+
+  foreach ($display->handler->get_option($types[$type]['plural']) as $id => $field) {
+    $fields[$id] = array();
+
+    $handler = $display->handler->get_handler($type, $id);
+    if (empty($handler)) {
+      $fields[$id]['class'] = 'broken';
+      $field_name = t('Broken/missing handler: @table > @field', array('@table' => $field['table'], '@field' => $field['field']));
+      $fields[$id]['title'] = l($field_name, "admin/build/views/nojs/config-item/$view->name/$display->id/$type/$id", array('attributes' => array('class' => 'views-ajax-link'), 'html' => TRUE));
+      $fields[$id]['info'] = '';
+      continue;
+    }
+
+    $field_name = $handler->ui_name(TRUE);
+    if (!empty($field['relationship']) && !empty($relationships[$field['relationship']])) {
+      $field_name = '(' . $relationships[$field['relationship']] . ') ' . $field_name;
+    }
+
+    $fields[$id]['title'] = l($field_name, "admin/build/views/nojs/config-item/$view->name/$display->id/$type/$id", array('attributes' => array('class' => 'views-ajax-link'), 'html' => TRUE));
+    $fields[$id]['class'] = views_ui_item_css($display->id . '-' . $type . '-' . $id);
+    if (!empty($view->changed_sections[$display->id . '-' . $type . '-' . $id])) {
+      $fields[$id]['changed'] = TRUE;
+    }
+    $fields[$id]['info'] = $handler->admin_summary();
+
+    if ($display->handler->use_group_by()) {
+      $fields[$id]['links'] = l('<span>' . t('Group settings') . '</span>', "admin/build/views/nojs/config-item-group/$view->name/$display->id/$type/$id", array('attributes' => array('class' => 'views-button-configure views-ajax-link', 'title' => t('Group settings')), 'html' => true));
+    }
+    if ($handler->has_extra_options()) {
+      $fields[$id]['links'] = l('<span>' . t('Settings') . '</span>', "admin/build/views/nojs/config-item-extra/$view->name/$display->id/$type/$id", array('attributes' => array('class' => 'views-button-configure views-ajax-link', 'title' => t('Settings')), 'html' => true));
+    }
+
+    if ($handler->needs_style_plugin()) {
+      $style_plugin = views_fetch_plugin_data('style', $handler->options['style_plugin']);
+      $style_title = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin['title'];
+      $pid = $id . '-style-plugin';
+
+      if (!empty($style_plugin['uses options'])) {
+        $fields[$pid]['links'] = l('<span>' . t('Change settings for this style') . '</span>', "admin/build/views/nojs/config-style/$view->name/$display->id/$type/$id", array('attributes' => array('class' => 'views-button-configure views-ajax-link', 'title' => t('Settings')), 'html' => true));
+      }
+
+      $fields[$pid]['title'] = ' ' . t('&nbsp; Style: !style', array('!style' => l($style_title, "admin/build/views/nojs/change-style/$view->name/$display->id/$type/$id", array('attributes' => array('class' => 'views-ajax-link')))));
+      $fields[$pid]['class'] = views_ui_item_css($display->id . '-' . $type . '-' . $pid);
+      if (!empty($view->changed_sections[$display->id . '-' . $type . '-' . $pid])) {
+        $fields[$pid]['changed'] = TRUE;
+      }
+      $fields[$pid]['info'] = '';
+    }
+
+    if ($grouping) {
+      $gid = $handler->options['group'];
+
+      // Show in default group if the group does not exist.
+      if (empty($group_info['groups'][$gid])) {
+        $gid = 0;
+      }
+      $groups[$gid][] = $id;
+    }
+  }
+
+  // If using grouping, re-order fields so that they show up properly in the list.
+  if ($type == 'filter' && $grouping) {
+    $store = $fields;
+    $fields = array();
+    foreach ($groups as $gid => $contents) {
+      if (!empty($fields)) {
+        $operator = ') ' . ($group_info['operator'] == 'OR' ? t('OR') : t('AND')) . ' (';
+      }
+      else {
+        $operator = '(';
+      }
+      $fields[] = array(
+        'class' => 'views-group-text',
+        'title' => $operator,
+        'info' => '',
+      );
+      $started = FALSE;
+      foreach ($contents as $pid) {
+        $operator = '&nbsp;&nbsp;';
+        if ($started) {
+          $operator .= ($group_info['groups'][$gid] == 'OR' ? t('OR') : t('AND')) . ' ';
+        }
+        $store[$pid]['title'] = $operator . $store[$pid]['title'];
+        $started = TRUE;
+        $fields[$pid] = $store[$pid];
+      }
+    }
+    $fields[] = array(
+      'class' => 'views-group-text',
+      'title' => ')',
+      'info' => '',
+    );
+  }
+
+  $vars['fields'] = $fields;
+  $vars['item_help_icon'] = theme('advanced_help_topic', 'views', $type);
+}
+
+/**
+ * Regenerate the tabs for AJAX updates.
+ */
+function views_ui_regenerate_tabs(&$view, $display_id = NULL, $object = NULL) {
+  if (empty($display_id)) {
+    $displays = array_keys($view->display);
+  }
+  elseif (!is_array($display_id)) {
+    $displays = array($display_id);
+    if ($display_id != 'default') {
+      $displays[] = 'default';
+    }
+  }
+  else {
+    $displays = $display_id;
+  }
+
+  if (!$view->set_display('default')) {
+    views_ajax_render(t('Invalid display id found while regenerating tabs'));
+  }
+
+  if (!is_object($object)) {
+    $object = new stdClass();
+  }
+
+  $object->replace = array();
+  foreach ($displays as $id) {
+    list($title, $body) = views_ui_display_tab($view, $view->display[$id]);
+    $object->replace['#views-tab-' . $id] = $body;
+    $object->replace['#views-tab-title-' . $id] = check_plain($title);
+  }
+
+  if (!empty($view->changed)) {
+    $object->changed = TRUE;
+  }
+
+  views_ajax_render($object);
+}
+
+/**
+ * Provide standard buttons for the forms to make it easy. Also provide
+ * a hidden op operator because the forms plugin doesn't seem to properly
+ * provide which button was clicked.
+ */
+function views_ui_standard_form_buttons(&$form, &$form_state, $form_id, $name = NULL, $third = NULL, $submit = NULL) {
+  $form['buttons'] = array(
+    '#prefix' => '<div class="clear-block"><div class="form-buttons">',
+    '#suffix' => '</div></div>',
+  );
+
+  if (empty($name)) {
+    $name = t('Update');
+  }
+  // remove default validate handler
+  $form['#validate'] = array();
+
+  if (empty($form_state['ok_button'])) {
+    // but be sure submit button validates!
+    $form['buttons']['submit'] = array(
+      '#type' => 'submit',
+      '#value' => $name,
+      '#submit' => array($form_id . '_submit'),
+      '#validate' => array('views_ui_standard_submit', $form_id . '_validate'),
+    );
+  }
+
+  $cancel_submit = function_exists($form_id . '_cancel') ? $form_id . '_cancel' : 'views_ui_standard_cancel';
+  $form['buttons']['cancel'] = array(
+    '#type' => 'submit',
+    '#value' => empty($form_state['ok_button']) ? t('Cancel') : t('Ok'),
+    '#submit' => array($cancel_submit),
+    '#validate' => array(),
+  );
+
+  if ($third) {
+    if (empty($submit)) {
+      $submit = 'third';
+    }
+    $third_submit = function_exists($form_id . '_' . $submit) ? $form_id . '_' . $submit : 'views_ui_standard_cancel';
+
+    $form['buttons'][$submit] = array(
+      '#type' => 'submit',
+      '#value' => $third,
+      '#validate' => array(),
+      '#submit' => array($third_submit),
+    );
+  }
+
+  // Compatibility, to be removed later:
+  // We used to set these items on the form, but now we want them on the $form_state:
+  if (isset($form['#title'])) {
+    $form_state['title'] = $form['#title'];
+  }
+  if (isset($form['#help_topic'])) {
+    $form_state['help_topic'] = $form['#help_topic'];
+  }
+  if (isset($form['#help_module'])) {
+    $form_state['help_module'] = $form['#help_module'];
+  }
+  if (isset($form['#url'])) {
+    $form_state['url'] = $form['#url'];
+  }
+  if (isset($form['#js'])) {
+    if (!empty($form_state['js settings']) && is_array($form_state['js settings'])) {
+      $form_state['js settings'] = array_merge($form_state['js settings'], $form['#js']);
+    }
+    else {
+      $form_state['js settings'] = $form['#js'];
+    }
+  }
+  if (isset($form['#section'])) {
+    $form_state['#section'] = $form['#section'];
+  }
+  // Finally, we never want these cached -- our object cache does that for us.
+  $form['#no_cache'] = TRUE;
+
+  // If this isn't an ajaxy form, then we want to set the title.
+  if (!empty($form['#title'])) {
+    drupal_set_title($form['#title']);
+  }
+  views_add_css('views-admin');
+}
+
+/**
+ * Basic submit handler applicable to all 'standard' forms
+ */
+function views_ui_standard_submit($form, &$form_state) {
+  if (!empty($form['#section'])) {
+    $form_state['view']->changed_sections[$form['#section']] = TRUE;
+  }
+}
+
+/**
+ * Submit handler for cancel button
+ */
+function views_ui_standard_cancel($form, &$form_state) {
+  if (!empty($form_state['view']->changed) && isset($form_state['view']->form_cache)) {
+    unset($form_state['view']->form_cache);
+    views_ui_cache_set($form_state['view']);
+  }
+
+  $form_state['redirect'] = 'admin/build/views/edit/' . $form_state['view']->name;
+}
+
+// --------------------------------------------------------------------------
+// Various subforms for editing the pieces of a view.
+
+function views_ui_ajax_forms($key = NULL) {
+  $forms = array(
+    'display' => array(
+      'form_id' => 'views_ui_edit_display_form',
+      'args' => array('section'),
+    ),
+    'remove-display' => array(
+      'form_id' => 'views_ui_remove_display_form',
+      'args' => array(),
+    ),
+    'config-type' => array(
+      'form_id' => 'views_ui_config_type_form',
+      'args' => array('type'),
+    ),
+    'rearrange' => array(
+      'form_id' => 'views_ui_rearrange_form',
+      'args' => array('type'),
+    ),
+    'rearrange-filter' => array(
+      'form_id' => 'views_ui_rearrange_filter_form',
+      'args' => array('type'),
+    ),
+    'add-item' => array(
+      'form_id' => 'views_ui_add_item_form',
+      'args' => array('type'),
+    ),
+    'config-item' => array(
+      'form_id' => 'views_ui_config_item_form',
+      'args' => array('type', 'id'),
+    ),
+    'config-item-group' => array(
+      'form_id' => 'views_ui_config_item_group_form',
+      'args' => array('type', 'id'),
+    ),
+    'config-item-extra' => array(
+      'form_id' => 'views_ui_config_item_extra_form',
+      'args' => array('type', 'id'),
+    ),
+    'change-style' => array(
+      'form_id' => 'views_ui_change_style_form',
+      'args' => array('type', 'id'),
+    ),
+    'config-style' => array(
+      'form_id' => 'views_ui_config_style_form',
+      'args' => array('type', 'id'),
+    ),
+  );
+
+  if ($key) {
+    return !empty($forms[$key]) ? $forms[$key] : NULL;
+  }
+
+  return $forms;
+}
+
+/**
+ * Build a form identifier that we can use to see if one form
+ * is the same as another. Since the arguments differ slightly
+ * we do a lot of spiffy concenation here.
+ */
+function views_ui_build_identifier($key, $view, $display_id, $args) {
+  $form = views_ui_ajax_forms($key);
+  // Automatically remove the single-form cache if it exists and
+  // does not match the key.
+  $identifier = implode('-', array($key, $view->name, $display_id));
+
+  foreach ($form['args'] as $id) {
+    $arg = (!empty($args)) ? array_shift($args) : NULL;
+    $identifier .= '-' . $arg;
+  }
+  return $identifier;
+}
+
+/**
+ * Build up a $form_state object suitable for use with drupal_build_form
+ * based on known information about a form.
+ */
+function views_ui_build_form_state($js, $key, &$view, $display_id, $args) {
+  $form = views_ui_ajax_forms($key);
+  // Build up form state
+  $form_state = array(
+    'form_key' => $key,
+    'form_id' => $form['form_id'],
+    'view' => &$view,
+    'ajax' => $js,
+    'display_id' => $display_id,
+    'no_redirect' => TRUE,
+  );
+
+  foreach ($form['args'] as $id) {
+    $form_state[$id] = (!empty($args)) ? array_shift($args) : NULL;
+  }
+
+  return $form_state;
+}
+
+/**
+ * Create the URL for one of our standard AJAX forms based upon known
+ * information about the form.
+ */
+function views_ui_build_form_url($form_state) {
+  $form = views_ui_ajax_forms($form_state['form_key']);
+  $ajax = empty($form_state['ajax']) ? 'nojs' : 'ajax';
+  $name = $form_state['view']->name;
+  $url = "admin/build/views/$ajax/$form_state[form_key]/$name/$form_state[display_id]";
+  foreach ($form['args'] as $arg) {
+    $url .= '/' . $form_state[$arg];
+  }
+  return $url;
+}
+
+/**
+ * Add another form to the stack; clicking 'update' will go to this form
+ * rather than closing the ajax pad.
+ */
+function views_ui_add_form_to_stack($key, &$view, $display_id, $args, $top = FALSE) {
+  if (empty($view->stack)) {
+    $view->stack = array();
+  }
+
+  $stack = array(views_ui_build_identifier($key, $view, $display_id, $args), $key, &$view, $display_id, $args);
+  if ($top) {
+    array_unshift($view->stack, $stack);
+  }
+  else {
+    $view->stack[] = $stack;
+  }
+}
+
+/**
+ * Generic entry point to handle forms.
+ *
+ * We do this for consistency and to make it easy to chain forms
+ * together. This only works for forms that use both $view
+ * and $display_id, so we have a couple of ajax forms that we don't
+ * use with this system.
+ */
+function views_ui_ajax_form($js, $key, $view, $display_id) {
+  $form = views_ui_ajax_forms($key);
+  if (empty($form)) {
+    return drupal_not_found();
+  }
+
+  views_include('ajax');
+  $args = func_get_args();
+  // Remove the known args
+  array_splice($args, 0, 4);
+
+  $form_state = views_ui_build_form_state($js, $key, $view, $display_id, $args);
+  // check to see if this is the top form of the stack. If it is, pop
+  // it off; if it isn't, the user clicked somewhere else and the stack is
+  // now irrelevant.
+  if (!empty($view->stack)) {
+    $identifier = views_ui_build_identifier($key, $view, $display_id, $args);
+    $top = array_shift($view->stack);
+    if (array_shift($top) != $identifier) {
+      $view->stack = array();
+    }
+  }
+
+  // Automatically remove the form cache if it is set and the key does
+  // not match. This way navigating away from the form without hitting
+  // update will work.
+  if (isset($view->form_cache) && $view->form_cache['key'] != $key) {
+    unset($view->form_cache);
+  }
+
+  $output = views_ajax_form_wrapper($form_state['form_id'], $form_state);
+
+  if (!$output) {
+    // Sometimes we need to re-generate the form for multi-step type operations.
+    $object = NULL;
+    if (!empty($view->stack)) {
+      $stack = $view->stack; // copy so the next shift doesn't break the array
+      $top = array_shift($stack);
+      $top[0] = $js; // change identifier into $js setting
+      $form_state = call_user_func_array('views_ui_build_form_state', $top);
+      $form_state['input'] = array(); // this is a new form, make sure it
+      // doesn't try to inherit $_POST info.
+      if (!$js) {
+        return drupal_goto(views_ui_build_form_url($form_state));
+      }
+      $object = views_ajax_form_wrapper($form_state['form_id'], $form_state);
+      $object->url = url(views_ui_build_form_url($form_state));
+    }
+    else if (!$js) {
+      // if nothing on the stack, non-js forms just go back to the main view editor.
+      return drupal_goto("admin/build/views/edit/$view->name");
+    }
+    // regenerate all tabs because changes to the default tab could ripple.
+    return views_ui_regenerate_tabs($view, NULL, $object);
+  }
+
+  return ($js) ? views_ajax_render($output) : $output;
+}
+
+/**
+ * AJAX callback to add a display.
+ */
+function views_ui_add_display($js, $view) {
+  views_include('ajax');
+  $form_state = array(
+    'view' => &$view,
+    'ajax' => $js,
+  );
+
+  $output = views_ajax_form_wrapper('views_ui_add_display_form', $form_state);
+
+  if ($js) {
+    // If we don't have an output object, it was submitted. Set up the submission.
+    if (empty($output)) {
+      $id = $form_state['id'];
+
+      // Make sure the new display is active
+      if (!$view->set_display('default')) {
+        views_ajax_render(t('Unable to initialize default display'));
+      }
+
+      // Render the new display
+      list($title, $body) = views_ui_display_tab($view, $view->display[$id]);
+
+      // Instruct the javascript on the browser to render the new tab.
+      $output = new stdClass;
+      $output->tab = array('#views-tab-' . $id => array('title' => $title, 'body' => $body));
+    }
+    // Render the command object. This automatically exits.
+    views_ajax_render($output);
+  }
+
+  // But the non-js variant will return output if it didn't redirect us.
+  return $output;
+}
+
+/**
+ * Form to add a display to a view.
+ */
+function views_ui_add_display_form(&$form_state) {
+  $view = &$form_state['view'];
+
+  $form['display']['display'] = array(
+    '#type' => 'select',
+    '#options' => views_fetch_plugin_names('display'),
+    '#default_value' => 'page',
+  );
+
+  $form['display']['add_display'] = array(
+    '#type' => 'submit',
+    '#value' => t('Add display'),
+    '#submit' => array('views_ui_add_display_form_submit'),
+  );
+
+  $form['#id'] = 'views-add-display-form';
+  $form['#attributes'] = array('class' => 'views-ajax-form');
+  $form['#action'] = url("admin/build/views/nojs/add-display/$view->name");
+
+  return $form;
+}
+
+/**
+ * Submit handler to add a display to a view.
+ */
+function views_ui_add_display_form_submit($form, &$form_state) {
+  // Create the new display
+  $plugin = $form_state['values']['display'];
+  $form_state['id'] = $form_state['view']->add_display($plugin);
+
+  // Store in cache
+  views_ui_cache_set($form_state['view']);
+
+  // Send it back
+  $form_state['redirect'] = array('admin/build/views/edit/' . $form_state['view']->name, NULL, 'views-tab-' . $form_state['id']);
+}
+
+/**
+ * Form to remove a display from a view.
+ */
+function views_ui_remove_display_form(&$form_state) {
+  $view = &$form_state['view'];
+  $display_id = $form_state['display_id'];
+
+  if (empty($view->display[$display_id]->deleted)) {
+    $form['display'] = array(
+      '#prefix' => '<div class="display-button remove-display">',
+      '#suffix' => '</div>',
+    );
+    $form['remove_display'] = array(
+      '#type' => 'submit',
+      '#value' => t('Remove display'),
+      '#submit' => array('views_ui_remove_display_form_submit'),
+    );
+  }
+  else {
+    $form['display'] = array(
+      '#prefix' => '<div class="display-button restore-display">',
+      '#suffix' => '</div>',
+    );
+    $form['restore_display'] = array(
+      '#type' => 'submit',
+      '#value' => t('Restore display'),
+      '#submit' => array('views_ui_remove_display_form_restore'),
+    );
+  }
+  $form['#action'] = url("admin/build/views/nojs/remove-display/$view->name/$display_id");
+  $form['#attributes'] = array('class' => 'views-ajax-form');
+
+  return $form;
+}
+
+/**
+ * Submit handler to add a remove to a display from a view.
+ */
+function views_ui_remove_display_form_submit($form, &$form_state) {
+  // Create the new display
+  $plugin = views_fetch_plugin_data('display', $form_state['view']->display[$form_state['display_id']]->display_plugin);
+  if (empty($plugin['no remove'])) {
+    $id = $form_state['display_id'];
+    $form_state['view']->display[$id]->deleted = TRUE;
+
+    // Store in cache
+    views_ui_cache_set($form_state['view']);
+  }
+}
+
+/**
+ * Submit handler to add a restore a removed display to a view.
+ */
+function views_ui_remove_display_form_restore($form, &$form_state) {
+  // Create the new display
+  $id = $form_state['display_id'];
+  $form_state['view']->display[$id]->deleted = FALSE;
+
+  // Store in cache
+  views_ui_cache_set($form_state['view']);
+}
+
+/**
+ * Page callback to display analysis information on a view.
+ */
+function views_ui_analyze_view($js, $view) {
+  views_include('ajax');
+  $form_state = array(
+    'view' => &$view,
+    'ajax' => $js,
+  );
+
+  $output = views_ajax_form_wrapper('views_ui_analyze_view_form', $form_state);
+
+  if ($js) {
+    // If we don't have an output object, it was submitted. Set up the submission.
+    if (empty($output)) {
+      return views_ui_regenerate_tabs($view);
+    }
+    return views_ajax_render($output);
+
+  }
+  return $output;
+}
+
+/**
+ * This form doesn't particularly do much; it's really just providing a link
+ * but a button seems like it would be nicer here.
+ *
+ * It has no submit or anything, as we will never actually submit this form
+ * where the form is placed.
+ */
+function views_ui_analyze_view_button(&$form_state, $view) {
+  $form['#action'] = url("admin/build/views/nojs/analyze/$view->name");
+  $form['#attributes'] = array('class' => 'views-ajax-form');
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Analyze'),
+  );
+
+  return $form;
+}
+
+/**
+ * Form constructor callback to display analysis information on a view
+ */
+function views_ui_analyze_view_form(&$form_state) {
+  $view = &$form_state['view'];
+
+  $form['#title'] = t('View analysis');
+  $form['#section'] = 'analyze';
+
+  views_include('analyze');
+  $messages = views_analyze_view($view);
+
+  $form['analysis'] = array(
+    '#prefix' => '<div class="form-item">',
+    '#suffix' => '</div>',
+    '#value' => views_analyze_format_result($view, $messages),
+  );
+
+  // Inform the standard button function that we want an OK button.
+  $form_state['ok_button'] = TRUE;
+  views_ui_standard_form_buttons($form, $form_state, 'views_ui_analyze_view_form');
+  return $form;
+}
+
+/**
+ * Submit handler for views_ui_analyze_view_form
+ */
+function views_ui_analyze_view_form_submit($form, &$form_state) {
+  $form_state['redirect'] = 'admin/build/views/edit/' . $form_state['view']->name;
+}
+
+/**
+ * Page callback to display analysis information on a view.
+ */
+function views_ui_reorder_view($js, $view) {
+  views_include('ajax');
+  $form_state = array(
+    'view' => &$view,
+    'ajax' => $js,
+  );
+
+  $output = views_ajax_form_wrapper('views_ui_reorder_displays_form', $form_state);
+
+  if ($js) {
+    if(empty($output)) {
+      // I don't want preprocess to modify the views -> no references
+      $vars = array('view' => $view);
+      template_preprocess_views_ui_edit_view($vars);
+      $output = new stdClass();
+      $output->replace['.views-tabset'] = $vars['tabs'];
+      // Not the right place to have html i know !
+      $output->replace['.views-quick-links'] = '<div class="views-quick-links">'. $vars['quick_links'] .'</div>';
+      // Doesn't work yet, maybe we should reload the page dunno
+      //return views_ui_regenerate_tabs($view);
+    }
+    return views_ajax_render($output);
+  }
+
+  return $output;
+}
+
+/**
+ * Form constructor callback to reorder displays on a view
+ */
+function views_ui_reorder_displays_form(&$form_state) {
+  $view = &$form_state['view'];
+
+  $form['view'] = array('#type' => 'value', '#value' => $view);
+
+  $form['#tree'] = TRUE;
+
+  $last_display = end($view->display);
+
+  foreach ($view->display as $display) {
+    $form[$display->id] = array(
+      'title'  => array('#value' => $display->display_title),
+      'weight' => array(
+        '#type' => 'weight',
+        '#value' => $display->position,
+        '#delta' => $last_display->position,
+      ),
+      '#tree' => TRUE,
+      '#display' => $display,
+      'removed' => array(
+        '#type' => 'checkbox',
+        '#id' => 'display-removed-' . $display->id,
+        '#attributes' => array('class' => 'views-remove-checkbox'),
+        '#default_value' => isset($display->deleted),
+      ),
+    );
+
+    if (isset($display->deleted) && $display->deleted) {
+      $form[$display->id]['deleted'] = array('#type' => 'value', '#value' => TRUE);
+    }
+    if ($display->id === 'default') {
+      unset($form[$display->id]['weight']);
+      unset($form[$display->id]['removed']);
+    }
+
+  }
+
+  $form['#title'] = t('Displays Reorder');
+  $form['#section'] = 'reorder';
+
+  // Add javascript settings that will be added via $.extend for tabledragging
+  $form['#js']['tableDrag']['reorder-displays']['weight'][0] = array(
+    'target' => 'weight',
+    'source' => NULL,
+    'relationship' => 'sibling',
+    'action' => 'order',
+    'hidden' => TRUE,
+    'limit' => 0,
+  );
+
+
+  $form['#action'] = url('admin/build/views/nojs/reorder-display/'. $view->name);
+
+  views_ui_standard_form_buttons($form, $form_state, 'views_ui_reorder_displays_form');
+
+  return $form;
+}
+
+
+/**
+ * Display position sorting function
+ */
+function _views_position_sort($display1, $display2) {
+  if ($display1->position != $display2->position) {
+    return $display1->position < $display2->position ? -1 : 1;
+  }
+
+  return 0;
+}
+
+/**
+ * Submit handler for rearranging display form
+ */
+function views_ui_reorder_displays_form_submit($form, &$form_state) {
+  foreach($form_state['input'] as $display => $info) {
+    // add each value that is a field with a weight to our list, but only if
+    // it has had its 'removed' checkbox checked.
+    if (is_array($info) && isset($info['weight']) && empty($info['removed'])) {
+      $order[$display] = $info['weight'];
+    }
+  }
+
+  // Sort the order array
+  asort($order);
+
+  // Fixing up positions
+  $position = 2;
+
+  foreach(array_keys($order) as $display) {
+    $order[$display] = $position++;
+  }
+
+  // Setting up position and removing deleted displays
+  $displays = $form_state['view']->display;
+  foreach($displays as $display_id => $display) {
+    // Don't touch the default !!!
+    if ($display_id === 'default') {
+      continue;
+    }
+    if (isset($order[$display_id])) {
+      $form_state['view']->display[$display_id]->position = $order[$display_id];
+    }
+    else {
+      $form_state['view']->display[$display_id]->deleted = TRUE;
+    }
+  }
+
+  // Sorting back the display array as the position is not enough
+  uasort($form_state['view']->display, '_views_position_sort');
+
+  // Store in cache
+  views_ui_cache_set($form_state['view']);
+  $form_state['redirect'] = array('admin/build/views/edit/' . $form_state['view']->name, NULL, 'views-tab-default');
+}
+
+/**
+ * Turn the reorder form into a proper table
+ */
+function theme_views_ui_reorder_displays_form($form) {
+  $rows = array();
+  foreach (element_children($form) as $key) {
+    if (isset($form[$key]['#display'])) {
+      $display = &$form[$key];
+
+      $row = array();
+      $row[] = drupal_render($display['title']);
+      $form[$key]['weight']['#attributes']['class'] = 'weight';
+      $row[] = drupal_render($form[$key]['weight']);
+      if (isset($display['removed'])) {
+        $row[] = drupal_render($form[$key]['removed']) .
+          l('<span>' . t('Remove') . '</span>',
+            'javascript:void()',
+            array(
+              'attributes' => array(
+                'id' => 'display-remove-link-' . $key,
+                'class' => 'views-button-remove display-remove-link',
+                'alt' => t('Remove this display'),
+                'title' => t('Remove this display')),
+              'html' => TRUE));
+      }
+      else {
+        $row[] = '';
+      }
+      $class = array();
+      $styles = array();
+      if (isset($form[$key]['weight']['#type'])) {
+        $class[] = 'draggable';
+      }
+      if (isset($form[$key]['deleted']['#value']) && $form[$key]['deleted']['#value']) {
+        $styles[] = 'display: none;';
+      }
+      $rows[] = array('data' => $row, 'class' => implode(' ', $class), 'id' => 'display-row-' . $key, 'style' => implode(' ', $styles));
+    }
+  }
+
+  $header = array(t('Display'), t('Weight'), t('Remove'));
+  $output = '';
+  drupal_add_tabledrag('reorder-displays', 'order', 'sibling', 'weight');
+
+  $output = drupal_render($form['override']);
+  $output .= theme('table', $header, $rows, array('id' => 'reorder-displays'));
+  $output .= drupal_render($form);
+
+  return $output;
+}
+
+/**
+ * This form doesn't particularly do much; it's really just providing a link
+ * but a button seems like it would be nicer here.
+ *
+ * It has no submit or anything, as we will never actually submit this form
+ * where the form is placed.
+ */
+function views_ui_reorder_displays_button(&$form_state, $view) {
+  $form['#action'] = url("admin/build/views/nojs/reorder-displays/$view->name");
+  $form['#attributes'] = array('class' => 'views-ajax-form');
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Reorder'),
+  );
+
+  return $form;
+}
+
+/**
+ * Page callback to edit details of a view.
+ */
+function views_ui_edit_details($js, $view) {
+  views_include('ajax');
+  $form_state = array(
+    'view' => &$view,
+    'ajax' => $js,
+  );
+
+  $output = views_ajax_form_wrapper('views_ui_edit_details_form', $form_state);
+
+  if ($js) {
+    // If we don't have an output object, it was submitted. Set up the submission.
+    if (empty($output)) {
+      return views_ui_regenerate_tabs($view);
+    }
+    return views_ajax_render($output);
+
+  }
+  return $output;
+}
+
+/**
+ * Form constructor callback to edit details of a view
+ */
+function views_ui_edit_details_form(&$form_state) {
+  $view = &$form_state['view'];
+
+  $form['#title'] = t('View details');
+  $form['#section'] = 'details';
+
+  $form['description'] = array(
+    '#type' => 'textfield',
+    '#title' => t('View description'),
+    '#description' => t('This description will appear on the Views administrative UI to tell you what the view is about.'),
+    '#default_value' => $view->description,
+  );
+
+  $form['tag'] = array(
+    '#type' => 'textfield',
+    '#title' => t('View tag'),
+    '#description' => t('Enter an optional tag for this view; it is used only to help sort views on the administrative page.'),
+    '#default_value' => $view->tag,
+    '#autocomplete_path' => 'admin/views/ajax/autocomplete/tag',
+  );
+
+  views_ui_standard_form_buttons($form, $form_state, 'views_ui_edit_details_form');
+  return $form;
+}
+
+/**
+ * Submit handler for views_ui_edit_details_form
+ */
+function views_ui_edit_details_form_submit($form, &$form_state) {
+  $form_state['view']->description = $form_state['values']['description'];
+  $form_state['view']->tag = $form_state['values']['tag'];
+  views_ui_cache_set($form_state['view']);
+  $form_state['redirect'] = 'admin/build/views/edit/' . $form_state['view']->name;
+}
+
+/**
+ * Form constructor callback to edit display of a view
+ */
+function views_ui_edit_display_form(&$form_state) {
+  $view = &$form_state['view'];
+  $display_id = $form_state['display_id'];
+  $section = $form_state['section'];
+
+  if (!$view->set_display($display_id)) {
+    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
+  }
+  $display = &$view->display[$display_id];
+
+  // Get form from the handler.
+  $display->handler->options_form($form, $form_state);
+  $name = NULL;
+  if (isset($form_state['update_name'])) {
+    $name = $form_state['update_name'];
+  }
+
+  views_ui_standard_form_buttons($form, $form_state, 'views_ui_edit_display_form', $name);
+  return $form;
+}
+
+/**
+ * Validate handler for views_ui_edit_display_form
+ */
+function views_ui_edit_display_form_validate($form, &$form_state) {
+  $display = &$form_state['view']->display[$form_state['display_id']];
+  $display->handler->options_validate($form, $form_state);
+}
+
+/**
+ * Submit handler for views_ui_edit_display_form
+ */
+function views_ui_edit_display_form_submit($form, &$form_state) {
+  $display = &$form_state['view']->display[$form_state['display_id']];
+  $display->handler->options_submit($form, $form_state);
+
+  views_ui_cache_set($form_state['view']);
+}
+
+/**
+ * Override handler for views_ui_edit_display_form
+ */
+function views_ui_edit_display_form_override($form, &$form_state) {
+  $display = &$form_state['view']->display[$form_state['display_id']];
+  $display->handler->options_override($form, $form_state);
+
+  views_ui_cache_set($form_state['view']);
+  $form_state['rerender'] = TRUE;
+  $form_state['rebuild'] = TRUE;
+}
+/**
+ * Form to config items in the views UI.
+ */
+function views_ui_config_type_form(&$form_state) {
+  $view = &$form_state['view'];
+  $display_id = $form_state['display_id'];
+  $type = $form_state['type'];
+
+  $types = views_object_types();
+  if (!$view->set_display($display_id)) {
+    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
+  }
+  $display = &$view->display[$display_id];
+  $form['#title'] = check_plain($display->display_title) . ': ';
+  $form['#title'] .= t('Configure @type', array('@type' => $types[$type]['ltitle']));
+  $form['#section'] = $display_id . 'config-item';
+
+  if ($display->handler->defaultable_sections($types[$type]['plural'])) {
+    $form_state['section'] = $types[$type]['plural'];
+    $display->handler->add_override_button($form, $form_state, $form_state['section']);
+  }
+
+  if (!empty($types[$type]['options']) && function_exists($types[$type]['options'])) {
+    $options = $type . '_options';
+    $form[$options] = array('#tree' => TRUE);
+    $types[$type]['options']($form, $form_state);
+  }
+
+  $name = NULL;
+  if (isset($form_state['update_name'])) {
+    $name = $form_state['update_name'];
+  }
+
+  views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_type_form', $name);
+  return $form;
+}
+
+/**
+ * Submit handler for type configuration form
+ */
+function views_ui_config_type_form_submit($form, &$form_state) {
+  $types = views_object_types();
+  $display = &$form_state['view']->display[$form_state['display_id']];
+
+  // Store in cache
+  views_ui_cache_set($form_state['view']);
+}
+
+/**
+ * Configure settings particular to filters.
+ */
+function views_ui_config_filters_form(&$form, &$form_state) {
+
+}
+
+/**
+ * Form to rearrange items in the views UI.
+ */
+function views_ui_rearrange_form(&$form_state) {
+  $view = &$form_state['view'];
+  $display_id = $form_state['display_id'];
+  $type = $form_state['type'];
+
+  $types = views_object_types();
+  if (!$view->set_display($display_id)) {
+    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
+  }
+  $display = &$view->display[$display_id];
+  $form['#title'] = check_plain($display->display_title) . ': ';
+  $form['#title'] .= t('Rearrange @type', array('@type' => $types[$type]['ltitle']));
+  $form['#section'] = $display_id . 'rearrange-item';
+
+  if ($display->handler->defaultable_sections($types[$type]['plural'])) {
+    $form_state['section'] = $types[$type]['plural'];
+    $display->handler->add_override_button($form, $form_state, $form_state['section']);
+  }
+
+  $count = 0;
+
+  // Get relationship labels
+  $relationships = array();
+  foreach ($display->handler->get_handlers('relationship') as $id => $handler) {
+    $relationships[$id] = $handler->label();
+  }
+
+  foreach ($display->handler->get_option($types[$type]['plural']) as $id => $field) {
+    $form[$id] = array('#tree' => TRUE);
+    $form[$id]['weight'] = array(
+      '#type' => 'textfield',
+      '#default_value' => ++$count,
+    );
+    $handler = $display->handler->get_handler($type, $id);
+    if ($handler) {
+      $name = $handler->ui_name() . ' ' . $handler->admin_summary();
+      if (!empty($field['relationship']) && !empty($relationships[$field['relationship']])) {
+        $name = '(' . $relationships[$field['relationship']] . ') ' . $name;
+      }
+
+      $form[$id]['name'] = array(
+        '#value' => $name,
+      );
+    }
+    else {
+      $form[$id]['name'] = array('#value' => t('Broken field @id', array('@id' => $id)));
+    }
+    $form[$id]['removed'] = array(
+      '#type' => 'checkbox',
+      '#id' => 'views-removed-' . $id,
+      '#attributes' => array('class' => 'views-remove-checkbox'),
+      '#default_value' => 0,
+    );
+  }
+
+  // Add javascript settings that will be added via $.extend for tabledragging
+  $form['#js']['tableDrag']['arrange']['weight'][0] = array(
+    'target' => 'weight',
+    'source' => NULL,
+    'relationship' => 'sibling',
+    'action' => 'order',
+    'hidden' => TRUE,
+    'limit' => 0,
+  );
+
+  $name = NULL;
+  if (isset($form_state['update_name'])) {
+    $name = $form_state['update_name'];
+  }
+
+  views_ui_standard_form_buttons($form, $form_state, 'views_ui_rearrange_form');
+  return $form;
+}
+
+/**
+ * Turn the rearrange form into a proper table
+ */
+function theme_views_ui_rearrange_form($form) {
+  $rows = array();
+  foreach (element_children($form) as $id) {
+    if (isset($form[$id]['name'])) {
+      $row = array();
+      $row[] = drupal_render($form[$id]['name']);
+      $form[$id]['weight']['#attributes']['class'] = 'weight';
+      $row[] = drupal_render($form[$id]['weight']);
+      $row[] = drupal_render($form[$id]['removed']) . l('<span>' . t('Remove') . '</span>', 'javascript:void()', array('attributes' => array('id' => 'views-remove-link-' . $id, 'class' => 'views-hidden views-button-remove views-remove-link', 'alt' => t('Remove this item'), 'title' => t('Remove this item')), 'html' => true));
+
+      $rows[] = array('data' => $row, 'class' => 'draggable', 'id' => 'views-row-' . $id);
+    }
+  }
+  if (empty($rows)) {
+    $rows[] = array(array('data' => t('No fields available.'), 'colspan' => '2'));
+  }
+
+  $header = array('', t('Weight'), t('Remove'));
+  drupal_add_tabledrag('arrange', 'order', 'sibling', 'weight');
+  $output = drupal_render($form['override']);
+  $output .= theme('table', $header, $rows, array('id' => 'arrange'));
+  $output .= drupal_render($form);
+  return $output;
+
+}
+
+/**
+ * Submit handler for rearranging form
+ */
+function views_ui_rearrange_form_submit($form, &$form_state) {
+  $types = views_object_types();
+  $display = &$form_state['view']->display[$form_state['display_id']];
+
+  $old_fields = $display->handler->get_option($types[$form_state['type']]['plural']);
+  $new_fields = $order = array();
+
+  // Make an array with the weights
+  foreach ($form_state['values'] as $field => $info) {
+    // add each value that is a field with a weight to our list, but only if
+    // it has had its 'removed' checkbox checked.
+    if (is_array($info) && isset($info['weight']) && empty($info['removed'])) {
+      $order[$field] = $info['weight'];
+    }
+  }
+
+  // Sort the array
+  asort($order);
+
+  // Create a new list of fields in the new order.
+  foreach (array_keys($order) as $field) {
+    $new_fields[$field] = $old_fields[$field];
+  }
+  $display->handler->set_option($types[$form_state['type']]['plural'], $new_fields);
+
+  // Store in cache
+  views_ui_cache_set($form_state['view']);
+}
+
+/**
+ * Form to rearrange items in the views UI.
+ */
+function views_ui_rearrange_filter_form(&$form_state) {
+  $view = &$form_state['view'];
+  $display_id = $form_state['display_id'];
+  $type = $form_state['type'];
+
+  $types = views_object_types();
+  if (!$view->set_display($display_id)) {
+    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
+  }
+  $display = &$view->display[$display_id];
+  $form['#title'] = check_plain($display->display_title) . ': ';
+  $form['#title'] .= t('Rearrange @type', array('@type' => $types[$type]['ltitle']));
+  $form['#section'] = $display_id . 'rearrange-item';
+
+  if ($display->handler->defaultable_sections($types[$type]['plural'])) {
+    $form_state['section'] = $types[$type]['plural'];
+    $display->handler->add_override_button($form, $form_state, $form_state['section']);
+  }
+
+  if (!empty($view->form_cache)) {
+    $groups = $view->form_cache['groups'];
+    $handlers = $view->form_cache['handlers'];
+  }
+  else {
+    $groups = $display->handler->get_option('filter_groups');
+    $handlers = $display->handler->get_option($types[$type]['plural']);
+  }
+  $count = 0;
+
+  // Get relationship labels
+  $relationships = array();
+  foreach ($display->handler->get_handlers('relationship') as $id => $handler) {
+    $relationships[$id] = $handler->label();
+  }
+
+  $group_options = array();
+
+  /**
+   * Filter groups is an array that contains:
+   * array(
+   *   'operator' => 'and' || 'or',
+   *   'groups' => array(
+   *     $group_id => 'and' || 'or',
+   *   ),
+   * );
+   */
+
+  $grouping = count(array_keys($groups['groups'])) > 1;
+
+  $form['filter_groups']['#tree'] = TRUE;
+  $form['filter_groups']['operator'] = array(
+    '#type' => 'select',
+    '#options' => array (
+      'AND' => t('And'),
+      'OR' => t('Or'),
+    ),
+    '#default_value' => $groups['operator'],
+    '#attributes' => array(
+      'class' => 'warning-on-change',
+    ),
+    '#title' => t('Operator to use on all groups'),
+    '#description' => t('Either "group 0 AND group 1 AND group 2" or "group 0 OR group 1 OR group 2", etc'),
+    '#access' => $grouping,
+  );
+
+  $form['remove_groups']['#tree'] = TRUE;
+
+  foreach ($groups['groups'] as $id => $group) {
+    $form['filter_groups']['groups'][$id] = array(
+      '#title' => t('Group operator'),
+      '#type' => 'select',
+      '#options' => array(
+        'AND' => t('And'),
+        'OR' => t('Or'),
+      ),
+      '#default_value' => $group,
+      '#attributes' => array(
+        'class' => 'warning-on-change',
+      ),
+    );
+
+    $form['remove_groups'][$id] = array(); // to prevent a notice
+    if ($id != 0) {
+      $form['remove_groups'][$id] = array(
+        '#type' => 'submit',
+        '#value' => t('Remove group @group', array('@group' => $id)),
+        '#group' => $id,
+      );
+    }
+    $group_options[$id] = $id == 0 ? t('Default group') : t('Group @group', array('@group' => $id));
+    $form['#group_renders'][$id] = array();
+  }
+
+  $form['#group_options'] = $group_options;
+  $form['#groups'] = $groups;
+  // We don't use get_handlers() because we want items without handlers to
+  // appear and show up as 'broken' so that the user can see them.
+  $form['filters'] = array('#tree' => TRUE);
+  foreach ($handlers as $id => $field) {
+    // If the group does not exist, move the filters to the default group.
+    if (empty($field['group']) || empty($groups['groups'][$field['group']])) {
+      $field['group'] = 0;
+    }
+
+    $handler = $display->handler->get_handler($type, $id);
+    if ($grouping && $handler && !$handler->can_group()) {
+      $field['group'] = 'ungroupable';
+    }
+
+    // If not grouping and the handler is set ungroupable, move it back to
+    // the default group to prevent weird errors from having it be in its
+    // own group:
+    if (!$grouping && $field['group'] == 'ungroupable') {
+      $field['group'] = 0;
+    }
+
+    // Place this item into the proper group for rendering.
+    $form['#group_renders'][$field['group']][] = $id;
+
+    $form['filters'][$id]['weight'] = array(
+      '#type' => 'textfield',
+      '#default_value' => ++$count,
+    );
+    $form['filters'][$id]['group'] = array(
+      '#type' => 'select',
+      '#options' => $group_options,
+      '#default_value' => $field['group'],
+      '#attributes' => array(
+        'class' => 'views-region-select views-region-' . $id,
+      ),
+      '#access' => $field['group'] !== 'ungroupable',
+    );
+
+    if ($handler) {
+      $name = $handler->ui_name() . ' ' . $handler->admin_summary();
+      if (!empty($field['relationship']) && !empty($relationships[$field['relationship']])) {
+        $name = '(' . $relationships[$field['relationship']] . ') ' . $name;
+      }
+
+      $form['filters'][$id]['name'] = array(
+        '#value' => $name,
+      );
+    }
+    else {
+      $form['filters'][$id]['name'] = array('#value' => t('Broken field @id', array('@id' => $id)));
+    }
+    $form['filters'][$id]['removed'] = array(
+      '#type' => 'checkbox',
+      '#id' => 'views-removed-' . $id,
+      '#attributes' => array('class' => 'views-remove-checkbox'),
+      '#default_value' => 0,
+    );
+  }
+
+  // Add javascript settings that will be added via $.extend for tabledragging
+  // Equivalent: drupal_add_tabledrag('arrange', 'order', 'sibling', 'weight');
+  $form['#js']['tableDrag']['arrange']['weight'][0] = array(
+    'target' => 'weight',
+    'source' => NULL,
+    'relationship' => 'sibling',
+    'action' => 'order',
+    'hidden' => TRUE,
+    'limit' => 0,
+  );
+
+  $form['#js']['tableDrag']['ungroupable_arrange']['weight'][0] = array(
+    'target' => 'weight',
+    'source' => NULL,
+    'relationship' => 'sibling',
+    'action' => 'order',
+    'hidden' => TRUE,
+    'limit' => 0,
+  );
+
+  foreach ($form['#group_renders'] as $group_id => $title) {
+    // Add javascript settings that will be added via $.extend for tabledragging
+    // Equivalent: drupal_add_tabledrag('arrange', 'match', 'sibling', 'views-group-select', 'views-group-' . $group_id);
+    $form['#js']['tableDrag']['arrange']['views-group-select'][] = array(
+      'target' => 'views-group-' . $group_id,
+      'source' => 'views-group-' . $group_id,
+      'relationship' => 'sibling',
+      'action' => 'match',
+      'hidden' => FALSE,
+      'limit' => 0,
+    );
+  }
+
+  if (isset($form_state['update_name'])) {
+    $name = $form_state['update_name'];
+  }
+
+  views_ui_standard_form_buttons($form, $form_state, 'views_ui_rearrange_filter_form');
+  $form['buttons']['add_group'] = array(
+    '#type' => 'submit',
+    '#value' => t('Add new group'),
+    '#id' => 'views-add-group',
+    '#group' => 'add',
+  );
+
+  return $form;
+}
+
+/**
+ * Turn the rearrange form into a proper table
+ */
+function theme_views_ui_rearrange_filter_form($form) {
+  $rows = $ungroupable_rows = array();
+  // Enable grouping only if > 1 group.
+  $grouping = count(array_keys($form['#group_options'])) > 1;
+
+  foreach ($form['#group_renders'] as $group_id => $contents) {
+    // Header row for the group.
+    if ($grouping && $group_id !== 'ungroupable') {
+      $row = array();
+      $row[] = array('class' => 'group group-title', 'data' => $form['#group_options'][$group_id]);
+      $row[] = array('class' => 'group container-inline', 'data' => drupal_render($form['filter_groups']['groups'][$group_id]), 'colspan' => 3);
+      $rows[] = array('class' => 'views-group', 'data' => $row, 'id' => 'views-group-' . $group_id);
+      // Row which will only appear if the group has nothing in it:
+      $row = array();
+      $class = 'group-' . (count($contents) ? 'populated' : 'empty');
+      $row[] = array('colspan' => 4, 'data' => '<span>' . t('This group is empty') . '</span> ' .
+      drupal_render($form['remove_groups'][$group_id]));
+      $rows[] = array('class' => "group-message group-$group_id-message " . $class, 'data' => $row, 'id' => 'views-group-' . $group_id);
+    }
+
+    foreach ($contents as $id) {
+      if (isset($form['filters'][$id]['name'])) {
+        $row = array();
+        $row[] = drupal_render($form['filters'][$id]['name']);
+        $form['filters'][$id]['weight']['#attributes']['class'] = 'weight';
+        $row[] = drupal_render($form['filters'][$id]['weight']);
+        $form['filters'][$id]['group']['#attributes']['class'] = 'views-group-select views-group-' . $group_id;
+        $row[] = drupal_render($form['filters'][$id]['group']);
+        $row[] = drupal_render($form['filters'][$id]['removed']) . l('<span>' . t('Remove') . '</span>', 'javascript:void()', array('attributes' => array('id' => 'views-remove-link-' . $id, 'class' => 'views-hidden views-button-remove views-groups-remove-link', 'alt' => t('Remove this item'), 'title' => t('Remove this item')), 'html' => true));
+
+        $row = array('data' => $row, 'class' => 'draggable', 'id' => 'views-row-' . $id);
+        if ($group_id !== 'ungroupable') {
+          $rows[] = $row;
+        }
+        else {
+          $ungroupable_rows[] = $row;
+        }
+      }
+    }
+  }
+  if (empty($rows)) {
+    $rows[] = array(array('data' => t('No fields available.'), 'colspan' => '2'));
+  }
+
+  $output = drupal_render($form['override']);
+  if ($grouping) {
+    $output .= drupal_render($form['filter_groups']['operator']);
+  }
+  else {
+    $form['filter_groups']['groups'][0]['#title'] = t('Operator');
+    $output .= drupal_render($form['filter_groups']['groups'][0]);
+  }
+
+  if (!empty($ungroupable_rows)) {
+    drupal_add_tabledrag('ungroupable_arrange', 'order', 'sibling', 'weight');
+    $header = array(t('Ungroupable filters'), t('Weight'), array('class' => 'views-hide-label', 'data' => t('Group')), array('class' => 'views-hide-label', 'data' => t('Remove')));
+    $output .= theme('table', $header, $ungroupable_rows, array('id' => 'ungroupable_arrange', 'class' => 'arrange'));
+  }
+
+  drupal_add_tabledrag('arrange', 'order', 'sibling', 'weight');
+  $header = array('', t('Weight'), t('Group'), t('Remove'));
+  $output .= theme('table', $header, $rows, array('id' => 'arrange', 'class' => 'arrange'));
+  $output .= drupal_render($form);
+  return $output;
+
+}
+
+/**
+ * Submit handler for rearranging form
+ */
+function views_ui_rearrange_filter_form_submit($form, &$form_state) {
+  $types = views_object_types();
+  $display = &$form_state['view']->display[$form_state['display_id']];
+  $remember_groups = array();
+
+  if (!empty($form_state['view']->form_cache)) {
+    $old_fields = $form_state['view']->form_cache['handlers'];
+  }
+  else {
+    $old_fields = $display->handler->get_option($types[$form_state['type']]['plural']);
+  }
+  $count = 0;
+
+  $groups = $form_state['values']['filter_groups'];
+  // Whatever button was clicked, re-calculate field information.
+  $new_fields = $order = array();
+
+  // Make an array with the weights
+  foreach ($form_state['values']['filters'] as $field => $info) {
+    // add each value that is a field with a weight to our list, but only if
+    // it has had its 'removed' checkbox checked.
+    if (is_array($info) && empty($info['removed'])) {
+      if (isset($info['weight'])) {
+        $order[$field] = $info['weight'];
+      }
+
+      if (isset($info['group'])) {
+        $old_fields[$field]['group'] = $info['group'];
+        $remember_groups[$info['group']][] = $field;
+      }
+    }
+  }
+
+  // Sort the array
+  asort($order);
+
+  // Create a new list of fields in the new order.
+  foreach (array_keys($order) as $field) {
+    $new_fields[$field] = $old_fields[$field];
+  }
+
+  // Save if the actual update button was clicked.
+  if (!empty($form_state['clicked_button']['#group'])) {
+    if ($form_state['clicked_button']['#group'] == 'add') {
+      // Add a new group
+      $groups['groups'][] = 'AND';
+    }
+    else {
+      // Renumber groups above the removed one down.
+      foreach (array_keys($groups['groups']) as $group_id) {
+        if ($group_id >= $form_state['clicked_button']['#group']) {
+          $old_group = $group_id + 1;
+          if (isset($groups['groups'][$old_group])) {
+            $groups['groups'][$group_id] = $groups['groups'][$old_group];
+            if (isset($remember_groups[$old_group])) {
+              foreach ($remember_groups[$old_group] as $id) {
+                $new_fields[$id]['group'] = $group_id;
+              }
+            }
+          }
+          else {
+            // If this is the last one, just unset it.
+            unset($groups['groups'][$group_id]);
+          }
+        }
+      }
+    }
+    // Update our cache with values so that cancel still works the way
+    // people expect.
+    $form_state['view']->form_cache = array(
+      'key' => 'rearrange-filter',
+      'groups' => $groups,
+      'handlers' => $new_fields,
+    );
+
+    // Return to this form except on actual Update.
+    views_ui_add_form_to_stack('rearrange-filter', $form_state['view'], $form_state['display_id'], array($form_state['type']));
+  }
+  else {
+    // Actually write changed handler values.
+    $display->handler->set_option($types[$form_state['type']]['plural'], $new_fields);
+    $display->handler->set_option('filter_groups', $groups);
+    if (isset($form_state['view']->form_cache)) {
+      unset($form_state['view']->form_cache);
+    }
+  }
+
+  // Store in cache
+  views_ui_cache_set($form_state['view']);
+}
+
+/**
+ * Form to add_item items in the views UI.
+ */
+function views_ui_add_item_form(&$form_state) {
+  $view = &$form_state['view'];
+  $display_id = $form_state['display_id'];
+  $type = $form_state['type'];
+
+  if (!$view->set_display($display_id)) {
+    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
+  }
+  $display = &$view->display[$display_id];
+
+  $types = views_object_types();
+
+  if (!empty($types[$type]['type'])) {
+    $type = $types[$type]['type'];
+  }
+
+  $form['#title'] = check_plain($display->display_title) . ': ';
+  $form['#title'] .= t('Add @type', array('@type' => $types[$type]['ltitle']));
+  $form['#section'] = $display_id . 'add-item';
+
+  // Figure out all the base tables allowed based upon what the relationships provide.
+  $base_tables = $view->get_base_tables();
+  $options = views_fetch_fields(array_keys($base_tables), $type, $display->handler->use_group_by());
+
+  if (!empty($options)) {
+    $groups = array('all' => t('<All>'));
+    $form['group'] = array(
+      '#type' => 'select',
+      '#title' => t('Groups'),
+      '#options' => array(),
+      '#attributes' => array('class' => 'views-master-dependent'),
+    );
+
+    $form['name'] = array(
+      '#prefix' => '<div class="views-radio-box form-checkboxes">',
+      '#suffix' => '</div>',
+      '#tree' => TRUE,
+      '#default_value' => 'all',
+    );
+
+    // Group options first to simplify the DOM objects that Views
+    // dependent JS will act upon.
+    $grouped_options = array();
+    foreach ($options as $key => $option) {
+      $group = preg_replace('/[^a-z0-9]/', '-', strtolower($option['group']));
+      $groups[$group] = $option['group'];
+      $grouped_options[$group][$key] = $option;
+    }
+
+    foreach ($grouped_options as $group => $group_options) {
+      $form['name'][$group . '_start'] = array('#type' => 'markup', '#value' => '<div class="views-dependent-all views-dependent-' . $group . '">');
+      foreach ($group_options as $key => $option) {
+        $form['name'][$key] = array(
+          '#type' => 'checkbox',
+          '#title' => t('!group: !field', array('!group' => $option['group'], '!field' => $option['title'])),
+          '#description' => $option['help'],
+          '#return_value' => $key,
+        );
+      }
+      $form['name'][$group . '_end'] = array('#type' => 'markup', '#value' => '</div>');
+    }
+
+    $form['group']['#options'] = $groups;
+  }
+  else {
+    $form['markup'] = array(
+      '#value' => '<div class="form-item">' . t('There are no @types available to add.', array('@types' =>  $types[$type]['ltitle'])) . '</div>',
+    );
+  }
+  views_ui_standard_form_buttons($form, $form_state, 'views_ui_add_item_form', t('Add'));
+
+  return $form;
+}
+
+/**
+ * Submit handler for adding new item(s) to a view.
+ */
+function views_ui_add_item_form_submit($form, &$form_state) {
+  $type = $form_state['type'];
+  $types = views_object_types();
+
+  if (!empty($form_state['values']['name']) && is_array($form_state['values']['name'])) {
+    // Loop through each of the items that were checked and add them to the view.
+    foreach (array_keys(array_filter($form_state['values']['name'])) as $field) {
+      list($table, $field) = explode('.', $field, 2);
+      $id = $form_state['view']->add_item($form_state['display_id'], $type, $table, $field);
+
+      // check to see if we have group by settings
+      if ($form_state['view']->display_handler->use_group_by()) {
+        views_ui_add_form_to_stack('config-item-group', $form_state['view'], $form_state['display_id'], array($type, $id));
+      }
+
+      // check to see if this type has settings, if so add the settings form first
+      $handler = views_get_handler($table, $field, $type);
+      if ($handler && $handler->has_extra_options()) {
+        views_ui_add_form_to_stack('config-item-extra', $form_state['view'], $form_state['display_id'], array($type, $id));
+      }
+      // Then add the form to the stack
+      views_ui_add_form_to_stack('config-item', $form_state['view'], $form_state['display_id'], array($type, $id));
+    }
+  }
+
+  if (isset($form_state['view']->form_cache)) {
+    unset($form_state['view']->form_cache);
+  }
+
+  // Store in cache
+  views_ui_cache_set($form_state['view']);
+}
+
+
+/**
+ * Form to config_item items in the views UI.
+ */
+function views_ui_config_item_form(&$form_state) {
+  $view = &$form_state['view'];
+  $display_id = $form_state['display_id'];
+  $type = $form_state['type'];
+  $id = $form_state['id'];
+
+  $form = array('options' => array('#tree' => TRUE));
+  if (!$view->set_display($display_id)) {
+    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
+  }
+  $item = $view->get_item($display_id, $type, $id);
+
+  if ($item) {
+    $handler = $view->display_handler->get_handler($type, $id);
+    if (empty($handler)) {
+      $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field'])));
+    }
+    else {
+      $types = views_object_types();
+
+      if ($view->display_handler->defaultable_sections($types[$type]['plural'])) {
+        $form_state['section'] = $types[$type]['plural'];
+        $view->display_handler->add_override_button($form['options'], $form_state, $form_state['section']);
+      }
+
+      // A whole bunch of code to figure out what relationships are valid for
+      // this item.
+      $relationships = $view->display_handler->get_option('relationships');
+      $relationship_options = array();
+
+      foreach ($relationships as $relationship) {
+        // relationships can't link back to self. But also, due to ordering,
+        // relationships can only link to prior relationships.
+        if ($type == 'relationship' && $id == $relationship['id']) {
+          break;
+        }
+        $relationship_handler = views_get_handler($relationship['table'], $relationship['field'], 'relationship');
+        // ignore invalid/broken relationships.
+        if (empty($relationship_handler)) {
+          continue;
+        }
+
+        // If this relationship is valid for this type, add it to the list.
+        $data = views_fetch_data($relationship['table']);
+        $base = $data[$relationship['field']]['relationship']['base'];
+        $base_fields = views_fetch_fields($base, $form_state['type'], $view->display_handler->use_group_by());
+        if (isset($base_fields[$item['table'] . '.' . $item['field']])) {
+          $relationship_handler->init($view, $relationship);
+          $relationship_options[$relationship['id']] = $relationship_handler->label();
+        }
+      }
+
+      if (!empty($relationship_options)) {
+        // Make sure the existing relationship is even valid. If not, force
+        // it to none.
+        $base_fields = views_fetch_fields($view->base_table, $form_state['type'], $view->display_handler->use_group_by());
+        if (isset($base_fields[$item['table'] . '.' . $item['field']])) {
+          $relationship_options = array_merge(array('none' => t('Do not use a relationship')), $relationship_options);
+        }
+        $rel = empty($item['relationship']) ? 'none' : $item['relationship'];
+        if (empty($relationship_options[$rel])) {
+          // Pick the first relationship.
+          $rel = key($relationship_options);
+          // We want this relationship option to get saved even if the user
+          // skips submitting the form.
+          $view->set_item_option($display_id, $type, $id, 'relationship', $rel);
+          $temp_view = $view->clone_view();
+          views_ui_cache_set($temp_view);
+        }
+
+        $form['options']['relationship'] = array(
+          '#type' => 'select',
+          '#title' => t('Relationship'),
+          '#options' => $relationship_options,
+          '#default_value' => $rel,
+        );
+      }
+      else {
+        $form['options']['relationship'] = array(
+          '#type' => 'value',
+          '#value' => 'none',
+        );
+      }
+
+      $form['#title'] = check_plain($view->display[$display_id]->display_title) . ': ';
+      $form['#title'] .= t('Configure @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->ui_name()));
+
+      $form['#section'] = $display_id . '-' . $type . '-' . $id;
+
+      // Get form from the handler.
+      $handler->options_form($form['options'], $form_state);
+      $form_state['handler'] = &$handler;
+    }
+
+    $name = NULL;
+    if (isset($form_state['update_name'])) {
+      $name = $form_state['update_name'];
+    }
+
+    views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_item_form', $name, t('Remove'), 'remove');
+  }
+  return $form;
+}
+
+/**
+ * Submit handler for configing new item(s) to a view.
+ */
+function views_ui_config_item_form_validate($form, &$form_state) {
+  $form_state['handler']->options_validate($form['options'], $form_state);
+}
+
+/**
+ * Submit handler for configing new item(s) to a view.
+ */
+function views_ui_config_item_form_submit($form, &$form_state) {
+  // Run it through the handler's submit function.
+  $form_state['handler']->options_submit($form['options'], $form_state);
+  $item = $form_state['handler']->options;
+  $types = views_object_types();
+
+  $type = $form_state['type'];
+  if (!empty($types[$type]['type'])) {
+    $type = $types[$type]['type'];
+  }
+
+  // Create a new handler and unpack the options from the form onto it. We
+  // can use that for storage.
+  $handler = views_get_handler($item['table'], $item['field'], $type);
+
+  // Add the incoming options to existing options because items using
+  // the extra form may not have everything in the form here.
+  $options = $form_state['values']['options'] + $form_state['handler']->options;
+
+  // This unpacks only options that are in the definition, ensuring random
+  // extra stuff on the form is not sent through.
+  $handler->unpack_options($handler->options, $options, NULL, FALSE);
+
+  // Store the item back on the view
+  $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $handler->options);
+
+  if ($form_state['handler'] && $form_state['handler']->needs_style_plugin()) {
+    views_ui_add_form_to_stack('change-style', $form_state['view'], $form_state['display_id'], array($form_state['type'], $form_state['id']), TRUE);
+  }
+
+  // Write to cache
+  views_ui_cache_set($form_state['view']);
+}
+
+/**
+ * Form to config_item items in the views UI.
+ */
+function views_ui_config_item_group_form(&$form_state) {
+  $view = &$form_state['view'];
+  $display_id = $form_state['display_id'];
+  $type = $form_state['type'];
+  $id = $form_state['id'];
+
+  $view->init_query();
+
+  $form = array('options' => array('#tree' => TRUE));
+  if (!$view->set_display($display_id)) {
+    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
+  }
+
+  $item = $view->get_item($display_id, $type, $id);
+
+  if ($item) {
+    $handler = $view->display_handler->get_handler($type, $id);
+    if (empty($handler)) {
+      $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field'])));
+    }
+    else {
+      $handler->init($view, $item);
+      $types = views_object_types();
+
+      $form['#title'] = check_plain($view->display[$display_id]->display_title) . ': ';
+      $form['#title'] .= t('Configure group settings for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->ui_name()));
+
+      $form['#section'] = $display_id . '-' . $type . '-' . $id;
+
+      $info = $view->query->get_aggregation_info();
+      foreach ($info as $id => $aggregate) {
+        $group_types[$id] = $aggregate['title'];
+      }
+
+      $form['group_type'] = array(
+        '#type' => 'select',
+        '#title' => t('Group type'),
+        '#default_value' => $handler->options['group_type'],
+        '#description' => t('Grouping is enabled for this display. You must select what function to use on this field.'),
+        '#options' => $group_types,
+      );
+      $form_state['handler'] = &$handler;
+    }
+
+    views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_item_group_form');
+  }
+  return $form;
+}
+
+/**
+ * Submit handler for configing group settings on a view.
+ */
+function views_ui_config_item_group_form_submit($form, &$form_state) {
+  $item = $form_state['handler']->options;
+
+  $item['group_type'] = $form_state['values']['group_type'];
+
+  // Store the item back on the view
+  $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
+
+  // Write to cache
+  views_ui_cache_set($form_state['view']);
+}
+
+/**
+ * Submit handler for removing an item from a view
+ */
+function views_ui_config_item_form_remove($form, &$form_state) {
+  // Store the item back on the view
+  $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], NULL);
+
+  // Write to cache
+  views_ui_cache_set($form_state['view']);
+}
+
+/**
+ * Override handler for views_ui_edit_display_form
+ */
+function views_ui_config_item_form_expose($form, &$form_state) {
+  $item = &$form_state['handler']->options;
+  // flip
+  $item['exposed'] = empty($item['exposed']);
+
+  // If necessary, set new defaults:
+  if ($item['exposed']) {
+    $form_state['handler']->expose_options();
+  }
+
+  $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
+
+  views_ui_cache_set($form_state['view']);
+  $form_state['rerender'] = TRUE;
+  $form_state['rebuild'] = TRUE;
+  $form_state['force_expose_options'] = TRUE;
+}
+
+/**
+ * Form to config_item items in the views UI.
+ */
+function views_ui_config_item_extra_form(&$form_state) {
+  $view = &$form_state['view'];
+  $display_id = $form_state['display_id'];
+  $type = $form_state['type'];
+  $id = $form_state['id'];
+
+  $form = array('options' => array('#tree' => TRUE));
+  if (!$view->set_display($display_id)) {
+    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
+  }
+  $item = $view->get_item($display_id, $type, $id);
+
+  if ($item) {
+    $handler = views_get_handler($item['table'], $item['field'], $type);
+    if (empty($handler)) {
+      $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field'])));
+      break;
+    }
+    else {
+      $handler->init($view, $item);
+      $types = views_object_types();
+
+      $form['#title'] = check_plain($view->display[$display_id]->display_title) . ': ';
+      $form['#title'] .= t('Configure extra settings for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->ui_name()));
+
+      $form['#section'] = $display_id . '-' . $type . '-' . $id;
+
+      // Get form from the handler.
+      $handler->extra_options_form($form['options'], $form_state);
+      $form_state['handler'] = &$handler;
+    }
+
+    views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_item_extra_form');
+  }
+  return $form;
+}
+
+/**
+ * Submit handler for configing new item(s) to a view.
+ */
+function views_ui_config_item_extra_form_validate($form, &$form_state) {
+  $form_state['handler']->extra_options_validate($form['options'], $form_state);
+}
+
+/**
+ * Submit handler for configing new item(s) to a view.
+ */
+function views_ui_config_item_extra_form_submit($form, &$form_state) {
+  // Run it through the handler's submit function.
+  $form_state['handler']->extra_options_submit($form['options'], $form_state);
+  $item = $form_state['handler']->options;
+
+  // Store the data we're given.
+  foreach ($form_state['values']['options'] as $key => $value) {
+    $item[$key] = $value;
+  }
+
+  // Store the item back on the view
+  $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
+
+  // Write to cache
+  views_ui_cache_set($form_state['view']);
+}
+
+/**
+ * Form to change_style items in the views UI.
+ */
+function views_ui_change_style_form(&$form_state) {
+  $view = &$form_state['view'];
+  $display_id = $form_state['display_id'];
+  $type = $form_state['type'];
+  $id = $form_state['id'];
+
+  $form = array('options' => array('#tree' => TRUE));
+  if (!$view->set_display($display_id)) {
+    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
+  }
+  $item = $view->get_item($display_id, $type, $id);
+
+  if ($item) {
+    $handler = views_get_handler($item['table'], $item['field'], $type);
+    if (empty($handler)) {
+      $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field'])));
+      break;
+    }
+    $handler->init($view, $item);
+    $types = views_object_types();
+    $form['#title'] = t('Change summary style for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->ui_name()));
+
+    $form['#section'] = $display_id . '-' . $type . '-' . $id . '-style-plugin';
+
+    $form['style_plugin'] =  array(
+      '#type' => 'radios',
+      '#options' => views_fetch_plugin_names('style', 'summary'),
+      '#default_value' => $item['style_plugin'],
+    );
+
+    $form_state['handler'] = &$handler;
+
+    views_ui_standard_form_buttons($form, $form_state, 'views_ui_change_style_form');
+  }
+  return $form;
+}
+
+function views_ui_change_style_form_validate($form, &$form_state) {
+  // Run it through the handler's submit function.
+  $form_state['handler']->options_validate($form['options'], $form_state);
+
+  $plugin = views_get_plugin('style', $form_state['values']['style_plugin']);
+  if (!$plugin) {
+    form_error($form['style_plugin'], t('Internal error: broken plugin.'));
+  }
+}
+
+/**
+ * Submit handler for configing new item(s) to a view.
+ */
+function views_ui_change_style_form_submit($form, &$form_state) {
+  // Run it through the handler's submit function.
+  $form_state['handler']->options_submit($form['options'], $form_state);
+  $item = $form_state['handler']->options;
+
+  $plugin = views_get_plugin('style', $form_state['values']['style_plugin']);
+  if (!$plugin) {
+    drupal_set_message(t('Internal error: broken plugin.'), 'error');
+    return;
+  }
+
+  $plugin->init($form_state['view'], $form_state['view']->display[$form_state['display_id']]);
+
+  // If changing style plugin, reset options to defaults.
+  if (empty($item['style_plugin']) || $item['style_plugin'] != $form_state['values']['style_plugin']) {
+    $item['style_options'] = $plugin->options;
+  }
+
+  // Store the data we're given.
+  $item['style_plugin'] = $form_state['values']['style_plugin'];
+
+  // Store the item back on the view
+  $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
+
+  if (!empty($plugin->definition['uses options'])) {
+    views_ui_add_form_to_stack('config-style', $form_state['view'], $form_state['display_id'], array($form_state['type'], $form_state['id']), TRUE);
+  }
+
+  // Write to cache
+  views_ui_cache_set($form_state['view']);
+}
+
+/**
+ * Form to config_style items in the views UI.
+ */
+function views_ui_config_style_form(&$form_state) {
+  $view = &$form_state['view'];
+  $display_id = $form_state['display_id'];
+  $type = $form_state['type'];
+  $id = $form_state['id'];
+
+  $form = array('options' => array('#tree' => TRUE));
+  if (!$view->set_display($display_id)) {
+    views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
+  }
+  $item = $view->get_item($display_id, $type, $id);
+
+  if ($item) {
+    $handler = views_get_handler($item['table'], $item['field'], $type);
+    if (empty($handler)) {
+      $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field'])));
+      break;
+    }
+    $handler->init($view, $item);
+    $types = views_object_types();
+
+    $form['#title'] = check_plain($view->display[$display_id]->display_title) . ': ';
+    $form['#title'] .= t('Configure summary style for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->ui_name()));
+
+    $form['#section'] = $display_id . '-' . $type . '-style-options';
+
+    $plugin = views_get_plugin('style', $handler->options['style_plugin']);
+    if ($plugin) {
+      $form['style_options'] = array(
+        '#tree' => TRUE,
+      );
+      $plugin->init($view, $view->display[$display_id], $handler->options['style_options']);
+
+      $plugin->options_form($form['style_options'], $form_state);
+    }
+
+    $form_state['handler'] = &$handler;
+
+    views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_style_form');
+  }
+  return $form;
+}
+
+/**
+ * Submit handler for configing new item(s) to a view.
+ */
+function views_ui_config_style_form_submit($form, &$form_state) {
+  // Run it through the handler's submit function.
+  $form_state['handler']->options_submit($form['style_options'], $form_state);
+  $item = $form_state['handler']->options;
+
+  // Store the data we're given.
+  $item['style_options'] = $form_state['values']['style_options'];
+
+  // Store the item back on the view
+  $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item);
+
+  // Write to cache
+  views_ui_cache_set($form_state['view']);
+}
+
+/**
+ * Get a list of roles in the system.
+ */
+function views_ui_get_roles() {
+  static $roles = NULL;
+  if (!isset($roles)) {
+    $roles = array();
+    $result = db_query("SELECT r.rid, r.name FROM {role} r ORDER BY r.name");
+    while ($obj = db_fetch_object($result)) {
+      $roles[$obj->rid] = $obj->name;
+    }
+  }
+
+  return $roles;
+}
+
+/**
+ * Get a css safe id for a particular section.
+ */
+function views_ui_item_css($item) {
+  return views_css_safe('views-item-' . $item);
+}
+
+/**
+ * Page callback for the Views enable page.
+ */
+function views_ui_enable_page($view) {
+  if (isset($_GET['token']) && drupal_valid_token($_GET['token'], 'views-enable')) {
+    $views_status = variable_get('views_defaults', array());
+    $views_status[$view->name] = FALSE; // false is enabled
+    variable_set('views_defaults', $views_status);
+    views_invalidate_cache();
+    menu_rebuild();
+    drupal_goto('admin/build/views');
+  }
+  else {
+    return drupal_access_denied();
+  }
+}
+
+/**
+ * Page callback for the Views enable page
+ */
+function views_ui_disable_page($view) {
+  if (isset($_GET['token']) && drupal_valid_token($_GET['token'], 'views-disable')) {
+    $views_status = variable_get('views_defaults', array());
+    $views_status[$view->name] = TRUE; // True is disabled
+    variable_set('views_defaults', $views_status);
+    views_invalidate_cache();
+    menu_rebuild();
+    drupal_goto('admin/build/views');
+  }
+  else {
+    return drupal_access_denied();
+  }
+}
+
+/**
+ * Page callback for the tools - other page
+ */
+function views_ui_admin_tools() {
+  $form['clear_cache'] = array(
+    '#type' => 'submit',
+    '#value' => t("Clear Views' cache"),
+    '#submit' => array('views_ui_tools_clear_cache'),
+  );
+
+  $form['views_sql_signature'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Add Views signature to all SQL queries'),
+    '#description' => t("All Views-generated queries will include a special 'VIEWS' = 'VIEWS' string in the WHERE clause. This makes identifying Views queries in database server logs simpler, but should only be used when troubleshooting."),
+    '#default_value' => variable_get('views_sql_signature', FALSE),
+  );
+
+  $form['views_skip_cache'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Disable views data caching'),
+    '#description' => t("Views caches data about tables, modules and views available, to increase performance. By checking this box, Views will skip this cache and always rebuild this data when needed. This can have a serious performance impact on your site."),
+    '#default_value' => variable_get('views_skip_cache', FALSE),
+  );
+
+  $form['views_hide_help_message'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Ignore missing advanced help module'),
+    '#description' => t("Views uses the advanced help module to provide help text; if this module is not present Views will complain, unless this setting is checked."),
+    '#default_value' => variable_get('views_hide_help_message', FALSE),
+  );
+
+  $form['views_ui_query_on_top'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show query above live preview'),
+    '#description' => t("The live preview feature will show you the output of the view you're creating, as well as the view. Check here to show the query and other information above the view; leave this unchecked to show that information below the view."),
+    '#default_value' => variable_get('views_ui_query_on_top', FALSE),
+  );
+
+  $form['views_ui_disable_live_preview'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Disable automatic live preview'),
+    '#description' => t("Don't automatically update the preview. This can speed up the editing of views a bit.'"),
+    '#default_value' => variable_get('views_ui_disable_live_preview', 0),
+  );
+
+  $form['views_show_additional_queries'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show other queries run during render during live preview'),
+    '#description' => t("Drupal has the potential to run many queries while a view is being rendered. Checking this box will display every query run during view render as part of the live preview."),
+    '#default_value' => variable_get('views_show_additional_queries', FALSE),
+  );
+
+  $form['views_no_hover_links'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Do not show hover links over views'),
+    '#description' => t("To make it easier to administrate your views, Views provides 'hover' links to take you to the edit and export screen of a view whenever the view is used. This can be distracting on some themes, though; if it is problematic, you can turn it off here."),
+    '#default_value' => variable_get('views_no_hover_links', FALSE),
+  );
+
+  $form['views_devel_output'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable views performance statistics via the Devel module'),
+    '#description' => t("Check this to enable some Views query and performance statistics <em>if Devel is installed</em>."),
+    '#default_value' => variable_get('views_devel_output', FALSE),
+  );
+
+  $form['views_no_javascript'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Disable javascript with Views'),
+    '#description' => t("If you are having problems with the javascript, you can disable it here; the Views UI should degrade and still be usable without javascript, it just not as good."),
+    '#default_value' => variable_get('views_no_javascript', FALSE),
+  );
+
+  $regions = system_region_list(variable_get('theme_default', 'garland'));
+  $regions['watchdog'] = t('Watchdog');
+
+  $form['views_devel_region'] = array(
+    '#type' => 'select',
+    '#title' => t('Page region to output performance statistics'),
+    '#default_value' => variable_get('views_devel_region', 'footer'),
+    '#options' => $regions,
+  );
+
+  $form['views_exposed_filter_any_label'] = array(
+    '#type' => 'select',
+    '#title' => t('Label for "Any" value on optional single-select exposed filters'),
+    '#options' => array('old_any' => '<Any>', 'new_any' => t('- Any -')),
+    '#default_value' => variable_get('views_exposed_filter_any_label', 'old_any'),
+  );
+
+  return system_settings_form($form);
+}
+
+/**
+ * Submit hook to clear the views cache.
+ */
+function views_ui_tools_clear_cache() {
+  views_invalidate_cache();
+  drupal_set_message(t('The cache has been cleared.'));
+}
+
+/**
+ * Submit hook to clear Drupal's theme registry (thereby triggering
+ * a templates rescan).
+ */
+function views_ui_config_item_form_rescan($form, &$form_state) {
+  drupal_rebuild_theme_registry();
+
+  // The 'Theme: Information' page is about to be shown again. That page
+  // analyzes the output of theme_get_registry(). However, this latter
+  // function uses an internal cache (which was initialized before we
+  // called drupal_rebuild_theme_registry()) so it won't reflect the
+  // current state of our theme registry. The only way to clear that cache
+  // is to re-initialize the theme system:
+  unset($GLOBALS['theme']);
+  init_theme();
+
+  $form_state['rerender'] = TRUE;
+  $form_state['rebuild'] = TRUE;
+}
+
+/**
+ * Override handler for views_ui_edit_display_form
+ */
+function views_ui_edit_display_form_change_theme($form, &$form_state) {
+  // This is just a temporary variable.
+  $form_state['view']->theme = $form_state['values']['theme'];
+
+  views_ui_cache_set($form_state['view']);
+  $form_state['rerender'] = TRUE;
+  $form_state['rebuild'] = TRUE;
+}
+
+/**
+ * Page callback for views tag autocomplete
+ */
+function views_ui_autocomplete_tag($string = '') {
+  $matches = array();
+  // get matches from default views:
+  views_include('view');
+  $views = views_discover_default_views();
+  foreach ($views as $view) {
+    if (!empty($view->tag) && strpos($view->tag, $string) === 0) {
+      $matches[$view->tag] = $view->tag;
+    }
+  }
+
+  if ($string) {
+    $result = db_query_range("SELECT DISTINCT tag FROM {views_view} WHERE LOWER(tag) LIKE LOWER('%s%%')", $string, 0, 10 - count($matches));
+    while ($view = db_fetch_object($result)) {
+      $matches[$view->tag] = check_plain($view->tag);
+    }
+  }
+
+  drupal_json($matches);
+}
+
+// ------------------------------------------------------------------
+// Get information from the Views data
+
+function _views_weight_sort($a, $b) {
+  if ($a['weight'] != $b['weight']) {
+    return $a['weight'] < $b['weight'] ? -1 : 1;
+  }
+  if ($a['title'] != $b['title']) {
+    return $a['title'] < $b['title'] ? -1 : 1;
+  }
+
+  return 0;
+}
+
+/**
+ * Fetch a list of all base tables available
+ *
+ * @return
+ *   A keyed array of in the form of 'base_table' => 'Description'.
+ */
+function views_fetch_base_tables() {
+  static $base_tables = array();
+  if (empty($base_tables)) {
+    $weights = array();
+    $tables = array();
+    $data = views_fetch_data();
+    foreach ($data as $table => $info) {
+      if (!empty($info['table']['base'])) {
+        $tables[$table] = array(
+          'title' => $info['table']['base']['title'],
+          'description' => $info['table']['base']['help'],
+          'weight' => !empty($info['table']['base']['weight']) ? $info['table']['base']['weight'] : 0,
+        );
+      }
+    }
+    uasort($tables, '_views_weight_sort');
+    $base_tables = $tables;
+  }
+
+  return $base_tables;
+}
+
+function _views_sort_types($a, $b) {
+  if ($a['group'] != $b['group']) {
+    return $a['group'] < $b['group'] ? -1 : 1;
+  }
+
+  if ($a['title'] != $b['title']) {
+    return $a['title'] < $b['title'] ? -1 : 1;
+  }
+
+  return 0;
+}
+
+/**
+ * Fetch a list of all fields available for a given base type.
+ *
+ * @return
+ *   A keyed array of in the form of 'base_table' => 'Description'.
+ */
+function views_fetch_fields($base, $type, $grouping = FALSE) {
+  static $fields = array();
+  if (empty($fields)) {
+    $data = views_fetch_data();
+    $start = views_microtime();
+    // This constructs this ginormous multi dimensional array to
+    // collect the important data about fields. In the end,
+    // the structure looks a bit like this (using nid as an example)
+    // $strings['nid']['filter']['title'] = 'string'.
+    //
+    // This is constructed this way because the above referenced strings
+    // can appear in different places in the actual data structure so that
+    // the data doesn't have to be repeated a lot. This essentially lets
+    // each field have a cheap kind of inheritance.
+
+    foreach ($data as $table => $table_data) {
+      $bases = array();
+      $strings = array();
+      $skip_bases = array();
+      foreach ($table_data as $field => $info) {
+        // Collect table data from this table
+        if ($field == 'table') {
+          // calculate what tables this table can join to.
+          if (!empty($info['join'])) {
+            $bases = array_keys($info['join']);
+          }
+          // And it obviously joins to itself.
+          $bases[] = $table;
+          continue;
+        }
+        foreach (array('field', 'sort', 'filter', 'argument', 'relationship', 'area') as $key) {
+          if (!empty($info[$key])) {
+            if ($grouping && !empty($info[$key]['no group by'])) {
+              continue;
+            }
+            if (!empty($info[$key]['skip base'])) {
+              foreach ((array) $info[$key]['skip base'] as $base_name) {
+                $skip_bases[$field][$key][$base_name] = TRUE;
+              }
+            }
+            elseif (!empty($info['skip base'])) {
+              foreach ((array) $info['skip base'] as $base_name) {
+                $skip_bases[$field][$key][$base_name] = TRUE;
+              }
+            }
+            foreach (array('title', 'group', 'help', 'base') as $string) {
+              // First, try the lowest possible level
+              if (!empty($info[$key][$string])) {
+                $strings[$field][$key][$string] = $info[$key][$string];
+              }
+              // Then try the field level
+              elseif (!empty($info[$string])) {
+                $strings[$field][$key][$string] = $info[$string];
+              }
+              // Finally, try the table level
+              elseif (!empty($table_data['table'][$string])) {
+                $strings[$field][$key][$string] = $table_data['table'][$string];
+              }
+              else {
+                if ($string != 'base') {
+                  $strings[$field][$key][$string] = t("Error: missing @component", array('@component' => $string));
+                }
+              }
+            }
+          }
+        }
+      }
+      foreach ($bases as $base_name) {
+        foreach ($strings as $field => $field_strings) {
+          foreach ($field_strings as $type_name => $type_strings) {
+            if (empty($skip_bases[$field][$type_name][$base_name])) {
+              $fields[$base_name][$type_name]["$table.$field"] = $type_strings;
+            }
+          }
+        }
+      }
+    }
+//    vsm('Views UI data build time: ' . (views_microtime() - $start) * 1000 . ' ms');
+  }
+
+  // If we have an array of base tables available, go through them
+  // all and add them together. Duplicate keys will be lost and that's
+  // Just Fine.
+  if (is_array($base)) {
+    $strings = array();
+    foreach ($base as $base_table) {
+      if (isset($fields[$base_table][$type])) {
+        $strings += $fields[$base_table][$type];
+      }
+    }
+    uasort($strings, '_views_sort_types');
+    return $strings;
+  }
+
+  if (isset($fields[$base][$type])) {
+    uasort($fields[$base][$type], '_views_sort_types');
+    return $fields[$base][$type];
+  }
+  return array();
+}
+
+/**
+ * Fetch a list of all base tables available
+ *
+ * @param $type
+ *   Either 'display', 'style' or 'row'
+ * @param $key
+ *   For style plugins, this is an optional type to restrict to. May be 'normal',
+ *   'summary', 'feed' or others based on the neds of the display.
+ * @param $base
+ *   An array of possible base tables.
+ *
+ * @return
+ *   A keyed array of in the form of 'base_table' => 'Description'.
+ */
+function views_fetch_plugin_names($type, $key = NULL, $base = array()) {
+  $data = views_fetch_plugin_data();
+
+  $plugins[$type] = array();
+
+  foreach ($data[$type] as $id => $plugin) {
+    // Skip plugins that don't conform to our key.
+    if ($key && (empty($plugin['type']) || $plugin['type'] != $key)) {
+      continue;
+    }
+    if (empty($plugin['no ui']) && (empty($base) || empty($plugin['base']) || array_intersect($base, $plugin['base']))) {
+      $plugins[$type][$id] = $plugin['title'];
+    }
+  }
+
+  if (!empty($plugins[$type])) {
+    asort($plugins[$type]);
+    return $plugins[$type];
+  }
+  // fall-through
+  return array();
+}
+
+
+/**
+ * Theme the form for the table style plugin
+ */
+function theme_views_ui_style_plugin_table($form) {
+  $output = drupal_render($form['description_markup']);
+
+  $header = array(
+    t('Field'),
+    t('Column'),
+    t('Align'),
+    t('Separator'),
+    array(
+      'data' => t('Sortable'),
+      'align' => 'center',
+    ),
+    array(
+      'data' => t('Default sort'),
+      'align' => 'center',
+    ),
+  );
+  $rows = array();
+  foreach (element_children($form['columns']) as $id) {
+    $row = array();
+    $row[] = drupal_render($form['info'][$id]['name']);
+    $row[] = drupal_render($form['columns'][$id]);
+    $row[] = drupal_render($form['info'][$id]['align']);
+    $row[] = drupal_render($form['info'][$id]['separator']);
+    if (!empty($form['info'][$id]['sortable'])) {
+      $row[] = array(
+        'data' => drupal_render($form['info'][$id]['sortable']),
+        'align' => 'center',
+      );
+      $row[] = array(
+        'data' => drupal_render($form['default'][$id]),
+        'align' => 'center',
+      );
+    }
+    else {
+      $row[] = '';
+      $row[] = '';
+    }
+    $rows[] = $row;
+  }
+
+  // Add the special 'None' row.
+  $rows[] = array(t('None'), '', '', '', array('align' => 'center', 'data' => drupal_render($form['default'][-1])));
+
+  $output .= theme('table', $header, $rows);
+  $output .= drupal_render($form);
+  return $output;
+}
+
Index: includes/ajax.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/ajax.inc,v
retrieving revision 1.20
diff -u -p -r1.20 ajax.inc
--- includes/ajax.inc	1 Jun 2009 23:12:22 -0000	1.20
+++ includes/ajax.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: ajax.inc,v 1.20 2009/06/01 23:12:22 merlinofchaos Exp $
+// $Id: ajax.inc,v 1.19.2.3 2010/04/07 23:40:32 merlinofchaos Exp $
 
 /**
  * @file ajax.inc
@@ -19,8 +19,17 @@ function views_ajax() {
     $display_id = $_REQUEST['view_display_id'];
     $args = isset($_REQUEST['view_args']) && $_REQUEST['view_args'] !== '' ? explode('/', $_REQUEST['view_args']) : array();
     $path = isset($_REQUEST['view_path']) ? $_REQUEST['view_path'] : NULL;
-    $dom_id = isset($_REQUEST['view_dom_id']) ? $_REQUEST['view_dom_id'] : NULL;
-    $pager_element = isset($_REQUEST['pager_element']) ? $_REQUEST['pager_element'] : NULL;
+    $dom_id = isset($_REQUEST['view_dom_id']) ? intval($_REQUEST['view_dom_id']) : NULL;
+    $pager_element = isset($_REQUEST['pager_element']) ? intval($_REQUEST['pager_element']) : NULL;
+
+    $ajax_arguments = array(
+      'view_name' => $name,
+      'view_display_id' => $display_id,
+      'view_args' => $_REQUEST['view_args'],
+      'view_path' => $path,
+      'view_dom_id' => $dom_id,
+      'pager_element' => $pager_element,
+    );
     views_include('ajax');
     $object = new stdClass();
 
@@ -28,7 +37,7 @@ function views_ajax() {
     $object->display = '';
 
     $arg = explode('/', $_REQUEST['view_path']);
-    
+
     if ($arg[0] == 'admin' || (variable_get('node_admin_theme', '0') && $arg[0] == 'node' && ($arg[1] == 'add' || $arg[2] == 'edit'))) {
         global $custom_theme;
         $custom_theme = variable_get('admin_theme', '0');
@@ -36,6 +45,7 @@ function views_ajax() {
     }
     // Load the view.
     if ($view = views_get_view($name)) {
+      $view->ajax_path = array($_GET['q'], $ajax_arguments);
       if ($view->access($display_id)) {
 
         // Fix 'q' for paging.
Index: includes/base.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/base.inc,v
retrieving revision 1.2
diff -u -p -r1.2 base.inc
--- includes/base.inc	6 Jun 2008 19:29:03 -0000	1.2
+++ includes/base.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: base.inc,v 1.2 2008/06/06 19:29:03 merlinofchaos Exp $
+// $Id: base.inc,v 1.2.2.6 2010/07/27 22:03:10 merlinofchaos Exp $
 /**
  * @file
  *
@@ -76,27 +76,39 @@ class views_object {
    * Unpack options over our existing defaults, drilling down into arrays
    * so that defaults don't get totally blown away.
    */
-  function unpack_options(&$storage, $options, $definition = NULL) {
-    if (!is_array($options)) {
+  function unpack_options(&$storage, $options, $definition = NULL, $all = TRUE, $check = TRUE) {
+    if ($check && !is_array($options)) {
       return;
     }
 
     if (!isset($definition)) {
       $definition = $this->option_definition();
     }
-
     foreach ($options as $key => $value) {
       if (is_array($value)) {
+        // Ignore arrays with no definition.
+        if (!$all && empty($definition[$key])) {
+          continue;
+        }
+
         if (!isset($storage[$key]) || !is_array($storage[$key])) {
           $storage[$key] = array();
         }
 
-        $this->unpack_options($storage[$key], $value, isset($definition[$key]) ? $definition[$key] : array());
+        // If we're just unpacking our known options, and we're dropping an
+        // unknown array (as might happen for a dependent plugin fields) go
+        // ahead and drop that in.
+        if (!$all && isset($definition[$key]) && !isset($definition[$key]['contains'])) {
+          $storage[$key] = $value;
+          continue;
+        }
+
+        $this->unpack_options($storage[$key], $value, isset($definition[$key]['contains']) ? $definition[$key]['contains'] : array(), $all, FALSE);
       }
       else if (!empty($definition[$key]['translatable']) && !empty($value)) {
         $storage[$key] = t($value);
       }
-      else {
+      else if ($all || !empty($definition[$key])) {
         $storage[$key] = $value;
       }
     }
@@ -125,4 +137,63 @@ class views_object {
       unset($this->query);
     }
   }
+
+  function export_options($indent, $prefix) {
+    $output = '';
+    foreach ($this->option_definition() as $option => $definition) {
+      $output .= $this->export_option($indent, $prefix, $this->options, $option, $definition, array());
+    }
+
+    return $output;
+  }
+
+  function export_option($indent, $prefix, $storage, $option, $definition, $parents) {
+    // Do not export options for which we have no settings.
+    if (!isset($storage[$option])) {
+      return;
+    }
+
+    if (isset($definition['export'])) {
+      if ($definition['export'] === FALSE) {
+        return;
+      }
+
+      // Special handling for some items
+      if (method_exists($this, $definition['export'])) {
+        return $this->{$definition['export']}($indent, $prefix, $storage, $option, $definition, $parents);
+      }
+    }
+
+    // Add the current option to the parents tree.
+    $parents[] = $option;
+    $output = '';
+
+    // If it has child items, export those separately.
+    if (isset($definition['contains'])) {
+      foreach ($definition['contains'] as $sub_option => $sub_definition) {
+        $output .= $this->export_option($indent, $prefix, $storage[$option], $sub_option, $sub_definition, $parents);
+      }
+    }
+    // Otherwise export just this item.
+    else {
+      $default = isset($definition['default']) ? $definition['default'] : NULL;
+      $value = $storage[$option];
+      if (isset($definition['bool'])) {
+        $value = (bool) $value;
+      }
+
+      if ($value !== $default) {
+        $output .= $indent . $prefix . "['" . implode("']['", $parents) . "'] = ";
+        if (isset($definition['bool'])) {
+          $output .= empty($storage[$option]) ? 'FALSE' : 'TRUE';
+        }
+        else {
+          $output .= views_var_export($storage[$option], $indent);
+        }
+
+        $output .= ";\n";
+      }
+    }
+    return $output;
+  }
 }
Index: includes/cache.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/cache.inc,v
retrieving revision 1.25
diff -u -p -r1.25 cache.inc
--- includes/cache.inc	1 Jun 2009 23:33:37 -0000	1.25
+++ includes/cache.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: cache.inc,v 1.25 2009/06/01 23:33:37 merlinofchaos Exp $
+// $Id: cache.inc,v 1.24.2.5 2010/03/12 01:51:42 merlinofchaos Exp $
 /**
  * @file cache.inc
  *
@@ -96,33 +96,57 @@ function _views_fetch_plugin_data($type 
  *
  * @return An associative array of all known default views.
  */
-function _views_discover_default_views() {
+function _views_discover_default_views($reset = FALSE) {
   static $cache = NULL;
 
-  if (!isset($cache)) {
-    $data = views_cache_get('views_default_views', TRUE);
+  if (!isset($cache) || $reset) {
+    $index = views_cache_get('views_default_views_index', TRUE);
 
-    if (isset($data->data) && is_array($data->data)) {
-      $cache = $data->data;
+    // Retrieve each cached default view
+    if (!$reset && isset($index->data) && is_array($index->data)) {
+      $cache = array();
+      foreach ($index->data as $view_name) {
+        $data = views_cache_get('views_default:' . $view_name, TRUE);
+        if (isset($data->data) && is_object($data->data)) {
+          $cache[$view_name] = $data->data;
+        }
+      }
     }
+    // If missing index, rebuild the cache
     else {
       views_include_default_views();
-      $defaults = module_invoke_all('views_default_views');
       $cache = array();
 
-      foreach ($defaults as $name => $view) {
-        // Only views with a sufficiently high api version are eligible.
-        if (isset($view->api_version) && $view->api_version >= 2) {
-          // Do not cache dead handlers.
-          $view->destroy();
-          $cache[$name] = $view;
+      foreach (module_implements('views_default_views') as $module) {
+        $results = call_user_func($module . "_views_default_views");
+        if (!empty($results) && is_array($results)) {
+          foreach($results as $name => $view) {
+            // Only views with a sufficiently high api version are eligible.
+            if (!empty($view->api_version) && $view->api_version >= 2) {
+              // Do not cache dead handlers.
+              $view->destroy();
+              if (!isset($cache[$name])) {
+                $cache[$name] = $view;
+              }
+              else {
+                watchdog('view', "View name '@name' is already taken", array('@name' => $name), WATCHDOG_ERROR);
+              }
+            }
+          }
         }
       }
 
       // Allow modules to modify default views before they are cached.
       drupal_alter('views_default_views', $cache);
 
-      views_cache_set('views_default_views', $cache, TRUE);
+      // Cache the index
+      $index = array_keys($cache);
+      views_cache_set('views_default_views_index', $index, TRUE);
+
+      // Cache each view
+      foreach ($cache as $name => $view) {
+        views_cache_set('views_default:' . $name, $view, TRUE);
+      }
     }
   }
 
Index: includes/convert.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/convert.inc,v
retrieving revision 1.15
diff -u -p -r1.15 convert.inc
--- includes/convert.inc	2 Jun 2009 20:31:00 -0000	1.15
+++ includes/convert.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: convert.inc,v 1.15 2009/06/02 20:31:00 merlinofchaos Exp $
+// $Id: convert.inc,v 1.14.2.3 2009/09/25 17:05:56 merlinofchaos Exp $
 /**
  * @file convert.inc
  *
@@ -67,10 +67,60 @@ function views_ui_admin_convert() {
   }
   $output = t('The table below lists Views version 1 views that are stored in the database. You can either convert them to work in Views version 2, or delete them. The views are convertible only if there is no Views 2 view with the same name.');
   $output .= theme('table', $header, $i);
+
+  $output .= drupal_get_form('views_ui_convert_cleanup_form');
   return $output;
 }
 
 /**
+ * Provide form to clean up Views 1 tables.
+ */
+function views_ui_convert_cleanup_form() {
+  $form['verify'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Remove all Views 1 tables'),
+    '#description' => t('Check this box and then click clean up to drop all Views 1 tables. Warning: this operation will not be reversible! Do this only if you are sure you no longer need this data.'),
+    '#required' => TRUE,
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Clean up'),
+  );
+
+  return $form;
+}
+
+function views_ui_convert_cleanup_form_submit($form, $form_state) {
+  if (empty($form_state['values']['verify'])) {
+    drupal_set_message('Please check the box to verify you want to destroy your Views 1 table data.');
+    return;
+  }
+
+  $ret = array();
+  if (db_table_exists('view_view')) {
+    db_drop_table($ret, 'view_view');
+  }
+  if (db_table_exists('view_sort')) {
+    db_drop_table($ret, 'view_sort');
+  }
+  if (db_table_exists('view_argument')) {
+    db_drop_table($ret, 'view_argument');
+  }
+  if (db_table_exists('view_tablefield')) {
+    db_drop_table($ret, 'view_tablefield');
+  }
+  if (db_table_exists('view_filter')) {
+    db_drop_table($ret, 'view_filter');
+  }
+  if (db_table_exists('view_exposed_filter')) {
+    db_drop_table($ret, 'view_exposed_filter');
+  }
+
+  drupal_set_message(t('All Views 1 tables have been removed.'));
+}
+
+/**
  * Page callback for the tools - Views 1 convert page
  */
 function views_ui_convert1($name) {
@@ -303,7 +353,8 @@ function views1_import($imported) {
     }
   }
   foreach ($imported->filter as $field) {
-    $id = $view->add_item('default', 'filter', $field['tablename'], $field['field']);
+    $options = $field['value'] == '' ? array() : array('value' => $field['value']);
+    $id = $view->add_item('default', 'filter', $field['tablename'], $field['field'], $options);
     foreach (module_implements('views_convert') as $module) {
       module_invoke($module, 'views_convert', 'default', 'filter', $view, $field, $id);
     }
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/form.inc,v
retrieving revision 1.10
diff -u -p -r1.10 form.inc
--- includes/form.inc	25 Jun 2008 21:10:10 -0000	1.10
+++ includes/form.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: form.inc,v 1.10 2008/06/25 21:10:10 merlinofchaos Exp $
+// $Id: form.inc,v 1.10.2.2 2010/01/05 01:33:43 merlinofchaos Exp $
 
 /**
  * @file form.inc
@@ -264,7 +264,8 @@ function drupal_validate_form_new($form_
  * - @code '#dependency' => array('id-of-form-without-the-#' => array(list, of, values, that, make, this, gadget, visible)); @endcode
  */
 function views_process_dependency($element, $edit, &$form_state, &$form) {
-  if (isset($element['#dependency'])) {
+  static $dependencies;
+  if (isset($element['#dependency']) && !isset($dependencies[$element['#id']])) {
     if (!isset($element['#dependency_count'])) {
       $element['#dependency_count'] = 1;
     }
@@ -276,7 +277,25 @@ function views_process_dependency($eleme
       $options['viewsAjax']['formRelationships'][$element['#id']] = array('num' => $element['#dependency_count'], 'values' => $element['#dependency']);
       drupal_add_js($options, 'setting');
     }
+    $dependencies[$element['#id']] = TRUE;
   }
 
   return $element;
 }
+
+/**
+ * #process callback to see if we need to check_plain() the options.
+ *
+ * Since FAPI is inconsistent, the #options are sanitized for you in all cases
+ * _except_ checkboxes. We have form elements that are sometimes 'select' and
+ * sometimes 'checkboxes', so we need decide late in the form rendering cycle
+ * if the options need to be sanitized before they're rendered. This callback
+ * inspects the type, and if it's still 'checkboxes', does the sanitation.
+ */
+function views_process_check_options($element, $edit, &$form_state, &$form) {
+  if ($element['#type'] == 'checkboxes' || $element['#type'] == 'checkbox') {
+    $element['#options'] = array_map('check_plain', $element['#options']);
+  }
+  return $element;
+}
+
Index: includes/handlers.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/handlers.inc,v
retrieving revision 1.114
diff -u -p -r1.114 handlers.inc
--- includes/handlers.inc	4 Jun 2009 20:20:45 -0000	1.114
+++ includes/handlers.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: handlers.inc,v 1.114 2009/06/04 20:20:45 merlinofchaos Exp $
+// $Id: handlers.inc,v 1.109.2.17 2010/06/30 19:19:02 merlinofchaos Exp $
 /**
  * @file handlers.inc
  * Defines the various handler objects to help build and display views.
@@ -14,11 +14,24 @@ function _views_create_handler($definiti
     return;
   }
 
-  if (!class_exists($definition['handler']) && !views_include_handler($definition, $type)) {
+  if (!empty($definition['override handler']) &&
+      !class_exists($definition['override handler']) &&
+      !views_include_handler($definition['override handler'], $definition, $type)) {
     return;
   }
 
-  $handler = new $definition['handler'];
+  if (!class_exists($definition['handler']) &&
+      !views_include_handler($definition['handler'], $definition, $type)) {
+    return;
+  }
+
+  if (!empty($definition['override handler'])) {
+    $handler = new $definition['override handler'];
+  }
+  else {
+    $handler = new $definition['handler'];
+  }
+
   $handler->set_definition($definition);
   // let the handler have something like a constructor.
   $handler->construct();
@@ -32,24 +45,24 @@ function _views_create_handler($definiti
  * This will also attempt to include all parents, though we're maxing the
  * parent chain to 10 to prevent infinite loops.
  */
-function views_include_handler($definition, $type, $count = 0) {
+function views_include_handler($handler, $definition, $type, $count = 0) {
   // Do not proceed if the class already exists.
-  if (isset($definition['handler']) && class_exists($definition['handler'])) {
+  if (isset($handler) && class_exists($handler)) {
     return TRUE;
   }
 
   // simple infinite loop prevention.
   if ($count > 10) {
-    vpr(t('Handler @handler include tried to loop infinitely!', array('@handler' => $definition['handler'])));
+    vpr(t('Handler @handler include tried to loop infinitely!', array('@handler' => $handler)));
     return FALSE;
   }
 
   if (!isset($definition['path'])) {
     if ($type == 'handler') {
-      $definition += views_fetch_handler_data($definition['handler']);
+      $definition += views_fetch_handler_data($handler);
     }
     else {
-      $definition += views_fetch_plugin_data($type, $definition['handler']);
+      $definition += views_fetch_plugin_data($type, $handler);
     }
   }
 
@@ -62,7 +75,7 @@ function views_include_handler($definiti
     }
 
     if ($parent) {
-      $rc = views_include_handler($parent, $type, $count + 1);
+      $rc = views_include_handler($parent['handler'], $parent, $type, $count + 1);
       // If the parent chain cannot be included, don't try; this will
       // help alleviate problems with modules with cross dependencies.
       if (!$rc) {
@@ -78,7 +91,7 @@ function views_include_handler($definiti
     }
   }
 
-  return class_exists($definition['handler']);
+  return class_exists($handler);
 }
 
 /**
@@ -262,6 +275,18 @@ class views_handler extends views_object
     $this->query = &$view->query;
   }
 
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['id'] = array('default' => '');
+    $options['table'] = array('default' => '');
+    $options['field'] = array('default' => '');
+    $options['relationship'] = array('default' => 'none');
+    $options['group_type'] = array('default' => 'group');
+
+    return $options;
+  }
+
   /**
    * Return a string representing this handler's name in the UI.
    */
@@ -271,15 +296,39 @@ class views_handler extends views_object
   }
 
   /**
-   * Provide a form for setting options.
-   */
-  function options_form(&$form, &$form_state) { }
+   * Shortcut to get a handler's raw field value.
+   *
+   * This should be overridden for handlers with formulae or other
+   * non-standard fields. Because this takes an argument, fields
+   * overriding this can just call return parent::get_field($formula)
+   */
+  function get_field($field = NULL) {
+    if (!isset($field)) {
+      if (!empty($this->formula)) {
+        $field = $this->get_formula();
+      }
+      else {
+        $field = $this->table_alias . '.' . $this->real_field;
+      }
+    }
+
+    // If grouping, check to see if the aggregation method needs to modify the field.
+    if ($this->view->display_handler->use_group_by()) {
+      $info = $this->query->get_aggregation_info();
+      if (!empty($info[$this->options['group_type']]['method']) && function_exists($info[$this->options['group_type']]['method'])) {
+        return $info[$this->options['group_type']]['method']($this->options['group_type'], $field);
+      }
+    }
+
+    return $field;
+  }
 
   /**
    * Validate the options form.
    */
   function options_validate($form, &$form_state) { }
 
+  function options_form(&$form, &$form_state) { }
   /**
    * Perform any necessary changes to the form values prior to storage.
    * There is no need for this function to actually store the data.
@@ -314,35 +363,142 @@ class views_handler extends views_object
   function extra_options_submit($form, &$form_state) { }
 
   /**
+   * Determine if a handler can be exposed.
+   */
+  function can_expose() { return FALSE; }
+
+  /**
    * Set new exposed option defaults when exposed setting is flipped
    * on.
    */
   function expose_options() { }
+
+  /**
+   * Get information about the exposed form for the form renderer.
+   */
+  function exposed_info() { }
+
   /**
-   * Render our chunk of the exposed filter form when selecting
+   * Render our chunk of the exposed handler form when selecting
    */
   function exposed_form(&$form, &$form_state) { }
 
   /**
-   * Validate the exposed filter form
+   * Validate the exposed handler form
    */
   function exposed_validate(&$form, &$form_state) { }
 
   /**
-   * Submit the exposed filter form
+   * Submit the exposed handler form
    */
   function exposed_submit(&$form, &$form_state) { }
 
   /**
-   * Get information about the exposed form for the form renderer.
+   * Overridable form for exposed handler options.
    *
-   * @return
-   *   An array with the following keys:
-   *   - operator: The $form key of the operator. Set to NULL if no operator.
-   *   - value: The $form key of the value. Set to NULL if no value.
-   *   - label: The label to use for this piece.
+   * If overridden, it is best to call the parent or re-implement
+   * the stuff here.
+   *
+   * Many handlers will need to override this in order to provide options
+   * that are nicely tailored to the given filter.
    */
-  function exposed_info() { }
+  function expose_form(&$form, &$form_state) {
+    $form['expose']['start_left'] = array(
+      '#value' => '<div class="views-left-50">',
+    );
+
+    $this->expose_form_left($form, $form_state);
+
+    $form['expose']['end_left'] = array(
+      '#value' => '</div>',
+    );
+
+    $form['expose']['start_checkboxes'] = array(
+      '#value' => '<div class="form-checkboxes views-left-40 clear-block">',
+    );
+
+    $this->expose_form_right($form, $form_state);
+
+    $form['expose']['end_checkboxes'] = array(
+      '#value' => '</div>',
+    );
+  }
+
+  function expose_form_left(&$form, &$form_state) { }
+
+  function expose_form_right(&$form, &$form_state){ }
+
+  /**
+   * Validate the options form.
+   */
+  function expose_validate($form, &$form_state) { }
+
+  /**
+   * Perform any necessary changes to the form exposes prior to storage.
+   * There is no need for this function to actually store the data.
+   */
+  function expose_submit($form, &$form_state) { }
+
+    /**
+   * Shortcut to display the expose/hide button.
+   */
+  function show_expose_button(&$form, &$form_state) {
+    $form['expose_button'] = array(
+      '#prefix' => '<div class="views-expose clear-block">',
+      '#suffix' => '</div>',
+    );
+    if (empty($this->options['exposed'])) {
+      $form['expose_button']['button'] = array(
+        '#type' => 'submit',
+        '#value' => t('Expose'),
+        '#submit' => array('views_ui_config_item_form_expose'),
+      );
+      $form['expose_button']['markup'] = array(
+        '#prefix' => '<div class="description">',
+        '#value' => t('This item is currently not exposed. If you <strong>expose</strong> it, users will be able to change the filter as they view it.'),
+        '#suffix' => '</div>',
+      );
+    }
+    else {
+      $form['expose_button']['button'] = array(
+        '#type' => 'submit',
+        '#value' => t('Hide'),
+        '#submit' => array('views_ui_config_item_form_expose'),
+      );
+      $form['expose_button']['markup'] = array(
+        '#prefix' => '<div class="description">',
+        '#value' => t('This item is currently exposed. If you <strong>hide</strong> it, users will not be able to change the filter as they view it.'),
+        '#suffix' => '</div>',
+      );
+    }
+  }
+
+  /**
+   * Shortcut to display the exposed options form.
+   */
+  function show_expose_form(&$form, &$form_state) {
+    if (empty($this->options['exposed'])) {
+      return;
+    }
+
+    $form['expose'] = array(
+      '#prefix' => '<div class="views-expose-options clear-block">',
+      '#suffix' => '</div>',
+    );
+    $this->expose_form($form, $form_state);
+
+    // When we click the expose button, we add new gadgets to the form but they
+    // have no data in $_POST so their defaults get wiped out. This prevents
+    // these defaults from getting wiped out. This setting will only be TRUE
+    // during a 2nd pass rerender.
+    if (!empty($form_state['force_expose_options'])) {
+      foreach (element_children($form['expose']) as $id) {
+        if (isset($form['expose'][$id]['#default_value']) && !isset($form['expose'][$id]['#value'])) {
+          $form['expose'][$id]['#value'] = $form['expose'][$id]['#default_value'];
+        }
+      }
+    }
+  }
 
  /**
   * Check whether current user has access to this handler.
@@ -403,7 +559,7 @@ class views_handler extends views_object
    *
    * If we were using PHP5, this would be abstract.
    */
-  function query() { }
+  function query($group_by = FALSE) { }
 
   /**
    * Ensure the main table for this handler is in the query. This is used
@@ -440,7 +596,7 @@ class views_handler extends views_object
   }
 
   /**
-   * Take input from exposed filters and assign to this handler, if necessary.
+   * Take input from exposed handlers and assign to this handler, if necessary.
    */
   function accept_exposed_input($input) { return TRUE; }
 
@@ -519,7 +675,7 @@ class views_many_to_one_helper {
     $form['reduce_duplicates'] = array(
       '#type' => 'checkbox',
       '#title' => t('Reduce duplicates'),
-      '#description' => t('This filter can cause items that have more than one of the selected options to appear as duplicate results. If this filter causes duplicate results to occur, this checkbox can reduce those duplicates; however, the more terms it has to search for, the less performant the query will be, so use this with caution.'),
+      '#description' => t('This filter can cause items that have more than one of the selected options to appear as duplicate results. If this filter causes duplicate results to occur, this checkbox can reduce those duplicates; however, the more terms it has to search for, the less performant the query will be, so use this with caution. Shouldn\'t be set on single-value fields, as it may cause values to disappear from display, if used on an incompatible field.'),
       '#default_value' => !empty($this->handler->options['reduce_duplicates']),
     );
   }
@@ -572,10 +728,9 @@ class views_many_to_one_helper {
     while ($r_join->left_table != $base_table) {
       $r_join = views_get_table_join($r_join->left_table, $base_table);
     }
-
     // If we found that there are tables in between, add the relationship.
     if ($r_join->table != $join->table) {
-      $relationship = $this->handler->query->add_relationship($this->handler->table, $r_join, $r_join->table, $this->handler->relationship);
+      $relationship = $this->handler->query->add_relationship($this->handler->table . '_' . $r_join->table, $r_join, $r_join->table, $this->handler->relationship);
     }
 
     // And now add our table, using the new relationship if one was used.
@@ -777,16 +932,29 @@ class views_many_to_one_helper {
  * @param $str
  *   The string to parse.
  * @param $filter
- *   The filter object to use as a base. If not specified one will
- *   be created.
+ *   The filter object to use as a base.
  *
  * @return $filter
  *   The new filter object.
  */
-function views_break_phrase($str, $filter = NULL) {
+function views_break_phrase($str, &$filter) {
   if (!$filter) {
     $filter = new stdClass();
   }
+
+  // Set up defaults:
+  if (!isset($filter->value)) {
+    $filter->value = array();
+  }
+
+  if (!isset($filter->operator)) {
+    $filter->operator = 'or';
+  }
+
+  if ($str == '') {
+    return $filter;
+  }
+
   if (preg_match('/^([0-9]+[+ ])+[0-9]+$/', $str)) {
     // The '+' character in a query string may be parsed as ' '.
     $filter->operator = 'or';
@@ -827,12 +995,17 @@ function views_get_timezone() {
   }
 
   // set up the database timezone
-  if (in_array($GLOBALS['db_type'], array('mysql', 'mysqli'))) {
+  if (in_array($GLOBALS['db_type'], array('mysql', 'mysqli', 'pgsql'))) {
+    $offset = '+00:00';
     static $already_set = false;
     if (!$already_set) {
-      if ($GLOBALS['db_type'] == 'mysqli' || version_compare(mysql_get_server_info(), '4.1.3', '>=')) {
-        db_query("SET @@session.time_zone = '+00:00'");
+      if ($GLOBALS['db_type'] == 'pgsql') {
+        db_query("SET TIME ZONE INTERVAL '$offset' HOUR TO MINUTE");
       }
+      elseif ($GLOBALS['db_type'] == 'mysqli' || version_compare(mysql_get_server_info(), '4.1.3', '>=')) {
+        db_query("SET @@session.time_zone = '$offset'");
+      }
+
       $already_set = true;
     }
   }
@@ -846,7 +1019,7 @@ function views_get_timezone() {
  * @param $field
  *   The real table and field name, like 'tablename.fieldname'.
  * @param $field_type
- *   The type of date field, 'int' or 'datetime'.
+ *  The type of date field, 'int' or 'datetime'.
  * @param $set_offset
  *   The name of a field that holds the timezone offset or a fixed timezone
  *   offset value. If not provided, the normal Drupal timezone handling
@@ -1068,6 +1241,9 @@ function views_views_handlers() {
       'views_handler_field_counter' => array(
         'parent' => 'views_handler_field',
       ),
+      'views_handler_field_math' => array(
+        'parent' => 'views_handler_field_numeric',
+      ),
 
       // filter handlers
       'views_handler_filter' => array(
@@ -1123,6 +1299,28 @@ function views_views_handlers() {
       'views_handler_sort_random' => array(
         'parent' => 'views_handler_sort',
       ),
+
+      // group by handlers
+      'views_handler_argument_group_by_numeric' => array(
+        'parent' => 'views_handler_argument',
+      ),
+      'views_handler_field_group_by_numeric' => array(
+        'parent' => 'views_handler_field',
+      ),
+      'views_handler_filter_group_by_numeric' => array(
+        'parent' => 'views_handler_filter_numeric',
+      ),
+      'views_handler_sort_group_by_numeric' => array(
+        'parent' => 'views_handler_sort',
+      ),
+
+      // area handlers
+      'views_handler_area' => array(
+        'parent' => 'views_handler',
+      ),
+      'views_handler_area_text' => array(
+        'parent' => 'views_handler_area',
+      ),
     ),
   );
 }
@@ -1217,14 +1415,24 @@ class views_join {
    * Build the SQL for the join this object represents.
    */
   function join($table, &$query) {
+    if (empty($this->definition['table formula'])) {
+      $right_table = "{" . $this->table . "}";
+    }
+    else {
+      $right_table = $this->definition['table formula'];
+    }
+
     if ($this->left_table) {
       $left = $query->get_table_info($this->left_table);
-      $output = " $this->type JOIN {" . $this->table . "} $table[alias] ON $left[alias].$this->left_field = $table[alias].$this->field";
+      $left_field = "$left[alias].$this->left_field";
     }
     else {
       // This can be used if left_field is a formula or something. It should be used only *very* rarely.
-      $output = " $this->type JOIN {" . $this->table . "} $table[alias] ON $this->left_field = $table[alias].$this->field";
+      $left_field = $this->left_field;
     }
+
+    $output = " $this->type JOIN $right_table $table[alias] ON $left_field = $table[alias].$this->field";
+
     // Tack on the extra.
     if (isset($this->extra)) {
       if (is_array($this->extra)) {
@@ -1322,7 +1530,8 @@ class views_join {
  */
 function views_views_api() {
   return array(
-    'api' => 2,
+    // in your modules do *not* use views_api_version()!!!
+    'api' => views_api_version(),
     'path' => drupal_get_path('module', 'views') . '/modules',
   );
 }
Index: includes/plugins.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/plugins.inc,v
retrieving revision 1.154
diff -u -p -r1.154 plugins.inc
--- includes/plugins.inc	2 Jun 2009 20:22:19 -0000	1.154
+++ includes/plugins.inc	11 Aug 2010 21:11:32 -0000
@@ -1,17 +1,16 @@
 <?php
-// $Id: plugins.inc,v 1.154 2009/06/02 20:22:19 merlinofchaos Exp $
+// $Id: plugins.inc,v 1.152.2.11 2010/03/12 18:51:17 merlinofchaos Exp $
 /**
  * @file plugins.inc
  * Built in plugins for Views output handling.
  *
- */
-
+ */ 
 /**
  * Implementation of hook_views_plugins
  */
 function views_views_plugins() {
   $path = drupal_get_path('module', 'views') . '/js';
-  return array(
+  $plugins = array(
     'module' => 'views', // This just tells our themes are elsewhere.
     'display' => array(
       'parent' => array(
@@ -95,8 +94,8 @@ function views_views_plugins() {
         'handler' => 'views_plugin_style_default',
         'theme' => 'views_view_unformatted',
         'uses row plugin' => TRUE,
-        'uses options' => TRUE,
         'uses grouping' => TRUE,
+        'uses options' => TRUE,
         'type' => 'normal',
         'help topic' => 'style-unformatted',
       ),
@@ -181,16 +180,18 @@ function views_views_plugins() {
       ),
     ),
     'argument default' => array(
-      // This type of plugin does not conform to the standard and
-      // uses 'fixed' as the parent rather than having a separate parent.
+      'parent' => array(
+        'no ui' => TRUE,
+        'handler' => 'views_plugin_argument_default',
+        'parent' => '',
+      ),
       'fixed' => array(
         'title' => t('Fixed entry'),
-        'handler' => 'views_plugin_argument_default',
+        'handler' => 'views_plugin_argument_default_fixed',
       ),
       'php' => array(
         'title' => t('PHP Code'),
         'handler' => 'views_plugin_argument_default_php',
-        'parent' => 'fixed',
       ),
     ),
     'argument validator' => array(
@@ -235,6 +236,18 @@ function views_views_plugins() {
         'help topic' => 'access-perm',
       ),
     ),
+    'query' => array(
+      'parent' => array(
+        'no ui' => TRUE,
+        'handler' => 'views_plugin_query',
+        'parent' => '',
+      ),
+      'views_query' => array(
+        'title' => t('SQL Query'),
+        'help' => t('Query will be generated and run using the Drupal database API.'),
+        'handler' => 'views_plugin_query_default'
+      ),
+    ),
     'cache' => array(
       'parent' => array(
         'no ui' => TRUE,
@@ -255,7 +268,89 @@ function views_views_plugins() {
         'help topic' => 'cache-time',
       ),
     ),
+    'exposed_form' => array(
+      'parent' => array(
+        'no ui' => TRUE,
+        'handler' => 'views_plugin_exposed_form',
+        'parent' => '',
+      ),
+      'basic' => array(
+        'title' => t('Basic'),
+        'help' => t('Basic exposed form'),
+        'handler' => 'views_plugin_exposed_form_basic',
+        'uses options' => TRUE,
+        'help topic' => 'exposed-form-basic',
+      ),
+      'input_required' => array(
+        'title' => t('Input required'),
+        'help' => t('An exposed form that only renders a view if the form contains user input.'),
+        'handler' => 'views_plugin_exposed_form_input_required',
+        'uses options' => TRUE,
+        'help topic' => 'exposed-form-input-required',
+      ),
+    ),
+    'pager' => array(
+      'parent' => array(
+        'no ui' => TRUE,
+        'handler' => 'views_plugin_pager',
+        'parent' => '',
+      ),
+      'none' => array(
+        'title' => t('Display all items'),
+        'help' => t("Display all items that this view might find"),
+        'handler' => 'views_plugin_pager_none',
+        'help topic' => 'pager-none',
+        'uses options' => TRUE,
+      ),
+      'some' => array(
+        'title' => t('Display a specified number of items'),
+        'help' => t('Display a limited number items that this view might find.'),
+        'handler' => 'views_plugin_pager_some',
+        'help topic' => 'pager-some',
+        'uses options' => TRUE,
+      ),
+      'full' => array(
+        'title' => t('Paged output, full pager'),
+        'help' => t('Paged output, full Drupal style'),
+        'handler' => 'views_plugin_pager_full',
+        'help topic' => 'pager-full',
+        'uses options' => TRUE,
+      ),
+      'mini' => array(
+        'title' => t('Paged output, mini pager'),
+        'help' => t('Use the mini pager output.'),
+        'handler' => 'views_plugin_pager_mini',
+        'help topic' => 'pager-mini',
+        'uses options' => TRUE,
+        'parent' => 'full',
+      ),
+    ),
   );
+
+  if (module_invoke('ctools', 'api_version', '1.3')) {
+    $plugins['style']['jump_menu_summary'] = array(
+      'title' => t('Jump menu'),
+      'help' => t('Puts all of the results into a select box and allows the user to go to a different page based upon the results.'),
+      'handler' => 'views_plugin_style_summary_jump_menu',
+      'theme' => 'views_view_summary_jump_menu',
+      'type' => 'summary', // only shows up as a summary style
+      'uses options' => TRUE,
+      'help topic' => 'style-summary-jump-menu',
+    );
+    $plugins['style']['jump_menu'] = array(
+      'title' => t('Jump menu'),
+      'help' => t('Puts all of the results into a select box and allows the user to go to a different page based upon the results.'),
+      'handler' => 'views_plugin_style_jump_menu',
+      'theme' => 'views_view_jump_menu',
+      'uses row plugin' => TRUE,
+      'uses fields' => TRUE,
+      'uses options' => TRUE,
+      'type' => 'normal',
+      'help topic' => 'style-jump-menu',
+    );
+  }
+
+  return $plugins;
 }
 
 /**
@@ -264,7 +359,7 @@ function views_views_plugins() {
  * @return Nested array of plugins, grouped by type.
  */
 function views_discover_plugins() {
-  $cache = array('display' => array(), 'style' => array(), 'row' => array(), 'argument default' => array(), 'argument validator' => array(), 'access' => array(), 'cache' => array());
+  $cache = array('display' => array(), 'style' => array(), 'row' => array(), 'argument default' => array(), 'argument validator' => array(), 'access' => array(), 'cache' => array(), 'exposed_form' => array());
   // Get plugins from all mdoules.
   foreach (module_implements('views_plugins') as $module) {
     $function = $module . '_views_plugins';
@@ -311,6 +406,9 @@ function views_discover_plugins() {
       }
     }
   }
+
+  // Let other modules modify the plugins.
+  drupal_alter('views_plugins', $cache);
   return $cache;
 }
 
@@ -340,7 +438,7 @@ class views_plugin extends views_object 
   /**
    * Handle any special handling on the validate form.
    */
-  function options_submit(&$form, &$form_state) { }
+  function options_submit($form, &$form_state) { }
 
   /**
    * Add anything to the query that we might need to.
Index: includes/view.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/view.inc,v
retrieving revision 1.159
diff -u -p -r1.159 view.inc
--- includes/view.inc	4 Jun 2009 18:40:45 -0000	1.159
+++ includes/view.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: view.inc,v 1.159 2009/06/04 18:40:45 merlinofchaos Exp $
+// $Id: view.inc,v 1.151.2.33 2010/04/29 18:39:31 merlinofchaos Exp $
 /**
  * @file view.inc
  * Provides the view object type and associated methods.
@@ -32,14 +32,10 @@ class view extends views_db_object {
   // Where the results of a query will go.
   var $result = array();
 
-  // pager variables
-  var $pager = array(
-    'use_pager' => FALSE,
-    'items_per_page' => 10,
-    'element' => 0,
-    'offset' => 0,
-    'current_page' => 0,
-  );
+  // May be used to override the current pager info.
+  var $current_page = NULL;
+  var $items_per_page = NULL;
+  var $offset = NULL;
 
   // Places to put attached renderings:
   var $attachment_before = '';
@@ -51,17 +47,18 @@ class view extends views_db_object {
 
   // Used to store views that were previously running if we recurse.
   var $old_view = array();
+
+  // Where the $query object will reside:
+  var $query = NULL;
   /**
    * Constructor
    */
-  function view() {
+  function __construct() {
     parent::init();
     // Make sure all of our sub objects are arrays.
     foreach ($this->db_objects() as $object) {
       $this->$object = array();
     }
-
-    $this->query = new stdClass();
   }
 
   /**
@@ -69,7 +66,7 @@ class view extends views_db_object {
    * stored on the display, and are used in the build process.
    */
   function display_objects() {
-    return array('argument', 'field', 'sort', 'filter', 'relationship');
+    return array('argument', 'field', 'sort', 'filter', 'relationship', 'header', 'footer', 'empty');
   }
 
   /**
@@ -92,35 +89,61 @@ class view extends views_db_object {
   }
 
   /**
-   * Set the page size for ranged or pager queries
+   * Change/Set the current page for the pager.
    */
-  function set_items_per_page($items_per_page) {
-    $this->pager['items_per_page'] = $items_per_page;
-    if (empty($items_per_page)) {
-      $this->pager['use_pager'] = FALSE;
+  function set_current_page($page) {
+    $this->current_page = $page;
+  }
+
+  /**
+   * Get the current page from the pager.
+   */
+  function get_current_page() {
+    if (!empty($this->query->pager)) {
+      return $this->query->pager->get_current_page();
     }
   }
 
   /**
-   * Whether or not the pager should be used.
+   * Get the items per page from the pager.
    */
-  function set_use_pager($use_pager) {
-    $this->pager['use_pager'] = $use_pager;
+  function get_items_per_page() {
+    if (!empty($this->query->pager)) {
+      return $this->query->pager->get_items_per_page();
+    }
+  }
+
+  /**
+   * Set the items per page on the pager.
+   */
+  function set_items_per_page($items_per_page) {
+    $this->items_per_page = $items_per_page;
+
+    // If the pager is already initialized, pass it through to the pager.
+    if (!empty($this->query->pager)) {
+      $this->query->pager->set_items_per_page($items_per_page);
+    }
   }
 
   /**
-   * The pager element id to use if use_apger is on
+   * Get the pager offset from the pager.
    */
-  function set_pager_element($pager_element) {
-    $this->pager['element'] = $pager_element;
+  function get_offset() {
+    if (!empty($this->query->pager)) {
+      return $this->query->pager->get_offset();
+    }
   }
 
   /**
-   * How many records to skip. This does not function if use_pager is
-   * set.
+   * Set the offset on the pager.
    */
   function set_offset($offset) {
-    $this->pager['offset'] = $offset;
+    $this->offset = $offset;
+
+    // If the pager is already initialized, pass it through to the pager.
+    if (!empty($this->query->pager)) {
+      $this->query->pager->set_offset($offset);
+    }
   }
 
   /**
@@ -322,6 +345,32 @@ class view extends views_db_object {
   }
 
   /**
+   * Initialize the pager
+   *
+   * Like style initialization, pager initialization is held until late
+   * to allow for overrides.
+   */
+  function init_pager() {
+    if (empty($this->query->pager)) {
+      $this->query->pager = $this->display_handler->get_plugin('pager');
+
+      if ($this->query->pager->use_pager()) {
+        $this->query->pager->set_current_page($this->current_page);
+      }
+
+      // These overrides may have been set earlier via $view->set_*
+      // functions.
+      if (isset($this->items_per_page)) {
+        $this->query->pager->set_items_per_page($this->items_per_page);
+      }
+
+      if (isset($this->offset)) {
+        $this->query->pager->set_offset($this->offset);
+      }
+    }
+  }
+
+  /**
    * Create a list of base tables eligible for this view. Used primarily
    * for the UI. Display must be already initialized.
    */
@@ -376,42 +425,6 @@ class view extends views_db_object {
   }
 
   /**
-   * Render the exposed filter form.
-   *
-   * This actually does more than that; because it's using FAPI, the form will
-   * also assign data to the appropriate handlers for use in building the
-   * query.
-   */
-  function render_exposed_form($block = FALSE) {
-    // Deal with any exposed filters we may have, before building.
-    $form_state = array(
-      'view' => &$this,
-      'display' => &$this->display_handler->display,
-      'method' => 'get',
-      'rerender' => TRUE,
-      'no_redirect' => TRUE,
-    );
-
-    // Some types of displays (eg. attachments) may wish to use the exposed
-    // filters of their parent displays instead of showing an additional
-    // exposed filter form for the attachment as well as that for the parent.
-    if (!$this->display_handler->displays_exposed() || (!$block && $this->display_handler->get_option('exposed_block'))) {
-      unset($form_state['rerender']);
-    }
-
-    if (!empty($this->ajax)) {
-      $form_state['ajax'] = TRUE;
-    }
-
-    $output = drupal_build_form('views_exposed_form', $form_state);
-    if (!empty($form_state['js settings'])) {
-      $this->js_settings = $form_state['js settings'];
-    }
-
-    return $output;
-  }
-
-  /**
    * Build all the arguments.
    */
   function _build_arguments() {
@@ -420,6 +433,12 @@ class view extends views_db_object {
     if (empty($this->argument)) {
       return TRUE;
     }
+ 
+    // Don't render exposed filter form when there's form errors.
+    // Applies when filters are in a block ("exposed_block" option).
+    if (form_get_errors() && empty($form_state['rerender'])) {
+      return NULL;
+    }
 
     // build arguments.
     $position = -1;
@@ -467,7 +486,7 @@ class view extends views_db_object {
         }
         else {
           $arg_title = $argument->get_title();
-          $argument->query();
+          $argument->query($this->display_handler->use_group_by());
         }
 
         // Add this argument's substitution
@@ -518,14 +537,26 @@ class view extends views_db_object {
    * Do some common building initialization.
    */
   function init_query() {
+    if (!empty($this->query)) {
+      $class = get_class($this->query);
+      if ($class && $class != 'stdClass') {
+        // return if query is already initialized.
+        return;
+      }
+    }
+
     // Create and initialize the query object.
     $views_data = views_fetch_data($this->base_table);
     $this->base_field = $views_data['table']['base']['field'];
     if (!empty($views_data['table']['base']['database'])) {
       $this->base_database = $views_data['table']['base']['database'];
     }
-    views_include('query');
-    $this->query = new views_query($this->base_table, $this->base_field);
+
+    // Create and initialize the query object.
+    $plugin = !empty($views_data['table']['base']['query class']) ? $views_data['table']['base']['query class'] : 'views_query';
+    $this->query = views_get_plugin('query', $plugin);
+
+    $this->query->init($this->base_table, $this->base_field);
   }
 
   /**
@@ -573,7 +604,8 @@ class view extends views_db_object {
     $this->_pre_query();
 
     if ($this->display_handler->uses_exposed()) {
-      $this->exposed_widgets = $this->render_exposed_form();
+      $exposed_form = $this->display_handler->get_plugin('exposed_form');
+      $this->exposed_widgets = $exposed_form->render_exposed_form();
       if (form_set_error() || !empty($this->build_info['abort'])) {
         $this->built = TRUE;
         return empty($this->build_info['fail']);
@@ -583,6 +615,15 @@ class view extends views_db_object {
     // Build all the relationships first thing.
     $this->_build('relationship');
 
+    // Set the filtering groups.
+    $filter_groups = $this->display_handler->get_option('filter_groups');
+    if ($filter_groups) {
+      $this->query->set_group_operator($filter_groups['operator']);
+      foreach($filter_groups['groups'] as $id => $operator) {
+        $this->query->set_where_group($operator, $id);
+      }
+    }
+
     // Build all the filters.
     $this->_build('filter');
 
@@ -591,6 +632,7 @@ class view extends views_db_object {
     // Arguments can, in fact, cause this whole thing to abort.
     if (!$this->_build_arguments()) {
       $this->build_time = views_microtime() - $start;
+      $this->attach_displays();
       return $this->built;
     }
 
@@ -612,27 +654,34 @@ class view extends views_db_object {
       if ($this->style_plugin->build_sort()) {
         $this->_build('sort');
       }
+      // allow the plugin to build second sorts as well.
+      $this->style_plugin->build_sort_post();
     }
 
     // Allow display handler to affect the query:
-    $this->display_handler->query();
+    $this->display_handler->query($this->display_handler->use_group_by());
 
     // Allow style handler to affect the query:
-    $this->style_plugin->query();
+    $this->style_plugin->query($this->display_handler->use_group_by());
+
+    // Allow exposed form to affect the query:
+    if (isset($exposed_form)) {
+      $exposed_form->query();
+    }
 
     if (variable_get('views_sql_signature', FALSE)) {
-      $this->query->add_field(NULL, "'" . $this->name . ':' . $this->current_display . "'", 'view_name');
+      $this->query->add_signature($this);
     }
 
     // Let modules modify the query just prior to finalizing it.
-    foreach (module_implements('views_query_alter') as $module) {
-      $function = $module . '_views_query_alter';
-      $function($this, $this->query);
+    $this->query->alter($this);
+
+    // Only build the query if we weren't interrupted.
+    if (empty($this->built)) {
+      // Build the necessary info to execute the query.
+      $this->query->build($this);
     }
 
-    $this->build_info['query'] = $this->query->query();
-    $this->build_info['count_query'] = $this->query->query(TRUE);
-    $this->build_info['query_args'] = $this->query->get_where_args();
     $this->built = TRUE;
     $this->build_time = views_microtime() - $start;
 
@@ -657,7 +706,7 @@ class view extends views_db_object {
           }
         }
         $handlers[$id]->set_relationship();
-        $handlers[$id]->query();
+        $handlers[$id]->query($this->display_handler->use_group_by());
       }
     }
   }
@@ -689,85 +738,18 @@ class view extends views_db_object {
 
     vpr($query);
 
-
     // Check for already-cached results.
     if (!empty($this->live_preview)) {
       $cache = FALSE;
     }
     else {
-      $cache = $this->display_handler->get_cache_plugin();
+      $cache = $this->display_handler->get_plugin('cache');
     }
     if ($cache && $cache->cache_get('results')) {
       vpr('Used cached results');
     }
     else {
-      $items = array();
-      if ($query) {
-        $replacements = module_invoke_all('views_query_substitutions', $this);
-        $query = str_replace(array_keys($replacements), $replacements, $query);
-        $count_query = 'SELECT COUNT(*) FROM (' . str_replace(array_keys($replacements), $replacements, $count_query) . ') count_alias';
-
-        if (is_array($args)) {
-          foreach ($args as $id => $arg) {
-            $args[$id] = str_replace(array_keys($replacements), $replacements, $arg);
-          }
-        }
-
-        // Allow for a view to query an external database.
-        if (isset($this->base_database)) {
-          db_set_active($this->base_database);
-          $external = TRUE;
-        }
-
-        $start = views_microtime();
-        if (!empty($this->pager['items_per_page'])) {
-          // We no longer use pager_query() here because pager_query() does not
-          // support an offset. This is fine as we don't actually need pager
-          // query; we've already been doing most of what it does, and we
-          // just need to do a little more playing with globals.
-          if (!empty($this->pager['use_pager']) || !empty($this->get_total_rows)) {
-            $this->total_rows = db_result(db_query($count_query, $args)) - $this->pager['offset'];
-          }
-
-          if (!empty($this->pager['use_pager'])) {
-            // dump information about what we already know into the globals
-            global $pager_page_array, $pager_total, $pager_total_items;
-            // total rows in query
-            $pager_total_items[$this->pager['element']] = $this->total_rows;
-            // total pages
-            $pager_total[$this->pager['element']] = ceil($pager_total_items[$this->pager['element']] / $this->pager['items_per_page']);
-
-            // What page was requested:
-            $pager_page_array = isset($_GET['page']) ? explode(',', $_GET['page']) : array();
-
-            // If the requested page was within range. $this->pager['current_page']
-            // defaults to 0 so we don't need to set it in an out-of-range condition.
-            if (!empty($pager_page_array[$this->pager['element']])) {
-              $page = intval($pager_page_array[$this->pager['element']]);
-              if ($page > 0 && $page < $pager_total[$this->pager['element']]) {
-                $this->pager['current_page'] = $page;
-              }
-            }
-            $pager_page_array[$this->pager['element']] = $this->pager['current_page'];
-          }
-
-          $offset = $this->pager['current_page'] * $this->pager['items_per_page'] + $this->pager['offset'];
-          $result = db_query_range($query, $args, $offset, $this->pager['items_per_page']);
-
-        }
-        else {
-          $result = db_query($query, $args);
-        }
-
-        $this->result = array();
-        while ($item = db_fetch_object($result)) {
-          $this->result[] = $item;
-        }
-        if (!empty($external)) {
-          db_set_active();
-        }
-        $this->execute_time = views_microtime() - $start;
-      }
+      $this->query->execute($this);
       if ($cache) {
         $cache->cache_set('results');
       }
@@ -787,17 +769,22 @@ class view extends views_db_object {
       return;
     }
 
+    init_theme();
+
     $start = views_microtime();
     if (!empty($this->live_preview) && variable_get('views_show_additional_queries', FALSE)) {
       $this->start_query_capture();
     }
 
+    $exposed_form = $this->display_handler->get_plugin('exposed_form');
+    $exposed_form->pre_render();
+
     // Check for already-cached output.
     if (!empty($this->live_preview)) {
       $cache = FALSE;
     }
     else {
-      $cache = $this->display_handler->get_cache_plugin();
+      $cache = $this->display_handler->get_plugin('cache');
     }
     if ($cache && $cache->cache_get('output')) {
       vpr('Used cached output');
@@ -818,6 +805,12 @@ class view extends views_db_object {
         $function($this);
       }
 
+      // Let the theme play too, because pre render is a very themey thing.
+      $function = $GLOBALS['theme'] . '_views_pre_render';
+      if (function_exists($function)) {
+        $function($this, $this->display_handler->output, $cache);
+      }
+
       // Give field handlers the opportunity to perform additional queries
       // using the entire resultset prior to rendering.
       if ($this->style_plugin->uses_fields()) {
@@ -833,6 +826,24 @@ class view extends views_db_object {
       }
     }
 
+    $exposed_form->post_render($this->display_handler->output);
+
+    if ($cache) {
+      $cache->post_render($this->display_handler->output);
+    }
+
+    // Let modules modify the view output after it is rendered.
+    foreach (module_implements('views_post_render') as $module) {
+      $function = $module . '_views_post_render';
+      $function($this, $this->display_handler->output, $cache);
+    }
+
+    // Let the theme play too, because post render is a very themey thing.
+    $function = $GLOBALS['theme'] . '_views_post_render';
+    if (function_exists($function)) {
+      $function($this, $this->display_handler->output, $cache);
+    }
+
     if (!empty($this->live_preview) && variable_get('views_show_additional_queries', FALSE)) {
       $this->end_query_capture();
     }
@@ -863,6 +874,8 @@ class view extends views_db_object {
    * If you simply want to view the display, use view::preview() instead.
    */
   function execute_display($display_id = NULL, $args = array()) {
+    $timer_id = 'execute_display' . $display_id;
+    timer_start($timer_id);
     if (empty($this->current_display) || $this->current_display != $this->choose_display($display_id)) {
       if (!$this->set_display($display_id)) {
         return FALSE;
@@ -875,6 +888,11 @@ class view extends views_db_object {
     $output = $this->display_handler->execute();
 
     $this->post_execute();
+
+    vpr("$this->name execute time: " . timer_read($timer_id) . " ms");
+
+    timer_stop($timer_id);
+
     return $output;
   }
 
@@ -886,6 +904,8 @@ class view extends views_db_object {
    * normalized output.
    */
   function preview($display_id = NULL, $args = array()) {
+    $timer_id = 'preview' . $display_id;
+    timer_start($timer_id);
     if (empty($this->current_display) || $this->current_display != $display_id) {
       if (!$this->set_display($display_id)) {
         return FALSE;
@@ -898,6 +918,11 @@ class view extends views_db_object {
     $output = $this->display_handler->preview();
 
     $this->post_execute();
+
+    vpr("$this->name execute time: " . timer_read($timer_id) . " ms");
+
+    timer_stop($timer_id);
+
     return $output;
   }
 
@@ -965,10 +990,14 @@ class view extends views_db_object {
   }
 
   /**
-   * Called to get hook_menu information from the view and the
-   * named display handler.
+   * Called to get hook_menu() information from the view and the named display handler.
+   *
+   * @param $display_id
+   *   A display id.
+   * @param $callbacks
+   *   A menu callback array passed from views_menu_alter().
    */
-  function execute_hook_menu($display_id = NULL) {
+  function execute_hook_menu($display_id = NULL, $callbacks = array()) {
     // Prepare the view with the information we have.
 
     // This was probably already called, but it's good to be safe.
@@ -978,7 +1007,7 @@ class view extends views_db_object {
 
     // Execute the view
     if (isset($this->display_handler)) {
-      return $this->display_handler->execute_hook_menu();
+      return $this->display_handler->execute_hook_menu($callbacks);
     }
   }
 
@@ -1382,7 +1411,7 @@ class view extends views_db_object {
   /**
    * Delete the view from the database.
    */
-  function delete() {
+  function delete($clear = TRUE) {
     if (empty($this->vid)) {
       return;
     }
@@ -1394,8 +1423,11 @@ class view extends views_db_object {
     }
 
     cache_clear_all('views_query:' . $this->name, 'cache_views');
-    cache_clear_all(); // In Drupal 5.0 and later this clears the page cache only.
-    menu_rebuild(); // force a menu rebuild when a view is deleted.
+
+    if ($clear) {
+      cache_clear_all(); // this clears the block and page caches only.
+      menu_rebuild(); // force a menu rebuild when a view is deleted.
+    }
   }
 
   /**
@@ -1406,10 +1438,11 @@ class view extends views_db_object {
     $output = '';
     $output .= $this->export_row('view', $indent);
     // Set the API version
-    $output .= $indent . '$view->api_version = 2' . ";\n";
+    $output .= $indent . '$view->api_version = ' . views_api_version() . ";\n";
     $output .= $indent . '$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */' . "\n";
 
     foreach ($this->display as $id => $display) {
+      $output .= $indent . "\n/* Display: $display->display_title */\n";
       $output .= $indent . '$handler = $view->new_display(' . views_var_export($display->display_plugin, $indent) . ', ' . views_var_export($display->display_title, $indent) . ', \'' . $id . "');\n";
       if (empty($display->handler)) {
         // @todo -- probably need a method of exporting broken displays as
@@ -1418,28 +1451,7 @@ class view extends views_db_object {
         continue;
       }
 
-      foreach ($display->handler->option_definition() as $option => $definition) {
-        // Special handling for some items
-        switch ($option) {
-          case 'defaults':
-            // skip these
-            break;
-          default:
-            if (!$display->handler->is_defaulted($option)) {
-              $value = $display->handler->get_option($option);
-              if ($id == 'default') {
-                $default = isset($definition['default']) ? $definition['default'] : NULL;
-              }
-              else {
-                $default = $this->display['default']->handler->get_option($option);
-              }
-
-              if ($value !== $default) {
-                $output .= $indent . '$handler->override_option(\'' . $option . '\', ' . views_var_export($value, $indent) . ");\n";
-              }
-            }
-        }
-      }
+      $output .= $display->handler->export_options($indent, '$handler->options');
     }
 
     return $output;
@@ -1471,7 +1483,7 @@ class view extends views_db_object {
   function clone_view() {
     $clone = version_compare(phpversion(), '5.0') < 0 ? $this : clone($this);
 
-    $keys = array('current_display', 'display_handler', 'build_info', 'built', 'executed', 'attachment_before', 'attachment_after', 'field', 'argument', 'filter', 'sort', 'relationship', 'query', 'inited', 'style_plugin', 'plugin_name', 'exposed_data', 'exposed_input', 'many_to_one_tables');
+    $keys = array('current_display', 'display_handler', 'build_info', 'built', 'executed', 'attachment_before', 'attachment_after', 'field', 'argument', 'filter', 'sort', 'relationship', 'header', 'footer', 'empty', 'query', 'inited', 'style_plugin', 'plugin_name', 'exposed_data', 'exposed_input', 'exposed_widgets', 'many_to_one_tables', 'feed_icon');
     foreach ($keys as $key) {
       if (isset($clone->$key)) {
         unset($clone->$key);
@@ -1535,6 +1547,17 @@ class view extends views_db_object {
       if (isset($this->query)) {
         unset($this->query);
       }
+
+      $keys = array('current_display', 'display_handler', 'build_info', 'built', 'executed', 'attachment_before', 'attachment_after', 'field', 'argument', 'filter', 'sort', 'relationship', 'header', 'footer', 'empty', 'query', 'result', 'inited', 'style_plugin', 'plugin_name', 'exposed_data', 'exposed_input', 'many_to_one_tables');
+      foreach ($keys as $key) {
+        if (isset($this->$key)) {
+          unset($this->$key);
+        }
+      }
+      $this->built = $this->executed = FALSE;
+      $this->build_info = array();
+      $this->attachment_before = '';
+      $this->attachment_after = '';
     }
   }
 
@@ -1847,7 +1870,14 @@ class views_db_object {
       'field' => $field,
     ) + $options;
 
-    $handler = views_get_handler($table, $field, $type);
+    if (!empty($types[$type]['type'])) {
+      $handler_type = $types[$type]['type'];
+    }
+    else {
+      $handler_type = $type;
+    }
+
+    $handler = views_get_handler($table, $field, $handler_type);
 
     $fields[$id] = $new_item;
     $this->display[$display_id]->handler->set_option($types[$type]['plural'], $fields);
@@ -1990,6 +2020,30 @@ function views_object_types() {
         'lstitle' => t('Relationship'),
         'plural' => 'relationships',
       ),
+      'header' => array(
+        'title' => t('Header'),
+        'ltitle' => t('header'),
+        'stitle' => t('Header'),
+        'lstitle' => t('Header'),
+        'plural' => 'header',
+        'type' => 'area',
+      ),
+      'footer' => array(
+        'title' => t('Footer'),
+        'ltitle' => t('footer'),
+        'stitle' => t('Footer'),
+        'lstitle' => t('Footer'),
+        'plural' => 'footer',
+        'type' => 'area',
+      ),
+      'empty' => array(
+        'title' => t('Empty text'),
+        'ltitle' => t('empty text'),
+        'stitle' => t('Empty text'),
+        'lstitle' => t('Empty text'),
+        'plural' => 'empty',
+        'type' => 'area',
+      ),
     );
   }
 
Index: js/ajax.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/js/ajax.js,v
retrieving revision 1.25
diff -u -p -r1.25 ajax.js
--- js/ajax.js	24 Mar 2009 23:03:32 -0000	1.25
+++ js/ajax.js	11 Aug 2010 21:11:32 -0000
@@ -1,4 +1,4 @@
-// $Id: ajax.js,v 1.25 2009/03/24 23:03:32 merlinofchaos Exp $
+// $Id: ajax.js,v 1.25.2.11 2010/04/08 21:29:51 merlinofchaos Exp $
 /**
  * @file ajax_admin.js
  *
@@ -25,7 +25,7 @@ Drupal.Views.Ajax.setForm = function(tit
  *   the id to append via $(key).append(value)
  * - 'replace': This is a keyed array of HTML output to add via replace. The key is
  *   the id to append via $(key).html(value)
- * 
+ *
  */
 Drupal.Views.Ajax.ajaxResponse = function(data) {
   $('a.views-throbbing').removeClass('views-throbbing');
@@ -53,11 +53,11 @@ Drupal.Views.Ajax.ajaxResponse = functio
     if (data.url) {
       var ajax_area = Drupal.settings.views.ajax.id;
       var ajax_title = Drupal.settings.views.ajax.title;
-    
+
       // Bind a click to the button to set the value for the button.
-      $('input[type=submit]', ajax_area).unbind('click');
-      $('input[type=submit]', ajax_area).click(function() {
-        $('form', ajax_area).append('<input type="hidden" name="' 
+      $('input[type=submit], button', ajax_area).unbind('click');
+      $('input[type=submit], button', ajax_area).click(function() {
+        $('form', ajax_area).append('<input type="hidden" name="'
           + $(this).attr('name') + '" value="' + $(this).val() + '">');
         $(this).after('<span class="views-throbbing">&nbsp</span>');
       });
@@ -67,10 +67,10 @@ Drupal.Views.Ajax.ajaxResponse = functio
       $('form', ajax_area).submit(function(arg) {
         $(this).ajaxSubmit({
           url: data.url,
-          data: '',
+          data: { 'js': 1 },
           type: 'POST',
           success: Drupal.Views.Ajax.ajaxResponse,
-          error: function() { $('span.views-throbbing').remove(); alert(Drupal.t("An error occurred at @path.", {'@path': data.url})); },
+          error: function(xhr) { $('span.views-throbbing').remove(); Drupal.Views.Ajax.handleErrors(xhr, data.url); },
           dataType: 'json'
         });
         return false;
@@ -79,14 +79,16 @@ Drupal.Views.Ajax.ajaxResponse = functio
 
     Drupal.attachBehaviors(ajax_area);
   }
-  else {
+  else if (!data.tab) {
     // If no display, reset the form.
     Drupal.Views.Ajax.setForm('', Drupal.settings.views.ajax.defaultForm);
     //Enable the save button.
     $('#edit-save').removeAttr('disabled');
     // Trigger an update for the live preview when we reach this state:
-    $('#views-ui-preview-form').trigger('submit');
-  } 
+    if ($('#views-ui-preview-form input#edit-live-preview').is(':checked')) {
+      $('#views-ui-preview-form').trigger('submit');
+    }
+  }
 
   // Go through the 'add' array and add any new content we're instructed to add.
   if (data.add) {
@@ -107,18 +109,22 @@ Drupal.Views.Ajax.ajaxResponse = functio
   // Go through and add any requested tabs
   if (data.tab) {
     for (id in data.tab) {
-      $('#views-tabset').addTab(id, data.tab[id]['title'], 0);
+      // Retrieve the tabset instance by stored ID.
+      var instance = Drupal.Views.Tabs.instances[$('#views-tabset').data('UI_TABS_UUID')];
+      instance.add(id, data.tab[id]['title'], 0);
+      instance.click(instance.$tabs.length);
+
       $(id).html(data.tab[id]['body']);
       $(id).addClass('views-tab');
-      Drupal.attachBehaviors(id);
 
-      // This is kind of annoying, but we have to actually to find where the new
-      // tab is.
-      var instance = $.ui.tabs.instances[$('#views-tabset').get(0).UI_TABS_UUID];
-      $('#views-tabset').clickTab(instance.$tabs.length);
+      // Update the preview widget to preview the new tab.
+      var display_id = id.replace('#views-tab-', '');
+      $("#preview-display-id").append('<option selected="selected" value="' + display_id + '">' + data.tab[id]['title'] + '</option>');
+
+      Drupal.attachBehaviors(id);
     }
   }
-  
+
   if (data.hilite) {
     $('.hilited').removeClass('hilited');
     $(data.hilite).addClass('hilited');
@@ -161,11 +167,11 @@ Drupal.Views.Ajax.previewResponse = func
     var url = $(ajax_area, 'form').attr('action');
 
     // if a URL was supplied, bind the form to it.
-    if (url) {   
+    if (url) {
       // Bind a click to the button to set the value for the button.
-      $('input[type=submit]', ajax_area).unbind('click');
-      $('input[type=submit]', ajax_area).click(function() {
-        $('form', ajax_area).append('<input type="hidden" name="' 
+      $('input[type=submit], button', ajax_area).unbind('click');
+      $('input[type=submit], button', ajax_area).click(function() {
+        $('form', ajax_area).append('<input type="hidden" name="'
           + $(this).attr('name') + '" value="' + $(this).val() + '">');
         $(this).after('<span class="views-throbbing">&nbsp</span>');
       });
@@ -175,10 +181,10 @@ Drupal.Views.Ajax.previewResponse = func
       $('form', ajax_area).submit(function() {
         $(this).ajaxSubmit({
           url: url,
-          data: '',
+          data: { 'js': 1 },
           type: 'POST',
           success: Drupal.Views.Ajax.previewResponse,
-          error: function() { $('span.views-throbbing').remove(); alert(Drupal.t("An error occurred at @path.", {'@path': url})); },
+          error: function(xhr) { $('span.views-throbbing').remove(); Drupal.Views.Ajax.handleErrors(xhr, url); },
           dataType: 'json'
         });
         return false;
@@ -193,13 +199,13 @@ Drupal.Views.updatePreviewForm = functio
   var url = $(this).attr('action');
   url = url.replace('nojs', 'ajax');
 
-  $('input[type=submit]', this).after('<span class="views-throbbing">&nbsp</span>');
+  $('input[type=submit], button', this).after('<span class="views-throbbing">&nbsp</span>');
   $(this).ajaxSubmit({
     url: url,
-    data: '',
+    data: { 'js': 1 },
     type: 'POST',
     success: Drupal.Views.Ajax.previewResponse,
-    error: function() { $('span.views-throbbing').remove(); alert(Drupal.t("An error occurred at @path.", {'@path': url})); },
+    error: function(xhr) { $('span.views-throbbing').remove(); Drupal.Views.Ajax.handleErrors(xhr, url); },
     dataType: 'json'
   });
 
@@ -210,14 +216,13 @@ Drupal.Views.updatePreviewFilterForm = f
   var url = $(this).attr('action');
   url = url.replace('nojs', 'ajax');
 
-  $('input[type=submit]', this).after('<span class="views-throbbing">&nbsp</span>');
   $('input[name=q]', this).remove(); // remove 'q' for live preview.
   $(this).ajaxSubmit({
     url: url,
-    data: '',
+    data: { 'js': 1 },
     type: 'GET',
     success: Drupal.Views.Ajax.previewResponse,
-    error: function() { $('span.views-throbbing').remove(); alert(Drupal.t("An error occurred at @path.", {'@path': url})); },
+    error: function(xhr) { $('span.views-throbbing').remove(); Drupal.Views.Ajax.handleErrors(xhr, url); },
     dataType: 'json'
   });
 
@@ -234,14 +239,14 @@ Drupal.Views.updatePreviewLink = functio
   $(this).addClass('views-throbbing');
   $.ajax({
     url: url,
-    data: '',
+    data: 'js=1',
     type: 'POST',
     success: Drupal.Views.Ajax.previewResponse,
-    error: function() { $(this).removeClass('views-throbbing'); alert(Drupal.t("An error occurred at @path.", {'@path': url})); },
+    error: function(xhr) { $(this).removeClass('views-throbbing'); Drupal.Views.Ajax.handleErrors(xhr, url); },
     dataType: 'json'
   });
 
-  return false;   
+  return false;
 }
 
 Drupal.behaviors.ViewsAjaxLinks = function() {
@@ -257,19 +262,19 @@ Drupal.behaviors.ViewsAjaxLinks = functi
 
     // Disable the save button.
     $('#edit-save').attr('disabled', 'true');
-    
+
     $(this).addClass('views-throbbing');
     $.ajax({
       type: "POST",
       url: url,
-      data: '',
+      data: 'js=1',
       success: Drupal.Views.Ajax.ajaxResponse,
-      error: function() { $(this).removeClass('views-throbbing'); alert(Drupal.t("An error occurred at @path.", {'@path': url})); },
+      error: function(xhr) { $(this).removeClass('views-throbbing'); Drupal.Views.Ajax.handleErrors(xhr, url); },
       dataType: 'json'
     });
-    
+
     return false;
-  });  
+  });
 
   $('form.views-ajax-form:not(.views-processed)').addClass('views-processed').submit(function(arg) {
     // Translate the href on the link to the ajax href. That way this degrades
@@ -280,14 +285,14 @@ Drupal.behaviors.ViewsAjaxLinks = functi
 //    $('input[@type=submit]', this).after('<span class="views-throbbing">&nbsp</span>');
     $(this).ajaxSubmit({
       url: url,
-      data: '',
+      data: { 'js': 1 },
       type: 'POST',
       success: Drupal.Views.Ajax.ajaxResponse,
-      error: function() { $('span.views-throbbing').remove(); alert(Drupal.t("An error occurred at @path.", {'@path': url})); },
+      error: function(xhr) { $('span.views-throbbing').remove(); Drupal.Views.Ajax.handleErrors(xhr, url); },
       dataType: 'json'
     });
 
-    return false;   
+    return false;
   });
 
   // Bind the live preview to where it's supposed to go.
@@ -298,7 +303,13 @@ Drupal.behaviors.ViewsAjaxLinks = functi
 
   $('div#views-live-preview form:not(.views-processed)')
     .addClass('views-processed')
-    .submit(Drupal.Views.updatePreviewFilterForm);
+    .submit(Drupal.Views.updatePreviewFilterForm)
+    .find('input[type=submit], button').click(function() {
+      $(this).after('<span class="views-throbbing">&nbsp</span>');
+      // We have to actually tell it what button got clicked if we want
+      // anything to be sent:
+      this.form.clk = this;
+    });
 
   $('div#views-live-preview a:not(.views-processed)')
     .addClass('views-processed')
@@ -306,8 +317,119 @@ Drupal.behaviors.ViewsAjaxLinks = functi
 }
 
 /**
+ * Sync preview display.
+ */
+Drupal.behaviors.syncPreviewDisplay = function() {
+  $("#views-tabset a").click(function() {
+    var href = $(this).attr('href');
+    // Cut of #views-tabset.
+    var display_id = href.substr(11);
+    // Set the form element.
+    $("#views-live-preview #preview-display-id").val(display_id);
+  });
+}
+
+/**
  * Get rid of irritating tabledrag messages
  */
-Drupal.theme.tableDragChangedWarning = function () { 
-  return ' '; 
+Drupal.theme.tableDragChangedWarning = function () {
+  return '<div></div>';
+}
+
+/**
+ * Display error in a more fashion way
+ */
+Drupal.Views.Ajax.handleErrors = function (xhr, path) {
+  var error_text = '';
+
+  if ((xhr.status == 500 && xhr.responseText) || xhr.status == 200) {
+    error_text = xhr.responseText;
+
+    // Replace all &lt; and &gt; by < and >
+    error_text = error_text.replace("/&(lt|gt);/g", function (m, p) {
+      return (p == "lt")? "<" : ">";
+    });
+
+    // Now, replace all html tags by empty spaces
+    error_text = error_text.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi,"");
+
+    // Fix end lines
+    error_text = error_text.replace(/[\n]+\s+/g,"\n");
+  }
+  else if (xhr.status == 500) {
+    error_text = xhr.status + ': ' + Drupal.t("Internal server error. Please see server or PHP logs for error information.");
+  }
+  else {
+    error_text = xhr.status + ': ' + xhr.statusText;
+  }
+
+  alert(Drupal.t("An error occurred at @path.\n\nError Description: @error", {'@path': path, '@error': error_text}));
 }
+
+// $Id: ajax.js,v 1.25.2.11 2010/04/08 21:29:51 merlinofchaos Exp $
+
+Drupal.behaviors.ViewsGroupedTableDrag = function(context) {
+  var table_id = 'arrange';
+  var table = $('table#arrange');
+  var tableDrag = Drupal.tableDrag[table_id];
+
+  if (tableDrag) {
+    // Add a handler for when a row is swapped, update empty regions.
+    tableDrag.row.prototype.onSwap = function(swappedRow) {
+      checkEmptyRegions(table, this);
+    };
+
+    $('a.views-groups-remove-link')
+      .addClass('views-processed')
+      .click(function() {
+        var id = $(this).attr('id').replace('views-remove-link-', '');
+        var $row = $('#views-row-' + id);
+        $row.hide().removeClass('draggable');
+        $('#views-removed-' + id).attr('checked', true);
+        tableDrag.rowObject = new tableDrag.row($row.get(0), 'mouse', tableDrag.indentEnabled, tableDrag.maxDepth, true);
+        // If there is a draggable row after the row we just removed, swap us
+        // down by one so that the empty region check does not see this row
+        // and think that the region is empty.
+        if ($row.next('tr').is('.draggable')) {
+          tableDrag.rowObject.swap('after', $row.next('tr').get(0));
+        }
+        checkEmptyRegions(table, tableDrag.rowObject);
+        return false;
+      });
+
+    // Add a handler so when a row is dropped, update fields dropped into new group.
+    tableDrag.onDrop = function() {
+      dragObject = this;
+      // If this occurs row is in an empty group or its is the first of the group
+      if ($(dragObject.rowObject.element).prev('tr').is('.group-message')) {
+        // Get the previous group, this contains the group id
+        var regionRow = $(dragObject.rowObject.element).prev('tr').get(0);
+        var groupId = regionRow.className.replace(/([^ ]+[ ]+)*group-([^ ]+)-message([ ]+[^ ]+)*/, '$2');
+        // Then, update the select group value
+        var selectGroupField = $('select.views-group-select', dragObject.rowObject.element);
+        selectGroupField.val(groupId);
+      }
+    }
+
+    var checkEmptyRegions = function(table, rowObject) {
+      $('tr.group-message', table).each(function() {
+        // If the dragged row is in this region, but above the message row, swap it down one space.
+        if ($(this).prev('tr').get(0) == rowObject.element) {
+          // Prevent a recursion problem when using the keyboard to move rows up.
+          if ((rowObject.method != 'keyboard' || rowObject.direction == 'down')) {
+            rowObject.swap('after', this);
+          }
+        }
+        // This region has become empty
+        if ($(this).next('tr').is(':not(.draggable)') || $(this).next('tr').size() == 0) {
+          $(this).removeClass('group-populated').addClass('group-empty');
+        }
+        // This region has become populated.
+        else if ($(this).is('.group-empty')) {
+          $(this).removeClass('group-empty').addClass('group-populated');
+        }
+      });
+    };
+  }
+}
+
Index: js/ajax_view.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/js/ajax_view.js,v
retrieving revision 1.18
diff -u -p -r1.18 ajax_view.js
--- js/ajax_view.js	2 Jun 2009 19:30:44 -0000	1.18
+++ js/ajax_view.js	11 Aug 2010 21:11:32 -0000
@@ -1,4 +1,4 @@
-// $Id: ajax_view.js,v 1.18 2009/06/02 19:30:44 merlinofchaos Exp $
+// $Id: ajax_view.js,v 1.17.2.8 2010/03/25 18:25:33 merlinofchaos Exp $
 
 /**
  * @file ajaxView.js
@@ -29,7 +29,7 @@ Drupal.Views.Ajax.ajaxViewResponse = fun
     $view = $newView;
     Drupal.attachBehaviors($view.parent());
   }
- 
+
   if (response.messages) {
     // Show any messages (but first remove old ones, if there are any).
     $view.find('.views-messages').remove().end().prepend(response.messages);
@@ -37,7 +37,7 @@ Drupal.Views.Ajax.ajaxViewResponse = fun
 };
 
 /**
- * Ajax behavior for views. 
+ * Ajax behavior for views.
  */
 Drupal.behaviors.ViewsAjaxView = function() {
   if (Drupal.settings && Drupal.settings.views && Drupal.settings.views.ajaxViews) {
@@ -65,6 +65,13 @@ Drupal.behaviors.ViewsAjaxView = functio
         // but this method is submitting elsewhere.
         $('input[name=q]', this).remove();
         var form = this;
+
+        $('input[type=submit], button', this).click(function () {
+          $(this).after('<span class="views-throbbing">&nbsp</span>');
+          // We have to actually tell it what button got clicked if we want
+          // anything to be sent:
+          form.clk = this;
+        });
         // ajaxSubmit doesn't accept a data argument, so we have to
         // pass additional fields this way.
         $.each(settings, function(key, setting) {
@@ -73,7 +80,6 @@ Drupal.behaviors.ViewsAjaxView = functio
       })
       .addClass('views-processed')
       .submit(function () {
-        $('input[type=submit]', this).after('<span class="views-throbbing">&nbsp</span>');
         var object = this;
         $(this).ajaxSubmit({
           url: ajax_path,
@@ -87,7 +93,7 @@ Drupal.behaviors.ViewsAjaxView = functio
               $('.views-throbbing', object).remove();
             }
           },
-          error: function() { alert(Drupal.t("An error occurred at @path.", {'@path': ajax_path})); $('.views-throbbing', object).remove(); },
+          error: function(xhr) { Drupal.Views.Ajax.handleErrors(xhr, ajax_path); $('.views-throbbing', object).remove(); },
           dataType: 'json'
         });
 
@@ -110,17 +116,19 @@ Drupal.behaviors.ViewsAjaxView = functio
             // Process pager, tablesort, and attachment summary links.
             .find('ul.pager > li > a, th.views-field a, .attachment .views-summary a')
             .each(function () {
-              var viewData = {};
+              var viewData = { 'js': 1 };
               // Construct an object using the settings defaults and then overriding
               // with data specific to the link.
               $.extend(
                 viewData,
-                settings,
                 Drupal.Views.parseQueryString($(this).attr('href')),
                 // Extract argument data from the URL.
-                Drupal.Views.parseViewArgs($(this).attr('href'), settings.view_base_path)
+                Drupal.Views.parseViewArgs($(this).attr('href'), settings.view_base_path),
+                // Settings must be used last to avoid sending url aliases to the server.
+                settings
               );
               $(this).click(function () {
+                $.extend(viewData, Drupal.Views.parseViewArgs($(this).attr('href'), settings.view_base_path));
                 $(this).addClass('views-throbbing');
                 $.ajax({
                   url: ajax_path,
@@ -132,9 +140,17 @@ Drupal.behaviors.ViewsAjaxView = functio
                     // to browse newly loaded content after e.g. clicking a pager
                     // link.
                     var offset = $(target).offset();
+                    // We can't guarantee that the scrollable object should be
+                    // the body, as the view could be embedded in something
+                    // more complex such as a modal popup. Recurse up the DOM
+                    // and scroll the first element that has a non-zero top.
+                    var scrollTarget = target;
+                    while ($(scrollTarget).scrollTop() == 0 && $(scrollTarget).parent()) {
+                      scrollTarget = $(scrollTarget).parent()
+                    }
                     // Only scroll upward
-                    if (offset.top - 10 < $(window).scrollTop()) {
-                      $('html,body').animate({scrollTop: (offset.top - 10)}, 500);
+                    if (offset.top - 10 < $(scrollTarget).scrollTop()) {
+                      $(scrollTarget).animate({scrollTop: (offset.top - 10)}, 500);
                     }
                     // Call all callbacks.
                     if (response.__callbacks) {
@@ -143,7 +159,7 @@ Drupal.behaviors.ViewsAjaxView = functio
                       });
                     }
                   },
-                  error: function() { $(this).removeClass('views-throbbing'); alert(Drupal.t("An error occurred at @path.", {'@path': ajax_path})); },
+                  error: function(xhr) { $(this).removeClass('views-throbbing'); Drupal.Views.Ajax.handleErrors(xhr, ajax_path); },
                   dataType: 'json'
                 });
 
Index: js/base.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/js/base.js,v
retrieving revision 1.11
diff -u -p -r1.11 base.js
--- js/base.js	2 Jun 2009 18:45:38 -0000	1.11
+++ js/base.js	11 Aug 2010 21:11:32 -0000
@@ -1,4 +1,4 @@
-// $Id: base.js,v 1.11 2009/06/02 18:45:38 merlinofchaos Exp $
+// $Id: base.js,v 1.10.2.4 2010/07/27 22:47:52 merlinofchaos Exp $
 /**
  * @file base.js
  *
@@ -11,11 +11,9 @@ Drupal.Views = {};
  * jQuery UI tabs, Views integration component
  */
 Drupal.behaviors.viewsTabs = function (context) {
-  if ($.ui && $.ui.tabs) {
-    $('#views-tabset:not(.views-processed)').addClass('views-processed').tabs({
-      selectedClass: 'active'
-    });
-  }
+  $('#views-tabset:not(.views-processed)').addClass('views-processed').each(function() {
+    new Drupal.Views.Tabs($(this), {selectedClass: 'active'});
+  });
 
   $('a.views-remove-link')
     .addClass('views-processed')
@@ -25,6 +23,18 @@ Drupal.behaviors.viewsTabs = function (c
       $('#views-removed-' + id).attr('checked', true);
       return false;
     });
+  /**
+   * Here is to handle display deletion 
+   * (checking in the hidden checkbox and hiding out the row) 
+   */
+  $('a.display-remove-link')
+    .addClass('display-processed')
+    .click(function() {
+      var id = $(this).attr('id').replace('display-remove-link-', '');
+      $('#display-row-' + id).hide();
+      $('#display-removed-' + id).attr('checked', true);
+      return false;
+    });
 }
 
 /**
@@ -66,10 +76,12 @@ Drupal.Views.parseQueryString = function
   }
   var pairs = query.split('&');
   for(var i in pairs) {
-    var pair = pairs[i].split('=');
-    // Ignore the 'q' path argument, if present.
-    if (pair[0] != 'q' && pair[1]) {
-      args[pair[0]] = decodeURIComponent(pair[1].replace(/\+/g, ' '));
+    if (typeof(pairs[i]) == 'string') {
+      var pair = pairs[i].split('=');
+      // Ignore the 'q' path argument, if present.
+      if (pair[0] != 'q' && pair[1]) {
+        args[pair[0]] = decodeURIComponent(pair[1].replace(/\+/g, ' '));
+      }
     }
   }
   return args;
@@ -121,3 +133,5 @@ Drupal.Views.getPath = function (href) {
   }
   return href;
 };
+
+
Index: js/dependent.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/js/dependent.js,v
retrieving revision 1.8
diff -u -p -r1.8 dependent.js
--- js/dependent.js	2 Jun 2009 17:12:13 -0000	1.8
+++ js/dependent.js	11 Aug 2010 21:11:32 -0000
@@ -1,4 +1,4 @@
-// $Id: dependent.js,v 1.8 2009/06/02 17:12:13 merlinofchaos Exp $
+// $Id: dependent.js,v 1.7.2.3 2009/11/18 02:43:30 merlinofchaos Exp $
 /**
  * @file dependent.js
  *
@@ -7,14 +7,14 @@
  *
  * To your $form item definition add:
  * - '#process' => array('views_process_dependency'),
- * - Add '#dependency' => array('id-of-form-item' => array(list, of, values, that, 
+ * - Add '#dependency' => array('id-of-form-item' => array(list, of, values, that,
      make, this, item, show),
  *
  * Special considerations:
  * - radios are harder. Because Drupal doesn't give radio groups individual ids,
- *   use 'radio:name-of-radio' 
+ *   use 'radio:name-of-radio'
  *
- * - Checkboxes don't have their own id, so you need to add one in a div 
+ * - Checkboxes don't have their own id, so you need to add one in a div
  *   around the checkboxes via #prefix and #suffix. You actually need to add TWO
  *   divs because it's the parent that gets hidden. Also be sure to retain the
  *   'expand_checkboxes' in the #process array, because the views process will
@@ -54,13 +54,13 @@ Drupal.Views.dependent.autoAttach = func
   // Iterate through all relationships
   for (id in Drupal.settings.viewsAjax.formRelationships) {
 
-    // Drupal.Views.dependent.activeBindings[id] is a boolean, 
+    // Drupal.Views.dependent.activeBindings[id] is a boolean,
     // whether the binding is active or not.  Defaults to no.
     Drupal.Views.dependent.activeBindings[id] = 0;
     // Iterate through all possible values
     for(bind_id in Drupal.settings.viewsAjax.formRelationships[id].values) {
       // This creates a backward relationship.  The bind_id is the ID
-      // of the element which needs to change in order for the id to hide or become shown.  
+      // of the element which needs to change in order for the id to hide or become shown.
       // The id is the ID of the item which will be conditionally hidden or shown.
       // Here we're setting the bindings for the bind
       // id to be an empty array if it doesn't already have bindings to it
@@ -81,6 +81,9 @@ Drupal.Views.dependent.autoAttach = func
 
       Drupal.Views.dependent.activeTriggers.push(trigger_id);
 
+      if (jQuery(trigger_id).attr('type') == 'checkbox') {
+        $(trigger_id).parent().addClass('hidden-options');
+      }
 
       var getValue = function(item, trigger) {
         if (item.substring(0, 6) == 'radio:') {
@@ -90,6 +93,14 @@ Drupal.Views.dependent.autoAttach = func
           switch (jQuery(trigger).attr('type')) {
             case 'checkbox':
               var val = jQuery(trigger).attr('checked') || 0;
+
+              if (val) {
+                $(trigger).parent().removeClass('hidden-options').addClass('expanded-options');
+              }
+              else {
+                $(trigger).parent().removeClass('expanded-options').addClass('hidden-options');
+              }
+
               break;
             default:
               var val = jQuery(trigger).val();
@@ -134,9 +145,15 @@ Drupal.Views.dependent.autoAttach = func
               object = jQuery('#' + id).parent();
             }
 
-            if (Drupal.settings.viewsAjax.formRelationships[id].num <= len) {
+            var rel_num = Drupal.settings.viewsAjax.formRelationships[id].num;
+            if (typeof rel_num === 'object') {
+              rel_num = Drupal.settings.viewsAjax.formRelationships[id].num[0];
+            }
+
+            if (rel_num <= len) {
               // Show if the element if criteria is matched
               object.show(0);
+              object.addClass('dependent-options');
             }
             else {
               // Otherwise hide
Index: js/tabs.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/js/tabs.js,v
retrieving revision 1.4
diff -u -p -r1.4 tabs.js
--- js/tabs.js	2 Jun 2009 17:12:13 -0000	1.4
+++ js/tabs.js	11 Aug 2010 21:11:32 -0000
@@ -1,438 +1,402 @@
-// $Id: tabs.js,v 1.4 2009/06/02 17:12:13 merlinofchaos Exp $
+// $Id: tabs.js,v 1.3.2.2 2010/03/10 20:06:03 merlinofchaos Exp $
 
 /**
  * @file tabs.js
  * jQuery UI Tabs (Tabs 3)
- * 
+ *
  * This is nothing more than the pure jquery UI tabs implementation.
+ * It has been implemented under the Drupal.Views.Tabs namespace to
+ * avoid conflicts with alternatve versions of jquery, jquery UI.
  */
-(function($) {
 
-   // if the UI scope is not availalable, add it
-  $.ui = $.ui || {};
+Drupal.Views = Drupal.Views || {};
 
-  $.fn.tabs = function(initial, options) {
-    if (initial && initial.constructor == Object) { // shift arguments
-      options = initial;
-      initial = null;
-    }
-    options = options || {};
-
-    // first get initial tab from options
-    initial = initial && initial.constructor == Number && --initial || 0;
-
-    return this.each(function() {
-    new $.ui.tabs(this, $.extend(options, { initial: initial }));
-    });
-  };
-
-  // chainable tabs methods
-  $.each(['add', 'remove', 'enable', 'disable', 'click', 'load'], function(i, method) {
-    $.fn[method + 'Tab'] = function() {
-      var args = arguments;
-      return this.each(function() {
-        var instance = $.ui.tabs.instances[this.UI_TABS_UUID];
-        instance[method].apply(instance, args);
-      });
-    };
-  });
-  $.fn.selectedTab = function(returnElement) {
-    var selected;
-    if (returnElement) {
-
-    } else {
-
-    }
-    return selected;
-  };
-
-  $.ui.tabs = function(el, options) {
-
-    this.source = el;
+Drupal.Views.Tabs = function(el, options) {
 
-    this.options = $.extend({
+  this.source = el;
 
-      // basic setup
-      initial: 0,
-      event: 'click',
-      disabled: [],
-      // TODO bookmarkable: $.ajaxHistory ? true : false,
-      unselected: false,
-      toggle: options.unselected ? true : false,
-
-      // Ajax
-      spinner: 'Loading&#8230;',
-      cache: false,
-      hashPrefix: 'tab-',
-
-      // animations
-      /*fxFade: null,
-      fxSlide: null,
-      fxShow: null,
-      fxHide: null,*/
-      fxSpeed: 'normal',
-      /*fxShowSpeed: null,
-      fxHideSpeed: null,*/
-
-      // callbacks
-      add: function() {},
-      remove: function() {},
-      enable: function() {},
-      disable: function() {},
-      click: function() {},
-      hide: function() {},
-      show: function() {},
-      load: function() {},
-
-      // CSS classes
-      navClass: 'ui-tabs-nav',
-      selectedClass: 'ui-tabs-selected',
-      disabledClass: 'ui-tabs-disabled',
-      containerClass: 'ui-tabs-container',
-      hideClass: 'ui-tabs-hide',
-      loadingClass: 'ui-tabs-loading'
-
-    }, options);
-
-    this.tabify(true);
-
-    // save instance for later
-    var uuid = 'instance-' + $.ui.tabs.prototype.count++;
-    $.ui.tabs.instances[uuid] = this;
-    this.source['UI_TABS_UUID'] = uuid;
-
-  };
-
-  // static
-  $.ui.tabs.instances = {};
-
-  $.extend($.ui.tabs.prototype, {
-    animating: false,
-    count: 0,
-    tabify: function(init) {
+  this.options = $.extend({
 
-      this.$tabs = $('a:first-child', this.source);
-      this.$containers = $([]);
+    // basic setup
+    initial: 0,
+    event: 'click',
+    disabled: [],
+    // TODO bookmarkable: $.ajaxHistory ? true : false,
+    unselected: false,
+    toggle: options.unselected ? true : false,
+
+    // Ajax
+    spinner: 'Loading&#8230;',
+    cache: false,
+    hashPrefix: 'tab-',
+
+    // animations
+    /*fxFade: null,
+    fxSlide: null,
+    fxShow: null,
+    fxHide: null,*/
+    fxSpeed: 'normal',
+    /*fxShowSpeed: null,
+    fxHideSpeed: null,*/
+
+    // callbacks
+    add: function() {},
+    remove: function() {},
+    enable: function() {},
+    disable: function() {},
+    click: function() {},
+    hide: function() {},
+    show: function() {},
+    load: function() {},
+
+    // CSS classes
+    navClass: 'ui-tabs-nav',
+    selectedClass: 'ui-tabs-selected',
+    disabledClass: 'ui-tabs-disabled',
+    containerClass: 'ui-tabs-container',
+    hideClass: 'ui-tabs-hide',
+    loadingClass: 'ui-tabs-loading'
+
+  }, options);
+
+  this.tabify(true);
+
+  // save instance for later
+  var uuid = 'instance-' + Drupal.Views.Tabs.prototype.count++;
+  Drupal.Views.Tabs.instances[uuid] = this;
+  this.source.data('UI_TABS_UUID', uuid);
+
+};
+
+// static
+Drupal.Views.Tabs.instances = {};
+
+$.extend(Drupal.Views.Tabs.prototype, {
+  animating: false,
+  count: 0,
+  tabify: function(init) {
+
+    this.$tabs = $('a:first-child', this.source);
+    this.$containers = $([]);
+
+    var self = this, o = this.options;
+
+    this.$tabs.each(function(i, a) {
+      // inline tab
+      if (a.hash && a.hash.replace('#', '')) { // safari 2 reports '#' for an empty hash
+        self.$containers = self.$containers.add(a.hash);
+      }
+      // remote tab
+      else {
+        var id = a.title && a.title.replace(/\s/g, '_') || o.hashPrefix + (self.count + 1) + '-' + (i + 1), url = a.href;
+        a.href = '#' + id;
+        a.url = url;
+        self.$containers = self.$containers.add(
+          $('#' + id)[0] || $('<div id="' + id + '" class="' + o.containerClass + '"></div>')
+            .insertAfter( self.$containers[i - 1] || self.source )
+        );
+      }
+    });
 
-      var self = this, o = this.options;
+    if (init) {
 
+      // Try to retrieve initial tab from fragment identifier in url if present,
+      // otherwise try to find selected class attribute on <li>.
       this.$tabs.each(function(i, a) {
-        // inline tab
-        if (a.hash && a.hash.replace('#', '')) { // safari 2 reports '#' for an empty hash
-          self.$containers = self.$containers.add(a.hash);
-        }
-        // remote tab
-        else {
-          var id = a.title && a.title.replace(/\s/g, '_') || o.hashPrefix + (self.count + 1) + '-' + (i + 1), url = a.href;
-          a.href = '#' + id;
-          a.url = url;
-          self.$containers = self.$containers.add(
-            $('#' + id)[0] || $('<div id="' + id + '" class="' + o.containerClass + '"></div>')
-              .insertAfter( self.$containers[i - 1] || self.source )
-          );
-        }
-      });
-
-      if (init) {
-
-        // Try to retrieve initial tab from fragment identifier in url if present,
-        // otherwise try to find selected class attribute on <li>.
-        this.$tabs.each(function(i, a) {
-          if (location.hash) {
-            if (a.hash == location.hash) {
-              o.initial = i;
-              // prevent page scroll to fragment
-              //if (($.browser.msie || $.browser.opera) && !o.remote) {
-              if ($.browser.msie || $.browser.opera) {
-                var $toShow = $(location.hash), toShowId = $toShow.attr('id');
-                $toShow.attr('id', '');
-                setTimeout(function() {
-                  $toShow.attr('id', toShowId); // restore id
-                }, 500);
-              }
-              scrollTo(0, 0);
-              return false; // break
-            }
-          } else if ( $(a).parents('li:eq(0)').is('li.' + o.selectedClass) ) {
+        if (location.hash) {
+          if (a.hash == location.hash) {
             o.initial = i;
+            // prevent page scroll to fragment
+            //if (($.browser.msie || $.browser.opera) && !o.remote) {
+            if ($.browser.msie || $.browser.opera) {
+              var $toShow = $(location.hash), toShowId = $toShow.attr('id');
+              $toShow.attr('id', '');
+              setTimeout(function() {
+                $toShow.attr('id', toShowId); // restore id
+              }, 500);
+            }
+            scrollTo(0, 0);
             return false; // break
           }
-        });
-
-        // attach necessary classes for styling if not present
-        $(this.source).is('.' + o.navClass) || $(this.source).addClass(o.navClass);
-        this.$containers.each(function() {
-          var $this = $(this);
-          $this.is('.' + o.containerClass) || $this.addClass(o.containerClass);
-        });
-
-        // highlight tab accordingly
-        var $lis = $('li', this.source);
-        this.$containers.addClass(o.hideClass);
-        $lis.removeClass(o.selectedClass);
-        if (!o.unselected) {
-          this.$containers.slice(o.initial, o.initial + 1).show();
-          $lis.slice(o.initial, o.initial + 1).addClass(o.selectedClass);
+        } else if ( $(a).parents('li:eq(0)').is('li.' + o.selectedClass) ) {
+          o.initial = i;
+          return false; // break
         }
+      });
 
-        // trigger load of initial tab is remote tab
-        if (this.$tabs[o.initial].url) {
-          this.load(o.initial + 1, this.$tabs[o.initial].url);
-          if (o.cache) {
-            this.$tabs[o.initial].url = null; // if loaded once do not load them again
-          }
-        }
+      // attach necessary classes for styling if not present
+      $(this.source).is('.' + o.navClass) || $(this.source).addClass(o.navClass);
+      this.$containers.each(function() {
+        var $this = $(this);
+        $this.is('.' + o.containerClass) || $this.addClass(o.containerClass);
+      });
 
-        // disabled tabs
-        for (var i = 0, position; position = o.disabled[i]; i++) {
-          this.disable(position);
+      // highlight tab accordingly
+      var $lis = $('li', this.source);
+      this.$containers.addClass(o.hideClass);
+      $lis.removeClass(o.selectedClass);
+      if (!o.unselected) {
+        this.$containers.slice(o.initial, o.initial + 1).show();
+        $lis.slice(o.initial, o.initial + 1).addClass(o.selectedClass);
+      }
+
+      // trigger load of initial tab is remote tab
+      if (this.$tabs[o.initial].url) {
+        this.load(o.initial + 1, this.$tabs[o.initial].url);
+        if (o.cache) {
+          this.$tabs[o.initial].url = null; // if loaded once do not load them again
         }
-
       }
 
-      // setup animations
-      var showAnim = {}, hideAnim = {}, showSpeed = o.fxShowSpeed || o.fxSpeed, 
-        hideSpeed = o.fxHideSpeed || o.fxSpeed;
-      if (o.fxSlide || o.fxFade) {
-        if (o.fxSlide) {
-          showAnim['height'] = 'show';
-          hideAnim['height'] = 'hide';
-        }
-        if (o.fxFade) {
-          showAnim['opacity'] = 'show';
-          hideAnim['opacity'] = 'hide';
-        }
-      } else {
-        if (o.fxShow) {
-          showAnim = o.fxShow;
-        } else { // use some kind of animation to prevent browser scrolling to the tab
-          showAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox
-          showSpeed = 1; // as little as 1 is sufficient
-        }
-        if (o.fxHide) {
-          hideAnim = o.fxHide;
-        } else { // use some kind of animation to prevent browser scrolling to the tab
-          hideAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox
-          hideSpeed = 1; // as little as 1 is sufficient
-        }
+      // disabled tabs
+      for (var i = 0, position; position = o.disabled[i]; i++) {
+        this.disable(position);
       }
 
-      // callbacks
-      var click = o.click, hide = o.hide, show = o.show;
+    }
 
-      // reset some styles to maintain print style sheets etc.
-      var resetCSS = { display: '', overflow: '', height: '' };
-      if (!$.browser.msie) { // not in IE to prevent ClearType font issue
-        resetCSS['opacity'] = '';
-      }
-
-      // hide a tab, animation prevents browser scrolling to fragment
-      function hideTab(clicked, $hide, $show) {
-        $hide.animate(hideAnim, hideSpeed, function() { //
-          $hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.            
-          hide(clicked, $show, $hide[0]);
-          if ($show) {
-            showTab(clicked, $hide, $show);
-          }
-        });
+    // setup animations
+    var showAnim = {}, hideAnim = {}, showSpeed = o.fxShowSpeed || o.fxSpeed,
+      hideSpeed = o.fxHideSpeed || o.fxSpeed;
+    if (o.fxSlide || o.fxFade) {
+      if (o.fxSlide) {
+        showAnim['height'] = 'show';
+        hideAnim['height'] = 'hide';
+      }
+      if (o.fxFade) {
+        showAnim['opacity'] = 'show';
+        hideAnim['opacity'] = 'hide';
       }
+    } else {
+      if (o.fxShow) {
+        showAnim = o.fxShow;
+      } else { // use some kind of animation to prevent browser scrolling to the tab
+        showAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox
+        showSpeed = 1; // as little as 1 is sufficient
+      }
+      if (o.fxHide) {
+        hideAnim = o.fxHide;
+      } else { // use some kind of animation to prevent browser scrolling to the tab
+        hideAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox
+        hideSpeed = 1; // as little as 1 is sufficient
+      }
+    }
 
-      // show a tab, animation prevents browser scrolling to fragment
-      function showTab(clicked, $hide, $show) {
-        // show next tab
-        if (!(o.fxSlide || o.fxFade || o.fxShow)) {
-          $show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab containers
-        }
-        $show.animate(showAnim, showSpeed, function() {
-          $show.removeClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
-          if ($.browser.msie) {
-            $hide[0].style.filter = '';
-            $show[0].style.filter = '';
-          }
-          show(clicked, $show[0], $hide[0]);
-          self.animating = false;
-        });
+    // callbacks
+    var click = o.click, hide = o.hide, show = o.show;
 
-      }
+    // reset some styles to maintain print style sheets etc.
+    var resetCSS = { display: '', overflow: '', height: '' };
+    if (!$.browser.msie) { // not in IE to prevent ClearType font issue
+      resetCSS['opacity'] = '';
+    }
 
-      // switch a tab
-      function switchTab(clicked, $hide, $show) {
-        /*if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click
-          $.ajaxHistory.update(clicked.hash);
-        }*/
-        $(clicked).parents('li:eq(0)').addClass(o.selectedClass)
-          .siblings().removeClass(o.selectedClass);
-        hideTab(clicked, $hide, $show);
-      }
-
-      // tab click handler
-      function tabClick(e) {
-
-        //var trueClick = e.clientX; // add to history only if true click occured, not a triggered click
-        var $li = $(this).parents('li:eq(0)'), $hide = self.$containers.filter(':visible'), $show = $(this.hash);
-
-        // if tab may be closed
-        if (o.toggle && !$li.is('.' + o.disabledClass) && !self.animating) {       
-          if ($li.is('.' + o.selectedClass)) {
-            $li.removeClass(o.selectedClass);
-            hideTab(this, $hide);
-            this.blur();
-            return false;
-          } else if (!$hide.length) {
-            $li.addClass(o.selectedClass);
-            showTab(this, $hide, $show);
-            this.blur();
-            return false;
-          }
+    // hide a tab, animation prevents browser scrolling to fragment
+    function hideTab(clicked, $hide, $show) {
+      $hide.animate(hideAnim, hideSpeed, function() { //
+        $hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
+        hide(clicked, $show, $hide[0]);
+        if ($show) {
+          showTab(clicked, $hide, $show);
         }
+      });
+    }
 
-        // If tab is already selected or disabled, animation is still running or click callback 
-        // returns false stop here.
-        // Check if click handler returns false last so that it is not executed for a disabled tab!
-        if ($li.is('.' + o.selectedClass + ', .' + o.disabledClass) 
-          || self.animating || click(this, $show[0], $hide[0]) === false) {
+    // show a tab, animation prevents browser scrolling to fragment
+    function showTab(clicked, $hide, $show) {
+      // show next tab
+      if (!(o.fxSlide || o.fxFade || o.fxShow)) {
+        $show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab containers
+      }
+      $show.animate(showAnim, showSpeed, function() {
+        $show.removeClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
+        if ($.browser.msie) {
+          $hide[0].style.filter = '';
+          $show[0].style.filter = '';
+        }
+        show(clicked, $show[0], $hide[0]);
+        self.animating = false;
+      });
+
+    }
+
+    // switch a tab
+    function switchTab(clicked, $hide, $show) {
+      /*if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click
+        $.ajaxHistory.update(clicked.hash);
+      }*/
+      $(clicked).parents('li:eq(0)').addClass(o.selectedClass)
+        .siblings().removeClass(o.selectedClass);
+      hideTab(clicked, $hide, $show);
+    }
+
+    // tab click handler
+    function tabClick(e) {
+
+      //var trueClick = e.clientX; // add to history only if true click occured, not a triggered click
+      var $li = $(this).parents('li:eq(0)'), $hide = self.$containers.filter(':visible'), $show = $(this.hash);
+
+      // if tab may be closed
+      if (o.toggle && !$li.is('.' + o.disabledClass) && !self.animating) {
+        if ($li.is('.' + o.selectedClass)) {
+          $li.removeClass(o.selectedClass);
+          hideTab(this, $hide);
+          this.blur();
+          return false;
+        } else if (!$hide.length) {
+          $li.addClass(o.selectedClass);
+          showTab(this, $hide, $show);
           this.blur();
           return false;
         }
+      }
 
-        self.animating = true;
+      // If tab is already selected or disabled, animation is still running or click callback
+      // returns false stop here.
+      // Check if click handler returns false last so that it is not executed for a disabled tab!
+      if ($li.is('.' + o.selectedClass + ', .' + o.disabledClass)
+        || self.animating || click(this, $show[0], $hide[0]) === false) {
+        this.blur();
+        return false;
+      }
 
-        // show new tab
-        if ($show.length) {
+      self.animating = true;
 
-          // prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled
-          /*if ($.browser.msie && o.bookmarkable) {
-            var showId = this.hash.replace('#', '');
-            $show.attr('id', '');
-            setTimeout(function() {
-              $show.attr('id', showId); // restore id
-            }, 0);
-          }*/
-
-          if (this.url) { // remote tab
-            var a = this;
-            self.load(self.$tabs.index(this) + 1, this.url, function() {
-              switchTab(a, $hide, $show);
-            });
-            if (o.cache) {
-              this.url = null; // if loaded once do not load them again
-            }
-          } else {
-            switchTab(this, $hide, $show);
-          }
+      // show new tab
+      if ($show.length) {
 
-          // Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash
-          /*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0;
-          var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0;
+        // prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled
+        /*if ($.browser.msie && o.bookmarkable) {
+          var showId = this.hash.replace('#', '');
+          $show.attr('id', '');
           setTimeout(function() {
-            scrollTo(scrollX, scrollY);
-          }, 0);*/
+            $show.attr('id', showId); // restore id
+          }, 0);
+        }*/
 
+        if (this.url) { // remote tab
+          var a = this;
+          self.load(self.$tabs.index(this) + 1, this.url, function() {
+            switchTab(a, $hide, $show);
+          });
+          if (o.cache) {
+            this.url = null; // if loaded once do not load them again
+          }
         } else {
-          throw Drupal.t('jQuery UI Tabs: Mismatching fragment identifier.');
+          switchTab(this, $hide, $show);
         }
 
-        this.blur(); // prevent IE from keeping other link focussed when using the back button
-
-        //return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE
-        return false;
+        // Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash
+        /*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0;
+        var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0;
+        setTimeout(function() {
+          scrollTo(scrollX, scrollY);
+        }, 0);*/
 
+      } else {
+        throw Drupal.t('jQuery UI Tabs: Mismatching fragment identifier.');
       }
 
-      // attach click event, avoid duplicates from former tabifying
-      this.$tabs.unbind(o.event, tabClick).bind(o.event, tabClick);
+      this.blur(); // prevent IE from keeping other link focussed when using the back button
 
-    },
-    add: function(url, text, position) {
-      if (url && text) {
-        var o = this.options;
-        position = position || this.$tabs.length; // append by default
-        if (position >= this.$tabs.length) {
-          var method = 'insertAfter';
-          position = this.$tabs.length;
-        } else {
-          var method = 'insertBefore';
-        }
-        if (url.indexOf('#') == 0) { // ajax container is created by tabify automatically
-          var $container = $(url);
-          // try to find an existing element before creating a new one
-          ($container.length && $container || $('<div id="' + url.replace('#', '') + '" class="' + o.containerClass + ' ' + o.hideClass + '"></div>'))
-            [method](this.$containers[position - 1]);
-        }
-        $('<li><a href="' + url + '"><span>' + text + '</span></a></li>')
-          [method](this.$tabs.slice(position - 1, position).parents('li:eq(0)'));
-        this.tabify();
-        o.add(this.$tabs[position - 1], this.$containers[position - 1]); // callback
+      //return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE
+      return false;
+
+    }
+
+    // attach click event, avoid duplicates from former tabifying
+    this.$tabs.unbind(o.event, tabClick).bind(o.event, tabClick);
+
+  },
+  add: function(url, text, position) {
+    if (url && text) {
+      var o = this.options;
+      position = position || this.$tabs.length; // append by default
+      if (position >= this.$tabs.length) {
+        var method = 'insertAfter';
+        position = this.$tabs.length;
       } else {
-        throw Drupal.t('jQuery UI Tabs: Not enough arguments to add tab.');
+        var method = 'insertBefore';
       }
-    },
-    remove: function(position) {
-      if (position && position.constructor == Number) {
-        this.$tabs.slice(position - 1, position).parents('li:eq(0)').remove();
-        this.$containers.slice(position - 1, position).remove();
-        this.tabify();
-      }
-      this.options.remove(); // callback
-    },
-    enable: function(position) {
-      var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options;
-      $li.removeClass(o.disabledClass);
-      if ($.browser.safari) { // fix disappearing tab after enabling in Safari... TODO check Safari 3
-        $li.animate({ opacity: 1 }, 1, function() {
+      if (url.indexOf('#') == 0) { // ajax container is created by tabify automatically
+        var $container = $(url);
+        // try to find an existing element before creating a new one
+        ($container.length && $container || $('<div id="' + url.replace('#', '') + '" class="' + o.containerClass + ' ' + o.hideClass + '"></div>'))
+          [method](this.$containers[position - 1]);
+      }
+      $('<li><a href="' + url + '"><span>' + text + '</span></a></li>')
+        [method](this.$tabs.slice(position - 1, position).parents('li:eq(0)'));
+      this.tabify();
+      o.add(this.$tabs[position - 1], this.$containers[position - 1]); // callback
+    } else {
+      throw Drupal.t('jQuery UI Tabs: Not enough arguments to add tab.');
+    }
+  },
+  remove: function(position) {
+    if (position && position.constructor == Number) {
+      this.$tabs.slice(position - 1, position).parents('li:eq(0)').remove();
+      this.$containers.slice(position - 1, position).remove();
+      this.tabify();
+    }
+    this.options.remove(); // callback
+  },
+  enable: function(position) {
+    var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options;
+    $li.removeClass(o.disabledClass);
+    if ($.browser.safari) { // fix disappearing tab after enabling in Safari... TODO check Safari 3
+      $li.animate({ opacity: 1 }, 1, function() {
+        $li.css({ opacity: '' });
+      });
+    }
+    o.enable(this.$tabs[position - 1], this.$containers[position - 1]); // callback
+  },
+  disable: function(position) {
+    var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options;
+    if ($.browser.safari) { // fix opacity of tab after disabling in Safari... TODO check Safari 3
+      $li.animate({ opacity: 0 }, 1, function() {
           $li.css({ opacity: '' });
-        });
-      }
-      o.enable(this.$tabs[position - 1], this.$containers[position - 1]); // callback
-    },
-    disable: function(position) {
-      var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options;      
-      if ($.browser.safari) { // fix opacity of tab after disabling in Safari... TODO check Safari 3
-        $li.animate({ opacity: 0 }, 1, function() {
-           $li.css({ opacity: '' });
-        });
-      }
-      $li.addClass(this.options.disabledClass);
-      o.disable(this.$tabs[position - 1], this.$containers[position - 1]); // callback
-    },
-    click: function(position) {
-      this.$tabs.slice(position - 1, position).trigger('click');
-    },
-    load: function(position, url, callback) {
-      var self = this,
-        o = this.options,
-        $a = this.$tabs.slice(position - 1, position).addClass(o.loadingClass),
-        $span = $('span', $a),
-        text = $span.html();
-
-      // shift arguments
-      if (url && url.constructor == Function) {
-        callback = url;
-      }
-
-      // set new URL
-      if (url) {
-        $a[0].url = url;
-      }
-
-      // load
-      if (o.spinner) {
-        $span.html('<em>' + o.spinner + '</em>');
-      }
-      setTimeout(function() { // timeout is again required in IE, "wait" for id being restored
-        $($a[0].hash).load(url, function() {
-          if (o.spinner) {
-            $span.html(text);
-          }
-          $a.removeClass(o.loadingClass);
-          // This callback is needed because the switch has to take place after loading
-          // has completed.
-          if (callback && callback.constructor == Function) {
-            callback();
-          }
-          o.load(self.$tabs[position - 1], self.$containers[position - 1]); // callback
-        });
-      }, 0);
+      });
+    }
+    $li.addClass(this.options.disabledClass);
+    o.disable(this.$tabs[position - 1], this.$containers[position - 1]); // callback
+  },
+  click: function(position) {
+    this.$tabs.slice(position - 1, position).trigger('click');
+  },
+  load: function(position, url, callback) {
+    var self = this,
+      o = this.options,
+      $a = this.$tabs.slice(position - 1, position).addClass(o.loadingClass),
+      $span = $('span', $a),
+      text = $span.html();
+
+    // shift arguments
+    if (url && url.constructor == Function) {
+      callback = url;
     }
-  });
-})(jQuery);
+
+    // set new URL
+    if (url) {
+      $a[0].url = url;
+    }
+
+    // load
+    if (o.spinner) {
+      $span.html('<em>' + o.spinner + '</em>');
+    }
+    setTimeout(function() { // timeout is again required in IE, "wait" for id being restored
+      $($a[0].hash).load(url, function() {
+        if (o.spinner) {
+          $span.html(text);
+        }
+        $a.removeClass(o.loadingClass);
+        // This callback is needed because the switch has to take place after loading
+        // has completed.
+        if (callback && callback.constructor == Function) {
+          callback();
+        }
+        o.load(self.$tabs[position - 1], self.$containers[position - 1]); // callback
+      });
+    }, 0);
+  }
+});
Index: modules/aggregator.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/aggregator.views.inc,v
retrieving revision 1.3
diff -u -p -r1.3 aggregator.views.inc
--- modules/aggregator.views.inc	2 Jun 2009 19:46:06 -0000	1.3
+++ modules/aggregator.views.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: aggregator.views.inc,v 1.3 2009/06/02 19:46:06 merlinofchaos Exp $
+// $Id: aggregator.views.inc,v 1.2.2.3 2010/07/27 22:45:24 merlinofchaos Exp $
 /**
  * @file
  * Provide views data and handlers for aggregator.module
@@ -35,6 +35,26 @@ function aggregator_views_data() {
   // ----------------------------------------------------------------
   // Fields
 
+  // item id.
+  $data['aggregator_item']['iid'] = array(
+    'title' => t('Feed Item ID'),
+    'help' => t('The unique ID of the aggregator item.'),
+    'field' => array(
+      'handler' => 'views_handler_field_numeric',
+      'click sortable' => TRUE,
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_numeric',
+      'numeric' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_numeric',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+
   // title
   $data['aggregator_item']['title'] = array(
     'title' => t('Title'), // The item it appears as on the UI,
@@ -98,7 +118,7 @@ function aggregator_views_data() {
     'help' => t('The actual content of the imported item.'),
      // Information for displaying a title as a field
     'field' => array(
-      'handler' => 'views_handler_field_xss',
+      'handler' => 'views_handler_field_aggregator_item_description',
       'click sortable' => FALSE,
      ),
     // Information for accepting a title as a filter
@@ -161,7 +181,7 @@ function aggregator_views_data() {
     'filter' => array(
       'handler' => 'views_handler_filter_numeric',
     ),
-    // Information for sorting on a nid.
+    // Information for sorting on a fid.
     'sort' => array(
       'handler' => 'views_handler_sort',
     ),
@@ -341,6 +361,9 @@ function aggregator_views_handlers() {
       'views_handler_field_aggregator_category' => array(
         'parent' => 'views_handler_field',
       ),
+      'views_handler_field_aggregator_item_description' => array(
+        'parent' => 'views_handler_field_xss',
+      ),
 
       // argument handlers
       'views_handler_argument_aggregator_fid' => array(
Index: modules/book.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/book.views.inc,v
retrieving revision 1.5
diff -u -p -r1.5 book.views.inc
--- modules/book.views.inc	2 Dec 2008 19:37:08 -0000	1.5
+++ modules/book.views.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: book.views.inc,v 1.5 2008/12/02 19:37:08 merlinofchaos Exp $
+// $Id: book.views.inc,v 1.5.2.3 2009/12/03 20:56:47 merlinofchaos Exp $
 /**
  * @file
  * Provide views data and handlers for book.module
@@ -31,7 +31,6 @@ function book_views_data() {
     'help' => t('The book the node is in.'),
     'relationship' => array(
       'base' => 'node',
-      'field' => 'bid',
       'handler' => 'views_handler_relationship',
       'label' => t('Book'),
     ),
@@ -85,7 +84,7 @@ function book_views_data() {
 
   $data['book_menu_links']['p'] = array(
     'title' => t('Hierarchy'),
-    'help' => t('The order of pages in the book hierarchy. If you want the exactly right order, remember to sort by weight, too.'),
+    'help' => t('The order of pages in the book hierarchy.'),
     'sort' => array(
       'handler' => 'views_handler_sort_menu_hierarchy',
     ),
@@ -111,7 +110,7 @@ function book_views_data() {
     'help' => t('The parent book node.'),
     'relationship' => array(
       'base' => 'node',
-      'field' => 'nid',
+      'base field' => 'nid',
       'handler' => 'views_handler_relationship',
       'label' => t('Book parent'),
     ),
Index: modules/book.views_convert.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/book.views_convert.inc,v
retrieving revision 1.2
diff -u -p -r1.2 book.views_convert.inc
--- modules/book.views_convert.inc	2 Jun 2009 20:31:00 -0000	1.2
+++ modules/book.views_convert.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: book.views_convert.inc,v 1.2 2009/06/02 20:31:00 merlinofchaos Exp $
+// $Id: book.views_convert.inc,v 1.1.2.2 2009/06/30 19:14:17 merlinofchaos Exp $
 
 /**
  * @file
@@ -37,7 +37,6 @@ function book_views_convert($display, $t
               $operators = array('AND' => '=', 'OR' => '=', 'NOT' => '!=');
               $item = $view->get_item($display, 'filter', $id);
               $item['operator'] = $operators[$field['operator']];
-              $item['value'] = $field['value'];
               $item['relationship'] = $view->add_item($display, 'relationship', 'book_parent', 'nid', array(), 'book_parent_nid');
               $item['table'] = 'node';
               $item['field'] = 'nid';
Index: modules/comment.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/comment.views.inc,v
retrieving revision 1.32
diff -u -p -r1.32 comment.views.inc
--- modules/comment.views.inc	8 Apr 2009 06:38:41 -0000	1.32
+++ modules/comment.views.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: comment.views.inc,v 1.32 2009/04/08 06:38:41 merlinofchaos Exp $
+// $Id: comment.views.inc,v 1.32.2.9 2010/07/27 22:31:21 merlinofchaos Exp $
 /**
  * @file
  * Provide views data and handlers for comment.module
@@ -86,7 +86,7 @@ function comment_views_data() {
       'handler' => 'views_handler_sort',
     ),
     'argument' => array(
-      'handler' => 'views_handler_argument',
+      'handler' => 'views_handler_argument_numeric',
     ),
   );
 
@@ -128,6 +128,44 @@ function comment_views_data() {
     ),
   );
 
+  // hostname
+  $data['comments']['hostname'] = array(
+    'title' => t('Hostname'),
+    'help' => t('Hostname of user that posted the comment.'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+     ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+
+  // mail
+  $data['comments']['mail'] = array(
+    'title' => t('Mail'),
+    'help' => t('Email of user that posted the comment. Will be empty if the author is a registered user.'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+     ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+
   // timestamp (when comment was posted)
   $data['comments']['timestamp'] = array(
     'title' => t('Post date'),
@@ -143,18 +181,72 @@ function comment_views_data() {
       'handler' => 'views_handler_filter_date',
     ),
   );
+  
+  $data['comments']['timestamp_fulldate'] = array(
+    'title' => t('Created date'),
+    'help' => t('In the form of CCYYMMDD.'),
+    'argument' => array(
+      'field' => 'timestamp',
+      'handler' => 'views_handler_argument_node_created_fulldate',
+    ),
+  );
+
+  $data['comments']['timestamp_year_month'] = array(
+    'title' => t('Created year + month'),
+    'help' => t('In the form of YYYYMM.'),
+    'argument' => array(
+      'field' => 'timestamp',
+      'handler' => 'views_handler_argument_node_created_year_month',
+    ),
+  );
+
+  $data['comments']['timestamp_year'] = array(
+    'title' => t('Created year'),
+    'help' => t('In the form of YYYY.'),
+    'argument' => array(
+      'field' => 'timestamp',
+      'handler' => 'views_handler_argument_node_created_year',
+    ),
+  );
+
+  $data['comments']['timestamp_month'] = array(
+    'title' => t('Created month'),
+    'help' => t('In the form of MM (01 - 12).'),
+    'argument' => array(
+      'field' => 'timestamp',
+      'handler' => 'views_handler_argument_node_created_month',
+    ),
+  );
+
+  $data['comments']['timestamp_day'] = array(
+    'title' => t('Created day'),
+    'help' => t('In the form of DD (01 - 31).'),
+    'argument' => array(
+      'field' => 'timestamp',
+      'handler' => 'views_handler_argument_node_created_day',
+    ),
+  );
+
+  $data['comments']['timestamp_week'] = array(
+    'title' => t('Created week'),
+    'help' => t('In the form of WW (01 - 53).'),
+    'argument' => array(
+      'field' => 'timestamp',
+      'handler' => 'views_handler_argument_node_created_week',
+    ),
+  );
 
   // status (approved or not)
   $data['comments']['status'] = array(
     'title' => t('In moderation'),
-    'help' => t('Whether or not the comment is currently in moderation.'),
+    'help' => t('Whether or not the comment is currently in the moderation queue.'),
     'field' => array(
       'handler' => 'views_handler_field_boolean',
       'click sortable' => TRUE,
     ),
     'filter' => array(
       'handler' => 'views_handler_filter_boolean_operator',
-      'label' => t('Moderated'),
+      'label' => t('In the moderation queue'),
       'type' => 'yes-no',
     ),
     'sort' => array(
@@ -198,14 +290,6 @@ function comment_views_data() {
     ),
   );
 
-  $data['comments']['node_link'] = array(
-    'field' => array(
-      'title' => t('Node link'),
-      'help' => t('Display the standard comment link used on regular nodes.'),
-      'handler' => 'views_handler_field_comment_node_link',
-    ),
-  );  
-
   $data['comments']['thread'] = array(
     'field' => array(
       'title' => t('Depth'),
@@ -224,7 +308,7 @@ function comment_views_data() {
     'help' => t('The node the comment is a reply to.'),
     'relationship' => array(
       'base' => 'node',
-      'field' => 'nid',
+      'base field' => 'nid',
       'handler' => 'views_handler_relationship',
       'label' => t('Node'),
     ),
@@ -235,7 +319,7 @@ function comment_views_data() {
     'help' => t("The User ID of the comment's author."),
     'relationship' => array(
       'base' => 'users',
-      'field' => 'uid',
+      'base field' => 'uid',
       'handler' => 'views_handler_relationship',
       'label' => t('User'),
     ),
@@ -251,7 +335,7 @@ function comment_views_data() {
       'title' => t('Parent comment'),
       'help' => t('The parent comment.'),
       'base' => 'comments',
-      'field' => 'cid',
+      'base field' => 'cid',
       'handler' => 'views_handler_relationship',
       'label' => t('Parent comment'),
     ),
@@ -267,7 +351,7 @@ function comment_views_data() {
   $data['node_comment_statistics']['table']['join'] = array(
     //...to the node table
     'node' => array(
-      'type' => 'INNER',      
+      'type' => 'INNER',
       'left_field' => 'nid',
       'field' => 'nid',
      ),
@@ -351,6 +435,15 @@ function comment_views_data_alter(&$data
     'help' => t('The number of new comments on the node.'),
     'field' => array(
       'handler' => 'views_handler_field_node_new_comments',
+      'no group by' => TRUE,
+    ),
+  );
+
+  $data['node']['comments_link'] = array(
+    'field' => array(
+      'title' => t('Add comment link'),
+      'help' => t('Display the standard add comment link used on regular nodes, which will only display if the viewing user has access to add a comment.'),
+      'handler' => 'views_handler_field_comment_node_link',
     ),
   );
 
@@ -505,12 +598,12 @@ function template_preprocess_views_view_
   $options = $vars['options'];
   $view = &$vars['view'];
   $plugin = &$view->style_plugin->row_plugin;
-  $comment = $plugin->comments[$vars['row']->cid];
+  $comment = $plugin->comments[$vars['row']->{$vars['field_alias']}];
   $node = node_load($comment->nid);
   // Put the view on the node so we can retrieve it in the preprocess.
   $node->view = &$view;
 
-  $links = '';
+  $links = array();
   if (!empty($options['links'])) {
     $links = module_invoke_all('link', 'comment', $comment, 0);
     drupal_alter('link', $links, $node);
Index: modules/comment.views_convert.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/comment.views_convert.inc,v
retrieving revision 1.3
diff -u -p -r1.3 comment.views_convert.inc
--- modules/comment.views_convert.inc	2 Jun 2009 20:31:00 -0000	1.3
+++ modules/comment.views_convert.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-//$Id: comment.views_convert.inc,v 1.3 2009/06/02 20:31:00 merlinofchaos Exp $
+//$Id: comment.views_convert.inc,v 1.2.2.2 2009/06/30 19:14:17 merlinofchaos Exp $
 
 /**
  * @file
@@ -82,26 +82,20 @@ function comment_views_convert($display,
       break;
     case 'filter':
       switch ($field['tablename']) {
-        case 'comments':
-          switch ($field['field']) {
-            case 'status':
-              $view->set_item_option($display, 'filter', $id, 'value', $field['value']);
-              break;
-          }
-          break;
         case 'node_comment_statistics':
           switch ($field['field']) {
             case 'comment_count':
               $view->set_item_option($display, 'filter', $id, 'operator', $field['operator']);
-              $view->set_item_option($display, 'filter', $id, 'value', $field['value']);
               break;
             case 'last_changed':
               $field['field'] = 'last_updated';
             case 'last_comment_timestamp':
               $item = $view->get_item($display, 'filter', $id);
               $item['operator'] = $field['operator'];
-              $item['value']['type'] = $field['value'] == 'now' ? 'offset' : 'date';
-              $item['value']['value'] = $field['value'];
+              $item['value'] = array(
+                'type' => $field['value'] == 'now' ? 'offset' : 'date',
+                'value' => $field['value'],
+              );
               if (!empty($field['options'])) {
                 $item['value']['value'] = intval($field['options']) .' seconds';
               }
Index: modules/comment.views_default.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/comment.views_default.inc,v
retrieving revision 1.7
diff -u -p -r1.7 comment.views_default.inc
--- modules/comment.views_default.inc	27 Jan 2009 20:24:09 -0000	1.7
+++ modules/comment.views_default.inc	11 Aug 2010 21:11:32 -0000
@@ -1,12 +1,12 @@
 <?php
-// $Id: comment.views_default.inc,v 1.7 2009/01/27 20:24:09 merlinofchaos Exp $
+// $Id: comment.views_default.inc,v 1.7.2.1 2010/03/10 20:02:20 merlinofchaos Exp $
 /**
  * @file
  * Contains default views on behalf of the comment module.
  */
 
 /**
- * Implementation of hook_default_view_views().
+ * Implementation of hook_views_default_views().
  */
 function comment_views_default_views() {
   $view = new view;
Index: modules/contact.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/contact.views.inc,v
retrieving revision 1.1
diff -u -p -r1.1 contact.views.inc
--- modules/contact.views.inc	1 Jun 2009 21:55:36 -0000	1.1
+++ modules/contact.views.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-//$Id: contact.views.inc,v 1.1 2009/06/01 21:55:36 merlinofchaos Exp $
+//$Id: contact.views.inc,v 1.1.2.2 2009/06/01 21:55:38 merlinofchaos Exp $
 /**
  * @file
  * Provide views data and handlers for contact.module
Index: modules/filter.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/filter.views.inc,v
retrieving revision 1.1
diff -u -p -r1.1 filter.views.inc
--- modules/filter.views.inc	3 Jun 2009 19:06:05 -0000	1.1
+++ modules/filter.views.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: filter.views.inc,v 1.1 2009/06/03 19:06:05 merlinofchaos Exp $
+// $Id: filter.views.inc,v 1.1.2.2 2009/06/12 16:17:42 merlinofchaos Exp $
 /**
  * @file
  * Provide basic views data for filter.module.
Index: modules/node.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/node.views.inc,v
retrieving revision 1.96
diff -u -p -r1.96 node.views.inc
--- modules/node.views.inc	3 Jun 2009 02:16:48 -0000	1.96
+++ modules/node.views.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: node.views.inc,v 1.96 2009/06/03 02:16:48 merlinofchaos Exp $
+// $Id: node.views.inc,v 1.93.2.14 2010/07/27 22:31:21 merlinofchaos Exp $
 /**
  * @file
  * Provide views data and handlers for node.module
@@ -203,8 +203,8 @@ function node_views_data() {
 
   // moderate
   $data['node']['moderate'] = array(
-    'title' => t('Moderated'), // The item it appears as on the UI,
-    'help' => t('Whether or not the node is moderated.'), // The help that appears on the UI,
+    'title' => t('In moderation'), // The item it appears as on the UI,
+    'help' => t('Whether or not the node is currently in the moderation queue.'), // The help that appears on the UI,
      // Information for displaying a title as a field
     'field' => array(
       'handler' => 'views_handler_field_boolean',
@@ -212,7 +212,7 @@ function node_views_data() {
     ),
     'filter' => array(
       'handler' => 'views_handler_filter_boolean_operator',
-      'label' => t('Moderated'),
+      'label' => t('In the moderation queue'),
       'type' => 'yes-no',
     ),
     'sort' => array(
@@ -228,6 +228,9 @@ function node_views_data() {
     'field' => array(
       'handler' => 'views_handler_field_boolean',
       'click sortable' => TRUE,
+      'output formats' => array(
+        'sticky' => array('', t('Sticky')),
+      ),
     ),
     'filter' => array(
       'handler' => 'views_handler_filter_boolean_operator',
@@ -236,6 +239,7 @@ function node_views_data() {
     ),
     'sort' => array(
       'handler' => 'views_handler_sort',
+      'help' => t('Whether or not the node is sticky. To list sticky nodes first, set this to descending.'),
     ),
   );
 
@@ -264,6 +268,15 @@ function node_views_data() {
       'handler' => 'views_handler_field_node_link_delete',
     ),
   );
+  
+  $data['node']['path'] = array(
+    'field' => array(
+      'title' => t('Path'),
+      'help' => t('The aliased path to this node.'),
+      'handler' => 'views_handler_field_node_path',
+    ),
+  );
+  
 
   // Bogus fields for aliasing purposes.
 
@@ -375,6 +388,18 @@ function node_views_data() {
     ),
   );
 
+  // uid field
+  $data['node']['uid'] = array(
+    'title' => t('Author'),
+    'help' => t('Relate a node to the user who created it.'),
+    'relationship' => array(
+      'handler' => 'views_handler_relationship',
+      'base' => 'users',
+      'base field' => 'uid',
+      'label' => t('user'),
+    ),
+  );
+
   // ----------------------------------------------------------------------
   // Node revisions table
 
@@ -398,7 +423,7 @@ function node_views_data() {
     ),
   );
 
-  // uid field
+  // uid field for node revisions
   $data['node_revisions']['uid'] = array(
     'title' => t('User'),
     'help' => t('Relate a node revision to the user who created the revision.'),
@@ -406,7 +431,7 @@ function node_views_data() {
       'handler' => 'views_handler_relationship',
       'base' => 'users',
       'field' => 'uid',
-      'label' => t('user'),
+      'label' => t('revision user'),
     ),
   );
 
@@ -473,7 +498,7 @@ function node_views_data() {
      // Information for displaying a title as a field
     'field' => array(
       'field' => 'title', // the real field
-      'handler' => 'views_handler_field_node',
+      'handler' => 'views_handler_field_node_revision',
       'click sortable' => TRUE,
      ),
     'sort' => array(
@@ -646,8 +671,8 @@ function node_views_handlers() {
       'views_handler_field_node_link' => array(
         'parent' => 'views_handler_field',
       ),
-      'views_handler_field_node_type' => array(
-        'parent' => 'views_handler_field_node',
+      'views_handler_field_node_path' => array(
+        'parent' => 'views_handler_field',
       ),
       'views_handler_field_node_link_edit' => array(
         'parent' => 'views_handler_field_node_link',
@@ -664,7 +689,9 @@ function node_views_handlers() {
       'views_handler_field_history_user_timestamp' => array(
         'parent' => 'views_handler_field_node',
       ),
-
+      'views_handler_field_node_revision' => array(
+        'parent' => 'views_handler_field_node',
+      ),
       // argument handlers
       'views_handler_argument_node_type' => array(
         'parent' => 'views_handler_argument',
@@ -805,7 +832,6 @@ function template_preprocess_views_view_
  * Implementation of hook_views_query_substitutions().
  */
 function node_views_query_substitutions() {
-  global $language;
   return array(
     '***ADMINISTER_NODES***' => intval(user_access('administer nodes')),
   );
@@ -834,6 +860,13 @@ function node_views_analyze($view) {
       }
     }
   }
+  foreach ($view->display as $id => $display) {
+    if ($display->display_plugin == 'page') {
+      if ($display->handler->get_option('path') == 'node/%') {
+        $ret[] = views_ui_analysis(t('Display %display has set node/% as path. This will not produce what you want. If you want to have multiple versions of the node view, use panels.', array('%display' => $display->display_title)), 'warning');
+      }
+    }
+  }
 
   return $ret;
 }
Index: modules/node.views_convert.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/node.views_convert.inc,v
retrieving revision 1.6
diff -u -p -r1.6 node.views_convert.inc
--- modules/node.views_convert.inc	2 Jun 2009 20:31:00 -0000	1.6
+++ modules/node.views_convert.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-//$Id: node.views_convert.inc,v 1.6 2009/06/02 20:31:00 merlinofchaos Exp $
+//$Id: node.views_convert.inc,v 1.5.2.2 2009/06/30 19:14:17 merlinofchaos Exp $
 
 /**
  * @file
@@ -61,16 +61,9 @@ function node_views_convert($display, $t
       switch ($field['tablename']) {
         case 'node':
           switch ($field['field']) {
-            case 'status':
-            case 'promote':
-            case 'sticky':
-            case 'moderate':
-              $view->set_item_option($display, 'filter', $id, 'value', $field['value']);
-              break;
             case 'type':
               $operators = array('OR' => 'in', 'NOR' => 'not in');
               $view->set_item_option($display, 'filter', $id, 'operator', $operators[$field['operator']]);
-              $view->set_item_option($display, 'filter', $id, 'value', $field['value']);
               break;
             case 'anon':
               $item = $view->get_item($display, 'filter', $id);
@@ -98,7 +91,6 @@ function node_views_convert($display, $t
             case 'title':
               $item = $view->get_item($display, 'filter', $id);
               $item['operator'] = $field['operator'];
-              $item['value'] = $field['value'];
               $item['case'] = FALSE;
               $view->set_item($display, 'filter', $id, $item);
               break;
@@ -106,8 +98,10 @@ function node_views_convert($display, $t
             case 'changed':
               $item = $view->get_item($display, 'filter', $id);
               $item['operator'] = $field['operator'];
-              $item['value']['type'] = $field['value'] == 'now' ? 'offset' : 'date';
-              $item['value']['value'] = $field['value'];
+              $item['value'] = array(
+                'type' => $field['value'] == 'now' ? 'offset' : 'date',
+                'value' => $field['value'],
+              );
               if (!empty($field['options'])) {
                 $item['value']['value'] = intval($field['options']) .' seconds';
               }
@@ -116,7 +110,6 @@ function node_views_convert($display, $t
             case 'body':
               $item = $view->get_item($display, 'filter', $id);
               $item['operator'] = $field['operator'];
-              $item['value'] = $field['value'];
               $item['case'] = FALSE;
               $item['table'] = 'node_revisions';
               $view->set_item($display, 'filter', $id, $item);
Index: modules/node.views_default.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/node.views_default.inc,v
retrieving revision 1.11
diff -u -p -r1.11 node.views_default.inc
--- modules/node.views_default.inc	18 Feb 2009 00:07:22 -0000	1.11
+++ modules/node.views_default.inc	11 Aug 2010 21:11:32 -0000
@@ -1,12 +1,12 @@
 <?php
-// $Id: node.views_default.inc,v 1.11 2009/02/18 00:07:22 merlinofchaos Exp $
+// $Id: node.views_default.inc,v 1.11.2.1 2010/03/10 20:02:20 merlinofchaos Exp $
 /**
  * @file
  * Contains default views on behalf of the node module.
  */
 
 /**
- * Implementation of hook_default_view_views().
+ * Implementation of hook_views_default_views().
  */
 function node_views_default_views() {
   $view = new view;
Index: modules/profile.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/profile.views.inc,v
retrieving revision 1.9
diff -u -p -r1.9 profile.views.inc
--- modules/profile.views.inc	24 Sep 2008 21:21:21 -0000	1.9
+++ modules/profile.views.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-//$Id: profile.views.inc,v 1.9 2008/09/24 21:21:21 merlinofchaos Exp $
+//$Id: profile.views.inc,v 1.9.2.3 2010/03/10 19:52:38 merlinofchaos Exp $
 /**
  * @file
  * Provide views data and handlers for user.module
@@ -97,7 +97,7 @@ function profile_views_get_fields() {
  */
 function profile_views_fetch_field($field) {
   $data = array(
-    'title' => t('@field-name', array('@field-name' => $field->title)),
+    'title' => t('@category: @field-name', array('@category' => $field->category, '@field-name' => $field->title)),
   );
 
   // Add fields specific to the profile type.
@@ -106,7 +106,7 @@ function profile_views_fetch_field($fiel
       $data += array(
         'help' => t('Profile textfield'),
         'field' => array(
-          'handler' => 'views_handler_field',
+          'handler' => 'views_handler_field_user',
           'click sortable' => TRUE,
         ),
         'sort' => array(
@@ -195,6 +195,7 @@ function profile_views_fetch_field($fiel
         'help' => t('Profile freeform list %field-name.', array('%field-name' => $field->title)),
         'field' => array(
           'handler' => 'views_handler_field_profile_list',
+          'no group by' => TRUE,
         ),
         'filter' => array(
           'handler' => 'views_handler_filter_string',
Index: modules/profile.views_convert.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/profile.views_convert.inc,v
retrieving revision 1.1
diff -u -p -r1.1 profile.views_convert.inc
--- modules/profile.views_convert.inc	3 Jun 2009 19:06:05 -0000	1.1
+++ modules/profile.views_convert.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: profile.views_convert.inc,v 1.1 2009/06/03 19:06:05 merlinofchaos Exp $
+// $Id: profile.views_convert.inc,v 1.1.2.3 2009/06/30 19:14:17 merlinofchaos Exp $
 
 /**
  * @file
@@ -29,12 +29,9 @@ function profile_views_convert($display,
           case 'selection':
             $operators = array('AND' => 'in', 'OR' => 'in', 'NOR' => 'not in');
             $view->set_item_option($display, 'filter', $id, 'operator', $operators[$field['operator']]);
-          case 'checkbox':
-            $view->set_item_option($display, 'filter', $id, 'value', $field['value']);
             break;
           default:
             $view->set_item_option($display, 'filter', $id, 'operator', $field['operator']);
-            $view->set_item_option($display, 'filter', $id, 'value', $field['value']);
             break;
         }
       }
Index: modules/search.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/search.views.inc,v
retrieving revision 1.17
diff -u -p -r1.17 search.views.inc
--- modules/search.views.inc	23 Feb 2009 23:30:38 -0000	1.17
+++ modules/search.views.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: search.views.inc,v 1.17 2009/02/23 23:30:38 merlinofchaos Exp $
+// $Id: search.views.inc,v 1.17.2.2 2009/12/24 00:55:16 merlinofchaos Exp $
 /**
  * @file
  * Provide views data and handlers for search.module
@@ -28,10 +28,6 @@ function search_views_data() {
       'left_field' => 'nid',
       'field' => 'sid',
     ),
-    'users' => array(
-      'left_field' => 'uid',
-      'field' => 'sid',
-    ),
   );
 
   $data['search_total']['table']['join'] = array(
@@ -126,6 +122,9 @@ function search_views_data() {
     'filter' => array(
       'handler' => 'views_handler_filter_search',
     ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_search',
+    ),
   );
 
   return $data;
@@ -150,6 +149,9 @@ function search_views_handlers() {
       'views_handler_filter_search' => array(
         'parent' => 'views_handler_filter',
       ),
+      'views_handler_argument_search' => array(
+        'parent' => 'views_handler_argument',
+      ),
     ),
   );
 }
Index: modules/search.views_convert.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/search.views_convert.inc,v
retrieving revision 1.1
diff -u -p -r1.1 search.views_convert.inc
--- modules/search.views_convert.inc	7 Apr 2009 23:24:55 -0000	1.1
+++ modules/search.views_convert.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: search.views_convert.inc,v 1.1 2009/04/07 23:24:55 merlinofchaos Exp $
+// $Id: search.views_convert.inc,v 1.1.2.1 2009/06/30 19:14:17 merlinofchaos Exp $
 
 /**
  * @file
@@ -13,11 +13,8 @@ function search_views_convert($display, 
         case 'temp_search_results':
           switch ($field['field']) {
             case 'word':
-              $item = $view->get_item($display, 'filter', $id);
-              $item['table'] = 'search_index';
-              $item['field'] = 'keys';
-              $item['value'] = $field['value'];
-              $view->set_item($display, 'filter', $id, $item);
+              $view->set_item_option($display, 'filter', $id, 'table', 'search_index');
+              $view->set_item_option($display, 'filter', $id, 'field', 'keys');
               break;
           }
           break;
Index: modules/search.views_default.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/search.views_default.inc,v
retrieving revision 1.6
diff -u -p -r1.6 search.views_default.inc
--- modules/search.views_default.inc	10 Jun 2008 21:30:43 -0000	1.6
+++ modules/search.views_default.inc	11 Aug 2010 21:11:32 -0000
@@ -1,12 +1,12 @@
 <?php
-// $Id: search.views_default.inc,v 1.6 2008/06/10 21:30:43 merlinofchaos Exp $
+// $Id: search.views_default.inc,v 1.6.2.1 2010/03/10 20:02:20 merlinofchaos Exp $
 /**
  * @file
  * Contains default views on behalf of the search module.
  */
 
 /**
- * Implementation of hook_default_view_views().
+ * Implementation of hook_views_default_views().
  */
 function search_views_default_views() {
   $view = new view;
Index: modules/statistics.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/statistics.views.inc,v
retrieving revision 1.9
diff -u -p -r1.9 statistics.views.inc
--- modules/statistics.views.inc	28 Oct 2008 20:21:37 -0000	1.9
+++ modules/statistics.views.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: statistics.views.inc,v 1.9 2008/10/28 20:21:37 merlinofchaos Exp $
+// $Id: statistics.views.inc,v 1.9.2.1 2009/11/02 23:25:10 merlinofchaos Exp $
 /**
  * @file
  * Provide views data and handlers for statistics.module
@@ -206,7 +206,7 @@ function statistics_views_data() {
     'relationship' => array(
       'handler' => 'views_handler_relationship',
       'base' => 'users',
-      'field' => 'uid',
+      'base field' => 'uid',
      ),
   );
 
Index: modules/statistics.views_convert.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/statistics.views_convert.inc,v
retrieving revision 1.1
diff -u -p -r1.1 statistics.views_convert.inc
--- modules/statistics.views_convert.inc	3 Jun 2009 19:06:05 -0000	1.1
+++ modules/statistics.views_convert.inc	11 Aug 2010 21:11:32 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: statistics.views_convert.inc,v 1.1 2009/06/03 19:06:05 merlinofchaos Exp $
+// $Id: statistics.views_convert.inc,v 1.1.2.2 2009/06/12 16:17:42 merlinofchaos Exp $
 
 /**
  * @file
Index: modules/statistics.views_default.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/statistics.views_default.inc,v
retrieving revision 1.5
diff -u -p -r1.5 statistics.views_default.inc
--- modules/statistics.views_default.inc	21 Jul 2008 21:05:12 -0000	1.5
+++ modules/statistics.views_default.inc	11 Aug 2010 21:11:33 -0000
@@ -1,12 +1,12 @@
 <?php
-// $Id: statistics.views_default.inc,v 1.5 2008/07/21 21:05:12 merlinofchaos Exp $
+// $Id: statistics.views_default.inc,v 1.5.2.1 2010/03/10 20:02:20 merlinofchaos Exp $
 /**
  * @file
  * Contains default views on behalf of the statistics module.
  */
 
 /**
- * Implementation of hook_default_view_views().
+ * Implementation of hook_views_default_views().
  */
 function statistics_views_default_views() {
   $view = new view;
Index: modules/taxonomy.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/taxonomy.views.inc,v
retrieving revision 1.54
diff -u -p -r1.54 taxonomy.views.inc
--- modules/taxonomy.views.inc	5 Jun 2009 01:26:35 -0000	1.54
+++ modules/taxonomy.views.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: taxonomy.views.inc,v 1.54 2009/06/05 01:26:35 merlinofchaos Exp $
+// $Id: taxonomy.views.inc,v 1.50.2.16 2010/05/24 09:13:03 dereine Exp $
 /**
  * @file
  *
@@ -46,11 +46,18 @@ function taxonomy_views_data() {
   // vocabulary name
   $data['vocabulary']['name'] = array(
     'title' => t('Vocabulary name'), // The item it appears as on the UI,
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
     'field' => array(
       'help' => t('Name of the vocabulary a term is a member of. This will be the vocabulary that whichever term the "Taxonomy: Term" field is; and can similarly cause duplicates.'),
       'handler' => 'views_handler_field',
       'click sortable' => TRUE,
     ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+      'help' => t('The taxonomy vocabulary name'),
+    ),
   );
   $data['vocabulary']['vid'] = array(
     'title' => t('Vocabulary ID'), // The item it appears as on the UI,
@@ -59,6 +66,9 @@ function taxonomy_views_data() {
       'handler' => 'views_handler_argument_vocabulary_vid',
       'name field' => 'name',
     ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
   );
 
   // ----------------------------------------------------------------------
@@ -98,7 +108,6 @@ function taxonomy_views_data() {
     'field' => array(
       'handler' => 'views_handler_field_numeric',
       'click sortable' => TRUE,
-      'skip base' => array('node', 'node_revision'),
     ),
     'sort' => array(
       'handler' => 'views_handler_sort',
@@ -106,6 +115,7 @@ function taxonomy_views_data() {
     'argument' => array(
       'handler' => 'views_handler_argument_numeric',
       'skip base' => array('node', 'node_revision'),
+      'zero is null' => TRUE,
     ),
     'filter' => array(
       'handler' => 'views_handler_filter_term_node_tid',
@@ -126,6 +136,10 @@ function taxonomy_views_data() {
     'sort' => array(
       'handler' => 'views_handler_sort',
     ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+      'help' => t('Taxonomy term name.'),
+    ),
     'argument' => array(
       'handler' => 'views_handler_argument_string',
       'help' => t('Taxonomy term name.'),
@@ -168,6 +182,15 @@ function taxonomy_views_data() {
     ),
   );
 
+  // Link to edit the term
+  $data['term_data']['edit_term'] = array(
+    'field' => array(
+      'title' => t('Term edit link'),
+      'help' => t('Provide a simple link to edit the term.'),
+      'handler' => 'views_handler_field_term_link_edit',
+    ),
+  );
+
   // ----------------------------------------------------------------------
   // term_node table
 
@@ -195,6 +218,17 @@ function taxonomy_views_data() {
     ),
   );
 
+  $data['term_node']['vid'] = array(
+    'title' => t('Node'),
+    'help' => t('Get all nodes tagged with a term.'),
+    'relationship' => array(
+      'handler' => 'views_handler_relationship',
+      'base' => 'node',
+      'base field' => 'vid',
+      'label' => t('node'),
+    ),
+  );
+
   // tid field
   $data['term_node']['tid'] = array(
     'title' => t('Term ID'),
@@ -204,6 +238,7 @@ function taxonomy_views_data() {
       'help' => t('Display all taxonomy terms associated with a node from specified vocabularies.'),
       'handler' => 'views_handler_field_term_node_tid',
       'skip base' => 'term_data',
+      'no group by' => TRUE,
     ),
     'argument' => array(
       'handler' => 'views_handler_argument_term_node_tid',
@@ -223,7 +258,46 @@ function taxonomy_views_data() {
     ),
   );
 
-  // @todo: term_relation
+  // term_relation
+
+  $data['term_relation']['table']['group']  = t('Taxonomy');
+
+  $data['term_relation']['table']['join'] = array(
+    'term_data' => array(
+      // links directly to term_data via tid
+      'left_field' => 'tid',
+      'field' => 'tid1',
+    ),
+    'term_relation' => array(
+      // links to self through left.tid1 = right.tid2
+      'left_field' => 'tid1',
+      'field' => 'tid2',
+    ),
+    'node' => array(
+      'left_table' => 'term_node',
+      'left_field' => 'tid',
+      'field' => 'tid1',
+    ),
+    'node_revisions' => array(
+      'left_table' => 'term_node',
+      'left_field' => 'tid',
+      'field' => 'tid1',
+    ),
+  );
+
+  $data['term_relation']['tid2'] = array(
+    'title' => t('Related terms'),
+    'help' => t('The related terms of the term. This can produce duplicate entries if there is more than one related term.'),
+    'relationship' => array(
+      'base' => 'term_data',
+      'field' => 'tid2',
+      'label' => t('Related term'),
+    ),
+    'argument' => array(
+      'help' => t('A related term of the term.'),
+      'handler' => 'views_handler_argument_numeric',
+    ),    
+  );
 
   // ----------------------------------------------------------------------
   // term_hierarchy table
@@ -266,7 +340,7 @@ function taxonomy_views_data() {
     'argument' => array(
       'help' => t('The parent term of the term.'),
       'handler' => 'views_handler_argument_numeric',
-    ),    
+    ),
   );
 
   // ----------------------------------------------------------------------
@@ -308,6 +382,17 @@ function taxonomy_views_data() {
  * Implementation of hook_views_data_alter().
  */
 function taxonomy_views_data_alter(&$data) {
+  $data['node']['term_node_tid'] = array(
+    'group' => t('Taxonomy'),
+    'title' => t('Related terms'),
+    'help' => t('Relate nodes to taxonomy terms, specifiying which vocabulary or vocabularies to use. This relationship will cause duplicated records if there are multiple terms.'),
+    'relationship' => array(
+      'handler' => 'views_handler_relationship_node_term_data',
+      'label' => t('term'),
+      'base' => 'term_data',
+    ),
+  );
+
   $data['node']['term_node_tid_depth'] = array(
     'group' => t('Taxonomy'),
     'title' => t('Term ID (with depth)'),
@@ -372,6 +457,12 @@ function taxonomy_views_handlers() {
       'views_handler_filter_term_node_tid_depth' => array(
         'parent' => 'views_handler_filter_term_node_tid',
       ),
+      'views_handler_relationship_node_term_data' => array(
+        'parent' => 'views_handler_relationship',
+      ),
+      'views_handler_field_term_link_edit' => array(
+        'parent' => 'views_handler_field',
+      ),
     ),
   );
 }
@@ -389,6 +480,14 @@ function taxonomy_views_plugins() {
         'path' => drupal_get_path('module', 'views') . '/modules/taxonomy',
       ),
     ),
+    'argument default' => array(
+      'taxonomy_tid' => array(
+        'title' => t('Taxonomy Term ID from URL'),
+        'handler' => 'views_plugin_argument_default_taxonomy_tid',
+        'path' => drupal_get_path('module', 'views') . '/modules/taxonomy',
+        'parent' => 'fixed',
+      ),
+    ),
   );
 }
 
@@ -407,8 +506,13 @@ function views_taxonomy_set_breadcrumb(&
     if ($parent->tid == $argument->argument) {
       continue;
     }
-    $args[$argument->position] = $parent->tid;
-    $path = $argument->view->get_url($args);
+    if ($argument->options['use_taxonomy_term_path']) {
+      $path = taxonomy_term_path($parent);
+    }
+    else {
+      $args[$argument->position] = $parent->tid;
+      $path = $argument->view->get_url($args);
+    }
     $breadcrumb[$path] = check_plain($parent->name);
   }
 }
Index: modules/taxonomy.views_convert.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/taxonomy.views_convert.inc,v
retrieving revision 1.3
diff -u -p -r1.3 taxonomy.views_convert.inc
--- modules/taxonomy.views_convert.inc	2 Jun 2009 20:31:00 -0000	1.3
+++ modules/taxonomy.views_convert.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-//$Id: taxonomy.views_convert.inc,v 1.3 2009/06/02 20:31:00 merlinofchaos Exp $
+//$Id: taxonomy.views_convert.inc,v 1.2.2.2 2009/06/30 19:14:17 merlinofchaos Exp $
 
 /**
  * @file
@@ -56,7 +56,6 @@ function taxonomy_views_convert($display
             }
             $item['operator'] = $operators[$field['operator']];
             $item['type'] = 'select';
-            $item['value'] = $field['value'];
             $view->set_item($display, 'filter', $id, $item);
             break;
         }
@@ -66,7 +65,6 @@ function taxonomy_views_convert($display
           case 'vid':
             $operators = array('AND' => 'in', 'OR' => 'in', 'NOR' => 'not in');
             $view->set_item_option($display, 'filter', $id, 'operator', $operators[$field['operator']]);
-            $view->set_item_option($display, 'filter', $id, 'value', $field['value']);
             break;
         }
       }
Index: modules/taxonomy.views_default.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/taxonomy.views_default.inc,v
retrieving revision 1.3
diff -u -p -r1.3 taxonomy.views_default.inc
--- modules/taxonomy.views_default.inc	10 Jun 2008 21:30:43 -0000	1.3
+++ modules/taxonomy.views_default.inc	11 Aug 2010 21:11:33 -0000
@@ -1,12 +1,12 @@
 <?php
-// $Id: taxonomy.views_default.inc,v 1.3 2008/06/10 21:30:43 merlinofchaos Exp $
+// $Id: taxonomy.views_default.inc,v 1.3.2.1 2010/03/10 20:02:20 merlinofchaos Exp $
 /**
  * @file
  * Contains default views on behalf of the statistics module.
  */
 
 /**
- * Implementation of hook_default_view_views().
+ * Implementation of hook_views_default_views().
  */
 function taxonomy_views_default_views() {
   $view = new view;
Index: modules/translation.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/translation.views.inc,v
retrieving revision 1.8
diff -u -p -r1.8 translation.views.inc
--- modules/translation.views.inc	7 Jan 2009 23:13:46 -0000	1.8
+++ modules/translation.views.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: translation.views.inc,v 1.8 2009/01/07 23:13:46 merlinofchaos Exp $
+// $Id: translation.views.inc,v 1.8.2.1 2010/03/19 23:09:49 merlinofchaos Exp $
 
 /**
  * @file
@@ -131,6 +131,17 @@ function translation_views_data_alter(&$
     ),
   );
 
+  // Translate node link.
+  $data['node']['translate_node'] = array(
+    'group' => t('Node translation'),
+    'title' => t('Translate link'),
+    'help' => t('Provide a simple link to translate the node.'),
+    'field' => array(
+      'handler' => 'views_handler_field_node_link_translate',
+    ),
+  );
+
+
 }
 
 /**
@@ -147,6 +158,9 @@ function translation_views_handlers() {
       'views_handler_field_node_language' => array(
         'parent' => 'views_handler_field_node',
       ),
+      'views_handler_field_node_link_translate' => array(
+        'parent' => 'views_handler_field_node_link',
+      ),
       // argument handlers
       'views_handler_argument_node_language' => array(
         'parent' => 'views_handler_argument',
Index: modules/upload.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/upload.views.inc,v
retrieving revision 1.15
diff -u -p -r1.15 upload.views.inc
--- modules/upload.views.inc	24 Nov 2008 19:58:31 -0000	1.15
+++ modules/upload.views.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: upload.views.inc,v 1.15 2008/11/24 19:58:31 merlinofchaos Exp $
+// $Id: upload.views.inc,v 1.15.2.3 2009/11/10 23:20:06 merlinofchaos Exp $
 /**
  * @file
  *
@@ -116,6 +116,7 @@ function upload_views_data_alter(&$data)
     'real field' => 'vid',
     'field' => array(
       'handler' => 'views_handler_field_upload_fid',
+      'no group by' => TRUE,
     ),
     'filter' => array(
       'handler' => 'views_handler_filter_upload_fid',
@@ -129,7 +130,7 @@ function upload_views_data_alter(&$data)
       'relationship table' => 'upload',
       'relationship field' => 'fid',
       'base' => 'files',
-      'field' => 'fid',
+      'base field' => 'fid',
       'handler' => 'views_handler_relationship',
       'label' => t('Files'),
     ),
@@ -150,7 +151,7 @@ function upload_views_handlers() {
         'parent' => 'views_handler_field_prerender_list',
       ),
       'views_handler_field_upload_description' => array(
-        'parent' => 'views_handler_field_prerender_list',
+        'parent' => 'views_handler_field',
       ),
       'views_handler_filter_upload_fid' => array(
         'parent' => 'views_handler_filter_boolean_operator',
Index: modules/upload.views_convert.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/upload.views_convert.inc,v
retrieving revision 1.3
diff -u -p -r1.3 upload.views_convert.inc
--- modules/upload.views_convert.inc	2 Jun 2009 20:31:00 -0000	1.3
+++ modules/upload.views_convert.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-//$Id: upload.views_convert.inc,v 1.3 2009/06/02 20:31:00 merlinofchaos Exp $
+//$Id: upload.views_convert.inc,v 1.2.2.2 2009/06/30 19:14:17 merlinofchaos Exp $
 
 /**
  * @file
@@ -64,14 +64,10 @@ function upload_views_convert($display, 
         case 'file_revisions':
           switch ($field['field']) {
             case 'fid':
-              $item = $view->get_item($display, 'filter', $id);
-              $item['value'] = $field['value'];
-              $item['table'] = 'node';
-              $item['field'] = 'upload_fid';
-              $view->set_item($display, 'filter', $id, $item);
+              $view->set_item_option($display, 'filter', $id, 'table', 'node');
+              $view->set_item_option($display, 'filter', $id, 'field', 'upload_fid');
               break;
             case 'list':
-              $view->set_item_option($display, 'filter', $id, 'value', $field['value']);
               $view->set_item_option($display, 'filter', $id, 'table', 'upload');
               break;
           }
@@ -82,17 +78,14 @@ function upload_views_convert($display, 
             case 'filemime':
               $item = $view->get_item($display, 'filter', $id);
               $item['operator'] = $field['operator'];
-              $item['value'] = $field['value'];
               $item['case'] = FALSE;
               $item['relationship'] = $view->add_item($display, 'relationship', 'node', 'upload_fid', array(), 'node_upload_fid');
               $view->set_item($display, 'filter', $id, $item);
               break;
             case 'filesize':
-              $item = $view->get_item($display, 'filter', $id);
-              $item['operator'] = $field['operator'];
-              $item['value'] = $field['value'];
-              $item['relationship'] = $view->add_item($display, 'relationship', 'node', 'upload_fid', array(), 'node_upload_fid');
-              $view->set_item($display, 'filter', $id, $item);
+              $relationship = $view->add_item($display, 'relationship', 'node', 'upload_fid', array(), 'node_upload_fid');
+              $view->set_item_option($display, 'filter', $id, 'relationship', $relationship);
+              $view->set_item_option($display, 'filter', $id, 'operator', $field['operator']);
               break;
           }
           break;
Index: modules/user.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/user.views.inc,v
retrieving revision 1.57
diff -u -p -r1.57 user.views.inc
--- modules/user.views.inc	2 Jun 2009 20:18:26 -0000	1.57
+++ modules/user.views.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-//$Id: user.views.inc,v 1.57 2009/06/02 20:18:26 merlinofchaos Exp $
+//$Id: user.views.inc,v 1.56.2.13 2010/07/27 23:00:45 merlinofchaos Exp $
 /**
  * @file
  * Provide views data and handlers for user.module
@@ -62,6 +62,15 @@ function user_views_data() {
     'sort' => array(
       'handler' => 'views_handler_sort',
     ),
+    'relationship' => array(
+      'title' => t('Nodes authored'),
+      'help' => t('Relate nodes to the user who created it. This relationship will create one record for every node created by the user.'),
+      'handler' => 'views_handler_relationship',
+      'base' => 'node',
+      'base field' => 'uid',
+      'field' => 'uid',
+      'label' => t('nodes'),
+    ),
   );
 
   // uid
@@ -89,6 +98,11 @@ function user_views_data() {
     'argument' => array(
       'handler' => 'views_handler_argument_string',
     ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+      'title' => t('Name (raw)'),
+      'help' => t('The user or author name. This filter does not check if the user exists and allows partial matching. Does not utilize autocomplete.')
+    ),
   );
 
   // mail
@@ -106,6 +120,9 @@ function user_views_data() {
     'filter' => array(
       'handler' => 'views_handler_filter_string',
     ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
   );
 
   // language
@@ -120,7 +137,10 @@ function user_views_data() {
       'handler' => 'views_handler_sort',
     ),
     'filter' => array(
-      'handler' => 'views_handler_filter_string',
+      'handler' => 'views_handler_filter_node_language',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_node_language',
     ),
   );
 
@@ -133,6 +153,9 @@ function user_views_data() {
       'handler' => 'views_handler_field_user_picture',
       'click sortable' => TRUE,
     ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
     'filter' => array(
       'handler' => 'views_handler_filter_boolean_operator_string',
       'label' => t('Has Avatar'),
@@ -188,7 +211,7 @@ function user_views_data() {
     ),
   );
 
-  // published status
+  // active status
   $data['users']['status'] = array(
     'title' => t('Active'), // The item it appears as on the UI,
     'help' => t('Whether a user is active or blocked.'), // The help that appears on the UI,
@@ -213,8 +236,9 @@ function user_views_data() {
     'help' => t("The user's signature."), // The help that appears on the UI,
      // Information for displaying a title as a field
     'field' => array(
-      'handler' => 'views_handler_field_xss',
-     ),
+      'handler' => 'views_handler_field_markup',
+      'format' => FILTER_FORMAT_DEFAULT,
+    ),
     'filter' => array(
       'handler' => 'views_handler_filter_string',
     ),
@@ -264,6 +288,7 @@ function user_views_data() {
     'help' => t('Roles that a user belongs to.'),
     'field' => array(
       'handler' => 'views_handler_field_user_roles',
+      'no group by' => TRUE,
     ),
     'filter' => array(
       'handler' => 'views_handler_filter_user_roles',
@@ -274,6 +299,7 @@ function user_views_data() {
       'name table' => 'role',
       'name field' => 'name',
       'empty field name' => t('No role'),
+      'zero is null' => TRUE,
       'numeric' => TRUE,
     ),
   );
@@ -305,6 +331,64 @@ function user_views_data() {
     ),
   );
 
+  // ----------------------------------------------------------------------
+  // authmap table
+
+  $data['authmap']['table']['group']  = t('User');
+  $data['authmap']['table']['join'] = array(
+     // Directly links to users table.
+    'users' => array(
+      'left_field' => 'uid',
+      'field' => 'uid',
+    ),
+    'node' => array(
+      'left_table' => 'users',
+      'left_field' => 'uid',
+      'field' => 'uid',
+    ),
+  );
+  $data['authmap']['aid'] = array(
+    'title' => t('Authmap ID'),
+    'help' => t('The Authmap ID.'),
+    'field' => array(
+      'handler' => 'views_handler_field_numeric',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_numeric',
+      'numeric' => TRUE,
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_numeric',
+      'numeric' => TRUE,
+    ),
+  );
+  $data['authmap']['authname'] = array(
+    'title' => t('Authentication name'),
+    'help' => t('The unique authentication name.'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+  $data['authmap']['module'] = array(
+    'title' => t('Authentication module'),
+    'help' => t('The name of the module managing the authentication entry.'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+
   return $data;
 }
 
Index: modules/user.views_convert.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/user.views_convert.inc,v
retrieving revision 1.2
diff -u -p -r1.2 user.views_convert.inc
--- modules/user.views_convert.inc	2 Jun 2009 20:31:00 -0000	1.2
+++ modules/user.views_convert.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: user.views_convert.inc,v 1.2 2009/06/02 20:31:00 merlinofchaos Exp $
+// $Id: user.views_convert.inc,v 1.1.2.2 2009/06/30 19:14:17 merlinofchaos Exp $
 
 /**
  * @file
@@ -28,7 +28,6 @@ function user_views_convert($display, $t
           case 'uid':
             $operators = array('OR' => 'in', 'NOR' => 'not in');
             $view->set_item_option($display, 'filter', $id, 'operator', $operators[$field['operator']]);
-            $view->set_item_option($display, 'filter', $id, 'value', $field['value']);
             if ($rid = (integer) substr($field['tablename'], 11)) {
               $view->add_item($display, 'filter', 'users_roles', 'rid', array('value' => $rid));
             }
@@ -40,7 +39,6 @@ function user_views_convert($display, $t
           case 'rid':
             $operators = array('AND' => 'and', 'OR' => 'or', 'NOR' => 'not');
             $view->set_item_option($display, 'filter', $id, 'operator', $operators[$field['operator']]);
-            $view->set_item_option($display, 'filter', $id, 'value', $field['value']);
             break;
         }
       }
Index: modules/views.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/views.views.inc,v
retrieving revision 1.7
diff -u -p -r1.7 views.views.inc
--- modules/views.views.inc	2 Jun 2009 17:29:26 -0000	1.7
+++ modules/views.views.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views.views.inc,v 1.7 2009/06/02 17:29:26 merlinofchaos Exp $
+// $Id: views.views.inc,v 1.6.2.3 2010/06/30 19:19:02 merlinofchaos Exp $
 /**
  * @file
  * Provide views data and handlers that aren't tied to any other module.
@@ -43,7 +43,7 @@ function views_views_data() {
       'handler' => 'views_handler_field_custom',
     ),
   );
-  
+
   $data['views']['counter'] = array(
     'title' => t('View result counter'),
     'help' => t('Displays the actual position of the view result'),
@@ -52,6 +52,24 @@ function views_views_data() {
     ),
   );
 
+  $data['views']['area'] = array(
+    'title' => t('Text area'),
+    'help' => t('Provide markup text for the area.'),
+    'area' => array(
+      'handler' => 'views_handler_area_text',
+    ),
+  );
+
+  if (module_invoke('ctools', 'api_version', '1.7.1')) {
+    $data['views']['expression'] = array(
+      'title' => t('Math expression'),
+      'help' => t('Evaluates a mathematical epression and displays it.'),
+      'field' => array(
+        'handler' => 'views_handler_field_math',
+      ),
+    );
+  }
+
   return $data;
 }
 
Index: modules/aggregator/views_handler_argument_aggregator_category_cid.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/aggregator/views_handler_argument_aggregator_category_cid.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_argument_aggregator_category_cid.inc
--- modules/aggregator/views_handler_argument_aggregator_category_cid.inc	2 Jun 2009 19:46:06 -0000	1.1
+++ modules/aggregator/views_handler_argument_aggregator_category_cid.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_argument_aggregator_category_cid.inc,v 1.1 2009/06/02 19:46:06 merlinofchaos Exp $
+// $Id: views_handler_argument_aggregator_category_cid.inc,v 1.1.2.2 2009/06/02 19:46:10 merlinofchaos Exp $
 
 /**
  * Argument handler to accept an aggregator category id.
Index: modules/aggregator/views_handler_field_aggregator_category.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/aggregator/views_handler_field_aggregator_category.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_field_aggregator_category.inc
--- modules/aggregator/views_handler_field_aggregator_category.inc	2 Jun 2009 19:46:06 -0000	1.1
+++ modules/aggregator/views_handler_field_aggregator_category.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_aggregator_category.inc,v 1.1 2009/06/02 19:46:06 merlinofchaos Exp $
+// $Id: views_handler_field_aggregator_category.inc,v 1.1.2.2 2009/06/02 19:46:10 merlinofchaos Exp $
 
 /**
  * Field handler to provide simple renderer that allows linking to aggregator
Index: modules/aggregator/views_handler_field_aggregator_title_link.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/aggregator/views_handler_field_aggregator_title_link.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_field_aggregator_title_link.inc
--- modules/aggregator/views_handler_field_aggregator_title_link.inc	7 Jan 2009 19:38:08 -0000	1.1
+++ modules/aggregator/views_handler_field_aggregator_title_link.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_aggregator_title_link.inc,v 1.1 2009/01/07 19:38:08 merlinofchaos Exp $
+// $Id: views_handler_field_aggregator_title_link.inc,v 1.1.2.1 2010/06/17 02:47:02 merlinofchaos Exp $
 
  /**
  * Field handler that turns an item's title into a clickable link to the original
@@ -38,7 +38,7 @@ class views_handler_field_aggregator_tit
       return l(check_plain($value), $link, array('html' => TRUE));
     }
     else {
-      return $value;
+      return check_plain($value);
     }
   }
-}
\ No newline at end of file
+}
Index: modules/aggregator/views_handler_filter_aggregator_category_cid.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/aggregator/views_handler_filter_aggregator_category_cid.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_handler_filter_aggregator_category_cid.inc
--- modules/aggregator/views_handler_filter_aggregator_category_cid.inc	10 Jun 2009 22:04:57 -0000	1.2
+++ modules/aggregator/views_handler_filter_aggregator_category_cid.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_aggregator_category_cid.inc,v 1.2 2009/06/10 22:04:57 merlinofchaos Exp $
+// $Id: views_handler_filter_aggregator_category_cid.inc,v 1.1.2.3 2009/06/10 22:05:24 merlinofchaos Exp $
 
 /**
  * Filter by aggregator category cid
Index: modules/aggregator/views_plugin_row_aggregator_rss.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/aggregator/views_plugin_row_aggregator_rss.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_plugin_row_aggregator_rss.inc
--- modules/aggregator/views_plugin_row_aggregator_rss.inc	7 Jan 2009 19:38:08 -0000	1.1
+++ modules/aggregator/views_plugin_row_aggregator_rss.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_row_aggregator_rss.inc,v 1.1 2009/01/07 19:38:08 merlinofchaos Exp $
+// $Id: views_plugin_row_aggregator_rss.inc,v 1.1.2.1 2009/12/28 21:11:50 merlinofchaos Exp $
 /**
  * @file
  * Contains the Aggregator Item RSS row style plugin.
@@ -9,6 +9,9 @@
  * Plugin which loads an aggregator item and formats it as an RSS item.
  */
 class views_plugin_row_aggregator_rss extends views_plugin_row {
+  var $base_table = 'aggregator_item';
+  var $base_field = 'iid';
+
   function option_definition() {
     $options = parent::option_definition();
 
@@ -32,12 +35,13 @@ class views_plugin_row_aggregator_rss ex
   }
 
   function render($row) {
+    $iid =  $row->{$this->field_alias};
     $sql =  "SELECT ai.iid, ai.fid, ai.title, ai.link, ai.author, ai.description, ";
     $sql .= "ai.timestamp, ai.guid, af.title AS feed_title, ai.link AS feed_LINK ";
     $sql .= "FROM {aggregator_item} ai LEFT JOIN {aggregator_feed} af ON ai.fid = af.fid ";
     $sql .= "WHERE ai.iid = %d";
 
-    $item = db_fetch_object(db_query($sql, $row->iid));
+    $item = db_fetch_object(db_query($sql, $iid));
 
     $item->elements = array(
       array('key' => 'pubDate', 'value' => gmdate('r', $item->timestamp)),
Index: modules/comment/views_handler_argument_comment_user_uid.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/comment/views_handler_argument_comment_user_uid.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_handler_argument_comment_user_uid.inc
--- modules/comment/views_handler_argument_comment_user_uid.inc	2 Jun 2009 18:50:56 -0000	1.2
+++ modules/comment/views_handler_argument_comment_user_uid.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_argument_comment_user_uid.inc,v 1.2 2009/06/02 18:50:56 merlinofchaos Exp $
+// $Id: views_handler_argument_comment_user_uid.inc,v 1.1.2.1 2009/06/02 18:50:50 merlinofchaos Exp $
 
 /**
  * Argument handler to accept a user id to check for nodes that
Index: modules/comment/views_handler_field_comment.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/comment/views_handler_field_comment.inc,v
retrieving revision 1.5
diff -u -p -r1.5 views_handler_field_comment.inc
--- modules/comment/views_handler_field_comment.inc	10 Feb 2009 20:37:49 -0000	1.5
+++ modules/comment/views_handler_field_comment.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_comment.inc,v 1.5 2009/02/10 20:37:49 merlinofchaos Exp $
+// $Id: views_handler_field_comment.inc,v 1.5.2.1 2010/01/19 21:59:04 merlinofchaos Exp $
 /**
  * Field handler to allow linking to a comment
  */
@@ -7,7 +7,7 @@ class views_handler_field_comment extend
   /**
    * Override init function to provide generic option to link to comment.
    */
-  function init(&$view, &$options) {
+  function init(&$view, $options) {
     parent::init($view, $options);
     if (!empty($this->options['link_to_comment'])) {
       $this->additional_fields['cid'] = 'cid';
Index: modules/comment/views_handler_field_comment_node_link.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/comment/views_handler_field_comment_node_link.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_field_comment_node_link.inc
--- modules/comment/views_handler_field_comment_node_link.inc	8 Apr 2009 06:38:41 -0000	1.1
+++ modules/comment/views_handler_field_comment_node_link.inc	11 Aug 2010 21:11:33 -0000
@@ -1,25 +1,22 @@
 <?php
-// $Id: views_handler_field_comment_node_link.inc,v 1.1 2009/04/08 06:38:41 merlinofchaos Exp $
+// $Id: views_handler_field_comment_node_link.inc,v 1.1.2.1 2009/11/30 19:34:04 merlinofchaos Exp $
 /**
 * Handler for showing comment module's node link.
  */
 class views_handler_field_comment_node_link extends views_handler_field {
   function construct() {
     parent::construct();
-    
+
     // Add the node fields that comment_link will need..
     $this->additional_fields['nid'] = array(
-      'table' => 'node', 
       'field' => 'nid',
-    );      
+    );
     $this->additional_fields['type'] = array(
-      'table' => 'node', 
       'field' => 'type',
-    );      
+    );
     $this->additional_fields['comment'] = array(
-      'table' => 'node', 
       'field' => 'comment',
-    );      
+    );
   }
 
   function option_definition() {
@@ -30,14 +27,14 @@ class views_handler_field_comment_node_l
 
   function options_form(&$form, &$form_state) {
     parent::options_form($form, $form_state);
-    
+
     $form['teaser'] = array(
       '#type' => 'checkbox',
       '#title' => t('Show teaser-style link'),
       '#default_value' => $this->options['teaser'],
       '#description' => 'Show the comment link in the form used on standard node teasers, rather than the full node form.',
     );
-    
+
   }
 
   function query() {
@@ -51,9 +48,9 @@ class views_handler_field_comment_node_l
     $node->nid      = $values->{$this->aliases['nid']};
     $node->type     = $values->{$this->aliases['type']};
     $node->comment  = $values->{$this->aliases['comment']};
-    
-    // Call comment.module's hook_link: comment_link($type, $node = NULL, $teaser = FALSE) 
-    $links = comment_link('node', $node, $this->options['teaser']); 
+
+    // Call comment.module's hook_link: comment_link($type, $node = NULL, $teaser = FALSE)
+    $links = comment_link('node', $node, $this->options['teaser']);
     // question: should we run these through:    drupal_alter('link', $links, $node);
     // might this have unexpected consequences if these hooks expect items in $node that we don't have?
 
Index: modules/comment/views_handler_field_node_new_comments.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/comment/views_handler_field_node_new_comments.inc,v
retrieving revision 1.6
diff -u -p -r1.6 views_handler_field_node_new_comments.inc
--- modules/comment/views_handler_field_node_new_comments.inc	7 Apr 2009 23:02:07 -0000	1.6
+++ modules/comment/views_handler_field_node_new_comments.inc	11 Aug 2010 21:11:33 -0000
@@ -1,10 +1,20 @@
 <?php
-// $Id: views_handler_field_node_new_comments.inc,v 1.6 2009/04/07 23:02:07 merlinofchaos Exp $
+// $Id: views_handler_field_node_new_comments.inc,v 1.6.2.1 2009/07/02 00:13:06 merlinofchaos Exp $
 
 /**
  * Field handler to display the number of new comments
  */
 class views_handler_field_node_new_comments extends views_handler_field_numeric {
+  function init(&$view, $options) {
+    parent::init($view, $options);
+    
+    // translate an older setting:
+    if (!empty($options['no_empty'])) {
+      $this->options['hide_empty'] = TRUE;
+      unset($this->options['no_empty']);
+    }
+  }
+
   function construct() {
     parent::construct();
     $this->additional_fields = array('nid' => 'nid', 'type' => 'type');
@@ -14,7 +24,6 @@ class views_handler_field_node_new_comme
     $options = parent::option_definition();
 
     $options['link_to_comment'] = array('default' => TRUE);
-    $options['no_empty'] = array('default' => TRUE);
 
     return $options;
   }
@@ -27,11 +36,6 @@ class views_handler_field_node_new_comme
       '#type' => 'checkbox',
       '#default_value' => $this->options['link_to_comment'],
     );
-    $form['no_empty'] = array(
-      '#title' => t('Display nothing if no new comments'),
-      '#type' => 'checkbox',
-      '#default_value' => $this->options['no_empty'],
-    );
   }
 
   function query() {
@@ -85,7 +89,7 @@ class views_handler_field_node_new_comme
   }
 
   function render($values) {
-    if (!empty($values->{$this->field_alias}) || empty($this->options['no_empty'])) {
+    if (!empty($values->{$this->field_alias})) {
       return $this->render_link(parent::render($values), $values);
     }
     else {
Index: modules/comment/views_handler_filter_comment_user_uid.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/comment/views_handler_filter_comment_user_uid.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_handler_filter_comment_user_uid.inc
--- modules/comment/views_handler_filter_comment_user_uid.inc	2 Jun 2009 18:50:56 -0000	1.2
+++ modules/comment/views_handler_filter_comment_user_uid.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_comment_user_uid.inc,v 1.2 2009/06/02 18:50:56 merlinofchaos Exp $
+// $Id: views_handler_filter_comment_user_uid.inc,v 1.1.2.1 2009/06/02 18:50:50 merlinofchaos Exp $
 
 /**
  * Filter handler to accept a user id to check for nodes that user posted or
Index: modules/comment/views_plugin_row_comment_rss.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/comment/views_plugin_row_comment_rss.inc,v
retrieving revision 1.3
diff -u -p -r1.3 views_plugin_row_comment_rss.inc
--- modules/comment/views_plugin_row_comment_rss.inc	8 Jan 2009 19:40:44 -0000	1.3
+++ modules/comment/views_plugin_row_comment_rss.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_row_comment_rss.inc,v 1.3 2009/01/08 19:40:44 merlinofchaos Exp $
+// $Id: views_plugin_row_comment_rss.inc,v 1.3.2.1 2009/12/28 21:11:50 merlinofchaos Exp $
 /**
  * @file
  * Contains the comment RSS row style plugin.
@@ -9,12 +9,14 @@
  * Plugin which formats the comments as RSS items.
  */
 class views_plugin_row_comment_rss extends views_plugin_row {
+  var $base_table = 'comments';
+  var $base_field = 'cid';
 
   function render($row) {
     global $base_url;
 
     // Load the specified comment:
-    $comment = _comment_load($row->cid);
+    $comment = _comment_load($row->{$this->field_alias});
 
     $item = new stdClass();
     $item->title = $comment->subject;
Index: modules/comment/views_plugin_row_comment_view.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/comment/views_plugin_row_comment_view.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_plugin_row_comment_view.inc
--- modules/comment/views_plugin_row_comment_view.inc	3 Sep 2008 19:21:29 -0000	1.1
+++ modules/comment/views_plugin_row_comment_view.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_row_comment_view.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos Exp $
+// $Id: views_plugin_row_comment_view.inc,v 1.1.2.1 2009/12/28 21:11:50 merlinofchaos Exp $
 /**
  * @file
  * Contains the node RSS row style plugin.
@@ -9,6 +9,9 @@
  * Plugin which performs a comment_view on the resulting object.
  */
 class views_plugin_row_comment_view extends views_plugin_row {
+  var $base_table = 'comments';
+  var $base_field = 'cid';
+
   function option_definition() {
     $options = parent::option_definition();
     $options['links'] = array('default' => TRUE);
Index: modules/contact/views_handler_field_contact_link.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/contact/views_handler_field_contact_link.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_field_contact_link.inc
--- modules/contact/views_handler_field_contact_link.inc	1 Jun 2009 21:55:36 -0000	1.1
+++ modules/contact/views_handler_field_contact_link.inc	11 Aug 2010 21:11:33 -0000
@@ -1,10 +1,10 @@
 <?php
-// $Id: views_handler_field_contact_link.inc,v 1.1 2009/06/01 21:55:36 merlinofchaos Exp $
+// $Id: views_handler_field_contact_link.inc,v 1.1.2.4 2010/07/27 22:06:36 merlinofchaos Exp $
 /**
  * A field that links to the user contact page, if access is permitted.
  */
 class views_handler_field_contact_link extends views_handler_field_user_link {
-  
+
   function option_definition() {
     $options = parent::option_definition();
     $options['link_display'] = array('default' => 'link', 'translatable' => FALSE);
@@ -27,23 +27,44 @@ class views_handler_field_contact_link e
     $form['text']['#default_value'] = empty($this->options['text']) ? t('contact') : $this->options['text'];
   }
 
+  // An example of field level access control.
+  // We must override the access method in the parent class, as that requires
+  // the 'access user profiles' permission, which the contact form does not.
+  function access() {
+    global $user;
+
+    // Only registered users can view other registered user's contact page.
+    if (empty($user->uid)) {
+      return FALSE;
+    }
+
+    return TRUE;
+  }
+
   function render($values) {
     global $user;
     $uid = $values->{$this->aliases['uid']};
-    $account = user_load(array('uid' => $uid));
-    
+
+    if (empty($uid)) {
+      return;
+    }
+
+    $account = user_load($uid);
+    if (empty($account)) {
+      return;
+    }
+
     // Check access when we pull up the user account so we know
     // if the user has made the contact page available.
-    if (! _contact_user_tab_access($account)) {
+    if (!_contact_user_tab_access($account) || empty($account->contact)) {
       return;
     }
-    if ($account !== FALSE && $account->contact && $user->uid > 0) {
-      if ($this->options['link_display'] == 'icon') {
-        return l(theme('image', 'misc/forum-new.png'), 'user/'. $account->uid .'/contact', array('html' => TRUE, 'attributes' => array('title' => t('Contact %user', array('%user' => $account->name)))));
-      }
-      else {
-        return l($this->options['text'], 'user/'. $account->uid .'/contact', array('attributes' => array('title' => t('Contact %user', array('%user' => $account->name)))));
-      }
+
+    if ($this->options['link_display'] == 'icon') {
+      return l(theme('image', 'misc/forum-new.png'), 'user/'. $account->uid .'/contact', array('html' => TRUE, 'attributes' => array('title' => t('Contact %user', array('%user' => $account->name)))));
+    }
+    else {
+      return l($this->options['text'], 'user/'. $account->uid .'/contact', array('attributes' => array('title' => t('Contact %user', array('%user' => $account->name)))));
     }
   }
 }
Index: modules/filter/views_handler_field_filter_format_name.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/filter/views_handler_field_filter_format_name.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_handler_field_filter_format_name.inc
--- modules/filter/views_handler_field_filter_format_name.inc	3 Jun 2009 02:16:48 -0000	1.2
+++ modules/filter/views_handler_field_filter_format_name.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_filter_format_name.inc,v 1.2 2009/06/03 02:16:48 merlinofchaos Exp $
+// $Id: views_handler_field_filter_format_name.inc,v 1.1.2.1 2009/06/03 02:16:43 merlinofchaos Exp $
 /**
  * Field handler to output the name of an input format.
  */
Index: modules/node/views_handler_argument_node_type.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/node/views_handler_argument_node_type.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_handler_argument_node_type.inc
--- modules/node/views_handler_argument_node_type.inc	2 Jun 2009 17:57:48 -0000	1.2
+++ modules/node/views_handler_argument_node_type.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_argument_node_type.inc,v 1.2 2009/06/02 17:57:48 merlinofchaos Exp $
+// $Id: views_handler_argument_node_type.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos Exp $
 /**
  * Argument handler to accept a node type.
  */
@@ -27,10 +27,8 @@ class views_handler_argument_node_type e
   function node_type($type) {
     $output = node_get_types('name', $type);
     if (empty($output)) {
-      return t('Unknown node type');
-    }
-    else {
-      return check_plain(t($output));
+      $output = t('Unknown node type');
     }
+    return check_plain($output);
   }
 }
Index: modules/node/views_handler_field_node.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/node/views_handler_field_node.inc,v
retrieving revision 1.4
diff -u -p -r1.4 views_handler_field_node.inc
--- modules/node/views_handler_field_node.inc	2 Jun 2009 20:54:38 -0000	1.4
+++ modules/node/views_handler_field_node.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_node.inc,v 1.4 2009/06/02 20:54:38 merlinofchaos Exp $
+// $Id: views_handler_field_node.inc,v 1.3.2.7 2010/03/16 23:09:03 merlinofchaos Exp $
 /**
  * @file
  * Contains the basic 'node' field handler.
@@ -9,12 +9,15 @@
  * Field handler to provide simple renderer that allows linking to a node.
  */
 class views_handler_field_node extends views_handler_field {
-  /**
-   * Constructor to provide additional field to add.
-   */
-  function construct() {
-    parent::construct();
-    $this->additional_fields['nid'] = 'nid';
+
+  function init(&$view, $options) {
+    parent::init($view, $options);
+    if (!empty($this->options['link_to_node'])) {
+      $this->additional_fields['nid'] = array('table' => 'node', 'field' => 'nid');
+      if (module_exists('translation')) {
+        $this->additional_fields['language'] = array('table' => 'node', 'field' => 'language');
+      }
+    }
   }
 
   function option_definition() {
@@ -45,7 +48,15 @@ class views_handler_field_node extends v
     if (!empty($this->options['link_to_node']) && $data !== NULL && $data !== '') {
       $this->options['alter']['make_link'] = TRUE;
       $this->options['alter']['path'] = "node/" . $values->{$this->aliases['nid']};
-      $this->options['alter']['alt'] = check_plain($data);
+      if (isset($this->aliases['language'])) {
+        $languages = language_list();
+        if (isset($languages[$values->{$this->aliases['language']}])) {
+          $this->options['alter']['language'] = $languages[$values->{$this->aliases['language']}];
+        }
+        else {
+          unset($this->options['alter']['language']);
+        }
+      }
     }
     return $data;
   }
Index: modules/node/views_handler_field_node_type.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/node/views_handler_field_node_type.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_handler_field_node_type.inc
--- modules/node/views_handler_field_node_type.inc	2 Jun 2009 23:14:57 -0000	1.2
+++ modules/node/views_handler_field_node_type.inc	11 Aug 2010 21:11:33 -0000
@@ -1,13 +1,43 @@
 <?php
-// $Id: views_handler_field_node_type.inc,v 1.2 2009/06/02 23:14:57 merlinofchaos Exp $
+// $Id: views_handler_field_node_type.inc,v 1.1.2.4 2010/04/29 18:33:36 merlinofchaos Exp $
 
 /**
  * Field handler to translate a node type into its readable form.
  */
 class views_handler_field_node_type extends views_handler_field_node {
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['machine_name'] = array('default' => FALSE);
+
+    return $options;
+  }
+
+  /**
+   * Provide machine_name option for to node type display.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['machine_name'] = array(
+      '#title' => t('Output machine name'),
+      '#description' => t('Display field as the node type machine name.'),
+      '#type' => 'checkbox',
+      '#default_value' => !empty($this->options['machine_name']),
+    );
+  }
+
+  /**
+   * Render node type as human readable name, unless using machine_name option.
+   */
+  function render_name($data, $values) {
+    if ($this->options['machine_name'] != 1 && $data !== NULL && $data !== '') {
+      return t(check_plain(node_get_types('name', $data)));
+    }
+    return check_plain($data);
+  }
+
   function render($values) {
-    $value = node_get_types('name', $values->{$this->field_alias});
-    return $this->render_link(t(check_plain($value)), $values);
+    return $this->render_link($this->render_name($values->{$this->field_alias}, $values), $values);
   }
 }
 
Index: modules/node/views_handler_filter_history_user_timestamp.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/node/views_handler_filter_history_user_timestamp.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_handler_filter_history_user_timestamp.inc
--- modules/node/views_handler_filter_history_user_timestamp.inc	2 Jun 2009 19:10:40 -0000	1.2
+++ modules/node/views_handler_filter_history_user_timestamp.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_history_user_timestamp.inc,v 1.2 2009/06/02 19:10:40 merlinofchaos Exp $
+// $Id: views_handler_filter_history_user_timestamp.inc,v 1.1.2.2 2009/06/25 18:48:24 merlinofchaos Exp $
 /**
  * Filter for new content
  */
@@ -38,7 +38,7 @@ class views_handler_filter_history_user_
     }
 
     // Don't filter if we're exposed and the checkbox isn't selected.
-    if (empty($this->value)) {
+    if ((!empty($this->options['exposed'])) && empty($this->value)) {
       return;
     }
 
Index: modules/node/views_handler_filter_node_access.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/node/views_handler_filter_node_access.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_filter_node_access.inc
--- modules/node/views_handler_filter_node_access.inc	2 Jun 2009 20:09:33 -0000	1.1
+++ modules/node/views_handler_filter_node_access.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_node_access.inc,v 1.1 2009/06/02 20:09:33 merlinofchaos Exp $
+// $Id: views_handler_filter_node_access.inc,v 1.1.2.3 2009/09/15 22:08:33 merlinofchaos Exp $
 /**
  * Filter by node_access records.
  */
@@ -17,7 +17,7 @@ class views_handler_filter_node_access e
     if (!user_access('administer nodes')) {
       $table = $this->ensure_my_table();
       $grants = array();
-      foreach (node_access_grants($op, $account) as $realm => $gids) {
+      foreach (node_access_grants('view') as $realm => $gids) {
         foreach ($gids as $gid) {
           $grants[] = "($table.gid = $gid AND $table.realm = '$realm')";
         }
Index: modules/node/views_handler_filter_node_status.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/node/views_handler_filter_node_status.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_handler_filter_node_status.inc
--- modules/node/views_handler_filter_node_status.inc	3 Jun 2009 00:26:39 -0000	1.2
+++ modules/node/views_handler_filter_node_status.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_node_status.inc,v 1.2 2009/06/03 00:26:39 merlinofchaos Exp $
+// $Id: views_handler_filter_node_status.inc,v 1.1.2.1 2009/06/03 00:26:14 merlinofchaos Exp $
 /**
  * Filter by published status
  */
Index: modules/node/views_handler_filter_node_type.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/node/views_handler_filter_node_type.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_handler_filter_node_type.inc
--- modules/node/views_handler_filter_node_type.inc	2 Jun 2009 17:57:48 -0000	1.2
+++ modules/node/views_handler_filter_node_type.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_node_type.inc,v 1.2 2009/06/02 17:57:48 merlinofchaos Exp $
+// $Id: views_handler_filter_node_type.inc,v 1.1.2.1 2009/09/15 22:00:18 merlinofchaos Exp $
 /**
  * Filter by node type
  */
Index: modules/node/views_plugin_argument_default_node.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/node/views_plugin_argument_default_node.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_plugin_argument_default_node.inc
--- modules/node/views_plugin_argument_default_node.inc	3 Sep 2008 19:21:29 -0000	1.1
+++ modules/node/views_plugin_argument_default_node.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_argument_default_node.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos Exp $
+// $Id: views_plugin_argument_default_node.inc,v 1.1.2.1 2009/11/26 00:35:16 merlinofchaos Exp $
 /**
  * @file
  * Contains the node from URL argument default plugin.
@@ -7,11 +7,10 @@
 
 /**
  * Default argument plugin to extract a node via menu_get_object
+ *
+ * This plugin actually has no options so it odes not need to do a great deal.
  */
 class views_plugin_argument_default_node extends views_plugin_argument_default {
-  function argument_form(&$form, &$form_state) {
-  }
-
   function get_argument() {
     foreach (range(1, 3) as $i) {
       $node = menu_get_object('node', $i);
Index: modules/node/views_plugin_argument_validate_node.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/node/views_plugin_argument_validate_node.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_plugin_argument_validate_node.inc
--- modules/node/views_plugin_argument_validate_node.inc	10 Jun 2009 22:04:57 -0000	1.2
+++ modules/node/views_plugin_argument_validate_node.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_argument_validate_node.inc,v 1.2 2009/06/10 22:04:57 merlinofchaos Exp $
+// $Id: views_plugin_argument_validate_node.inc,v 1.1.2.3 2010/01/05 01:30:20 merlinofchaos Exp $
 /**
  * @file
  * Contains the 'node' argument validator plugin.
@@ -9,58 +9,63 @@
  * Validate whether an argument is an acceptable node.
  */
 class views_plugin_argument_validate_node extends views_plugin_argument_validate {
-  var $option_name = 'validate_argument_node_type';
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['types'] = array('default' => array());
+    $options['access'] = array('default' => FALSE);
+    $options['nid_type'] = array('default' => 'nid');
 
-  function validate_form(&$form, &$form_state) {
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
     $types = node_get_types();
     foreach ($types as $type => $info) {
       $options[$type] = check_plain(t($info->name));
     }
 
-    $arg = $this->get_argument();
-    if (empty($arg)) {
-      $arg = array();
-    }
-
-    $form[$this->option_name] = array(
+    $form['types'] = array(
       '#type' => 'checkboxes',
-      '#prefix' => '<div id="edit-options-validate-argument-node-type-wrapper">',
-      '#suffix' => '</div>',
       '#title' => t('Types'),
       '#options' => $options,
-      '#default_value' => $arg,
+      '#default_value' => $this->options['types'],
       '#description' => t('If you wish to validate for specific node types, check them; if none are checked, all nodes will pass.'),
-      '#process' => array('expand_checkboxes', 'views_process_dependency'),
-      '#dependency' => array('edit-options-validate-type' => array($this->id)),
     );
 
-    $form['validate_argument_node_access'] = array(
+    $form['access'] = array(
       '#type' => 'checkbox',
       '#title' => t('Validate user has access to the node'),
-      '#default_value' => !empty($this->argument->options['validate_argument_node_access']),
-      '#process' => array('views_process_dependency'),
-      '#dependency' => array('edit-options-validate-type' => array($this->id)),
+      '#default_value' => $this->options['access'],
     );
 
-    $form['validate_argument_nid_type'] = array(
+    $form['nid_type'] = array(
       '#type' => 'select',
       '#title' => t('Argument type'),
       '#options' => array(
         'nid' => t('Node ID'),
         'nids' => t('Node IDs separated by , or +'),
       ),
-      '#default_value' => isset($this->argument->options['validate_argument_nid_type']) ? $this->argument->options['validate_argument_nid_type'] : 'nid',
-      '#process' => array('views_process_dependency'),
-      '#dependency' => array('edit-options-validate-type' => array($this->id)),
+      '#default_value' => $this->options['nid_type'],
     );
   }
 
-  function validate_argument($argument) {
-    $types = array_filter($this->argument->options[$this->option_name]);
+  function options_submit(&$form, &$form_state, &$options) {
+    // filter trash out of the options so we don't store giant unnecessary arrays
+    $options['types'] = array_filter($options['types']);
+  }
 
-    $type = isset($this->argument->options['validate_argument_nid_type']) ? $this->argument->options['validate_argument_nid_type'] : 'nid';
+  function convert_options(&$options) {
+    if (!isset($options['types']) && !empty($this->argument->options['validate_argument_node_type'])) {
+      $options['types'] = $this->argument->options['validate_argument_node_type'];
+      $options['access'] = !empty($this->argument->options['validate_argument_node_access']);
+      $options['nid_type'] = $this->argument->options['validate_argument_nid_type'];
+    }
+  }
+
+  function validate_argument($argument) {
+    $types = $this->options['types'];
 
-    switch ($type) {
+    switch ($this->options['nid_type']) {
       case 'nid':
         if (!is_numeric($argument)) {
           return FALSE;
@@ -70,7 +75,7 @@ class views_plugin_argument_validate_nod
           return FALSE;
         }
 
-        if (!empty($this->argument->options['validate_argument_node_access'])) {
+        if (!empty($this->options['access'])) {
           if (!node_access('view', $node)) {
             return FALSE;
           }
@@ -104,7 +109,7 @@ class views_plugin_argument_validate_nod
             return FALSE;
           }
 
-          if (!empty($this->argument->options['validate_argument_node_access'])) {
+          if (!empty($this->options['access'])) {
             if (!node_access('view', $node)) {
               return FALSE;
             }
Index: modules/node/views_plugin_row_node_rss.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/node/views_plugin_row_node_rss.inc,v
retrieving revision 1.7
diff -u -p -r1.7 views_plugin_row_node_rss.inc
--- modules/node/views_plugin_row_node_rss.inc	2 Jun 2009 20:14:43 -0000	1.7
+++ modules/node/views_plugin_row_node_rss.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_row_node_rss.inc,v 1.7 2009/06/02 20:14:43 merlinofchaos Exp $
+// $Id: views_plugin_row_node_rss.inc,v 1.6.2.3 2010/04/29 18:31:30 merlinofchaos Exp $
 /**
  * @file
  * Contains the node RSS row style plugin.
@@ -92,7 +92,9 @@ class views_plugin_row_node_rss extends 
 
     $item = new stdClass();
     $item->title = $node->title;
-    $item->link = url("node/$row->nid", array('absolute' => TRUE));
+    $item->link = url("node/$node->nid", array('absolute' => TRUE));
+    $item->nid = $node->nid;
+    $item->readmore = $node->readmore;
 
     // Allow modules to add additional item fields and/or modify $item
     $extra = node_invoke_nodeapi($node, 'rss item');
Index: modules/profile/views_handler_field_profile_list.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/profile/views_handler_field_profile_list.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_field_profile_list.inc
--- modules/profile/views_handler_field_profile_list.inc	3 Sep 2008 19:21:29 -0000	1.1
+++ modules/profile/views_handler_field_profile_list.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_profile_list.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos Exp $
+// $Id: views_handler_field_profile_list.inc,v 1.1.2.4 2010/03/22 19:28:23 merlinofchaos Exp $
 /**
  * Field handler display a profile list item.
  */
@@ -7,14 +7,28 @@ class views_handler_field_profile_list e
   /**
    * Break up our field into a proper list.
    */
-  function render($value) {
-    $field = $value->{$this->field_alias};
-    $this->items[$field] = array();
-    foreach (split("[,\n\r]", $field) as $item) {
-      if ($item != '' && $item !== NULL) {
-        $this->items[$field][] = $item;
+  function pre_render($values) {
+    $this->items = array();
+    foreach ($values as $value) {
+      $field = $value->{$this->field_alias};
+      $this->items[$field] = array();
+      foreach (split("[,\n\r]", $field) as $item) {
+        if ($item != '' && $item !== NULL) {
+          $this->items[$field][] = array('item' => $item);
+        }
       }
     }
-    return parent::render($value);
+  }
+
+  function render_item($count, $item) {
+    return $item['item'];
+  }
+
+  function document_self_tokens(&$tokens) {
+    $tokens['[' . $this->options['id'] . '-item' . ']'] = t('The text of the profile item.');
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    $tokens['[' . $this->options['id'] . '-item' . ']'] = $item['item'];
   }
 }
Index: modules/search/views_handler_filter_search.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/search/views_handler_filter_search.inc,v
retrieving revision 1.5
diff -u -p -r1.5 views_handler_filter_search.inc
--- modules/search/views_handler_filter_search.inc	10 Apr 2009 19:32:19 -0000	1.5
+++ modules/search/views_handler_filter_search.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_search.inc,v 1.5 2009/04/10 19:32:19 merlinofchaos Exp $
+// $Id: views_handler_filter_search.inc,v 1.5.2.1 2009/12/24 00:37:04 merlinofchaos Exp $
 
 /**
  * Field handler to provide simple renderer that allows linking to a node.
@@ -77,7 +77,7 @@ class views_handler_filter_search extend
   function query() {
     if (!isset($this->search_query) || empty($this->search_query[3])) {
       if ($this->operator == 'required') {
-        $this->query->add_where($this->options['group'], '0');
+        $this->query->add_where($this->options['group'], 'FALSE');
       }
     }
     else {
Index: modules/system/views_handler_field_file.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/system/views_handler_field_file.inc,v
retrieving revision 1.3
diff -u -p -r1.3 views_handler_field_file.inc
--- modules/system/views_handler_field_file.inc	30 Jan 2009 00:01:42 -0000	1.3
+++ modules/system/views_handler_field_file.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_file.inc,v 1.3 2009/01/30 00:01:42 merlinofchaos Exp $
+// $Id: views_handler_field_file.inc,v 1.3.2.1 2010/01/19 21:59:04 merlinofchaos Exp $
 /**
  * Field handler to provide simple renderer that allows linking to a file.
  */
@@ -7,7 +7,7 @@ class views_handler_field_file extends v
   /**
    * Constructor to provide additional field to add.
    */
-  function init(&$view, &$options) {
+  function init(&$view, $options) {
     parent::init($view, $options);
     if (!empty($options['link_to_file'])) {
       $this->additional_fields['filepath'] = 'filepath';
Index: modules/taxonomy/views_handler_argument_term_node_tid.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/taxonomy/views_handler_argument_term_node_tid.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_argument_term_node_tid.inc
--- modules/taxonomy/views_handler_argument_term_node_tid.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ modules/taxonomy/views_handler_argument_term_node_tid.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_argument_term_node_tid.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+// $Id: views_handler_argument_term_node_tid.inc,v 1.1.2.1 2009/12/24 00:24:02 merlinofchaos Exp $
 /**
  * Allow taxonomy term ID(s) as argument
  */
@@ -7,6 +7,7 @@ class views_handler_argument_term_node_t
   function option_definition() {
     $options = parent::option_definition();
     $options['set_breadcrumb'] = array('default' => FALSE);
+    $options['use_synonym_for_summary_links'] = array('default' => FALSE);
     return $options;
   }
 
@@ -18,6 +19,12 @@ class views_handler_argument_term_node_t
       '#description' => t('If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received.'),
       '#default_value' => !empty($this->options['set_breadcrumb']),
     );
+    $form['use_synonym_for_summary_links'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Use term synonyms for summary links'),
+      '#description' => t('If selected, summary views will use a synonym defined for each term when creating the URL to link to that term. Note that this only works reliably if terms have at most one synonym.'),
+      '#default_value' => !empty($this->options['use_synonym_for_summary_links']),
+    );
   }
 
   function set_breadcrumb(&$breadcrumb) {
@@ -38,5 +45,16 @@ class views_handler_argument_term_node_t
     }
     return $titles;
   }
+
+  function summary_argument($data) {
+    if (!empty($this->options['use_synonym_for_summary_links'])) {
+      $synonym = db_result(db_query_range("SELECT name FROM {term_synonym} WHERE tid = %d", $data->{$this->base_alias}, 0, 1));
+      if (!empty($synonym)) {
+        return $synonym;
+      }
+    }
+    return $data->{$this->base_alias};
+  }
+
 }
 
Index: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/taxonomy/views_handler_argument_term_node_tid_depth.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_argument_term_node_tid_depth.inc
--- modules/taxonomy/views_handler_argument_term_node_tid_depth.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ modules/taxonomy/views_handler_argument_term_node_tid_depth.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_argument_term_node_tid_depth.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+// $Id: views_handler_argument_term_node_tid_depth.inc,v 1.1.2.3 2010/03/16 23:38:22 merlinofchaos Exp $
 /**
  * Argument handler for taxonomy terms with depth.
  *
@@ -13,6 +13,7 @@ class views_handler_argument_term_node_t
     $options['depth'] = array('default' => 0);
     $options['break_phrase'] = array('default' => FALSE);
     $options['set_breadcrumb'] = array('default' => FALSE);
+    $options['use_taxonomy_term_path'] = array('default' => FALSE);
 
     return $options;
   }
@@ -39,6 +40,15 @@ class views_handler_argument_term_node_t
       '#description' => t('If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received.'),
       '#default_value' => !empty($this->options['set_breadcrumb']),
     );
+
+    $form['use_taxonomy_term_path'] = array(
+      '#type' => 'checkbox',
+      '#title' => t("Use Drupal's taxonomy term path to create breadcrumb links"),
+      '#description' => t('If selected, the links in the breadcrumb trail will be created using the standard drupal method instead of the custom views method. This is useful if you are using modules like taxonomy redirect to modify your taxonomy term links.'),
+      '#default_value' => !empty($this->options['use_taxonomy_term_path']),
+      '#process' => array('views_process_dependency'),
+      '#dependency' => array('edit-options-set-breadcrumb' => array(TRUE)),
+    );
   }
 
   function set_breadcrumb(&$breadcrumb) {
Index: modules/taxonomy/views_handler_field_term_node_tid.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/taxonomy/views_handler_field_term_node_tid.inc,v
retrieving revision 1.3
diff -u -p -r1.3 views_handler_field_term_node_tid.inc
--- modules/taxonomy/views_handler_field_term_node_tid.inc	7 Apr 2009 22:02:40 -0000	1.3
+++ modules/taxonomy/views_handler_field_term_node_tid.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_term_node_tid.inc,v 1.3 2009/04/07 22:02:40 merlinofchaos Exp $
+// $Id: views_handler_field_term_node_tid.inc,v 1.3.2.1 2009/07/01 23:06:44 merlinofchaos Exp $
 
 /**
  * Field handler for terms.
@@ -82,17 +82,38 @@ class views_handler_field_term_node_tid 
         $voc = " AND td.vid IN (" . implode(', ', array_keys(array_filter($this->options['vids']))) . ")";
       }
 
-      $result = db_query("SELECT tn.vid AS node_vid, td.* FROM {term_data} td INNER JOIN {term_node} tn ON td.tid = tn.tid WHERE tn.vid IN (" . implode(', ', $vids) . ")$voc ORDER BY td.weight, td.name");
+      $result = db_query("SELECT tn.vid AS node_vid, td.*, v.name as vocabulary FROM {term_data} td INNER JOIN {term_node} tn ON td.tid = tn.tid INNER JOIN {vocabulary} v ON v.vid = td.vid WHERE tn.vid IN (" . implode(', ', $vids) . ")$voc ORDER BY td.weight, td.name");
 
       while ($term = db_fetch_object($result)) {
-        if (empty($this->options['link_to_taxonomy'])) {
-          $this->items[$term->node_vid][$term->tid] = check_plain($term->name);
-        }
-        else {
-          $this->items[$term->node_vid][$term->tid] = l($term->name, taxonomy_term_path($term));
+        $this->items[$term->node_vid][$term->tid]['name'] = check_plain($term->name);
+        $this->items[$term->node_vid][$term->tid]['tid'] = $term->tid;
+        $this->items[$term->node_vid][$term->tid]['vid'] = $term->vid;
+        $this->items[$term->node_vid][$term->tid]['vocabulary'] = check_plain($term->vocabulary);
+        
+        if (!empty($this->options['link_to_taxonomy'])) {
+          $this->items[$term->node_vid][$term->tid]['make_link'] = TRUE;
+          $this->items[$term->node_vid][$term->tid]['path'] = taxonomy_term_path($term);
         }
       }
     }
   }
+
+  function render_item($count, $item) {
+    return $item['name'];
+  }
+
+  function document_self_tokens(&$tokens) {
+    $tokens['[' . $this->options['id'] . '-tid' . ']'] = t('The taxonomy term ID for the term.');
+    $tokens['[' . $this->options['id'] . '-name' . ']'] = t('The taxonomy term name for the term.');
+    $tokens['[' . $this->options['id'] . '-vid' . ']'] = t('The vocabulary ID for the vocabulary the term belongs to.');
+    $tokens['[' . $this->options['id'] . '-vocabulary' . ']'] = t('The name for the vocabulary the term belongs to.');
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    $tokens['[' . $this->options['id'] . '-tid' . ']'] = $item['tid'];
+    $tokens['[' . $this->options['id'] . '-name' . ']'] = $item['name'];
+    $tokens['[' . $this->options['id'] . '-vid' . ']'] = $item['vid'];
+    $tokens['[' . $this->options['id'] . '-vocabulary' . ']'] = $item['vocabulary'];
+  }
 }
 
Index: modules/taxonomy/views_handler_filter_term_node_tid.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/taxonomy/views_handler_filter_term_node_tid.inc,v
retrieving revision 1.8
diff -u -p -r1.8 views_handler_filter_term_node_tid.inc
--- modules/taxonomy/views_handler_filter_term_node_tid.inc	7 Apr 2009 23:21:01 -0000	1.8
+++ modules/taxonomy/views_handler_filter_term_node_tid.inc	11 Aug 2010 21:11:33 -0000
@@ -1,10 +1,12 @@
 <?php
-// $Id: views_handler_filter_term_node_tid.inc,v 1.8 2009/04/07 23:21:01 merlinofchaos Exp $
+// $Id: views_handler_filter_term_node_tid.inc,v 1.8.2.4 2010/07/27 22:55:56 merlinofchaos Exp $
 
 /**
  * Filter by term id
  */
 class views_handler_filter_term_node_tid extends views_handler_filter_many_to_one {
+  function can_group() { return FALSE; }
+
   function has_extra_options() { return TRUE; }
 
   function get_value_options() { /* don't overwrite the value options */ }
@@ -15,6 +17,7 @@ class views_handler_filter_term_node_tid
     $options['type'] = array('default' => 'textfield');
     $options['limit'] = array('default' => TRUE);
     $options['vid'] = array('default' => 0);
+    $options['hierarchy'] = array('default' => 0);
 
     return $options;
   }
@@ -116,10 +119,10 @@ class views_handler_filter_term_node_tid
       else {
         $options = array();
         if ($this->options['limit']) {
-          $result = db_query("SELECT * FROM {term_data} WHERE vid = %d ORDER BY weight, name", $vocabulary->vid);
+          $result = db_query(db_rewrite_sql("SELECT * FROM {term_data} t WHERE vid = %d ORDER BY weight, name", 't', 'tid'), $vocabulary->vid);
         }
         else {
-          $result = db_query("SELECT td.* FROM {term_data} td INNER JOIN {vocabulary} v ON td.vid = v.vid ORDER BY v.weight, v.name, td.weight, td.name");
+          $result = db_query(db_rewrite_sql("SELECT td.* FROM {term_data} td INNER JOIN {vocabulary} v ON td.vid = v.vid ORDER BY v.weight, v.name, td.weight, td.name", 'td', 'tid'));
         }
         while ($term = db_fetch_object($result)) {
           $options[$term->tid] = $term->name;
@@ -174,7 +177,7 @@ class views_handler_filter_term_node_tid
     }
   }
 
-  function value_validate(&$form, &$form_state) {
+  function value_validate($form, &$form_state) {
     // We only validate if they've chosen the text field style.
     if ($this->options['type'] != 'textfield') {
       return;
Index: modules/taxonomy/views_handler_filter_term_node_tid_depth.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/taxonomy/views_handler_filter_term_node_tid_depth.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_filter_term_node_tid_depth.inc
--- modules/taxonomy/views_handler_filter_term_node_tid_depth.inc	5 Jun 2009 01:26:35 -0000	1.1
+++ modules/taxonomy/views_handler_filter_term_node_tid_depth.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_term_node_tid_depth.inc,v 1.1 2009/06/05 01:26:35 merlinofchaos Exp $
+// $Id: views_handler_filter_term_node_tid_depth.inc,v 1.1.2.2 2009/06/12 16:17:42 merlinofchaos Exp $
 /**
  * Filter handler for taxonomy terms with depth.
  *
Index: modules/taxonomy/views_handler_filter_vocabulary_vid.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/taxonomy/views_handler_filter_vocabulary_vid.inc,v
retrieving revision 1.3
diff -u -p -r1.3 views_handler_filter_vocabulary_vid.inc
--- modules/taxonomy/views_handler_filter_vocabulary_vid.inc	10 Jun 2009 22:04:58 -0000	1.3
+++ modules/taxonomy/views_handler_filter_vocabulary_vid.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_vocabulary_vid.inc,v 1.3 2009/06/10 22:04:58 merlinofchaos Exp $
+// $Id: views_handler_filter_vocabulary_vid.inc,v 1.2.2.1 2009/06/10 22:05:24 merlinofchaos Exp $
 
 /**
  * Filter by vocabulary id
Index: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc,v
retrieving revision 1.5
diff -u -p -r1.5 views_plugin_argument_validate_taxonomy_term.inc
--- modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc	2 Jun 2009 18:36:36 -0000	1.5
+++ modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_argument_validate_taxonomy_term.inc,v 1.5 2009/06/02 18:36:36 merlinofchaos Exp $
+// $Id: views_plugin_argument_validate_taxonomy_term.inc,v 1.4.2.6 2010/03/19 23:44:15 merlinofchaos Exp $
 /**
  * @file
  * Contains the 'taxonomy term' argument validator plugin.
@@ -9,26 +9,31 @@
  * Validate whether an argument is an acceptable node.
  */
 class views_plugin_argument_validate_taxonomy_term extends views_plugin_argument_validate {
-  function validate_form(&$form, &$form_state) {
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['vids'] = array('default' => array());
+    $options['type'] = array('default' => 'tid');
+    $options['transform'] = array('default' => FALSE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
     $vocabularies = taxonomy_get_vocabularies();
     $options = array();
     foreach ($vocabularies as $voc) {
       $options[$voc->vid] = check_plain($voc->name);
     }
 
-    $form['validate_argument_vocabulary'] = array(
+    $form['vids'] = array(
       '#type' => 'checkboxes',
-      '#prefix' => '<div id="edit-options-validate-argument-vocabulary-wrapper">',
-      '#suffix' => '</div>',
       '#title' => t('Vocabularies'),
       '#options' => $options,
-      '#default_value' => isset($this->argument->options['validate_argument_vocabulary']) ? $this->argument->options['validate_argument_vocabulary'] : array(),
+      '#default_value' => $this->options['vids'],
       '#description' => t('If you wish to validate for specific vocabularies, check them; if none are checked, all terms will pass.'),
-      '#process' => array('expand_checkboxes', 'views_process_dependency'),
-      '#dependency' => array('edit-options-validate-type' => array($this->id)),
     );
 
-    $form['validate_argument_type'] = array(
+    $form['type'] = array(
       '#type' => 'select',
       '#title' => t('Argument type'),
       '#options' => array(
@@ -37,25 +42,34 @@ class views_plugin_argument_validate_tax
         'name' => t('Term name or synonym'),
         'convert' => t('Term name/synonym converted to Term ID'),
       ),
-      '#default_value' => isset($this->argument->options['validate_argument_type']) ? $this->argument->options['validate_argument_type'] : 'tid',
+      '#default_value' => $this->options['type'],
       '#description' => t('Select the form of this argument; if using term name, it is generally more efficient to convert it to a term ID and use Taxonomy: Term ID rather than Taxonomy: Term Name" as an argument.'),
-      '#process' => array('views_process_dependency'),
-      '#dependency' => array('edit-options-validate-type' => array($this->id)),
     );
 
-    $form['validate_argument_transform'] = array(
+    $form['transform'] = array(
       '#type' => 'checkbox',
       '#title' => t('Transform dashes in URL to spaces in term name arguments'),
-      '#default_value' => isset($this->argument->options['validate_argument_transform']) ? $this->argument->options['validate_argument_transform'] : FALSE,
-      '#process' => array('views_process_dependency'),
-      '#dependency' => array('edit-options-validate-type' => array($this->id)),
+      '#default_value' => $this->options['transform'],
     );
   }
 
+  function options_submit($form, &$form_state, &$options) {
+    // filter trash out of the options so we don't store giant unnecessary arrays
+    $options['vids'] = array_filter($options['vids']);
+  }
+
+  function convert_options(&$options) {
+    if (!isset($options['vids']) && !empty($this->argument->options['validate_argument_vocabulary'])) {
+      $options['vids'] = $this->argument->options['validate_argument_vocabulary'];
+      $options['type'] = $this->argument->options['validate_argument_type'];
+      $options['transform'] = $this->argument->options['validate_argument_transform'];
+    }
+  }
+
   function validate_argument($argument) {
-    $vids = isset($this->argument->options['validate_argument_vocabulary']) ? array_filter($this->argument->options['validate_argument_vocabulary']) : array();
-    $type = isset($this->argument->options['validate_argument_type']) ? $this->argument->options['validate_argument_type'] : 'tid';
-    $transform = isset($this->argument->options['validate_argument_transform']) ? $this->argument->options['validate_argument_transform'] : FALSE;
+    $vids = array_filter($this->options['vids']);
+    $type = $this->options['type'];
+    $transform = $this->options['transform'];
 
     switch ($type) {
       case 'tid':
@@ -67,8 +81,8 @@ class views_plugin_argument_validate_tax
         if (!$result) {
           return FALSE;
         }
-
         return empty($vids) || !empty($vids[$result->vid]);
+
       case 'tids':
         $tids = new stdClass();
         $tids->value = $argument;
@@ -77,19 +91,38 @@ class views_plugin_argument_validate_tax
           return FALSE;
         }
 
-        $placeholders = implode(', ', array_fill(0, sizeof($tids->value), '%d'));
-
         $test = drupal_map_assoc($tids->value);
         $titles = array();
 
-        $result = db_query("SELECT * FROM {term_data} WHERE tid IN ($placeholders)", $tids->value);
-        while ($term = db_fetch_object($result)) {
-          if ($vids && empty($vids[$term->vid])) {
-            return FALSE;
+        // check, if some tids already verified
+        static $validated_cache = array();
+        foreach ($test as $tid) {
+          if (isset($validated_cache[$tid])) {
+            if ($validated_cache[$tid] === FALSE) {
+              return FALSE;
+            }
+            else {
+              $titles[] = $validated_cache[$tid];
+              unset($test[$tid]);
+            }
           }
+        }
+
 
-          $titles[] = check_plain($term->name);
-          unset($test[$term->tid]);
+        // if unverified tids left - verify them and cache results
+        if (count($test)) {
+          $placeholders = implode(', ', array_fill(0, count($test), '%d'));
+
+          $result = db_query("SELECT * FROM {term_data} WHERE tid IN ($placeholders)", $test);
+          while ($term = db_fetch_object($result)) {
+            if ($vids && empty($vids[$term->vid])) {
+              $validated_cache[$term->tid] = FALSE;
+              return FALSE;
+            }
+
+            $titles[] = $validated_cache[$term->tid] = check_plain($term->name);
+            unset($test[$term->tid]);
+          }
         }
 
         // Remove duplicate titles
@@ -98,6 +131,7 @@ class views_plugin_argument_validate_tax
         $this->argument->validated_title = implode($tids->operator == 'or' ? ' + ' : ', ', $titles);
         // If this is not empty, we did not find a tid.
         return empty($test);
+
       case 'name':
       case 'convert':
         $and = '';
@@ -105,9 +139,11 @@ class views_plugin_argument_validate_tax
           $and = " AND td.vid IN(" . implode(', ', $vids) . ')';
         }
         if ($transform) {
-          $argument = str_replace('-', ' ', $argument);
+          $result = db_fetch_object(db_query("SELECT td.* FROM {term_data} td LEFT JOIN {term_synonym} ts ON ts.tid = td.tid WHERE (replace(td.name, ' ', '-') = '%s' OR replace(ts.name, ' ', '-') = '%s')$and", $argument, $argument));
+        }
+        else {
+          $result = db_fetch_object(db_query("SELECT td.* FROM {term_data} td LEFT JOIN {term_synonym} ts ON ts.tid = td.tid WHERE (td.name = '%s' OR ts.name = '%s')$and", $argument, $argument));
         }
-        $result = db_fetch_object(db_query("SELECT td.* FROM {term_data} td LEFT JOIN {term_synonym} ts ON ts.tid = td.tid WHERE (td.name = '%s' OR ts.name = '%s')$and", $argument, $argument));
         if (!$result) {
           return FALSE;
         }
Index: modules/upload/views_handler_field_upload_description.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/upload/views_handler_field_upload_description.inc,v
retrieving revision 1.3
diff -u -p -r1.3 views_handler_field_upload_description.inc
--- modules/upload/views_handler_field_upload_description.inc	30 Jan 2009 00:01:42 -0000	1.3
+++ modules/upload/views_handler_field_upload_description.inc	11 Aug 2010 21:11:33 -0000
@@ -1,11 +1,11 @@
 <?php
-// $Id: views_handler_field_upload_description.inc,v 1.3 2009/01/30 00:01:42 merlinofchaos Exp $
+// $Id: views_handler_field_upload_description.inc,v 1.3.2.4 2010/04/07 23:40:32 merlinofchaos Exp $
 
 /**
  * Field handler to provide a list of roles.
  */
-class views_handler_field_upload_description extends views_handler_field_prerender_list {
-  function init(&$view, &$options) {
+class views_handler_field_upload_description extends views_handler_field {
+  function init(&$view, $options) {
     parent::init($view, $options);
     if (!empty($options['link_to_file'])) {
       $this->additional_fields['fid'] = 'fid';
@@ -43,7 +43,6 @@ class views_handler_field_upload_descrip
     }
 
     if ($fids) {
-      // Support "only listed files" option.
       $result = db_query("SELECT f.fid, f.filepath FROM {files} f WHERE f.fid IN (" . implode(', ', $fids) . ")");
       while ($file = db_fetch_object($result)) {
         $this->items[$file->fid] = $file;
@@ -52,7 +51,7 @@ class views_handler_field_upload_descrip
   }
 
   function render($values) {
-    return $this->render_link($values->{$this->field_alias}, $values);
+    return $this->render_link(check_plain($values->{$this->field_alias}), $values);
   }
 
   /**
@@ -66,6 +65,9 @@ class views_handler_field_upload_descrip
       $this->options['alter']['make_link'] = TRUE;
       $this->options['alter']['path'] = file_create_url($values->filepath);
     }
+    else {
+      $this->options['alter']['make_link'] = FALSE;
+    }
     return $data;
   }
 }
Index: modules/upload/views_handler_field_upload_fid.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/upload/views_handler_field_upload_fid.inc,v
retrieving revision 1.6
diff -u -p -r1.6 views_handler_field_upload_fid.inc
--- modules/upload/views_handler_field_upload_fid.inc	7 Apr 2009 22:48:03 -0000	1.6
+++ modules/upload/views_handler_field_upload_fid.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_upload_fid.inc,v 1.6 2009/04/07 22:48:03 merlinofchaos Exp $
+// $Id: views_handler_field_upload_fid.inc,v 1.6.2.2 2009/08/11 22:06:15 dww Exp $
 /**
  * Field handler to provide a list of roles.
  */
@@ -8,10 +8,6 @@ class views_handler_field_upload_fid ext
     parent::construct();
   }
 
-  function allow_advanced_render() {
-    return FALSE;
-  }
-
   function option_definition() {
     $options = parent::option_definition();
     $options['link_to_file'] = array('default' => FALSE);
@@ -48,22 +44,41 @@ class views_handler_field_upload_fid ext
       if (!empty($this->options['only_listed'])) {
         $where = " AND u.list <> 0";
       }
-      $result = db_query("SELECT u.vid, u.fid, f.filepath, u.description FROM {upload} u LEFT JOIN {files} f ON f.fid = u.fid WHERE u.vid IN (" . implode(', ', $vids) . ")$where ORDER BY u.weight");
-      while ($file = db_fetch_object($result)) {
-        $this->items[$file->vid][$file->fid] = $this->render_link(check_plain($file->description), $file);
+      $result = db_query("SELECT u.vid, u.fid, f.filename, f.filepath, f.filesize, f.filemime, u.description FROM {upload} u LEFT JOIN {files} f ON f.fid = u.fid WHERE u.vid IN (" . implode(', ', $vids) . ")$where ORDER BY u.weight");
+      while ($file = db_fetch_array($result)) {
+        $file['filename'] = check_plain($file['filename']);
+        $file['filemime'] = check_plain($file['filemime']);
+        $file['description'] = check_plain($file['description']);
+        $file['filesize'] = format_size($file['filesize']);
+        $file['filepath'] = file_create_url($file['filepath']);
+        if (!empty($this->options['link_to_file']) ) {
+          $file['make_link'] = TRUE;
+          $file['path'] = $file['filepath'];
+        }
+        $this->items[$file['vid']][$file['fid']] = $file;
       }
     }
   }
 
-  /**
-   * Render whatever the data is as a link to the file.
-   *
-   * Data should be made XSS safe prior to calling this function.
-   */
-  function render_link($data, $values) {
-    if (!empty($this->options['link_to_file']) && $data !== NULL && $data !== '') {
-      return l($data, file_create_url($values->filepath), array('html' => TRUE));
-    }
-    return $data;
+  function render_item($count, $item) {
+    return $item['description'];
+  }
+
+  function document_self_tokens(&$tokens) {
+    $tokens['[' . $this->options['id'] . '-fid' . ']'] = t('The file ID for the file.');
+    $tokens['[' . $this->options['id'] . '-name' . ']'] = t('The name of the attached file.');
+    $tokens['[' . $this->options['id'] . '-type' . ']'] = t('The MIME type of the attached file.');
+    $tokens['[' . $this->options['id'] . '-description' . ']'] = t('The name of the attached file.');
+    $tokens['[' . $this->options['id'] . '-path' . ']'] = t('The path of the attached file.');
+    $tokens['[' . $this->options['id'] . '-size' . ']'] = t('The size of the attached file.');
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    $tokens['[' . $this->options['id'] . '-fid' . ']'] = $item['fid'];
+    $tokens['[' . $this->options['id'] . '-name' . ']'] = $item['filename'];
+    $tokens['[' . $this->options['id'] . '-type' . ']'] = $item['filemime'];
+    $tokens['[' . $this->options['id'] . '-description' . ']'] = $item['description'];
+    $tokens['[' . $this->options['id'] . '-path' . ']'] = $item['filepath'];
+    $tokens['[' . $this->options['id'] . '-size' . ']'] = $item['filesize'];
   }
 }
Index: modules/user/views_handler_field_user_language.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/user/views_handler_field_user_language.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_field_user_language.inc
--- modules/user/views_handler_field_user_language.inc	2 Jun 2009 20:18:26 -0000	1.1
+++ modules/user/views_handler_field_user_language.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_user_language.inc,v 1.1 2009/06/02 20:18:26 merlinofchaos Exp $ 
+// $Id: views_handler_field_user_language.inc,v 1.1.2.2 2009/06/02 20:18:31 merlinofchaos Exp $ 
 /**
  * @file
  *   Views field handler for userlanguage.
Index: modules/user/views_handler_field_user_link_edit.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/user/views_handler_field_user_link_edit.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_field_user_link_edit.inc
--- modules/user/views_handler_field_user_link_edit.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ modules/user/views_handler_field_user_link_edit.inc	11 Aug 2010 21:11:33 -0000
@@ -1,18 +1,18 @@
 <?php
-// $Id: views_handler_field_user_link_edit.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+// $Id: views_handler_field_user_link_edit.inc,v 1.1.2.1 2010/03/19 22:59:06 merlinofchaos Exp $
 /**
  * Field handler to present a link to user edit.
  */
 class views_handler_field_user_link_edit extends views_handler_field_user_link {
-  // An example of field level access control.
-  function access() {
-    return user_access('administer users');
-  }
-
   function render($values) {
     $text = !empty($this->options['text']) ? $this->options['text'] : t('edit');
     $uid = $values->{$this->aliases['uid']};
-    return l($text, "user/$uid/edit", array('query' => drupal_get_destination()));
+    // Fake object to check access.
+    $account = new stdClass();
+    $account->uid = $uid;
+    if (user_edit_access($account)) {
+      return l($text, "user/$uid/edit", array('query' => drupal_get_destination()));
+    }
   }
 }
 
Index: modules/user/views_handler_field_user_picture.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/user/views_handler_field_user_picture.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_field_user_picture.inc
--- modules/user/views_handler_field_user_picture.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ modules/user/views_handler_field_user_picture.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_user_picture.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+// $Id: views_handler_field_user_picture.inc,v 1.1.2.3 2010/01/06 20:55:10 merlinofchaos Exp $
 
 /**
  * Field handler to provide simple renderer that allows using a themed user link
@@ -9,6 +9,11 @@ class views_handler_field_user_picture e
     parent::construct();
     $this->additional_fields['uid'] = 'uid';
     $this->additional_fields['name'] = 'name';
+    $this->additional_fields['mail'] = 'mail';   
+  }
+
+  function element_type() {
+    return 'div';
   }
 
   function render($values) {
@@ -16,6 +21,7 @@ class views_handler_field_user_picture e
     $account = new stdClass();
     $account->uid = $values->{$this->aliases['uid']};
     $account->name = $values->{$this->aliases['name']};
+    $account->mail = $values->{$this->aliases['mail']};
     $account->picture = $values->{$this->field_alias};
 
     return theme('user_picture', $account);
Index: modules/user/views_handler_field_user_roles.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/user/views_handler_field_user_roles.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_field_user_roles.inc
--- modules/user/views_handler_field_user_roles.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ modules/user/views_handler_field_user_roles.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_field_user_roles.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+// $Id: views_handler_field_user_roles.inc,v 1.1.2.1 2009/07/01 23:06:44 merlinofchaos Exp $
 /**
  * Field handler to provide a list of roles.
  */
@@ -25,8 +25,23 @@ class views_handler_field_user_roles ext
     if ($uids) {
       $result = db_query("SELECT u.uid, u.rid, r.name FROM {role} r INNER JOIN {users_roles} u ON u.rid = r.rid WHERE u.uid IN (" . implode(', ', $uids) . ") ORDER BY r.name");
       while ($role = db_fetch_object($result)) {
-        $this->items[$role->uid][$role->rid] = check_plain($role->name);
+        $this->items[$role->uid][$role->rid]['role'] = check_plain($role->name);
+        $this->items[$role->uid][$role->rid]['rid'] = $role->rid;
       }
     }
   }
+
+  function render_item($count, $item) {
+    return $item['role'];
+  }
+
+  function document_self_tokens(&$tokens) {
+    $tokens['[' . $this->options['id'] . '-role' . ']'] = t('The name of the role.');
+    $tokens['[' . $this->options['id'] . '-rid' . ']'] = t('The role ID of the role.');
+  }
+
+  function add_self_tokens(&$tokens, $item) {
+    $tokens['[' . $this->options['id'] . '-role' . ']'] = $item['role'];
+    $tokens['[' . $this->options['id'] . '-rid' . ']'] = $item['rid'];
+  }
 }
Index: modules/user/views_handler_filter_user_current.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/user/views_handler_filter_user_current.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_filter_user_current.inc
--- modules/user/views_handler_filter_user_current.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ modules/user/views_handler_filter_user_current.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_user_current.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+// $Id: views_handler_filter_user_current.inc,v 1.1.2.1 2009/09/15 16:18:35 merlinofchaos Exp $
 
 /**
  * Filter handler for the current user
@@ -12,6 +12,17 @@ class views_handler_filter_user_current 
 
   function query() {
     $this->ensure_my_table();
-    $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field " . (empty($this->value) ? '!=' : '=') . " ***CURRENT_USER***");
+    $where = "$this->table_alias.$this->real_field ";
+
+    if (empty($this->value)) {
+      $where .= '<> ***CURRENT_USER***';
+      if ($this->accept_null) {
+        $where = '(' . $where . " OR $this->table_alias.$this->real_field IS NULL)";
+      }
+    }
+    else {
+      $where .= '= ***CURRENT_USER***';
+    }
+    $this->query->add_where($this->options['group'], $where);    
   }
 }
Index: modules/user/views_handler_filter_user_name.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/user/views_handler_filter_user_name.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_handler_filter_user_name.inc
--- modules/user/views_handler_filter_user_name.inc	22 Sep 2008 23:41:14 -0000	1.2
+++ modules/user/views_handler_filter_user_name.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_handler_filter_user_name.inc,v 1.2 2008/09/22 23:41:14 merlinofchaos Exp $
+// $Id: views_handler_filter_user_name.inc,v 1.2.2.1 2010/01/19 21:59:04 merlinofchaos Exp $
 
 /**
  * Filter handler for usernames
@@ -36,7 +36,7 @@ class views_handler_filter_user_name ext
     }
   }
 
-  function value_validate(&$form, &$form_state) {
+  function value_validate($form, &$form_state) {
     $values = drupal_explode_tags($form_state['values']['options']['value']);
     $uids = $this->validate_user_strings($form['value'], $values);
 
Index: modules/user/views_plugin_argument_default_current_user.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/user/views_plugin_argument_default_current_user.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_plugin_argument_default_current_user.inc
--- modules/user/views_plugin_argument_default_current_user.inc	1 Oct 2008 19:50:31 -0000	1.1
+++ modules/user/views_plugin_argument_default_current_user.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_argument_default_current_user.inc,v 1.1 2008/10/01 19:50:31 merlinofchaos Exp $
+// $Id: views_plugin_argument_default_current_user.inc,v 1.1.2.1 2009/11/26 00:35:16 merlinofchaos Exp $
 /**
  * @file
  * Contains the current user argument default plugin.
@@ -7,6 +7,8 @@
 
 /**
  * Default argument plugin to extract the global $user
+ *
+ * This plugin actually has no options so it odes not need to do a great deal.
  */
 class views_plugin_argument_default_current_user extends views_plugin_argument_default {
   function get_argument() {
Index: modules/user/views_plugin_argument_default_user.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/user/views_plugin_argument_default_user.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_plugin_argument_default_user.inc
--- modules/user/views_plugin_argument_default_user.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ modules/user/views_plugin_argument_default_user.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_argument_default_user.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+// $Id: views_plugin_argument_default_user.inc,v 1.1.2.1 2009/11/26 00:35:16 merlinofchaos Exp $
 /**
  * @file
  * Contains the user from URL argument default plugin.
@@ -9,22 +9,27 @@
  * Default argument plugin to extract a user via menu_get_object
  */
 class views_plugin_argument_default_user extends views_plugin_argument_default {
-  var $option_name = 'default_argument_user';
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['user'] = array('default' => '');
 
-  function argument_form(&$form, &$form_state) {
-    $form[$this->option_name] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Also look for a node and use the node author'),
-      '#default_value' => !empty($this->argument->options[$this->option_name]),
-      '#process' => array('views_process_dependency'),
-      '#dependency' => array(
-        'radio:options[default_action]' => array('default'),
-        'radio:options[default_argument_type]' => array($this->id)
-      ),
-      '#dependency_count' => 2,
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['user'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Default argument'),
+      '#default_value' => $this->options['user'],
     );
   }
 
+  function convert_options(&$options) {
+    if (!isset($options['user']) && isset($this->argument->options['default_argument_user'])) {
+      $options['user'] = $this->argument->options['default_argument_user'];
+    }
+  }
+
   function get_argument() {
     foreach (range(1, 3) as $i) {
       $user = menu_get_object('user', $i);
@@ -40,7 +45,7 @@ class views_plugin_argument_default_user
       }
     }
 
-    if (!empty($this->argument->options[$this->option_name])) {
+    if (!empty($this->options['user'])) {
       foreach (range(1, 3) as $i) {
         $node = menu_get_object('node', $i);
         if (!empty($node)) {
Index: modules/user/views_plugin_argument_validate_user.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/user/views_plugin_argument_validate_user.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_plugin_argument_validate_user.inc
--- modules/user/views_plugin_argument_validate_user.inc	17 Feb 2009 23:32:33 -0000	1.2
+++ modules/user/views_plugin_argument_validate_user.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_argument_validate_user.inc,v 1.2 2009/02/17 23:32:33 merlinofchaos Exp $
+// $Id: views_plugin_argument_validate_user.inc,v 1.2.2.5 2010/06/16 20:17:44 merlinofchaos Exp $
 
 /**
  * Validate whether an argument is a valid user.
@@ -9,15 +9,17 @@
  * argument's title to the username.
  */
 class views_plugin_argument_validate_user extends views_plugin_argument_validate {
-  function validate_form(&$form, &$form_state) {
-    // We are unable to rely on options having already been set, so let's make
-    // sure defaults are here:
-    if (!isset($this->argument->options['validate_user_argument_type'])) {
-      $this->argument->options['validate_user_argument_type'] = 'uid';
-      $this->argument->options['validate_user_roles'] = array();
-    }
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['type'] = array('default' => 'uid');
+    $options['restrict_roles'] = array('default' => FALSE);
+    $options['roles'] = array('default' => array());
+
+    return $options;
+  }
 
-    $form['validate_user_argument_type'] = array(
+  function options_form(&$form, &$form_state) {
+    $form['type'] = array(
       '#type' => 'radios',
       '#title' => t('Type of user argument to allow'),
       '#options' => array(
@@ -25,49 +27,60 @@ class views_plugin_argument_validate_use
         'name' => t('Only allow string usernames'),
         'either' => t('Allow both numeric UIDs and string usernames'),
       ),
-      '#default_value' => $this->argument->options['validate_user_argument_type'],
-      '#process' => array('expand_radios', 'views_process_dependency'),
-      '#dependency' => array('edit-options-validate-type' => array($this->id)),
-      '#prefix' => '<div id="edit-options-validate-user-argument-type-wrapper">',
-      '#suffix' => '</div>',
+      '#default_value' => $this->options['type'],
     );
 
-    $form['validate_user_restrict_roles'] = array(
+    $form['restrict_roles'] = array(
       '#type' => 'checkbox',
       '#title' => t('Restrict user based on role'),
-      '#default_value' => !empty($this->argument->options['validate_user_restrict_roles']),
-      '#process' => array('views_process_dependency'),
-      '#dependency' => array('edit-options-validate-type' => array($this->id)),
+      '#default_value' => $this->options['restrict_roles'],
     );
 
-    $form['validate_user_roles'] = array(
+    $form['roles'] = array(
       '#type' => 'checkboxes',
-      '#prefix' => '<div id="edit-options-validate-user-roles-wrapper">',
+      '#prefix' => '<div id="edit-options-argument-validate-user-roles-wrapper">',
       '#suffix' => '</div>',
       '#title' => t('Restrict to the selected roles'),
       '#options' => user_roles(TRUE),
-      '#default_value' => $this->argument->options['validate_user_roles'],
+      '#default_value' => $this->options['roles'],
       '#description' => t('If no roles are selected, users from any role will be allowed.'),
       '#process' => array('expand_checkboxes', 'views_process_dependency'),
       '#dependency' => array(
-        'edit-options-validate-type' => array($this->id),
-        'edit-options-validate-user-restrict-roles' => array(1),
+        'edit-options-argument-validate-user-restrict-roles' => array(1),
       ),
-      '#dependency_count' => 2,
     );
   }
 
+  function options_submit($form, &$form_state, &$options) {
+    // filter trash out of the options so we don't store giant unnecessary arrays
+    $options['roles'] = array_filter($options['roles']);
+  }
+
+  function convert_options(&$options) {
+    if (!isset($options['type']) && isset($this->argument->options['validate_user_argument_type'])) {
+      $options['type'] = $this->argument->options['validate_user_argument_type'];
+      $options['restrict_roles'] = $this->argument->options['validate_user_restrict_roles'];
+      $options['roles'] = $this->argument->options['validate_user_roles'];
+    }
+  }
+
   function validate_argument($argument) {
-    $type = $this->argument->options['validate_user_argument_type'];
+    $type = $this->options['type'];
     // is_numeric() can return false positives, so we ensure it's an integer.
     // However, is_integer() will always fail, since $argument is a string.
     if (is_numeric($argument) && $argument == (int)$argument) {
       if ($type == 'uid' || $type == 'either') {
+        if ($argument == $GLOBALS['user']->uid) {
+          $account = $GLOBALS['user'];
+        }
         $where = 'uid = %d';
       }
     }
     else {
       if ($type == 'name' || $type == 'either') {
+        if ($argument == $GLOBALS['user']->name) {
+          $account = $GLOBALS['user'];
+        }
         $where = "name = '%s'";
       }
     }
@@ -77,23 +90,25 @@ class views_plugin_argument_validate_use
       return FALSE;
     }
 
-    $query = "SELECT uid, name FROM {users} WHERE $where";
-    $account = db_fetch_object(db_query($query, $argument));
+    if (!isset($account)) {
+      $query = "SELECT uid, name FROM {users} WHERE $where";
+      $account = db_fetch_object(db_query($query, $argument));
+    }
     if (empty($account)) {
       // User not found.
       return FALSE;
     }
 
     // See if we're filtering users based on roles.
-    if (!empty($this->argument->options['validate_user_restrict_roles']) && !empty($this->argument->options['validate_user_roles'])) {
-      $roles = $this->argument->options['validate_user_roles'];
-      $acccont->roles = array();
+    if (!empty($this->options['restrict_roles']) && !empty($this->options['roles'])) {
+      $roles = $this->options['roles'];
+      $account->roles = array();
       $account->roles[] = $account->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID;
       $result = db_query('SELECT rid FROM {users_roles} WHERE uid = %d', $account->uid);
       while ($role = db_fetch_object($result)) {
         $account->roles[] = $role->rid;
       }
-      if (!(bool)array_intersect($account->roles, $roles)) {
+      if (!(bool) array_intersect($account->roles, $roles)) {
         return FALSE;
       }
     }
Index: plugins/views_plugin_access.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_access.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_plugin_access.inc
--- plugins/views_plugin_access.inc	8 Sep 2008 22:50:17 -0000	1.1
+++ plugins/views_plugin_access.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_access.inc,v 1.1 2008/09/08 22:50:17 merlinofchaos Exp $
+// $Id: views_plugin_access.inc,v 1.1.2.2 2010/01/19 21:59:04 merlinofchaos Exp $
 
 /**
  * The base plugin to handle access control.
@@ -18,19 +18,19 @@ class views_plugin_access extends views_
   function init(&$view, &$display) {
     $this->view = &$view;
     $this->display = &$display;
-    $this->options = array();
 
     if (is_object($display->handler)) {
-    // Note: The below is read only.
-      $this->options = $display->handler->get_option('access');
+      $options = $display->handler->get_option('access');
+      // Overlay incoming options on top of defaults
+      $this->unpack_options($this->options, $options);
     }
   }
 
   /**
-   * Retrieve the default options when this is a new access
+   * Retrieve the options when this is a new access
    * control plugin
    */
-  function option_defaults(&$options) { }
+  function option_definition() { return array(); }
 
   /**
    * Provide the default form for setting options.
@@ -45,7 +45,7 @@ class views_plugin_access extends views_
   /**
    * Provide the default form form for submitting options
    */
-  function options_submit(&$form, &$form_state) { }
+  function options_submit($form, &$form_state) { }
 
   /**
    * Return a string to display as the clickable title for the
Index: plugins/views_plugin_access_perm.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_access_perm.inc,v
retrieving revision 1.3
diff -u -p -r1.3 views_plugin_access_perm.inc
--- plugins/views_plugin_access_perm.inc	7 Jan 2009 23:31:13 -0000	1.3
+++ plugins/views_plugin_access_perm.inc	11 Aug 2010 21:11:33 -0000
@@ -1,24 +1,28 @@
 <?php
-// $Id: views_plugin_access_perm.inc,v 1.3 2009/01/07 23:31:13 merlinofchaos Exp $
+// $Id: views_plugin_access_perm.inc,v 1.3.2.2 2010/03/10 21:03:22 merlinofchaos Exp $
 
 /**
  * Access plugin that provides permission-based access control.
  */
 class views_plugin_access_perm extends views_plugin_access {
   function access($account) {
-    return user_access($this->options['perm'], $account);
+    return views_check_perm($this->options['perm'], $account);
   }
 
   function get_access_callback() {
-    return array('user_access', array($this->options['perm']));
+    return array('views_check_perm', array($this->options['perm']));
   }
 
   function summary_title() {
     return t($this->options['perm']);
   }
 
-  function option_defaults(&$options) {
-    $options['perm'] = 'access content';
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['perm'] = array('default' => 'access content');
+
+    return $options;
   }
 
   function options_form(&$form, &$form_state) {
Index: plugins/views_plugin_access_role.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_access_role.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_plugin_access_role.inc
--- plugins/views_plugin_access_role.inc	7 Jan 2009 23:31:13 -0000	1.2
+++ plugins/views_plugin_access_role.inc	11 Aug 2010 21:11:33 -0000
@@ -1,14 +1,12 @@
 <?php
-// $Id: views_plugin_access_role.inc,v 1.2 2009/01/07 23:31:13 merlinofchaos Exp $
+// $Id: views_plugin_access_role.inc,v 1.2.2.2 2010/03/10 21:03:22 merlinofchaos Exp $
 
 /**
  * Access plugin that provides role-based access control.
  */
 class views_plugin_access_role extends views_plugin_access {
   function access($account) {
-    $roles = array_keys($account->roles);
-    $roles[] = $account->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID;
-    return array_intersect(array_filter($this->options['role']), $roles);
+    return views_check_roles(array_filter($this->options['role']), $account);
   }
 
   function get_access_callback() {
@@ -30,8 +28,12 @@ class views_plugin_access_role extends v
     }
   }
 
-  function option_defaults(&$options) {
-    $options['role'] = array();
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['role'] = array('default' => array());
+
+    return $options;
   }
 
   function options_form(&$form, &$form_state) {
Index: plugins/views_plugin_argument_default.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_argument_default.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_plugin_argument_default.inc
--- plugins/views_plugin_argument_default.inc	1 Jun 2009 23:34:55 -0000	1.2
+++ plugins/views_plugin_argument_default.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_argument_default.inc,v 1.2 2009/06/01 23:34:55 merlinofchaos Exp $
+// $Id: views_plugin_argument_default.inc,v 1.1.2.3 2010/01/19 21:59:04 merlinofchaos Exp $
 /**
  * @file
  * Contains the fixed argument default plugin.
@@ -19,58 +19,76 @@
  * The fixed argument default handler; also used as the base.
  */
 class views_plugin_argument_default extends views_plugin {
-  var $option_name = 'default_argument_fixed';
+  /**
+   * Return the default argument.
+   *
+   * This needs to be overridden by every default argument handler to properly do what is needed.
+   */
+  function get_argument() { }
+
   /**
    * Initialize this plugin with the view and the argument
    * it is linked to.
    */
-  function init(&$view, &$argument, $id = NULL) {
+  function init(&$view, &$argument, $options) {
     $this->view = &$view;
     $this->argument = &$argument;
-    $this->id = $id;
+
+    $this->convert_options($options);
+    $this->unpack_options($this->options, $options);
   }
 
   /**
+   * Retrieve the options when this is a new access
+   * control plugin
+   */
+  function option_definition() { return array(); }
+
+  /**
+   * Provide the default form for setting options.
+   */
+  function options_form(&$form, &$form_state) { }
+
+  /**
+   * Provide the default form form for validating options
+   */
+  function options_validate(&$form, &$form_state) { }
+
+  /**
+   * Provide the default form form for submitting options
+   */
+  function options_submit($form, &$form_state) { }
+
+  /**
    * Determine if the administrator has the privileges to use this
    * plugin
    */
   function access() { return TRUE; }
 
-  function argument_form(&$form, &$form_state) {
-    $form[$this->option_name] = array(
-      '#type' => 'textfield',
-      '#title' => t('Default argument'),
-      '#default_value' => $this->get_argument(),
-      '#process' => array('views_process_dependency'),
-      '#dependency' => array(
-        'radio:options[default_action]' => array('default'),
-        'radio:options[default_argument_type]' => array($this->id)
-      ),
-      '#dependency_count' => 2,
-    );
-
-    // Only do this if using one simple standard form gadget
-    $this->check_access($form);
-  }
-
   /**
    * If we don't have access to the form but are showing it anyway, ensure that
    * the form is safe and cannot be changed from user input.
+   *
+   * This is only called by child objects if specified in the options_form(),
+   * so it will not always be used.
    */
-  function check_access(&$form) {
+  function check_access(&$form, $option_name) {
     if (!$this->access()) {
-      $form[$this->option_name]['#disabled'] = TRUE;
-      $form[$this->option_name]['#value'] = $form[$this->option_name]['#default_value'];
-      $form[$this->option_name]['#description'] .= ' <strong>' . t('Note: you do not have permission to modify this. If you change the default argument type, this setting will be lost and you will NOT be able to get it back.') . '</strong>';
+      $form[$option_name]['#disabled'] = TRUE;
+      $form[$option_name]['#value'] = $form[$this->option_name]['#default_value'];
+      $form[$option_name]['#description'] .= ' <strong>' . t('Note: you do not have permission to modify this. If you change the default argument type, this setting will be lost and you will NOT be able to get it back.') . '</strong>';
     }
   }
 
   /**
-   * Return the default argument.
+   * Convert options from the older style.
+   *
+   * In Views 3, the method of storing default argument options has changed
+   * and each plugin now gets its own silo. This method can be used to
+   * move arguments from the old style to the new style. See
+   * views_plugin_argument_default_fixed for a good example of this method.
    */
-  function get_argument() {
-    return isset($this->argument->options[$this->option_name]) ? $this->argument->options[$this->option_name] : '';
-  }
+  function convert_options(&$options) { }
 }
 
 /**
Index: plugins/views_plugin_argument_default_php.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_argument_default_php.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_plugin_argument_default_php.inc
--- plugins/views_plugin_argument_default_php.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ plugins/views_plugin_argument_default_php.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_argument_default_php.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+// $Id: views_plugin_argument_default_php.inc,v 1.1.2.1 2009/11/26 00:35:16 merlinofchaos Exp $
 /**
  * @file
  * Contains the php code argument default plugin.
@@ -9,23 +9,30 @@
  * Default argument plugin to provide a PHP code block.
  */
 class views_plugin_argument_default_php extends views_plugin_argument_default {
-  var $option_name = 'default_argument_php';
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['code'] = array('default' => '');
 
-  function argument_form(&$form, &$form_state) {
-    $form[$this->option_name] = array(
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['code'] = array(
       '#type' => 'textarea',
       '#title' => t('PHP argument code'),
-      '#default_value' => $this->get_argument(TRUE), // the true forces it raw.
+      '#default_value' => $this->options['code'],
       '#process' => array('views_process_dependency'),
       '#description' => t('Enter PHP code that returns a value to use for this argument. Do not use &lt;?php ?&gt;. You must return only a single value for just this argument.'),
-      '#dependency' => array(
-        'radio:options[default_action]' => array('default'),
-        'radio:options[default_argument_type]' => array($this->id)
-      ),
-      '#dependency_count' => 2,
     );
 
-    $this->check_access($form);
+    // Only do this if using one simple standard form gadget
+    $this->check_access($form, 'code');
+  }
+
+  function convert_options(&$options) {
+    if (!isset($options['code']) && isset($this->argument->options['default_argument_php'])) {
+      $options['code'] = $this->argument->options['default_argument_php'];
+    }
   }
 
   /**
@@ -36,16 +43,12 @@ class views_plugin_argument_default_php 
     return user_access('use PHP for block visibility');
   }
 
-  function get_argument($raw = FALSE) {
-    if ($raw) {
-      return parent::get_argument();
-    }
-
+  function get_argument() {
     // set up variables to make it easier to reference during the argument.
     $view = &$this->view;
     $argument = &$this->argument;
     ob_start();
-    $result = eval($this->argument->options[$this->option_name]);
+    $result = eval($this->options['code']);
     ob_end_clean();
     return $result;
   }
Index: plugins/views_plugin_argument_validate.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_argument_validate.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_plugin_argument_validate.inc
--- plugins/views_plugin_argument_validate.inc	1 Jun 2009 23:34:55 -0000	1.2
+++ plugins/views_plugin_argument_validate.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_argument_validate.inc,v 1.2 2009/06/01 23:34:55 merlinofchaos Exp $
+// $Id: views_plugin_argument_validate.inc,v 1.1.2.2 2009/11/26 00:35:16 merlinofchaos Exp $
 /**
  * @file
  * Contains the base argument validator plugin.
@@ -20,48 +20,70 @@
  * @ingroup views_argument_validate_plugins
  */
 class views_plugin_argument_validate extends views_plugin {
-  var $option_name = 'validate_argument';
 
   /**
    * Initialize this plugin with the view and the argument
    * it is linked to.
    */
-  function init(&$view, &$argument, $id = NULL) {
+  function init(&$view, &$argument, $options) {
     $this->view = &$view;
     $this->argument = &$argument;
-    $this->id = $id;
+
+    $this->convert_options($options);
+    $this->unpack_options($this->options, $options);
   }
 
   /**
-   * Determine if the administrator has the privileges to use this
-   * plugin
+   * Retrieve the options when this is a new access
+   * control plugin
    */
-  function access() { return TRUE; }
+  function option_definition() { return array(); }
 
-  function argument_form(&$form, &$form_state) {
-  }
+  /**
+   * Provide the default form for setting options.
+   */
+  function options_form(&$form, &$form_state) { }
+
+  /**
+   * Provide the default form form for validating options
+   */
+  function options_validate(&$form, &$form_state) { }
+
+  /**
+   * Provide the default form form for submitting options
+   */
+  function options_submit(&$form, &$form_state) { }
+
+  /**
+   * Convert options from the older style.
+   *
+   * In Views 3, the method of storing default argument options has changed
+   * and each plugin now gets its own silo. This method can be used to
+   * move arguments from the old style to the new style. See
+   * views_plugin_argument_default_fixed for a good example of this method.
+   */
+  function convert_options(&$options) { }
+
+  /**
+   * Determine if the administrator has the privileges to use this plugin
+   */
+  function access() { return TRUE; }
 
   /**
    * If we don't have access to the form but are showing it anyway, ensure that
    * the form is safe and cannot be changed from user input.
+   *
+   * This is only called by child objects if specified in the options_form(),
+   * so it will not always be used.
    */
-  function check_access(&$form) {
+  function check_access(&$form, $option_name) {
     if (!$this->access()) {
-      $form[$this->option_name]['#disabled'] = TRUE;
-      $form[$this->option_name]['#value'] = $form[$this->option_name]['#default_value'];
-      $form[$this->option_name]['#description'] .= ' <strong>' . t('Note: you do not have permission to modify this. If you change the validator, this setting will be lost and you will NOT be able to get it back.') . '</strong>';
+      $form[$option_name]['#disabled'] = TRUE;
+      $form[$option_name]['#value'] = $form[$this->option_name]['#default_value'];
+      $form[$option_name]['#description'] .= ' <strong>' . t('Note: you do not have permission to modify this. If you change the default argument type, this setting will be lost and you will NOT be able to get it back.') . '</strong>';
     }
   }
 
-  /**
-   * Return the validate argument.
-   */
-  function get_argument() {
-    return isset($this->argument->options[$this->option_name]) ? $this->argument->options[$this->option_name] : '';
-  }
-
-  function validate_form(&$form, &$form_state) { }
-
   function validate_argument($arg) { return TRUE; }
 }
 
Index: plugins/views_plugin_argument_validate_numeric.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_argument_validate_numeric.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_plugin_argument_validate_numeric.inc
--- plugins/views_plugin_argument_validate_numeric.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ plugins/views_plugin_argument_validate_numeric.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_argument_validate_numeric.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+// $Id: views_plugin_argument_validate_numeric.inc,v 1.1.2.1 2009/11/26 00:35:16 merlinofchaos Exp $
 /**
  * @file
  * Contains the numeric argument validator plugin.
@@ -11,16 +11,6 @@
  * @ingroup views_argument_validate_plugins
  */
 class views_plugin_argument_validate_numeric extends views_plugin_argument_validate {
-  var $option_name = 'validate_argument_numeric';
-
-  /**
-   * Only let users with PHP block visibility permissions set/modify this
-   * validate plugin.
-   */
-  function access() {
-    return !empty($this->argument->definition['numeric']);
-  }
-
   function validate_argument($argument) {
     return is_numeric($argument);
   }
Index: plugins/views_plugin_argument_validate_php.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_argument_validate_php.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_plugin_argument_validate_php.inc
--- plugins/views_plugin_argument_validate_php.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ plugins/views_plugin_argument_validate_php.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_argument_validate_php.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+// $Id: views_plugin_argument_validate_php.inc,v 1.1.2.1 2009/11/26 00:35:16 merlinofchaos Exp $
 /**
  * @file
  * Contains the php code argument validator plugin.
@@ -11,19 +11,22 @@
  * @ingroup views_argument_validate_plugins
  */
 class views_plugin_argument_validate_php extends views_plugin_argument_validate {
-  var $option_name = 'validate_argument_php';
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['code'] = array('default' => '');
 
-  function validate_form(&$form, &$form_state) {
-    $form[$this->option_name] = array(
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['code'] = array(
       '#type' => 'textarea',
       '#title' => t('PHP validate code'),
-      '#default_value' => $this->get_argument(),
-      '#description' => t('Enter PHP code that returns TRUE or FALSE. No return is the same as FALSE, so be SURE to return something if you do not want to declare the argument invalid. Do not use &lt;?php ?&gt;. The argument to validate will be "$argument" and the view will be "$view". You may change the argument by setting "$handler->argument".'),
-      '#process' => array('views_process_dependency'),
-      '#dependency' => array('edit-options-validate-type' => array($this->id)),
+      '#default_value' => $this->options['code'],
+      '#description' => t('Enter PHP code that returns TRUE or FALSE. No return is the same as FALSE, so be SURE to return something if you do not want to declare the argument invalid. Do not use &lt;?php ?&gt;. The argument to validate will be "$argument" and the view will be "$view". You may change the argument by setting "$handler->argument". You may change the title used for substitutions for this argument by setting "$argument->validated_title".'),
     );
 
-    $this->check_access($form);
+    $this->check_access($form, 'code');
   }
 
   /**
@@ -34,13 +37,19 @@ class views_plugin_argument_validate_php
     return user_access('use PHP for block visibility');
   }
 
+  function convert_options(&$options) {
+    if (!isset($options['code']) && isset($this->argument->options['validate_argument_php'])) {
+      $options['code'] = $this->argument->options['validate_argument_php'];
+    }
+  }
+
   function validate_argument($argument) {
     // set up variables to make it easier to reference during the argument.
     $view = &$this->view;
     $handler = &$this->argument;
 
     ob_start();
-    $result = eval($this->argument->options[$this->option_name]);
+    $result = eval($this->options['code']);
     ob_end_clean();
     return $result;
   }
Index: plugins/views_plugin_cache.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_cache.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_plugin_cache.inc
--- plugins/views_plugin_cache.inc	3 Jun 2009 23:39:52 -0000	1.2
+++ plugins/views_plugin_cache.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_cache.inc,v 1.2 2009/06/03 23:39:52 merlinofchaos Exp $
+// $Id: views_plugin_cache.inc,v 1.1.2.7 2010/01/05 01:12:34 merlinofchaos Exp $
 
 /**
  * The base plugin to handle caching.
@@ -28,21 +28,15 @@ class views_plugin_cache extends views_p
   function init(&$view, &$display) {
     $this->view = &$view;
     $this->display = &$display;
-    $this->options = array();
 
     if (is_object($display->handler)) {
-      // Note: The below is read only.
-      $this->options = $display->handler->get_option('cache');
+      $options = $display->handler->get_option('cache');
+      // Overlay incoming options on top of defaults
+      $this->unpack_options($this->options, $options);
     }
   }
 
   /**
-   * Retrieve the default options when this is a new access
-   * control plugin
-   */
-  function option_defaults(&$options) { }
-
-  /**
    * Return a string to display as the clickable title for the
    * access control.
    */
@@ -74,7 +68,7 @@ class views_plugin_cache extends views_p
         $data = array(
           'result' => $this->view->result,
           'total_rows' => $this->view->total_rows,
-          'pager' => $this->view->pager,
+          'current_page' => $this->view->get_current_page(),
         );
         cache_set($this->get_results_key(), $data, $this->table);
         break;
@@ -100,12 +94,12 @@ class views_plugin_cache extends views_p
         return FALSE;
       case 'results':
         // Values to set: $view->result, $view->total_rows, $view->execute_time,
-        // $view->pager['current_page'].
+        // $view->current_page.
         if ($cache = cache_get($this->get_results_key(), $this->table)) {
           if (!$cutoff || $cache->created > $cutoff) {
             $this->view->result = $cache->data['result'];
             $this->view->total_rows = $cache->data['total_rows'];
-            $this->view->pager = $cache->data['pager'];
+            $this->view->set_current_page = $cache->data['current_page'];
             $this->view->execute_time = 0;
             return TRUE;
           }
@@ -135,6 +129,28 @@ class views_plugin_cache extends views_p
   }
 
   /**
+   * Post process any rendered data.
+   *
+   * This can be valuable to be able to cache a view and still have some level of
+   * dynamic output. In an ideal world, the actual output will include HTML
+   * comment based tokens, and then the post process can replace those tokens.
+   *
+   * Example usage. If it is known that the view is a node view and that the
+   * primary field will be a nid, you can do something like this:
+   *
+   * <!--post-FIELD-NID-->
+   *
+   * And then in the post render, create an array with the text that should
+   * go there:
+   *
+   * strtr($output, array('<!--post-FIELD-1-->', 'output for FIELD of nid 1');
+   *
+   * All of the cached result data will be available in $view->result, as well,
+   * so all ids used in the query should be discoverable.
+   */
+  function post_render(&$output) { }
+
+  /**
    * Start caching javascript, css and other out of band info.
    *
    * This takes a snapshot of the current system state so that we don't
@@ -229,6 +245,8 @@ class views_plugin_cache extends views_p
       $key_data = array(
         'build_info' => $this->view->build_info,
         'roles' => array_keys($user->roles),
+        'super-user' => $user->uid == 1, // special caching for super user.
+        'language' => $GLOBALS['language'],
       );
       foreach (array('exposed_info', 'page', 'sort', 'order') as $key) {
         if (isset($_GET[$key])) {
@@ -248,6 +266,9 @@ class views_plugin_cache extends views_p
       $key_data = array(
         'result' => $this->view->result,
         'roles' => array_keys($user->roles),
+        'super-user' => $user->uid == 1, // special caching for super user.
+        'theme' => $GLOBALS['theme'],
+        'language' => $GLOBALS['language'],
       );
 
       $this->_output_key = $this->view->name . ':' . $this->display->id . ':output:' . md5(serialize($key_data));
Index: plugins/views_plugin_cache_none.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_cache_none.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_plugin_cache_none.inc
--- plugins/views_plugin_cache_none.inc	3 Jun 2009 23:39:52 -0000	1.2
+++ plugins/views_plugin_cache_none.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_cache_none.inc,v 1.2 2009/06/03 23:39:52 merlinofchaos Exp $
+// $Id: views_plugin_cache_none.inc,v 1.1.2.3 2009/06/03 23:40:06 merlinofchaos Exp $
 
 /**
  * Caching plugin that provides no caching at all.
Index: plugins/views_plugin_cache_time.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_cache_time.inc,v
retrieving revision 1.2
diff -u -p -r1.2 views_plugin_cache_time.inc
--- plugins/views_plugin_cache_time.inc	3 Jun 2009 23:39:52 -0000	1.2
+++ plugins/views_plugin_cache_time.inc	11 Aug 2010 21:11:33 -0000
@@ -1,13 +1,16 @@
 <?php
-// $Id: views_plugin_cache_time.inc,v 1.2 2009/06/03 23:39:52 merlinofchaos Exp $
+// $Id: views_plugin_cache_time.inc,v 1.1.2.5 2009/11/13 22:07:54 merlinofchaos Exp $
 
 /**
  * Simple caching of query results for Views displays.
  */
 class views_plugin_cache_time extends views_plugin_cache {
-  function option_defaults(&$options) {
-    $options['results_lifespan'] = 3600;
-    $options['output_lifespan'] = 3600;
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['results_lifespan'] = array('default' => 3600);
+    $options['output_lifespan'] = array('default' => 3600);
+
+    return $options;
   }
 
   function options_form(&$form, &$form_state) {
@@ -38,6 +41,7 @@ class views_plugin_cache_time extends vi
   function cache_expire($type) {
     if ($lifespan = $this->options[$type . '_lifespan']) {
       $cutoff = time() - $lifespan;
+      return $cutoff;
     }
     else {
       return FALSE;
Index: plugins/views_plugin_display.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_display.inc,v
retrieving revision 1.24
diff -u -p -r1.24 views_plugin_display.inc
--- plugins/views_plugin_display.inc	10 Jun 2009 22:01:31 -0000	1.24
+++ plugins/views_plugin_display.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_display.inc,v 1.24 2009/06/10 22:01:31 merlinofchaos Exp $
+// $Id: views_plugin_display.inc,v 1.20.2.42 2010/07/27 22:25:04 merlinofchaos Exp $
 /**
  * @file
  * Contains the base display plugin.
@@ -41,6 +41,79 @@ class views_plugin_display extends views
     }
 
     $this->unpack_options($this->options, $options);
+
+    // Translate changed settings:
+    // Check if any of the previous values now managed by
+    // pluggable pagers have been changed.
+    // If yes, perform the conversion
+    $items_per_page = $this->get_option('items_per_page');
+    $offset = $this->get_option('offset');
+    $type = $this->get_option('use_pager');
+    if ((!empty($items_per_page) && $items_per_page != 10) || !empty($offset) || !empty($type)) {
+      if (!$type) {
+        $type = $items_per_page ? 'some' : 'none';
+      }
+
+      if ($type == 1) {
+        $type = 'full';
+      }
+
+      $pager = array(
+        'type' => $type,
+        'options' => array(
+          'offset' => $offset,
+        ),
+      );
+
+      if ($items_per_page) {
+        $pager['options']['items_per_page'] = $items_per_page;
+      }
+      if ($id = $this->get_option('pager_element')) {
+        $pager['options']['id'] = $id;
+      }
+
+      // Unset the previous options
+      // After edit and save the view they will be erased
+      $this->set_option('items_per_page', NULL);
+      $this->set_option('offset', NULL);
+      $this->set_option('use_pager', NULL);
+      $this->set_option('pager', $pager);
+    }
+
+    // Plugable headers, footer and empty texts are
+    // not compatible with previous version of views
+    // This code converts old values into a configured handler for each area
+    foreach (array('header', 'footer', 'empty') as $area) {
+      $converted = FALSE;
+      if (isset($this->options[$area]) && !is_array($this->options[$area])) {
+        if (!empty($this->options[$area])) {
+          $content = $this->get_option($area);
+          if (!empty($content) && !is_array($content)) {
+            $format = $this->get_option($area . '_format');
+            $options = array(
+              'id' => 'area',
+              'table' => 'views',
+              'field' => 'area',
+              'label' => '',
+              'relationship' => 'none',
+              'group_type' => 'group',
+              'content' => $content,
+              'format' => !empty($format) ? $format : variable_get('filter_default_format', 1),
+            );
+
+            if ($area != 'empty' && $empty = $this->get_option($area . '_empty')) {
+              $options['empty'] = $empty;
+            }
+            $this->set_option($area, array('text' => $options));
+            $converted = TRUE;
+          }
+        }
+        // Ensure that options are at least an empty array
+        if (!$converted) {
+          $this->set_option($area, array());
+        }
+      }
+    }
   }
 
   function destroy() {
@@ -71,15 +144,20 @@ class views_plugin_display extends views
    */
   function uses_exposed() {
     if (!isset($this->has_exposed)) {
-      foreach (array('field', 'filter') as $type) {
-        foreach ($this->view->$type as $key => $handler) {
-          if ($handler->is_exposed()) {
+      foreach ($this->handlers as $type => $value) {
+        foreach ($this->view->$type as $id => $handler) {
+          if ($handler->can_expose() && $handler->is_exposed()) {
             // one is all we need; if we find it, return true.
             $this->has_exposed = TRUE;
             return TRUE;
           }
         }
       }
+      $pager = $this->get_plugin('pager');
+      if (isset($pager) && $pager->uses_exposed()) {
+        $this->has_exposed = TRUE;
+        return TRUE;
+      }
       $this->has_exposed = FALSE;
     }
 
@@ -113,10 +191,10 @@ class views_plugin_display extends views
    * Does the display have a pager enabled?
    */
   function use_pager() {
-    if (!empty($this->definition['use pager'])) {
-      return $this->get_option('use_pager');
+    $pager = $this->get_plugin('pager');
+    if ($pager) {
+      return $pager->use_pager();
     }
-    return FALSE;
   }
 
   /**
@@ -130,6 +208,23 @@ class views_plugin_display extends views
   }
 
   /**
+   * Does the display have a more link enabled?
+   */
+  function use_group_by() {
+    return $this->get_option('group_by');
+  }
+
+  /**
+   * Should the enabled display more link be shown when no more items?
+   */
+  function use_more_always() {
+    if (!empty($this->definition['use more'])) {
+      return $this->get_option('use_more_always');
+    }
+    return FALSE;
+  }
+
+  /**
    * Does the display have custom link text?
    */
   function use_more_text() {
@@ -160,16 +255,15 @@ class views_plugin_display extends views
       'access' => array('access'),
       'cache' => array('cache'),
       'title' => array('title'),
-      'header' => array('header', 'header_format', 'header_empty'),
-      'footer' => array('footer', 'footer_format', 'footer_empty'),
-      'empty' => array('empty', 'empty_format'),
+      'css_class' => array('css_class'),
       'use_ajax' => array('use_ajax'),
       'items_per_page' => array('items_per_page', 'offset', 'use_pager', 'pager_element'),
-      'use_pager' => array('items_per_page', 'offset', 'use_pager', 'pager_element'),
-      'use_more' => array('use_more', 'use_more_text'),
+      'pager' => array('pager'),
+      'use_more' => array('use_more', 'use_more_always', 'use_more_text'),
       'link_display' => array('link_display'),
       'distinct' => array('distinct'),
       'exposed_block' => array('exposed_block'),
+      'exposed_form' => array('exposed_form'),
 
       // Force these to cascade properly.
       'style_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
@@ -178,11 +272,14 @@ class views_plugin_display extends views
       'row_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
 
       // These guys are special
+      'header' => array('header'),
+      'footer' => array('footer'),
+      'empty' => array('empty'),
       'relationships' => array('relationships'),
       'fields' => array('fields'),
       'sorts' => array('sorts'),
       'arguments' => array('arguments'),
-      'filters' => array('filters'),
+      'filters' => array('filters', 'filter_groups'),
     );
     if ($section) {
       if (!empty($sections[$section])) {
@@ -225,102 +322,53 @@ class views_plugin_display extends views
           'access' => TRUE,
           'cache' => TRUE,
           'title' => TRUE,
-          'header' => TRUE,
-          'header_format' => TRUE,
-          'header_empty' => TRUE,
-          'footer' => TRUE,
-          'footer_format' => TRUE,
-          'footer_empty' => TRUE,
-          'empty' => TRUE,
-          'empty_format' => TRUE,
+          'css_class' => TRUE,
 
           'use_ajax' => TRUE,
           'items_per_page' => TRUE,
-          'offset' => TRUE,
           'use_pager' => TRUE,
-          'pager_element'  => TRUE,
+          'offset' => TRUE,
+          'pager' => TRUE,
           'use_more' => TRUE,
+          'use_more_always' => TRUE,
           'use_more_text' => TRUE,
           'distinct' => TRUE,
           'exposed_block' => TRUE,
+          'exposed_form' => TRUE,
 
           'link_display' => TRUE,
+          'group_by' => TRUE,
 
           'style_plugin' => TRUE,
           'style_options' => TRUE,
           'row_plugin' => TRUE,
           'row_options' => TRUE,
 
+          'header' => TRUE,
+          'footer' => TRUE,
+          'empty' => TRUE,
+
           'relationships' => TRUE,
           'fields' => TRUE,
           'sorts' => TRUE,
           'arguments' => TRUE,
           'filters' => TRUE,
+          'filter_groups' => TRUE,
         ),
+        'export' => FALSE,
       ),
-      'relationships' => array(
-        'default' => array(),
-        'export' => 'export_item',
-      ),
-      'fields' => array(
-        'default' => array(),
-        'export' => 'export_item',
-      ),
-      'sorts' => array(
-        'default' => array(),
-        'export' => 'export_item',
-      ),
-      'arguments' => array(
-        'default' => array(),
-        'export' => 'export_item',
-      ),
-      'filters' => array(
-        'default' => array(),
-        'export' => 'export_item',
-      ),
-      'access' => array(
-        'contains' => array(
-          'type' => array('default' => 'none'),
-         ),
-      ),
-      'cache' => array(
-        'contains' => array(
-          'type' => array('default' => 'none'),
-         ),
-      ),
+
       'title' => array(
         'default' => '',
         'translatable' => TRUE,
       ),
-      'header' => array(
+      'css_class' => array(
         'default' => '',
-        'translatable' => TRUE,
-      ),
-      'header_format' => array(
-        'default' => FILTER_FORMAT_DEFAULT,
-      ),
-      'header_empty' => array(
-        'default' => FALSE,
-      ),
-      'footer' => array(
-        'default' => '',
-        'translatable' => TRUE,
-      ),
-      'footer_format' => array(
-        'default' => FILTER_FORMAT_DEFAULT,
-      ),
-      'footer_empty' => array(
-        'default' => FALSE,
-      ),
-      'empty' => array(
-        'default' => '',
-        'translatable' => TRUE,
-      ),
-      'empty_format' => array(
-        'default' => FILTER_FORMAT_DEFAULT,
+        'translatable' => FALSE,
       ),
       'use_ajax' => array(
         'default' => FALSE,
+        'bool' => TRUE,
       ),
       'items_per_page' => array(
         'default' => 10,
@@ -330,12 +378,15 @@ class views_plugin_display extends views
       ),
       'use_pager' => array(
         'default' => FALSE,
-      ),
-      'pager_element' => array(
-        'default' => 0,
+        'bool' => TRUE,
       ),
       'use_more' => array(
         'default' => FALSE,
+        'bool' => TRUE,
+      ),
+      'use_more_always' => array(
+        'default' => FALSE,
+        'bool' => TRUE,
       ),
       'use_more_text' => array(
         'default' => 'more',
@@ -346,24 +397,111 @@ class views_plugin_display extends views
       ),
       'distinct' => array(
         'default' => FALSE,
+        'bool' => TRUE,
+      ),
+      'group_by' => array(
+        'default' => FALSE,
+        'bool' => TRUE,
+      ),
+
+      // These types are all plugins that can have individual settings
+      // and therefore need special handling.
+      'access' => array(
+        'contains' => array(
+          'type' => array('default' => 'none', 'export' => 'export_plugin'),
+         ),
+      ),
+      'cache' => array(
+        'contains' => array(
+          'type' => array('default' => 'none', 'export' => 'export_plugin'),
+         ),
+      ),
+      // Note that exposed_form plugin has options in a separate array,
+      // while access and cache do not. access and cache are legacy and
+      // that pattern should not be repeated, but it is left as is to
+      // reduce the need to modify older views. Let's consider the
+      // pattern used here to be the template from which future plugins
+      // should be copied.
+      'exposed_form' => array(
+        'contains' => array(
+          'type' => array('default' => 'basic', 'export' => 'export_plugin'),
+          'options' => array('default' => array(), 'export' => FALSE),
+         ),
+      ),
+      'pager' => array(
+        'contains' => array(
+          'type' => array('default' => 'full', 'export' => 'export_plugin'),
+          'options' => array('default' => array(), 'export' => FALSE),
+         ),
       ),
 
+      // Note that the styles have their options completely independent.
+      // Like access and cache above, this is a legacy pattern and
+      // should not be repeated.
       'style_plugin' => array(
         'default' => 'default',
+        'export' => 'export_style',
       ),
       'style_options' => array(
         'default' => array(),
+        'export' => FALSE,
       ),
       'row_plugin' => array(
         'default' => 'fields',
+        'export' => 'export_style',
       ),
       'row_options' => array(
         'default' => array(),
+        'export' => FALSE,
       ),
 
       'exposed_block' => array(
         'default' => FALSE,
       ),
+
+      'header' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+      ),
+      'footer' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+      ),
+      'empty' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+      ),
+
+      // We want these to export last.
+      // These are the 5 handler types.
+      'relationships' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+      ),
+      'fields' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+      ),
+      'sorts' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+      ),
+      'arguments' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+      ),
+      'filter_groups' => array(
+        'contains' => array(
+          'operator' => array('default' => 'AND'),
+          'groups' => array('default' => array(0 => 'AND')),
+        ),
+      ),
+      'filters' => array(
+        'default' => array(),
+        'export' => 'export_handler',
+      ),
+
+
     );
 
     if ($this->is_default_display()) {
@@ -475,48 +613,42 @@ class views_plugin_display extends views
    * Get the display or row plugin, if it exists.
    */
   function get_plugin($type = 'style', $name = NULL) {
-    if (!$name) {
-      $name = $this->get_option($type . '_plugin');
-    }
+    static $cache = array();
+    if (!isset($cache[$type][$name])) {
+      switch ($type) {
+        case 'style':
+        case 'row':
+          $option_name = $type . '_plugin';
+          $options = $this->get_option($type . '_options');
+          if (!$name) {
+            $name = $this->get_option($option_name);
+          }
 
-    $plugin = views_get_plugin($type, $name);
-    if ($plugin) {
-      $options = $this->get_option($type . '_options');
-      $plugin->init($this->view, $this->display, $options);
-      return $plugin;
-    }
-  }
+          break;
+        default:
+          $option_name = $type;
+          $options = $this->get_option($type);
+          if (!$name) {
+            $name = $options['type'];
+          }
 
-  /**
-   * Get the access plugin
-   */
-  function get_access_plugin($name = NULL) {
-    if (!$name) {
-      $access = $this->get_option('access');
-      $name = $access['type'];
-    }
+          // access & cache store their options as siblings with the
+          // type; all others use an 'options' array.
+          if ($type != 'access' && $type != 'cache') {
+            $options = $options['options'];
+          }
+      }
 
-    $plugin = views_get_plugin('access', $name);
-    if ($plugin) {
-      $plugin->init($this->view, $this->display);
-      return $plugin;
-    }
-  }
+      $plugin = views_get_plugin($type, $name);
+      if (!$plugin) {
+        return;
+      }
 
-  /**
-   * Get the cache plugin
-   */
-  function get_cache_plugin($name = NULL) {
-    if (!$name) {
-      $cache = $this->get_option('cache');
-      $name = $cache['type'];
+      $plugin->init($this->view, $this->display, $options);
+      $cache[$type][$name] = $plugin;
     }
 
-    $plugin = views_get_plugin('cache', $name);
-    if ($plugin) {
-      $plugin->init($this->view, $this->display);
-      return $plugin;
-    }
+    return $cache[$type][$name];
   }
 
   /**
@@ -545,7 +677,32 @@ class views_plugin_display extends views
       $types = views_object_types();
       $plural = $types[$type]['plural'];
       foreach ($this->get_option($plural) as $id => $info) {
-        $handler = views_get_handler($info['table'], $info['field'], $type);
+        if ($info['id'] != $id) {
+          $info['id'] = $id;
+        }
+
+        // If aggregation is on, the group type might override the actual
+        // handler that is in use. This piece of code checks that and,
+        // if necessary, sets the override handler.
+        $override = NULL;
+        if ($this->use_group_by() && !empty($info['group_type'])) {
+          if (empty($this->view->query)) {
+            $this->view->init_query();
+          }
+          $aggregate = $this->view->query->get_aggregation_info();
+          if (!empty($aggregate[$info['group_type']]['handler'][$type])) {
+            $override = $aggregate[$info['group_type']]['handler'][$type];
+          }
+        }
+
+        if (!empty($types[$type]['type'])) {
+          $handler_type = $types[$type]['type'];
+        }
+        else {
+          $handler_type = $type;
+        }
+
+        $handler = views_get_handler($info['table'], $info['field'], $handler_type, $override);
         if ($handler) {
           $handler->init($this->view, $info);
           $this->handlers[$type][$id] = &$handler;
@@ -560,6 +717,35 @@ class views_plugin_display extends views
   }
 
   /**
+   * Retrieve a list of fields for the current display with the
+   *  relationship associated if it exists.
+   */
+  function get_field_labels() {
+    $options = array();
+    foreach ($this->get_handlers('relationship') as $relationship => $handler) {
+      if ($label = $handler->label()) {
+        $relationships[$relationship] = $label;
+      }
+      else {
+        $relationships[$relationship] = $handler->ui_name();
+      }
+    }
+
+    foreach ($this->get_handlers('field') as $id => $handler) {
+      if ($label = $handler->label()) {
+        $options[$id] = $label;
+      }
+      else {
+        $options[$id] = $handler->ui_name();
+      }
+      if (!empty($handler->options['relationship']) && !empty($relationships[$handler->options['relationship']])) {
+        $options[$id] = '(' . $relationships[$handler->options['relationship']] . ') ' . $options[$id];
+      }
+    }
+    return $options;
+  }
+
+  /**
    * Intelligently set an option either from this display or from the
    * default display, if directed to do so.
    */
@@ -609,10 +795,30 @@ class views_plugin_display extends views
    * This output is returned as an array.
    */
   function options_summary(&$categories, &$options) {
-    $categories['basic'] = array(
-      'title' => t('Basic settings'),
+    $categories = array(
+      'basic' => array(
+        'title' => t('Basic settings'),
+      ),
+      'advanced' => array(
+        'title' => t('Advanced settings'),
+      ),
+      'style' => array(
+        'title' => t('Style settings'),
+      ),
+      'exposed' => array(
+        'title' => t('Exposed form'),
+      ),
     );
 
+    if ($this->display->id != 'default') {
+      $options['display_id'] = array(
+        'category' => 'basic',
+        'title' => t('Machine Name'),
+        'value' => !empty($this->display->new_id) ? check_plain($this->display->new_id) : check_plain($this->display->id),
+        'desc' => t('Change the machine name of this display.'),
+      );
+    }
+
     $options['display_title'] = array(
       'category' => 'basic',
       'title' => t('Name'),
@@ -638,7 +844,7 @@ class views_plugin_display extends views
     $style = '';
 
     $options['style_plugin'] = array(
-      'category' => 'basic',
+      'category' => 'style',
       'title' => t('Style'),
       'value' => $style_title,
       'desc' => t('Change the style plugin.'),
@@ -654,7 +860,7 @@ class views_plugin_display extends views
       $row_title = empty($row_plugin['title']) ? t('Missing style plugin') : $row_plugin['title'];
 
       $options['row_plugin'] = array(
-        'category' => 'basic',
+        'category' => 'style',
         'title' => t('Row style'),
         'value' => $row_title,
         'desc' => t('Change the row plugin.'),
@@ -666,7 +872,7 @@ class views_plugin_display extends views
     }
     if (!empty($this->definition['use ajax'])) {
       $options['use_ajax'] = array(
-        'category' => 'basic',
+        'category' => 'advanced',
         'title' => t('Use AJAX'),
         'value' => $this->get_option('use_ajax') ? t('Yes') : t('No'),
         'desc' => t('Change whether or not this display will use AJAX.'),
@@ -674,21 +880,26 @@ class views_plugin_display extends views
     }
 
     if (!empty($this->definition['use pager'])) {
-      $options['use_pager'] = array(
+
+      $pager_plugin = $this->get_plugin('pager');
+      if (!$pager_plugin) {
+        // default to the no pager plugin.
+        $pager_plugin = views_get_plugin('pager', 'none');
+      }
+
+      $pager_str = $pager_plugin->summary_title();
+
+      $options['pager'] = array(
         'category' => 'basic',
         'title' => t('Use pager'),
-        'value' => $this->get_option('use_pager') ? ($this->get_option('use_pager') === 'mini' ? t('Mini') : t('Yes')) : t('No'),
+        'value' => $pager_str,
         'desc' => t("Change this display's pager setting."),
       );
     }
 
-    $items = intval($this->get_option('items_per_page'));
-    $options['items_per_page'] = array(
-      'category' => 'basic',
-      'title' => $this->use_pager() ? t('Items per page') : t('Items to display'),
-      'value' => $items ? $items : t('Unlimited'),
-      'desc' => t('Change how many items to display.'),
-    );
+    if (!empty($pager_plugin->definition['uses options'])) {
+      $options['pager']['links']['pager_options'] = t('Change settings for this pager type.');
+    }
 
     if (!empty($this->definition['use more'])) {
       $options['use_more'] = array(
@@ -700,13 +911,23 @@ class views_plugin_display extends views
     }
 
     $options['distinct'] = array(
-      'category' => 'basic',
+      'category' => 'advanced',
       'title' => t('Distinct'),
       'value' => $this->get_option('distinct') ? t('Yes') : t('No'),
       'desc' => t('Display only distinct items, without duplicates.'),
     );
 
-    $access_plugin = $this->get_access_plugin();
+    $this->view->init_query();
+    if ($this->view->query->get_aggregation_info()) {
+      $options['group_by'] = array(
+        'category' => 'advanced',
+        'title' => t('Use grouping'),
+        'value' => $this->get_option('group_by') ? t('Yes') : t('No'),
+        'desc' => t('Allow grouping and aggregation (calculation) of fields.'),
+      );
+    }
+
+    $access_plugin = $this->get_plugin('access');
     if (!$access_plugin) {
       // default to the no access control plugin.
       $access_plugin = views_get_plugin('access', 'none');
@@ -725,7 +946,7 @@ class views_plugin_display extends views
       $options['access']['links']['access_options'] = t('Change settings for this access type.');
     }
 
-    $cache_plugin = $this->get_cache_plugin();
+    $cache_plugin = $this->get_plugin('cache');
     if (!$cache_plugin) {
       // default to the no cache control plugin.
       $cache_plugin = views_get_plugin('cache', 'none');
@@ -734,7 +955,7 @@ class views_plugin_display extends views
     $cache_str = $cache_plugin->summary_title();
 
     $options['cache'] = array(
-      'category' => 'basic',
+      'category' => 'advanced',
       'title' => t('Caching'),
       'value' => $cache_str,
       'desc' => t('Specify caching type for this display.'),
@@ -744,6 +965,10 @@ class views_plugin_display extends views
       $options['cache']['links']['cache_options'] = t('Change settings for this caching type.');
     }
 
+    if (!empty($access_plugin->definition['uses options'])) {
+      $options['access']['links']['access_options'] = t('Change settings for this access type.');
+    }
+
     if ($this->uses_link_display()) {
       // Only show the 'link display' if there is more than one option.
       $count = 0;
@@ -769,42 +994,45 @@ class views_plugin_display extends views
     }
 
     $options['exposed_block'] = array(
-      'category' => 'basic',
+      'category' => 'exposed',
       'title' => t('Exposed form in block'),
       'value' => $this->get_option('exposed_block') ? t('Yes') : t('No'),
       'desc' => t('Allow the exposed form to appear in a block instead of the view.'),
     );
 
-    foreach (array('header' => t('Header'), 'footer' => t('Footer'), 'empty' => t('Empty text')) as $type => $name) {
-      if (!$this->get_option($type)) {
-        $field = t('None');
-      }
-      else {
-        // A lot of code to get the name of the filter format.
-        $fmt_string = $this->get_option($type . '_format');
-        if (empty($fmt_string)) {
-          $fmt_string = FILTER_FORMAT_DEFAULT;
-        }
-        $format_val = filter_resolve_format($fmt_string);
-        $format = filter_formats($format_val);
-        if ($format) {
-          $field = check_plain($format->name);
-        }
-        else {
-          $field = t('Unknown/missing format');
-        }
-      }
+    $exposed_form_plugin = $this->get_plugin('exposed_form');
+    if (!$exposed_form_plugin) {
+      // default to the no cache control plugin.
+      $exposed_form_plugin = views_get_plugin('exposed_form', 'basic');
+    }
 
-      $options[$type] = array(
-        'category' => 'basic',
-        'title' => $name,
-        'value' => $field,
-        'desc' => t("Change this display's !name.", array('!name' => strtolower($name))),
-      );
+    $exposed_form_str = $exposed_form_plugin->summary_title();
+
+    $options['exposed_form'] = array(
+      'category' => 'exposed',
+      'title' => t('Exposed form style'),
+      'value' => $exposed_form_str,
+      'desc' => t('Select the kind of exposed filter to use.'),
+    );
+
+    if (!empty($exposed_form_plugin->definition['uses options'])) {
+      $options['exposed_form']['links']['exposed_form_options'] = t('Exposed form settings for this exposed form style.');
+    }
+
+    $css_class = check_plain(trim($this->get_option('css_class')));
+    if (!$css_class) {
+      $css_class = t('None');
     }
 
+    $options['css_class'] = array(
+      'category' => 'style',
+      'title' => t('CSS class'),
+      'value' => $css_class,
+      'desc' => t('Change the CSS class name(s) that will be added to this display.'),
+    );
+
     $options['analyze-theme'] = array(
-      'category' => 'basic',
+      'category' => 'style',
       'title' => t('Theme'),
       'value' => t('Information'),
       'desc' => t('Get information on how to theme this display'),
@@ -832,6 +1060,16 @@ class views_plugin_display extends views
     }
 
     switch ($form_state['section']) {
+      case 'display_id':
+        $form['#title'] .= t('The machine name of this display');
+        $form['display_id'] = array(
+          '#type' => 'textfield',
+          '#description' => t('This is machine name of the display.'),
+          '#default_value' => !empty($this->display->new_id) ? $this->display->new_id : $this->display->id,
+          '#required' => TRUE,
+          '#size' => 64,
+        );
+        break;
       case 'display_title':
         $form['#title'] .= t('The name of this display');
         $form['display_title'] = array(
@@ -848,6 +1086,14 @@ class views_plugin_display extends views
           '#default_value' => $this->get_option('title'),
         );
         break;
+      case 'css_class':
+        $form['#title'] .= t('CSS class');
+        $form['css_class'] = array(
+          '#type' => 'textfield',
+          '#description' => t('The CSS class names will be added to the view. This enables you to use specific CSS code for each view. You may define multiples classes separated by spaces.'),
+          '#default_value' => $this->get_option('css_class'),
+        );
+        break;
       case 'use_ajax':
         $form['#title'] .= t('Use AJAX when available to load this view');
         $form['description'] = array(
@@ -861,35 +1107,6 @@ class views_plugin_display extends views
           '#default_value' => $this->get_option('use_ajax') ? 1 : 0,
         );
         break;
-      case 'use_pager':
-        $form['#title'] .= t('Use a pager for this view');
-        $form['use_pager'] = array(
-          '#type' => 'radios',
-          '#options' => array(TRUE => t('Full pager'), 'mini' => t('Mini pager'), 0 => t('No')),
-          '#default_value' => $this->get_option('use_pager'),
-        );
-        $form['pager_element'] = array(
-          '#type' => 'textfield',
-          '#title' => t('Pager element'),
-          '#description' => t("Unless you're experiencing problems with pagers related to this view, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible."),
-          '#default_value' => intval($this->get_option('pager_element')),
-        );
-        break;
-      case 'items_per_page':
-        $form['#title'] .= $this->use_pager() ? t('Items per page') : t('Items to display');
-
-        $form['items_per_page'] = array(
-          '#type' => 'textfield',
-          '#description' => t('The number of items to display per page. Enter 0 for no limit.'),
-          '#default_value' => intval($this->get_option('items_per_page')),
-        );
-        $form['offset'] = array(
-          '#type' => 'textfield',
-          '#title' => t('Offset'),
-          '#description' => t('The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed. Offset can not be used if items to display is 0; instead use a very large number there.'),
-          '#default_value' => intval($this->get_option('offset')),
-        );
-        break;
       case 'use_more':
         $form['#title'] .= t('Add a more link to the bottom of the display.');
         $form['use_more'] = array(
@@ -898,6 +1115,12 @@ class views_plugin_display extends views
           '#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."),
           '#default_value' => $this->get_option('use_more'),
         );
+        $form['use_more_always'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Always display more link'),
+          '#description' => t("This will display the more link even if there are no more items to display."),
+          '#default_value' => $this->get_option('use_more_always'),
+        );
         $form['#title'] .= t('Text to use for the more link.');
         $form['use_more_text'] = array(
           '#type' => 'textfield',
@@ -915,6 +1138,15 @@ class views_plugin_display extends views
           '#default_value' => $this->get_option('distinct'),
         );
         break;
+      case 'group_by':
+        $form['#title'] .= t('Allow grouping and aggregation (calculation) of fields.');
+        $form['group_by'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Group by'),
+          '#description' => t('If enabled, some fields may become unavailable. All fields that are selected for grouping will be collapsed to one record per distinct value. Other fields which are selected for aggregation will have the function run on them. For example, you can group nodes on title and count the number of nids in order to get a list of duplicate titles.'),
+          '#default_value' => $this->get_option('group_by'),
+        );
+        break;
       case 'access':
         $form['#title'] .= t('Access restrictions');
         $form['access'] = array(
@@ -935,17 +1167,18 @@ class views_plugin_display extends views
           $form['markup'] = array(
             '#prefix' => '<div class="form-item description">',
             '#suffix' => '</div>',
-            '#value' => t('You may also adjust the !settings for the currently selected style by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'access_options'))),
+            '#value' => t('You may also adjust the !settings for the currently selected access restriction by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'access_options'))),
           );
         }
 
         break;
       case 'access_options':
         $access = $this->get_option('access');
-        $plugin = $this->get_access_plugin();
+        $plugin = $this->get_plugin('access');
         $form['#title'] .= t('Access options');
         if ($plugin) {
           $form['#help_topic'] = $plugin->definition['help topic'];
+          $form['#help_module'] = $plugin->definition['module'];
 
           $form['access_options'] = array(
             '#tree' => TRUE,
@@ -977,16 +1210,17 @@ class views_plugin_display extends views
           $form['markup'] = array(
             '#prefix' => '<div class="form-item description">',
             '#suffix' => '</div>',
-            '#value' => t('You may also adjust the !settings for the currently selected style by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'cache_options'))),
+            '#value' => t('You may also adjust the !settings for the currently selected cache mechanism by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'cache_options'))),
           );
         }
         break;
       case 'cache_options':
         $cache = $this->get_option('cache');
-        $plugin = $this->get_cache_plugin();
+        $plugin = $this->get_plugin('cache');
         $form['#title'] .= t('Caching options');
         if ($plugin) {
           $form['#help_topic'] = $plugin->definition['help topic'];
+          $form['#help_module'] = $plugin->definition['module'];
 
           $form['cache_options'] = array(
             '#tree' => TRUE,
@@ -998,49 +1232,6 @@ class views_plugin_display extends views
           $plugin->options_form($form['cache_options'], $form_state);
         }
         break;
-      case 'header':
-        $form['#title'] .= t('Header');
-        $form['header_empty'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Display even if view has no result'),
-          '#default_value' => $this->get_option('header_empty'),
-        );
-        $form['header'] = array(
-          '#type' => 'textarea',
-          '#default_value' => $this->get_option('header'),
-          '#rows' => 6,
-          '#description' => t('Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional.'),
-        );
-
-        $form['header_format'] = filter_form($this->get_option('header_format'), NULL, array('header_format'));
-        break;
-      case 'footer':
-        $form['#title'] .= t('Footer');
-        $form['footer_empty'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Display even if view has no result'),
-          '#default_value' => $this->get_option('footer_empty'),
-        );
-        $form['footer'] = array(
-          '#type' => 'textarea',
-          '#default_value' => $this->get_option('footer'),
-          '#rows' => 6,
-          '#description' => t('Text to display beneath the view. May contain an explanation or links or whatever you like. Optional.'),
-        );
-
-        $form['footer_format'] = filter_form($this->get_option('footer_format'), NULL, array('footer_format'));
-        break;
-      case 'empty':
-        $form['#title'] .= t('Empty text');
-        $form['empty'] = array(
-          '#type' => 'textarea',
-          '#default_value' => $this->get_option('empty'),
-          '#rows' => 6,
-          '#description' => t('Text to display if the view has no results. Optional.'),
-        );
-
-        $form['empty_format'] = filter_form($this->get_option('empty_format'), NULL, array('empty_format'));
-        break;
       case 'style_plugin':
         $form['#title'] .= t('How should this view be styled');
         $form['#help_topic'] = 'style';
@@ -1080,6 +1271,7 @@ class views_plugin_display extends views
         if ($plugin) {
           if (isset($plugin->definition['help topic'])) {
             $form['#help_topic'] = $plugin->definition['help topic'];
+            $form['#help_module'] = $plugin->definition['module'];
           }
           $form[$form_state['section']] = array(
             '#tree' => TRUE,
@@ -1185,6 +1377,14 @@ class views_plugin_display extends views
           '#value' => '<p>' . t('This section lists all possible templates for the display plugin and for the style plugins, ordered roughly from the least specific to the most specific. The active template for each plugin -- which is the most specific template found on the system -- is highlighted in bold.') . '</p>',
         );
 
+        if (isset($this->view->display[$this->view->current_display]->new_id)) {
+          $form['important']['new_id'] = array(
+            '#prefix' => '<div class="description">',
+            '#suffix' => '</div>',
+            '#value' => t("<strong>Important!</strong> You have changed the display's machine name. Anything that attached to this display specifically, such as theming, may stop working until it is updated. To see theme suggestions for it, you need to save the view."),
+          );
+        }
+
         foreach (list_themes() as $key => $theme) {
           $options[$key] = $theme->info['name'];
         }
@@ -1344,7 +1544,81 @@ class views_plugin_display extends views
           '#default_value' => $this->get_option('exposed_block') ? 1 : 0,
         );
         break;
+      case 'exposed_form':
+        $form['#title'] .= t('Exposed Form');
+        $form['exposed_form'] = array(
+          '#prefix' => '<div class="clear-block">',
+          '#suffix' => '</div>',
+          '#tree' => TRUE,
+        );
+
+        $exposed_form = $this->get_option('exposed_form');
+        $form['exposed_form']['type'] =  array(
+          '#type' => 'radios',
+          '#options' => views_fetch_plugin_names('exposed_form'),
+          '#default_value' => $exposed_form['type'],
+        );
+
+        $exposed_form_plugin = views_fetch_plugin_data('exposed_form', $exposed_form['type']);
+        if (!empty($exposed_form_plugin['uses options'])) {
+          $form['markup'] = array(
+            '#prefix' => '<div class="form-item description">',
+            '#suffix' => '</div>',
+            '#value' => t('You may also adjust the !settings for the currently selected style by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'exposed_form_options'))),
+          );
+        }
+        break;
+      case 'exposed_form_options':
+        $plugin = $this->get_plugin('exposed_form');
+        $form['#title'] .= t('Exposed form options');
+        if ($plugin) {
+          $form['#help_topic'] = $plugin->definition['help topic'];
+
+          $form['exposed_form_options'] = array(
+            '#tree' => TRUE,
+          );
+          $plugin->options_form($form['exposed_form_options'], $form_state);
+        }
+        break;
+      case 'pager':
+        $form['#title'] .= t('Select which pager, if any, to use for this view');
+        $form['pager'] = array(
+          '#prefix' => '<div class="clear-block">',
+          '#suffix' => '</div>',
+          '#tree' => TRUE,
+        );
+
+        $pager = $this->get_option('pager');
+        $form['pager']['type'] =  array(
+          '#type' => 'radios',
+          '#options' => views_fetch_plugin_names('pager'),
+          '#default_value' => $pager['type'],
+        );
+
+        $pager_plugin = views_fetch_plugin_data('pager', $pager['type']);
+        if (!empty($pager_plugin['uses options'])) {
+          $form['markup'] = array(
+            '#prefix' => '<div class="form-item description">',
+            '#suffix' => '</div>',
+            '#value' => t('You may also adjust the !settings for the currently selected pager by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'pager_options'))),
+          );
+        }
+
+        break;
+      case 'pager_options':
+        $plugin = $this->get_plugin('pager');
+        $form['#title'] .= t('Pager options');
+        if ($plugin) {
+          $form['#help_topic'] = $plugin->definition['help topic'];
+
+          $form['pager_options'] = array(
+            '#tree' => TRUE,
+          );
+          $plugin->options_form($form['pager_options'], $form_state);
+        }
+        break;
     }
+
   }
 
   /**
@@ -1387,8 +1661,27 @@ class views_plugin_display extends views
   /**
    * Validate the options form.
    */
-  function options_validate($form, &$form_state) {
+  function options_validate(&$form, &$form_state) {
     switch ($form_state['section']) {
+      case 'css_class':
+        $css_class = $form_state['values']['css_class'];
+        if (preg_match('/[^a-zA-Z0-9- ]/', $css_class)) {
+          form_error($form['css_class'], t('CSS classes must be alphanumeric or dashes only.'));
+        }
+      break;
+      case 'display_id':
+        if ($form_state['values']['display_id']) {
+          if (preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['display_id'])) {
+            form_error($form['display_id'], t('Display id must be alphanumeric or underscores only.'));
+          }
+
+          foreach ($this->view->display as $id => $display) {
+            if ($id != $this->view->current_display && ($form_state['values']['display_id'] == $id || $form_state['values']['display_id'] == $display->new_id)) {
+              form_error($form['display_id'], t('Display id should be unique.'));
+            }
+          }
+        }
+        break;
       case 'style_options':
         $style = TRUE;
       case 'row_options':
@@ -1399,17 +1692,29 @@ class views_plugin_display extends views
         }
         break;
       case 'access_options':
-        $plugin = $this->get_access_plugin();
+        $plugin = $this->get_plugin('access');
         if ($plugin) {
           $plugin->options_validate($form['access_options'], $form_state);
         }
         break;
       case 'cache_options':
-        $plugin = $this->get_cache_plugin();
+        $plugin = $this->get_plugin('cache');
         if ($plugin) {
           $plugin->options_validate($form['cache_options'], $form_state);
         }
         break;
+      case 'exposed_form_options':
+        $plugin = $this->get_plugin('exposed_form');
+        if ($plugin) {
+          $plugin->options_validate($form['exposed_form_options'], $form_state);
+        }
+        break;
+      case 'pager_options':
+        $plugin = $this->get_plugin('pager');
+        if ($plugin) {
+          $plugin->options_validate($form['pager_options'], $form_state);
+        }
+        break;
     }
   }
 
@@ -1417,15 +1722,20 @@ class views_plugin_display extends views
    * Perform any necessary changes to the form values prior to storage.
    * There is no need for this function to actually store the data.
    */
-  function options_submit(&$form, &$form_state) {
+  function options_submit($form, &$form_state) {
     // Not sure I like this being here, but it seems (?) like a logical place.
-    $cache_plugin = $this->get_cache_plugin();
+    $cache_plugin = $this->get_plugin('cache');
     if ($cache_plugin) {
       $cache_plugin->cache_flush();
     }
 
     $section = $form_state['section'];
     switch ($section) {
+      case 'display_id':
+        if (isset($form_state['values']['display_id'])) {
+          $this->display->new_id = $form_state['values']['display_id'];
+        }
+        break;
       case 'display_title':
         $this->display->display_title = $form_state['values']['display_title'];
         break;
@@ -1435,7 +1745,6 @@ class views_plugin_display extends views
           $plugin = views_get_plugin('access', $form_state['values']['access']['type']);
           if ($plugin) {
             $access = array('type' => $form_state['values']['access']['type']);
-            $plugin->option_defaults($access);
             $this->set_option('access', $access);
             if (!empty($plugin->definition['uses options'])) {
               views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('access_options'));
@@ -1457,7 +1766,6 @@ class views_plugin_display extends views
           $plugin = views_get_plugin('cache', $form_state['values']['cache']['type']);
           if ($plugin) {
             $cache = array('type' => $form_state['values']['cache']['type']);
-            $plugin->option_defaults($cache);
             $this->set_option('cache', $cache);
             if (!empty($plugin->definition['uses options'])) {
               views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('cache_options'));
@@ -1474,26 +1782,24 @@ class views_plugin_display extends views
         }
         break;
       case 'title':
+      case 'css_class':
       case 'link_display':
         $this->set_option($section, $form_state['values'][$section]);
         break;
       case 'use_ajax':
         $this->set_option($section, (bool)$form_state['values'][$section]);
         break;
-      case 'use_pager':
-        $this->set_option($section, $form_state['values'][$section]);
-        $this->set_option('pager_element', intval($form_state['values']['pager_element']));
-        break;
-      case 'items_per_page':
-        $this->set_option($section, intval($form_state['values'][$section]));
-        $this->set_option('offset', intval($form_state['values']['offset']));
-        break;
       case 'use_more':
         $this->set_option($section, intval($form_state['values'][$section]));
+        $this->set_option('use_more_always', intval($form_state['values']['use_more_always']));
         $this->set_option('use_more_text', $form_state['values']['use_more_text']);
+        break;
       case 'distinct':
         $this->set_option($section, $form_state['values'][$section]);
         break;
+      case 'group_by':
+        $this->set_option($section, $form_state['values'][$section]);
+        break;
       case 'row_plugin':
         // This if prevents resetting options to default if they don't change
         // the plugin.
@@ -1535,18 +1841,59 @@ class views_plugin_display extends views
         }
         $this->set_option($section, $form_state['values'][$section]);
         break;
-      case 'header':
-      case 'footer':
-      case 'empty':
-        $this->set_option($section, $form_state['values'][$section]);
-        $this->set_option($section . '_format', $form_state['values'][$section . '_format']);
-        if ($section != 'empty') {
-          $this->set_option($section . '_empty', $form_state['values'][$section . '_empty']);
-        }
-        break;
       case 'exposed_block':
         $this->set_option($section, (bool) $form_state['values'][$section]);
         break;
+      case 'exposed_form':
+        $exposed_form = $this->get_option('exposed_form');
+        if ($exposed_form['type'] != $form_state['values']['exposed_form']['type']) {
+          $plugin = views_get_plugin('exposed_form', $form_state['values']['exposed_form']['type']);
+          if ($plugin) {
+            $exposed_form = array('type' => $form_state['values']['exposed_form']['type'], 'options' => array());
+            $this->set_option('exposed_form', $exposed_form);
+            if (!empty($plugin->definition['uses options'])) {
+              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('exposed_form_options'));
+            }
+          }
+        }
+
+        break;
+      case 'exposed_form_options':
+        $plugin = $this->get_plugin('exposed_form');
+        if ($plugin) {
+          $exposed_form = $this->get_option('exposed_form');
+          $plugin->options_submit($form['exposed_form_options'], $form_state);
+          $exposed_form['options'] = $form_state['values'][$section];
+          $this->set_option('exposed_form', $exposed_form);
+        }
+        break;
+      case 'pager':
+        $pager = $this->get_option('pager');
+        if ($pager['type'] != $form_state['values']['pager']['type']) {
+          $plugin = views_get_plugin('pager', $form_state['values']['pager']['type']);
+          if ($plugin) {
+            // Because pagers have very similar options, let's allow pagers to
+            // try to carry the options over.
+            $plugin->init($this->view, $this->display, $pager['options']);
+
+            $pager = array('type' => $form_state['values']['pager']['type'], 'options' => $plugin->options);
+            $this->set_option('pager', $pager);
+            if (!empty($plugin->definition['uses options'])) {
+              views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('pager_options'));
+            }
+          }
+        }
+
+        break;
+      case 'pager_options':
+        $plugin = $this->get_plugin('pager');
+        if ($plugin) {
+          $pager = $this->get_option('pager');
+          $plugin->options_submit($form['pager_options'], $form_state);
+          $pager['options'] = $form_state['values'][$section];
+          $this->set_option('pager', $pager);
+        }
+        break;
     }
   }
 
@@ -1650,7 +1997,7 @@ class views_plugin_display extends views
    * Render the 'more' link
    */
   function render_more_link() {
-    if ($this->use_more() && $this->view->total_rows > $this->view->pager['items_per_page']) {
+    if ($this->use_more() && ($this->use_more_always() || $this->view->query->pager->has_more_records())) {
       $path = $this->get_path();
       if ($path) {
         $path = $this->view->get_url(NULL, $path);
@@ -1660,72 +2007,51 @@ class views_plugin_display extends views
         }
         $theme = views_theme_functions('views_more', $this->view, $this->display);
         $path = check_url(url($path, $url_options));
-        return theme($theme, $path, $this->use_more_text());
+        return theme($theme, $path, check_plain($this->use_more_text()));
       }
     }
   }
 
   /**
-   * Render a text area, using the proper format.
+   * If this display creates a block, implement one of these.
    */
-  function render_textarea($area) {
-    static $formats = array();
-
-    $value = $this->get_option($area);
-    // Check to make sure the filter format exists; if not, we don't
-    // display anything.
-    $format = filter_resolve_format($this->get_option($area . '_format'));
+  function hook_block($op = 'list', $delta = 0, $edit = array()) { return array(); }
 
-    if (!array_key_exists($format, $formats)) {
-      $formats[$format] = db_result(db_query("SELECT name FROM {filter_formats} WHERE format = %d", $format));
-    }
+  /**
+   * If this display creates a page with a menu item, implement it here.
+   */
+  function hook_menu() { return array(); }
 
-    if (!$formats[$format]) {
-      return;
-    }
+  /**
+   * Render this display.
+   */
+  function render() {
+    return theme($this->theme_functions(), $this->view);
+  }
 
-    if ($value) {
-      return check_markup($value, $format, FALSE);
+  function render_area($area, $empty = FALSE) {
+    $return = '';
+    foreach ($this->get_handlers($area) as $area) {
+      $return .= $area->render($empty);
     }
+    return $return;
   }
 
   /**
-   * Render the header of the view.
+   * Legacy functions.
    */
   function render_header() {
-    if (!empty($this->view->result) || $this->get_option('header_empty')) {
-      return $this->render_textarea('header');
-    }
+    $empty = !empty($this->view->result);
+    return $this->render_area('header', $empty);
   }
 
-  /**
-   * Render the footer of the view.
-   */
   function render_footer() {
-    if (!empty($this->view->result) || $this->get_option('footer_empty')) {
-      return $this->render_textarea('footer');
-    }
+    $empty = !empty($this->view->result);
+    return $this->render_area('footer', $empty);
   }
 
-  /**
-   * Render the empty text of the view.
-   */
-  function render_empty() { return $this->render_textarea('empty'); }
-  /**
-   * If this display creates a block, implement one of these.
-   */
-  function hook_block($op = 'list', $delta = 0, $edit = array()) { return array(); }
-
-  /**
-   * If this display creates a page with a menu item, implement it here.
-   */
-  function hook_menu() { return array(); }
-
-  /**
-   * Render this display.
-   */
-  function render() {
-    return theme($this->theme_functions(), $this->view);
+  function render_empty() {
+    return $this->render_area('empty');
   }
 
   /**
@@ -1742,7 +2068,7 @@ class views_plugin_display extends views
       return TRUE;
     }
 
-    $plugin = $this->get_access_plugin();
+    $plugin = $this->get_plugin('access');
     if ($plugin) {
       return $plugin->access($account);
     }
@@ -1758,14 +2084,14 @@ class views_plugin_display extends views
    */
   function pre_execute() {
     $this->view->set_use_ajax($this->use_ajax());
-    // Copy pager information from the display.
-    $this->view->set_use_pager($this->use_pager());
-    $this->view->set_pager_element($this->get_option('pager_element'));
-    $this->view->set_items_per_page($this->get_option('items_per_page'));
-    $this->view->set_offset($this->get_option('offset'));
     if ($this->use_more()) {
       $this->view->get_total_rows = TRUE;
     }
+    $this->view->init_handlers();
+    if ($this->uses_exposed()) {
+      $exposed_form = $this->get_plugin('exposed_form');
+      $exposed_form->pre_execute();
+    }
   }
 
   /**
@@ -1828,15 +2154,10 @@ class views_plugin_display extends views
 
     // Validate handlers
     foreach (views_object_types() as $type => $info) {
-      $plural = $info['plural'];
-      // Skip handlers which are defaulted as there is no point in
-      // validating them again.
-      if (!$this->is_defaulted($plural)) {
-        foreach ($this->get_handlers($type) as $handler) {
-          $result = $handler->validate();
-          if (!empty($result) && is_array($result)) {
-            $errors = array_merge($errors, $result);
-          }
+      foreach ($this->get_handlers($type) as $handler) {
+        $result = $handler->validate();
+        if (!empty($result) && is_array($result)) {
+          $errors = array_merge($errors, $result);
         }
       }
     }
@@ -1845,6 +2166,22 @@ class views_plugin_display extends views
   }
 
   /**
+   * Check if the provided identifier is unique.
+   */
+  function is_identifier_unique($id, $identifier) {
+    foreach (views_object_types() as $type => $info) {
+      foreach ($this->get_handlers($type) as $key => $handler) {
+        if ($handler->can_expose() && $handler->is_exposed()) {
+          if ($id != $key && $identifier == $handler->options['expose']['identifier']) {
+            return FALSE;
+          }
+        }
+      }
+    }
+    return TRUE;
+  }
+
+  /**
    * Provide the block system with any exposed widget blocks for this display.
    */
   function get_special_blocks() {
@@ -1868,12 +2205,150 @@ class views_plugin_display extends views
         return;
       }
       $this->view->init_handlers();
-      return array(
-        'content' => $this->view->render_exposed_form(TRUE),
-      );
+      if ($this->uses_exposed()) {
+        $exposed_form = $this->get_plugin('exposed_form');
+        return array(
+          'content' => $exposed_form->render_exposed_form(TRUE),
+        );
+      }
     }
   }
 
+  /**
+   * Override of export_option()
+   *
+   * Because displays do not want to export options that are NOT overridden from the
+   * default display, we need some special handling during the export process.
+   */
+  function export_option($indent, $prefix, $storage, $option, $definition, $parents) {
+    // The $prefix is wrong because we store our actual options a little differently:
+    $prefix = '$handler->display->display_options';
+    $output = '';
+    if (!$parents && !$this->is_default_display()) {
+      // Do not export items that are not overridden.
+      if ($this->is_defaulted($option)) {
+        return;
+      }
+
+      // If this is not defaulted and is overrideable, flip the switch to say this
+      // is overridden.
+      if ($this->defaultable_sections($option)) {
+        $output .= $indent . $prefix . "['defaults']['$option'] = FALSE;\n";
+      }
+    }
+
+    $output .= parent::export_option($indent, $prefix, $storage, $option, $definition, $parents);
+    return $output;
+  }
+
+  /**
+   * Special method to export items that have handlers.
+   *
+   * This method was specified in the option_definition() as the method to utilize to
+   * export fields, filters, sort criteria, relationships and arguments. This passes
+   * the export off to the individual handlers so that they can export themselves
+   * properly.
+   */
+  function export_handler($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+
+    // cut the 's' off because the data is stored as the plural form but we need
+    // the singular form. Who designed that anyway? Oh yeah, I did. :(
+    if ($option != 'header' && $option != 'footer' && $option != 'empty') {
+      $type = substr($option, 0, -1);
+    }
+    else {
+      $type = $option;
+    }
+    $types = views_object_types();
+    foreach ($storage[$option] as $id => $info) {
+      if (!empty($types[$type]['type'])) {
+        $handler_type = $types[$type]['type'];
+      }
+      else {
+        $handler_type = $type;
+      }
+      $handler = views_get_handler($info['table'], $info['field'], $handler_type);
+      if ($handler) {
+        $handler->init($this->view, $info);
+        $output .= $indent . '/* ' . $types[$type]['stitle'] . ': ' . $handler->ui_name() . " */\n";
+        $output .= $handler->export_options($indent, $prefix . "['$option']['$id']");
+      }
+
+      // Prevent reference problems.
+      unset($handler);
+    }
+
+    return $output;
+  }
+
+  /**
+   * Special handling for the style export.
+   *
+   * Styles are stored as style_plugin and style_options or row_plugin and
+   * row_options accordingly. The options are told not to export, and the
+   * export for the plugin should export both.
+   */
+  function export_style($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+    $style_plugin = $this->get_plugin();
+    if ($option == 'style_plugin') {
+      $type = 'style';
+      $options_field = 'style_options';
+      $plugin = $style_plugin;
+    }
+    else {
+      if (!$style_plugin || !$style_plugin->uses_row_plugin()) {
+        return;
+      }
+
+      $type = 'row';
+      $options_field = 'row_options';
+      $plugin = $this->get_plugin('row');
+      // If the style plugin doesn't use row plugins, don't even bother.
+    }
+
+    if ($plugin) {
+      // Write which plugin to use.
+      $value = $this->get_option($option);
+      $output .= $indent . $prefix . "['$option'] = '$value';\n";
+
+      // Pass off to the plugin to export itself.
+      $output .= $plugin->export_options($indent, $prefix . "['$options_field']");
+    }
+
+    return $output;
+  }
+
+  /**
+   * Special handling for plugin export
+   *
+   * Plugins other than styles are stored in array with 'type' being the key
+   * to the plugin. For modern plugins, the options are stored in the 'options'
+   * array, but for legacy plugins (access and cache) options are stored as
+   * siblings to the type.
+   */
+  function export_plugin($indent, $prefix, $storage, $option, $definition, $parents) {
+    $output = '';
+    $plugin_type = end($parents);
+    $plugin = $this->get_plugin($plugin_type);
+    if ($plugin) {
+      // Write which plugin to use.
+      $value = $storage[$option];
+      $new_prefix = $prefix . "['$plugin_type']";
+
+      $output .= $indent . $new_prefix . "['$option'] = '$value';\n";
+
+      if ($plugin_type != 'access' && $plugin_type!= 'cache') {
+        $new_prefix .= "['options']";
+      }
+
+      // Pass off to the plugin to export itself.
+      $output .= $plugin->export_options($indent, $new_prefix);
+    }
+
+    return $output;
+  }
 }
 
 
Index: plugins/views_plugin_display_attachment.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_display_attachment.inc,v
retrieving revision 1.4
diff -u -p -r1.4 views_plugin_display_attachment.inc
--- plugins/views_plugin_display_attachment.inc	20 May 2009 02:53:30 -0000	1.4
+++ plugins/views_plugin_display_attachment.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_display_attachment.inc,v 1.4 2009/05/20 02:53:30 merlinofchaos Exp $
+// $Id: views_plugin_display_attachment.inc,v 1.3.2.5 2010/01/19 21:59:04 merlinofchaos Exp $
 /**
  * @file
  * Contains the attachment display plugin.
@@ -21,6 +21,8 @@ class views_plugin_display_attachment ex
     $options['attachment_position'] = array('default' => 'before');
     $options['inherit_arguments'] = array('default' => TRUE);
     $options['inherit_exposed_filters'] = array('default' => FALSE);
+    $options['inherit_pager'] = array('default' => FALSE);
+    $options['render_pager'] = array('default' => TRUE);
     $options['displays'] = array('default' => array());
 
     return $options;
@@ -69,6 +71,18 @@ class views_plugin_display_attachment ex
       'value' => $this->get_option('inherit_exposed_filters') ? t('Yes') : t('No'),
     );
 
+    $options['inherit_pager'] = array(
+      'category' => 'attachment',
+      'title' => t('Inherit pager'),
+      'value' => $this->get_option('inherit_pager') ? t('Yes') : t('No'),
+    );
+
+    $options['render_pager'] = array(
+      'category' => 'attachment',
+      'title' => t('Render pager'),
+      'value' => $this->get_option('render_pager') ? t('Yes') : t('No'),
+    );
+
     $options['attachment_position'] = array(
       'category' => 'attachment',
       'title' => t('Position'),
@@ -123,6 +137,24 @@ class views_plugin_display_attachment ex
           '#default_value' => $this->get_option('inherit_exposed_filters'),
         );
         break;
+      case 'inherit_pager':
+        $form['#title'] .= t('Inherit pager');
+        $form['inherit_pager'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Inherit'),
+          '#description' => t('Should this display inherit its paging values from the parent display to which it is attached? Note that this will provide unexpected results if the number of items to display do not match.'),
+          '#default_value' => $this->get_option('inherit_pager'),
+        );
+        break;
+      case 'render_pager':
+        $form['#title'] .= t('Render pager');
+        $form['render_pager'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Render'),
+          '#description' => t('Should this display render the pager values? If not it can inherit from the parent...'),
+          '#default_value' => $this->get_option('render_pager'),
+        );
+        break;
       case 'attachment_position':
         $form['#title'] .= t('Position');
         $form['attachment_position'] = array(
@@ -159,6 +191,8 @@ class views_plugin_display_attachment ex
     parent::options_submit($form, $form_state);
     switch ($form_state['section']) {
       case 'inherit_arguments':
+      case 'inherit_pager':
+      case 'render_pager':
       case 'inherit_exposed_filters':
       case 'attachment_position':
       case 'displays':
@@ -177,6 +211,10 @@ class views_plugin_display_attachment ex
       return;
     }
 
+    if (!$this->access()) {
+      return;
+    }
+
     // Get a fresh view because our current one has a lot of stuff on it because it's
     // already been executed.
     $view = $this->view->clone_view();
@@ -184,6 +222,11 @@ class views_plugin_display_attachment ex
 
     $args = $this->get_option('inherit_arguments') ? $this->view->args : array();
     $view->set_arguments($args);
+    $view->set_display($this->display->id);
+    if ($this->get_option('inherit_pager')) {
+      $view->display_handler->use_pager = $this->view->display[$display_id]->handler->use_pager();
+      $view->display_handler->set_option('pager_element', $this->view->display[$display_id]->handler->get_option('pager_element'));
+    }
 
     // because of this, it is very very important that displays that can accept
     // attachments not also be attachments, or this could explode messily.
@@ -225,4 +268,12 @@ class views_plugin_display_attachment ex
   function displays_exposed() {
     return $this->options['inherit_exposed_filters'] ? FALSE : TRUE;
   }
+
+  function use_pager() {
+    return !empty($this->use_pager);
+  }
+
+  function render_pager() {
+    return !empty($this->use_pager) && $this->get_option('render_pager');
+  }
 }
Index: plugins/views_plugin_display_block.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_display_block.inc,v
retrieving revision 1.4
diff -u -p -r1.4 views_plugin_display_block.inc
--- plugins/views_plugin_display_block.inc	1 Jun 2009 21:38:44 -0000	1.4
+++ plugins/views_plugin_display_block.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_display_block.inc,v 1.4 2009/06/01 21:38:44 merlinofchaos Exp $
+// $Id: views_plugin_display_block.inc,v 1.2.2.4 2010/01/19 21:59:04 merlinofchaos Exp $
 /**
  * @file
  * Contains the block display plugin.
Index: plugins/views_plugin_display_feed.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_display_feed.inc,v
retrieving revision 1.4
diff -u -p -r1.4 views_plugin_display_feed.inc
--- plugins/views_plugin_display_feed.inc	20 May 2009 02:53:30 -0000	1.4
+++ plugins/views_plugin_display_feed.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_display_feed.inc,v 1.4 2009/05/20 02:53:30 merlinofchaos Exp $
+// $Id: views_plugin_display_feed.inc,v 1.3.2.6 2010/07/27 22:19:12 merlinofchaos Exp $
 /**
  * @file
  * Contains the feed display plugin.
@@ -30,7 +30,10 @@ class views_plugin_display_feed extends 
   }
 
   function preview() {
-    return '<pre>' . check_plain($this->view->render()) . '</pre>';
+    if (!empty($this->view->live_preview)) {
+      return '<pre>' . check_plain($this->view->render()) . '</pre>';
+    }
+    return $this->view->render();
   }
 
   /**
@@ -192,4 +195,8 @@ class views_plugin_display_feed extends 
       $plugin->attach_to($display_id, $this->get_path(), $clone->get_title());
     }
   }
+  
+  function uses_link_display() {
+    return TRUE;
+  }
 }
Index: plugins/views_plugin_display_page.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_display_page.inc,v
retrieving revision 1.7
diff -u -p -r1.7 views_plugin_display_page.inc
--- plugins/views_plugin_display_page.inc	2 Jun 2009 20:37:15 -0000	1.7
+++ plugins/views_plugin_display_page.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_display_page.inc,v 1.7 2009/06/02 20:37:15 merlinofchaos Exp $
+// $Id: views_plugin_display_page.inc,v 1.5.2.11 2010/03/11 00:01:56 merlinofchaos Exp $
 /**
  * @file
  * Contains the page display plugin.
@@ -38,6 +38,7 @@ class views_plugin_display_page extends 
         'title' => array('default' => '', 'translatable' => FALSE),
         'description' => array('default' => '', 'translatable' => FALSE),
         'weight' => array('default' => 0),
+        'name' => array('default' => 'navigation'),
        ),
     );
 
@@ -47,7 +48,7 @@ class views_plugin_display_page extends 
   /**
    * Add this display's path information to Drupal's menu system.
    */
-  function execute_hook_menu() {
+  function execute_hook_menu($callbacks) {
     $items = array();
     // Replace % with the link to our standard views argument loader
     // views_arg_load -- which lives in views.module
@@ -66,8 +67,10 @@ class views_plugin_display_page extends 
 
     $path = implode('/', $bits);
 
-    $access_plugin = $this->get_access_plugin();
-
+    $access_plugin = $this->get_plugin('access');
+    if (!isset($access_plugin)) {
+      $access_plugin = views_get_plugin('access', 'none');
+    }
     if ($path) {
       $items[$path] = array(
         // default views page entry
@@ -135,6 +138,7 @@ class views_plugin_display_page extends 
               'load arguments'  => array($this->view->name, $this->display->id, '%index'),
               'title' => $tab_options['title'],
               'description' => $tab_options['description'],
+              'menu_name' => $tab_options['name'],
             );
             switch ($tab_options['type']) {
               default:
@@ -389,6 +393,27 @@ class views_plugin_display_page extends 
           '#process' => array('views_process_dependency'),
           '#dependency' => array('radio:tab_options[type]' => array('normal', 'tab')),
         );
+        // Only display the menu selector if menu module is enabled.
+        if (module_exists('menu')) {
+          $form['tab_options']['name'] = array(
+            '#title' => t('Menu'),
+            '#type' => 'select',
+            '#options' => menu_get_menus(),
+            '#default_value' => $tab_options['name'],
+            '#description' => t('Insert item into an available menu.'),
+            '#process' => array('views_process_dependency'),
+            '#dependency' => array('radio:tab_options[type]' => array('normal')),
+          );
+        }
+        else {
+          $form['tab_options']['name'] = array(
+            '#type' => 'value',
+            '#value' => $tab_options['name'],
+          );
+          $form['tab_options']['markup'] = array(
+            '#value' => t('Menu selection requires the activation of menu module.'),
+          );
+        }
         $form['tab_options']['weight'] = array(
           '#suffix' => '</div>',
           '#title' => t('Tab weight'),
@@ -403,7 +428,7 @@ class views_plugin_display_page extends 
     }
   }
 
-  function options_validate($form, &$form_state) {
+  function options_validate(&$form, &$form_state) {
     // It is very important to call the parent function here:
     parent::options_validate($form, $form_state);
     switch ($form_state['section']) {
Index: plugins/views_plugin_row.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_row.inc,v
retrieving revision 1.4
diff -u -p -r1.4 views_plugin_row.inc
--- plugins/views_plugin_row.inc	1 Jun 2009 23:34:55 -0000	1.4
+++ plugins/views_plugin_row.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_row.inc,v 1.4 2009/06/01 23:34:55 merlinofchaos Exp $
+// $Id: views_plugin_row.inc,v 1.3.2.2 2009/12/28 21:11:50 merlinofchaos Exp $
 /**
  * @file
  * Contains the base row style plugin.
@@ -108,12 +108,14 @@ class views_plugin_row extends views_plu
   function options_submit($form, &$form_state) { }
 
   function query() {
-    if (isset($this->base_table) && isset($this->options['relationship']) && isset($this->view->relationship[$this->options['relationship']])) {
-      $relationship = $this->view->relationship[$this->options['relationship']];
-      $this->field_alias = $this->view->query->add_field($relationship->alias, $this->base_field);
-    }
-    else {
-      $this->field_alias = $this->view->base_field;
+    if (isset($this->base_table)) {
+      if (isset($this->options['relationship']) && isset($this->view->relationship[$this->options['relationship']])) {
+        $relationship = $this->view->relationship[$this->options['relationship']];
+        $this->field_alias = $this->view->query->add_field($relationship->alias, $this->base_field);
+      }
+      else {
+        $this->field_alias = $this->view->query->add_field($this->base_table, $this->base_field);
+      }
     }
   }
 
Index: plugins/views_plugin_row_fields.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_row_fields.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_plugin_row_fields.inc
--- plugins/views_plugin_row_fields.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ plugins/views_plugin_row_fields.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_row_fields.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+// $Id: views_plugin_row_fields.inc,v 1.1.2.2 2010/03/11 00:06:14 merlinofchaos Exp $
 /**
  * @file
  * Contains the base row style plugin.
@@ -19,6 +19,7 @@ class views_plugin_row_fields extends vi
 
     $options['inline'] = array('default' => array());
     $options['separator'] = array('default' => '');
+    $options['hide_empty'] = array('default' => FALSE);
     return $options;
   }
 
@@ -26,10 +27,7 @@ class views_plugin_row_fields extends vi
    * Provide a form for setting options.
    */
   function options_form(&$form, &$form_state) {
-    $options = array();
-    foreach ($this->display->handler->get_handlers('field') as $field => $handler) {
-      $options[$field] = $handler->ui_name();
-    }
+    $options = $this->display->handler->get_field_labels();
 
     if (empty($this->options['inline'])) {
       $this->options['inline'] = array();
@@ -50,6 +48,14 @@ class views_plugin_row_fields extends vi
       '#default_value' => isset($this->options['separator']) ? $this->options['separator'] : '',
       '#description' => t('The separator may be placed between inline fields to keep them from squishing up next to each other. You can use HTML in this field.'),
     );
+
+    $form['hide_empty'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Hide empty fields'),
+      '#default_value' => $this->options['hide_empty'],
+      '#description' => t('Do not display fields, labels or markup for fields that are empty.'),
+    );
+
   }
 
   /**
Index: plugins/views_plugin_style.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_style.inc,v
retrieving revision 1.6
diff -u -p -r1.6 views_plugin_style.inc
--- plugins/views_plugin_style.inc	1 Jun 2009 23:34:55 -0000	1.6
+++ plugins/views_plugin_style.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_style.inc,v 1.6 2009/06/01 23:34:55 merlinofchaos Exp $
+// $Id: views_plugin_style.inc,v 1.5.2.9 2010/04/29 18:21:50 merlinofchaos Exp $
 
 /**
  * @defgroup views_style_plugins Views' style plugins
@@ -89,15 +89,7 @@ class views_plugin_style extends views_p
     // @TODO: Document "uses grouping" in docs.php when docs.php is written.
     if ($this->uses_fields() && $this->definition['uses grouping']) {
       $options = array('' => t('<None>'));
-      foreach ($this->display->handler->get_handlers('field') as $field => $handler) {
-
-        if ($label = $handler->label()) {
-          $options[$field] = $label;
-        }
-        else {
-          $options[$field] = $handler->ui_name();
-        }
-      }
+      $options += $this->display->handler->get_field_labels();
 
       // If there are no fields, we can't group on them.
       if (count($options) > 1) {
@@ -120,6 +112,12 @@ class views_plugin_style extends views_p
   function build_sort() { return TRUE; }
 
   /**
+   * Called by the view builder to let the style build a second set of
+   * sorts that will come after any other sorts in the view.
+   */
+  function build_sort_post() { }
+
+  /**
    * Allow the style to do stuff before each row is rendered.
    *
    * @param $result
@@ -149,7 +147,8 @@ class views_plugin_style extends views_p
     foreach ($sets as $title => $records) {
       if ($this->uses_row_plugin()) {
         $rows = array();
-        foreach ($records as $label => $row) {
+        foreach ($records as $row_index => $row) {
+          $this->view->row_index = $row_index;
           $rows[] = $this->row_plugin->render($row);
         }
       }
@@ -159,6 +158,7 @@ class views_plugin_style extends views_p
 
       $output .= theme($this->theme_functions(), $this->view, $this->options, $rows, $title);
     }
+    unset($this->view->row_index);
     return $output;
   }
 
@@ -174,20 +174,22 @@ class views_plugin_style extends views_p
    *   The grouped record set.
    */
   function render_grouping($records, $grouping_field = '') {
+    // Make sure fields are rendered
+    $this->render_fields($this->view->result);
     $sets = array();
     if ($grouping_field) {
-      foreach ($records as $row) {
+      foreach ($records as $index => $row) {
         $grouping = '';
         // Group on the rendered version of the field, not the raw.  That way,
         // we can control any special formatting of the grouping field through
         // the admin or theme layer or anywhere else we'd like.
         if (isset($this->view->field[$grouping_field])) {
-          $grouping = $this->view->field[$grouping_field]->theme($row);
+          $grouping = $this->get_field($index, $grouping_field);
           if ($this->view->field[$grouping_field]->options['label']) {
             $grouping = $this->view->field[$grouping_field]->options['label'] . ': ' . $grouping;
           }
         }
-        $sets[$grouping][] = $row;
+        $sets[$grouping][$index] = $row;
       }
     }
     else {
@@ -197,6 +199,51 @@ class views_plugin_style extends views_p
     return $sets;
   }
 
+  /**
+   * Render all of the fields for a given style and store them on the object.
+   *
+   * @param $result
+   *   The result array from $view->result
+   */
+  function render_fields($result) {
+    if (!$this->uses_fields()) {
+      return;
+    }
+
+    $start = views_microtime();
+    if (isset($this->rendered_fields)) {
+      return $this->rendered_fields;
+    }
+
+    $this->view->row_index = 0;
+    $keys = array_keys($this->view->field);
+    foreach ($result as $count => $row) {
+      $this->view->row_index = $count;
+      foreach ($keys as $id) {
+        $this->rendered_fields[$count][$id] = $this->view->field[$id]->theme($row);
+      }
+    }
+    unset($this->view->row_index);
+  }
+
+  /**
+   * Get a rendered field.
+   *
+   * @param $index
+   *   The index count of the row.
+   * @param $field
+   *    The id of the field.
+   */
+  function get_field($index, $field) {
+    if (!isset($this->rendered_fields)) {
+      $this->render_fields($this->view->result);
+    }
+
+    if (isset($this->rendered_fields[$index][$field])) {
+      return $this->rendered_fields[$index][$field];
+    }
+  }
+
   function validate() {
     $errors = parent::validate();
 
@@ -205,6 +252,12 @@ class views_plugin_style extends views_p
       if (empty($plugin)) {
         $errors[] = t('Style @style requires a row style but the row plugin is invalid.', array('@style' => $this->definition['title']));
       }
+      else {
+        $result = $plugin->validate();
+        if (!empty($result) && is_array($result)) {
+          $errors = array_merge($errors, $result);
+        }
+      }
     }
     return $errors;
   }
Index: plugins/views_plugin_style_grid.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_style_grid.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_plugin_style_grid.inc
--- plugins/views_plugin_style_grid.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ plugins/views_plugin_style_grid.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_style_grid.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+// $Id: views_plugin_style_grid.inc,v 1.1.2.1 2010/06/16 19:18:22 merlinofchaos Exp $
 /**
  * @file
  * Contains the grid style plugin.
@@ -19,6 +19,7 @@ class views_plugin_style_grid extends vi
 
     $options['columns'] = array('default' => '4');
     $options['alignment'] = array('default' => 'horizontal');
+    $options['fill_single_line'] = array('default' => TRUE);
 
     return $options;
   }
@@ -40,6 +41,13 @@ class views_plugin_style_grid extends vi
       '#default_value' => $this->options['alignment'],
       '#description' => t('Horizontal alignment will place items starting in the upper left and moving right. Vertical alignment will place items starting in the upper left and moving down.'),
     );
+    
+    $form['fill_single_line'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Fill up single line'),
+      '#description' => t('If you disable this option a grid with only one row will have the amount of items as tds. If you disable it this can cause problems with your css.'),
+      '#default_value' => !empty($this->options['fill_single_line']),
+    );
   }
 }
 
Index: plugins/views_plugin_style_summary.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_style_summary.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_plugin_style_summary.inc
--- plugins/views_plugin_style_summary.inc	3 Sep 2008 19:21:30 -0000	1.1
+++ plugins/views_plugin_style_summary.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_style_summary.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+// $Id: views_plugin_style_summary.inc,v 1.1.2.3 2009/11/26 00:35:16 merlinofchaos Exp $
 /**
  * @file
  * Contains the default summary style plugin, which displays items in an HTML list.
@@ -14,8 +14,8 @@ class views_plugin_style_summary extends
   function option_definition() {
     $options = parent::option_definition();
 
-    $options['count'] = array('default' => TRUE);
-    $options['override'] = array('default' => FALSE);
+    $options['count'] = array('default' => TRUE, 'bool' => TRUE);
+    $options['override'] = array('default' => FALSE, 'bool' => TRUE);
     $options['items_per_page'] = array('default' => 25);
 
     return $options;
Index: plugins/views_plugin_style_table.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_style_table.inc,v
retrieving revision 1.5
diff -u -p -r1.5 views_plugin_style_table.inc
--- plugins/views_plugin_style_table.inc	15 Oct 2008 22:25:36 -0000	1.5
+++ plugins/views_plugin_style_table.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_plugin_style_table.inc,v 1.5 2008/10/15 22:25:36 merlinofchaos Exp $
+// $Id: views_plugin_style_table.inc,v 1.5.2.6 2010/03/11 00:06:14 merlinofchaos Exp $
 /**
  * @file
  * Contains the table style plugin.
@@ -28,10 +28,27 @@ class views_plugin_style_table extends v
    * Determine if we should provide sorting based upon $_GET inputs.
    */
   function build_sort() {
+    if (!isset($_GET['order']) && ($this->options['default'] == -1 || empty($this->view->field[$this->options['default']]))) {
+      return TRUE;
+    }
+
+    // If a sort we don't know anything about gets through, exit gracefully.
+    if (isset($_GET['order']) && empty($this->view->field[$_GET['order']])) {
+      return TRUE;
+    }
+
+    // Let the builder know whether or not we're overriding the default sorts.
+    return empty($this->options['override']);
+  }
+
+  /**
+   * Add our actual sort criteria
+   */
+  function build_sort_post() {
     if (!isset($_GET['order'])) {
       // check for a 'default' clicksort. If there isn't one, exit gracefully.
       if (empty($this->options['default'])) {
-        return TRUE;
+        return;
       }
       $sort = $this->options['default'];
       $this->order = !empty($this->options['order']) ? $this->options['order'] : 'asc';
@@ -44,7 +61,7 @@ class views_plugin_style_table extends v
 
     // If a sort we don't know anything about gets through, exit gracefully.
     if (empty($this->view->field[$sort])) {
-      return TRUE;
+      return;
     }
 
     // Ensure $this->order is valid.
@@ -57,9 +74,6 @@ class views_plugin_style_table extends v
 
     // Tell the field to click sort.
     $this->view->field[$sort]->click_sort($this->order);
-
-    // Let the builder know whether or not we're overriding the default sorts.
-    return empty($this->options['override']);
   }
 
   /**
@@ -158,14 +172,7 @@ class views_plugin_style_table extends v
     $columns = $this->sanitize_columns($this->options['columns']);
 
     // Create an array of allowed columns from the data we know:
-    foreach ($handlers as $field => $handler) {
-      if ($label = $handler->label()) {
-        $field_names[$field] = $label;
-      }
-      else {
-        $field_names[$field] = $handler->ui_name();
-      }
-    }
+    $field_names = $this->display->handler->get_field_labels();
 
     if (isset($this->options['default'])) {
       $default = $this->options['default'];
@@ -208,6 +215,18 @@ class views_plugin_style_table extends v
           '#dependency' => array($id => array($field)),
         );
       }
+      $form['info'][$field]['align'] = array(
+        '#type' => 'select',
+        '#default_value' => !empty($this->options['info'][$field]['align']) ? $this->options['info'][$field]['align'] : '',
+        '#options' => array(
+          '' => t('None'),
+          'views-align-left' => t('Left'),
+          'views-align-center' => t('Center'),
+          'views-align-right' => t('Right'),
+          ),
+        '#process' => array('views_process_dependency'),
+        '#dependency' => array($id => array($field)),
+      );
       $form['info'][$field]['separator'] = array(
         '#type' => 'textfield',
         '#size' => 10,
Index: theme/theme.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/theme/theme.inc,v
retrieving revision 1.76
diff -u -p -r1.76 theme.inc
--- theme/theme.inc	2 Jun 2009 20:28:52 -0000	1.76
+++ theme/theme.inc	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: theme.inc,v 1.76 2009/06/02 20:28:52 merlinofchaos Exp $
+// $Id: theme.inc,v 1.73.2.31 2010/07/27 22:51:27 merlinofchaos Exp $
 
 /**
  * @file theme.inc
@@ -49,67 +49,49 @@ function template_preprocess_views_view(
   $vars['name']       = $view->name;
   $vars['display_id'] = $view->current_display;
 
-  if (!$vars['rows']) {
-    $vars['empty']    = $view->display_handler->render_empty();
-    if (!$view->display_handler->get_option('header_empty')) {
-      $vars['header'] = '';
-    }
-    if (!$view->display_handler->get_option('footer_empty')) {
-      $vars['footer'] = '';
-    }
-  }
-  else {
-    $vars['empty']    = '';
-    $header = TRUE;
+  // Basic classes
+  $vars['classes_array'] = array();
+  $vars['classes_array'][] = 'view';
+  $vars['classes_array'][] = 'view-' . views_css_safe($vars['name']);
+  $vars['classes_array'][] = 'view-id-' . $vars['name'];
+  $vars['classes_array'][] = 'view-display-id-' . $vars['display_id'];
+
+  $css_class = $view->display_handler->get_option('css_class');
+  if (!empty($css_class)) {
+    $vars['css_class'] = preg_replace('/[^a-zA-Z0-9- ]/', '-', $css_class);
+    $vars['classes_array'][] = $vars['css_class'];
+  }
+
+  $empty = empty($vars['rows']);
+
+  $vars['header'] = $view->display_handler->render_area('header', $empty);
+  $vars['footer'] = $view->display_handler->render_area('footer', $empty);
+  if ($empty) {
+    $vars['empty'] = $view->display_handler->render_area('empty');
   }
 
   $vars['exposed']    = !empty($view->exposed_widgets) ? $view->exposed_widgets : '';
-  if (!isset($vars['header'])) {
-    $vars['header']   = $view->display_handler->render_header();
-  }
-  if (!isset($vars['footer'])) {
-    $vars['footer']   = $view->display_handler->render_footer();
-  }
   $vars['more']       = $view->display_handler->render_more_link();
   $vars['feed_icon']  = !empty($view->feed_icon) ? $view->feed_icon : '';
+  $vars['pager']      = $view->query->render_pager();
 
   $vars['attachment_before'] = !empty($view->attachment_before) ? $view->attachment_before : '';
   $vars['attachment_after'] = !empty($view->attachment_after) ? $view->attachment_after : '';
 
-  $vars['pager']      = '';
-
-  $exposed_input = isset($view->exposed_data_raw) ? $view->exposed_data_raw : NULL;
-  if (!empty($view->pager['use_pager'])) {
-    $pager_type = ($view->pager['use_pager'] === 'mini' ? 'views_mini_pager' : 'pager');
-    $pager_theme = views_theme_functions($pager_type, $view, $view->display_handler->display);
-    $vars['pager']    = theme($pager_theme, $exposed_input, $view->pager['items_per_page'], $view->pager['element']);
-  }
-
   // if administrator, add some links. These used to be tabs, but this is better.
   if (user_access('administer views') && module_exists('views_ui') && empty($view->hide_admin_links) && !variable_get('views_no_hover_links', FALSE)) {
     $vars['admin_links_raw'] = array(
       array(
-        'title' => t('Edit'),
+        'title' => t('Edit view'),
         'alt' => t("Edit this view"),
         'href' => "admin/build/views/edit/$view->name",
         'fragment' => 'views-tab-' . $view->current_display,
         'query' => drupal_get_destination(),
       ),
-      array(
-        'title' => t('Export'),
-        'alt' => t("Export this view"),
-        'href' => "admin/build/views/export/$view->name",
-      ),
-      array(
-        'title' => t('Clone'),
-        'alt' => t("Create a copy of this view"),
-        'href' => "admin/build/views/clone/$view->name",
-      ),
     );
 
     drupal_alter('views_admin_links', $vars['admin_links_raw'], $view);
     $vars['admin_links'] = theme('links', $vars['admin_links_raw']);
-    views_add_css('views');
   }
   else {
     $vars['admin_links'] = '';
@@ -127,6 +109,7 @@ function template_preprocess_views_view(
   // wrapper.
   static $dom_id = 1;
   $vars['dom_id'] = !empty($view->dom_id) ? $view->dom_id : $dom_id++;
+  $vars['classes_array'][] = 'view-dom-id-' . $vars['dom_id'];
 
   // If using AJAX, send identifying data about this view.
   if ($view->use_ajax) {
@@ -145,7 +128,7 @@ function template_preprocess_views_view(
             'view_dom_id' => $vars['dom_id'],
             // To fit multiple views on a page, the programmer may have
             // overridden the display's pager_element.
-            'pager_element' => $view->pager['element'],
+            'pager_element' => isset($view->query->pager) ? $view->query->pager->get_pager_id() : 0,
           ),
         ),
       ),
@@ -154,6 +137,8 @@ function template_preprocess_views_view(
     drupal_add_js($settings, 'setting');
     views_add_js('ajax_view');
   }
+  // Flatten the classes to a string for the template file.
+  $vars['classes'] = implode(' ', $vars['classes_array']);
 }
 
 /**
@@ -167,8 +152,9 @@ function template_preprocess_views_view_
   $vars['fields'] = array(); // ensure it's at least an empty array.
   foreach ($view->field as $id => $field) {
     // render this even if set to exclude so it can be used elsewhere.
-    $field_output = $view->field[$id]->theme($vars['row']);
-    if (empty($field->options['exclude'])) {
+    $field_output = $view->style_plugin->get_field($view->row_index, $id);
+    $empty = $field_output !== 0 && empty($field_output);
+    if (empty($field->options['exclude']) && (!$empty || empty($field->options['hide_empty']))) {
       $object = new stdClass();
 
       $object->content = $field_output;
@@ -205,7 +191,8 @@ function template_preprocess_views_view_
  * this: @code { $row->{$field->field_alias} @endcode
  */
 function theme_views_view_field($view, $field, $row) {
-  return $field->advanced_render($row);
+  // Reference safe for PHP 4:
+  return $view->field[$field->options['id']]->advanced_render($row);
 }
 
 /**
@@ -231,6 +218,7 @@ function template_preprocess_views_view_
   if (!empty($view->exposed_raw_input)) {
     $url_options['query'] = $view->exposed_raw_input;
   }
+  $vars['classes'] = array();
   foreach ($vars['rows'] as $id => $row) {
     $vars['rows'][$id]->link = $argument->summary_name($row);
     $args = $view->args;
@@ -238,6 +226,9 @@ function template_preprocess_views_view_
 
     $vars['rows'][$id]->url = url($view->get_url($args), $url_options);
     $vars['rows'][$id]->count = intval($row->{$argument->count_alias});
+    if ($vars['rows'][$id]->url == base_path() . $_GET['q'] || $vars['rows'][$id]->url == base_path() . drupal_get_path_alias($_GET['q'])) {
+      $vars['classes'][$id] = 'active';
+    }
   }
 }
 
@@ -248,6 +239,7 @@ function template_preprocess_views_view_
 function template_preprocess_views_view_summary_unformatted(&$vars) {
   $view     = $vars['view'];
   $argument = $view->argument[$view->build_info['summary_level']];
+  $vars['classes'] = array();
 
   $url_options = array();
 
@@ -267,6 +259,9 @@ function template_preprocess_views_view_
 
     $vars['rows'][$id]->url = url($view->get_url($args), $url_options);
     $vars['rows'][$id]->count = intval($row->{$argument->count_alias});
+    if ($vars['rows'][$id]->url == base_path() . $_GET['q'] || $vars['rows'][$id]->url == base_path() . drupal_get_path_alias($_GET['q'])) {
+      $vars['classes'][$id] = 'active';
+    }
   }
 }
 
@@ -280,7 +275,8 @@ function template_preprocess_views_view_
   // However, the template also needs to use for the rendered fields.  We
   // therefore swap the raw data out to a new variable and reset $vars['rows']
   // so that it can get rebuilt.
-  $result   = $vars['rows'];
+  // Store rows so that they may be used by further preprocess functions.
+  $result   = $vars['result'] = $vars['rows'];
   $vars['rows'] = array();
 
   $options  = $view->style_plugin->options;
@@ -299,13 +295,7 @@ function template_preprocess_views_view_
 
   // Fields must be rendered in order as of Views 2.3, so we will pre-render
   // everything.
-  $renders = array();
-  $keys = array_keys($view->field);
-  foreach ($result as $count => $row) {
-    foreach ($keys as $id) {
-      $renders[$count][$id] = $view->field[$id]->theme($row);
-    }
-  }
+  $renders = $handler->render_fields($result);
 
   foreach ($columns as $field => $column) {
     // render the header labels
@@ -342,6 +332,11 @@ function template_preprocess_views_view_
       $vars['fields'][$field] .= ' active';
     }
 
+    // Add a CSS align class to each field if one was set
+    if (!empty($options['info'][$field]['align'])) {
+      $vars['fields'][$field] .= ' ' . views_css_safe($options['info'][$field]['align']);
+    }
+
     // Render each field into its appropriate column.
     foreach ($result as $num => $row) {
       if (!empty($fields[$field]) && empty($fields[$field]->options['exclude'])) {
@@ -367,15 +362,20 @@ function template_preprocess_views_view_
     }
   }
 
+  $count = 0;
   foreach ($vars['rows'] as $num => $row) {
-    $vars['row_classes'][$num][] = ($num % 2 == 0) ? 'odd' : 'even';
+    $vars['row_classes'][$num][] = ($count++ % 2 == 0) ? 'odd' : 'even';
   }
 
+  $vars['row_classes'][0][] = 'views-row-first';
+  $vars['row_classes'][count($vars['row_classes']) - 1][] = 'views-row-last';
+
   $vars['class'] = 'views-table';
   if (!empty($options['sticky'])) {
     drupal_add_js('misc/tableheader.js');
     $vars['class'] .= " sticky-enabled";
   }
+  $vars['class'] .= ' cols-'. count($vars['rows']);
 }
 
 /**
@@ -393,14 +393,23 @@ function template_preprocess_views_view_
 
   if ($options['alignment'] == 'horizontal') {
     $row = array();
+    $row_count = 0;
     foreach ($vars['rows'] as $count => $item) {
       $row[] = $item;
+      $row_count++;
       if (($count + 1) % $columns == 0) {
         $rows[] = $row;
         $row = array();
+        $row_count = 0;
       }
     }
     if ($row) {
+      // Fill up the last line only if it's configured, but this is default.
+      if (!empty($handler->options['fill_single_line']) || count($rows)) {
+        for ($i = 0; $i < ($columns - $row_count); $i++) {
+          $row[] = '';
+        }
+      }
       $rows[] = $row;
     }
   }
@@ -424,6 +433,12 @@ function template_preprocess_views_view_
         $remainders--;
       }
     }
+    for ($i = 0; $i < count($rows[0]); $i++) {
+      // This should be string so that's okay :)
+      if (!isset($rows[count($rows) - 1][$i])) {
+        $rows[count($rows) - 1][$i] = '';
+      }
+    }
   }
   $vars['rows'] = $rows;
 }
@@ -438,14 +453,19 @@ function template_preprocess_views_view_
   $vars['classes'] = array();
   // Set up striping values.
   foreach ($rows as $id => $row) {
-    $vars['classes'][$id] = 'views-row';
-    $vars['classes'][$id] .= ' views-row-' . ($id + 1);
-    $vars['classes'][$id] .= ' views-row-' . ($id % 2 ? 'even' : 'odd');
+    $row_classes = array();
+    $row_classes[] = 'views-row';
+    $row_classes[] = 'views-row-' . ($id + 1);
+    $row_classes[] = 'views-row-' . ($id % 2 ? 'even' : 'odd');
     if ($id == 0) {
-      $vars['classes'][$id] .= ' views-row-first';
+      $row_classes[] = 'views-row-first';
+    }
+    if ($id == count($rows) -1) {
+      $row_classes[] = 'views-row-last';
     }
+    // Flatten the classes to a string for each row for the template file.
+    $vars['classes'][$id] = implode(' ', $row_classes);
   }
-  $vars['classes'][$id] .= ' views-row-last';
 }
 
 /**
@@ -538,7 +558,6 @@ function template_preprocess_views_view_
  * Default theme function for all filter forms.
  */
 function template_preprocess_views_exposed_form(&$vars) {
-  views_add_css('views');
   $form = &$vars['form'];
 
   // Put all single checkboxes together in the last spot.
@@ -559,6 +578,7 @@ function template_preprocess_views_expos
     // set up defaults so that there's always something there.
     $widget->label = $widget->operator = $widget->widget = NULL;
 
+    $widget->id = $form[$info['value']]['#id'];
     if (!empty($info['label'])) {
       $widget->label = $info['label'];
     }
@@ -583,6 +603,19 @@ function template_preprocess_views_expos
   unset($form['form_build_id']);
   unset($form['form_token']);
 
+  if (isset($form['sort_by'])) {
+    $vars['sort_by'] = drupal_render($form['sort_by']);
+    $vars['sort_order'] = drupal_render($form['sort_order']);
+  }
+  if (isset($form['items_per_page'])) {
+    $vars['items_per_page'] = drupal_render($form['items_per_page']);
+  }
+  if (isset($form['offset'])) {
+    $vars['offset'] = drupal_render($form['offset']);
+  }
+  if (isset($form['reset'])) {
+    $vars['reset_button'] = drupal_render($form['reset']);
+  }
   // This includes the submit button.
   $vars['button'] = drupal_render($form);
 }
Index: theme/views-exposed-form.tpl.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/theme/views-exposed-form.tpl.php,v
retrieving revision 1.4
diff -u -p -r1.4 views-exposed-form.tpl.php
--- theme/views-exposed-form.tpl.php	7 May 2008 23:00:25 -0000	1.4
+++ theme/views-exposed-form.tpl.php	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views-exposed-form.tpl.php,v 1.4 2008/05/07 23:00:25 merlinofchaos Exp $
+// $Id: views-exposed-form.tpl.php,v 1.4.2.4 2010/07/27 21:39:58 merlinofchaos Exp $
 /**
  * @file views-exposed-form.tpl.php
  *
@@ -10,6 +10,11 @@
  * - $widget->label: The visible label to print. May be optional.
  * - $widget->operator: The operator for the widget. May be optional.
  * - $widget->widget: The widget itself.
+ * - $sort_by: The select box to sort the view using an exposed form.
+ * - $sort_order: The select box with the ASC, DESC options to define order. May be optional.
+ * - $items_per_page: The select box with the available items per page. May be optional.
+ * - $offset: A textfield to define the offset of the view. May be optional.
+ * - $reset_button: A button to reset the exposed filter applied. May be optional.
  * - $button: The submit button for the form.
  *
  * @ingroup views_templates
@@ -25,9 +30,9 @@
 <div class="views-exposed-form">
   <div class="views-exposed-widgets clear-block">
     <?php foreach($widgets as $id => $widget): ?>
-      <div class="views-exposed-widget">
+      <div class="views-exposed-widget views-widget-<?php print $id ?>">
         <?php if (!empty($widget->label)): ?>
-          <label>
+          <label for="<?php print $widget->id; ?>">
             <?php print $widget->label; ?>
           </label>
         <?php endif; ?>
@@ -41,8 +46,31 @@
         </div>
       </div>
     <?php endforeach; ?>
+    <?php if (!empty($sort_by)): ?>
+      <div class="views-exposed-widget">
+        <?php print $sort_by; ?>
+      </div>
+      <div class="views-exposed-widget">
+        <?php print $sort_order; ?>
+      </div>
+    <?php endif; ?>
+    <?php if (!empty($items_per_page)): ?>
+      <div class="views-exposed-widget">
+        <?php print $items_per_page; ?>
+      </div>
+    <?php endif; ?>
+    <?php if (!empty($offset)): ?>
+      <div class="views-exposed-widget">
+        <?php print $offset; ?>
+      </div>
+    <?php endif; ?>
+    <?php if (!empty($reset_button)): ?>
+      <div class="views-exposed-widget">
+        <?php print $reset_button; ?>
+      </div>
+    <?php endif; ?>
     <div class="views-exposed-widget">
       <?php print $button ?>
     </div>
   </div>
-</div>
\ No newline at end of file
+</div>
Index: theme/views-more.tpl.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/theme/views-more.tpl.php,v
retrieving revision 1.3
diff -u -p -r1.3 views-more.tpl.php
--- theme/views-more.tpl.php	2 Jun 2009 20:35:52 -0000	1.3
+++ theme/views-more.tpl.php	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views-more.tpl.php,v 1.3 2009/06/02 20:35:52 merlinofchaos Exp $
+// $Id: views-more.tpl.php,v 1.2.2.1 2009/06/02 20:35:56 merlinofchaos Exp $
 /**
  * @file views-more.tpl.php
  * Theme the more link
Index: theme/views-ui-edit-tab.tpl.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/theme/views-ui-edit-tab.tpl.php,v
retrieving revision 1.11
diff -u -p -r1.11 views-ui-edit-tab.tpl.php
--- theme/views-ui-edit-tab.tpl.php	8 Aug 2008 16:57:44 -0000	1.11
+++ theme/views-ui-edit-tab.tpl.php	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views-ui-edit-tab.tpl.php,v 1.11 2008/08/08 16:57:44 merlinofchaos Exp $
+// $Id: views-ui-edit-tab.tpl.php,v 1.11.2.1 2010/01/19 22:11:28 merlinofchaos Exp $
 /**
  * @file views-ui-edit-tab.tpl.php
  * Template for the primary view editing window.
@@ -67,12 +67,11 @@
   <?php // middle section ?>
   <div class="middle tab-section">
     <div class="inside">
+      <?php foreach ($areas as $area): ?>
       <div class="views-category">
-        <?php print $relationships; ?>
-      </div>
-      <div class="views-category">
-        <?php print $arguments; ?>
+        <?php print $area; ?>
       </div>
+      <?php endforeach;?>
       <?php if (!empty($fields)): ?>
         <div class="views-category">
           <?php print $fields; ?>
@@ -85,6 +84,12 @@
   <div class="right tab-section">
     <div class="inside">
       <div class="views-category">
+        <?php print $relationships; ?>
+      </div>
+      <div class="views-category">
+        <?php print $arguments; ?>
+      </div>
+      <div class="views-category">
         <?php print $sorts; ?>
       </div>
       <div class="views-category">
@@ -93,4 +98,4 @@
     </div>
   </div>
 
-</div>
\ No newline at end of file
+</div>
Index: theme/views-view-grid.tpl.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/theme/views-view-grid.tpl.php,v
retrieving revision 1.3
diff -u -p -r1.3 views-view-grid.tpl.php
--- theme/views-view-grid.tpl.php	14 Jun 2008 17:42:43 -0000	1.3
+++ theme/views-view-grid.tpl.php	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views-view-grid.tpl.php,v 1.3 2008/06/14 17:42:43 merlinofchaos Exp $
+// $Id: views-view-grid.tpl.php,v 1.3.2.1 2010/03/12 01:05:42 merlinofchaos Exp $
 /**
  * @file views-view-grid.tpl.php
  * Default simple view template to display a rows in a grid.
@@ -21,7 +21,7 @@
         if ($row_number == 0) {
           $row_class .= ' row-first';
         }
-        elseif (count($rows) == ($row_number + 1)) {
+        if (count($rows) == ($row_number + 1)) {
           $row_class .= ' row-last';
         }
       ?>
Index: theme/views-view-summary-unformatted.tpl.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/theme/views-view-summary-unformatted.tpl.php,v
retrieving revision 1.2
diff -u -p -r1.2 views-view-summary-unformatted.tpl.php
--- theme/views-view-summary-unformatted.tpl.php	7 Jan 2009 19:21:34 -0000	1.2
+++ theme/views-view-summary-unformatted.tpl.php	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views-view-summary-unformatted.tpl.php,v 1.2 2009/01/07 19:21:34 merlinofchaos Exp $
+// $Id: views-view-summary-unformatted.tpl.php,v 1.2.2.1 2010/03/16 23:12:29 merlinofchaos Exp $
 /**
  * @file views-view-summary-unformatted.tpl.php
  * Default simple view template to display a group of summary lines
@@ -9,10 +9,10 @@
  * @ingroup views_templates
  */
 ?>
-<?php foreach ($rows as $row): ?>
+<?php foreach ($rows as $id => $row): ?>
   <?php print (!empty($options['inline']) ? '<span' : '<div') . ' class="views-summary views-summary-unformatted">'; ?>
     <?php if (!empty($row->separator)) { print $row->separator; } ?>
-    <a href="<?php print $row->url; ?>"><?php print $row->link; ?></a>
+    <a href="<?php print $row->url; ?>"<?php print !empty($classes[$id]) ? ' class="'. $classes[$id] .'"' : ''; ?>><?php print $row->link; ?></a>
     <?php if (!empty($options['count'])): ?>
       (<?php print $row->count; ?>)
     <?php endif; ?>
Index: theme/views-view-summary.tpl.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/theme/views-view-summary.tpl.php,v
retrieving revision 1.6
diff -u -p -r1.6 views-view-summary.tpl.php
--- theme/views-view-summary.tpl.php	7 Jan 2009 19:21:34 -0000	1.6
+++ theme/views-view-summary.tpl.php	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views-view-summary.tpl.php,v 1.6 2009/01/07 19:21:34 merlinofchaos Exp $
+// $Id: views-view-summary.tpl.php,v 1.6.2.1 2010/03/16 23:12:29 merlinofchaos Exp $
 /**
  * @file views-view-summary.tpl.php
  * Default simple view template to display a list of summary lines
@@ -9,8 +9,8 @@
 ?>
 <div class="item-list">
   <ul class="views-summary">
-  <?php foreach ($rows as $row): ?>
-    <li><a href="<?php print $row->url; ?>"><?php print $row->link; ?></a>
+  <?php foreach ($rows as $id => $row): ?>
+    <li><a href="<?php print $row->url; ?>"<?php print !empty($classes[$id]) ? ' class="'. $classes[$id] .'"' : ''; ?>><?php print $row->link; ?></a>
       <?php if (!empty($options['count'])): ?>
         (<?php print $row->count?>)
       <?php endif; ?>
Index: theme/views-view.tpl.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/theme/views-view.tpl.php,v
retrieving revision 1.13
diff -u -p -r1.13 views-view.tpl.php
--- theme/views-view.tpl.php	2 Jun 2009 19:30:44 -0000	1.13
+++ theme/views-view.tpl.php	11 Aug 2010 21:11:33 -0000
@@ -1,11 +1,20 @@
 <?php
-// $Id: views-view.tpl.php,v 1.13 2009/06/02 19:30:44 merlinofchaos Exp $
+// $Id: views-view.tpl.php,v 1.12.2.3 2010/03/25 20:25:23 merlinofchaos Exp $
 /**
  * @file views-view.tpl.php
  * Main view template
  *
  * Variables available:
+ * - $classes_array: An array of classes determined in
+ *   template_preprocess_views_view(). Default classes are:
+ *     .view
+ *     .view-[css_name]
+ *     .view-id-[view_name]
+ *     .view-display-id-[display_name]
+ *     .view-dom-id-[dom_id]
+ * - $classes: A string version of $classes_array for use in the class attribute
  * - $css_name: A css-safe version of the view name.
+ * - $css_class: The user-specified classes names, if any
  * - $header: The view header
  * - $footer: The view footer
  * - $rows: The results of the view query, if any
@@ -20,7 +29,7 @@
  * @ingroup views_templates
  */
 ?>
-<div class="view view-<?php print $css_name; ?> view-id-<?php print $name; ?> view-display-id-<?php print $display_id; ?> view-dom-id-<?php print $dom_id; ?>">
+<div class="<?php print $classes; ?>">
   <?php if ($admin_links): ?>
     <div class="views-admin-links views-hide">
       <?php print $admin_links; ?>
Index: views_export/views_export.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/views_export/views_export.module,v
retrieving revision 1.6
diff -u -p -r1.6 views_export.module
--- views_export/views_export.module	2 Jun 2009 19:36:25 -0000	1.6
+++ views_export/views_export.module	11 Aug 2010 21:11:33 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: views_export.module,v 1.6 2009/06/02 19:36:25 merlinofchaos Exp $
+// $Id: views_export.module,v 1.4.2.4 2009/09/15 17:26:53 merlinofchaos Exp $
 
 /**
  * @file views_export.module
@@ -189,10 +189,10 @@ function views_export_export_form_submit
 
   $types = system_elements();
 
-  $info  = '; $Id: views_export.module,v 1.6 2009/06/02 19:36:25 merlinofchaos Exp $'."\n";
+  $info  = '; $Id: views_export.module,v 1.4.2.4 2009/09/15 17:26:53 merlinofchaos Exp $'."\n";
   $info .= "\n";
-  $info .= t("name = @module Export Module\n", array('@module' => $form_state['values']['name']));
-  $info .= t("description = Exports some views of @module\n", array('@module' => $form_state['values']['name']));
+  $info .= strtr("name = @module Export Module\n", array('@module' => $form_state['values']['name']));
+  $info .= strtr("description = Exports some views of @module\n", array('@module' => $form_state['values']['name']));
   $info .= "dependencies[] = views\n";
   $info .= "core = 6.x\n";
 
@@ -228,7 +228,7 @@ function views_export_export_form_submit
     '#type' => 'textarea',
     '#id' => 'export-api-textarea',
     '#name' => 'export-api-textarea',
-    '#attributes' => array(),
+    '#attributes' => array( 'dir' => 'ltr' ),
     '#rows' => 9,
     '#cols' => 60,
     '#value' => $api,
@@ -241,7 +241,7 @@ function views_export_export_form_submit
     '#type' => 'textarea',
     '#id' => 'export-textarea',
     '#name' => 'export-textarea',
-    '#attributes' => array(),
+    '#attributes' => array( 'dir' => 'ltr' ),
     '#rows' => min($lines, 150),
     '#value' => $code,
     '#parents' => array('dummy'),
