? .git
Index: handlers/views_handler_area.inc
===================================================================
RCS file: handlers/views_handler_area.inc
diff -N handlers/views_handler_area.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ handlers/views_handler_area.inc	31 Dec 2009 19:24:55 -0000
@@ -0,0 +1,104 @@
+<?php
+// $Id$
+/**
+ * @file
+ * Views area handlers.
+ */
+
+/**
+ * @defgroup views_area_handlers Views' relationship handlers
+ * @{
+ * Handlers to tell Views what can display in header, footer
+ * and empty text in a view.
+ */
+
+class views_handler_area extends views_handler {
+  /**
+   * Get this field's label.
+   */
+  function label() {
+    if (!isset($this->options['label'])) {
+      return $this->ui_name();
+    }
+    return $this->options['label'];
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $label = !empty($this->definition['label']) ? $this->definition['label'] : $this->definition['field'];
+    $options['label'] = array('default' => $label, 'translatable' => TRUE);
+    $options['empty'] = array('default' => 0, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  /**
+   * Provide extra data to the administration form
+   */
+  function admin_summary() {
+    return $this->label();
+  }
+
+  /**
+   * Default options form that provides the label widget that all fields
+   * should have.
+   */
+  function options_form(&$form, &$form_state) {
+    $form['label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Label'),
+      '#default_value' => isset($this->options['label']) ? $this->options['label'] : '',
+      '#description' => t('The label for this area that will be displayed only administratively.'),
+    );
+
+    if ($form_state['type'] != 'empty') {
+      $form['empty'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Display even if view has no result'),
+        '#default_value' => isset($this->options['empty']) ? $this->options['empty'] : 0,
+        '#description' => t('If checked this area will be rended, even if the views has no results.'),
+      );
+    }
+  }
+
+  /**
+   * Don't run a query
+   */
+  function query() { }
+
+  /**
+   * Render the area
+   */
+  function render($empty = FALSE) {
+    return '';
+  }
+}
+
+/**
+ * A special handler to take the place of missing or broken handlers.
+ */
+class views_handler_area_broken extends views_handler_area {
+  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 render($empty = FALSE) { return ''; }
+  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_area_text.inc
===================================================================
RCS file: handlers/views_handler_area_text.inc
diff -N handlers/views_handler_area_text.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ handlers/views_handler_area_text.inc	31 Dec 2009 19:24:55 -0000
@@ -0,0 +1,60 @@
+<?php
+// $Id$
+
+class views_handler_area_text extends views_handler_area {
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['content'] = array('default' => '', 'translatable' => TRUE);
+    $options['format'] = array('default' => variable_get('filter_default_format', 1));
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['content'] = array(
+      '#type' => 'textarea',
+      '#default_value' => $this->options['content'],
+      '#rows' => 6,
+      '#description' => $description,
+    );
+
+    $form['format'] = filter_form($this->options['format']);
+  }
+
+  function options_submit(&$form, &$form_state) {
+    $form_state['values']['options']['format'] = $form_state['values']['format'];
+    parent::options_submit($form, $form_state);
+  }
+
+  function render($empty = FALSE) {
+    if (!$empty || !empty($this->options['empty'])) {
+      return $this->render_textarea($this->options['content'], $this->options['format']);
+    }
+    return '';
+  }
+
+  /**
+   * Render a text area, using the proper format.
+   */
+  function render_textarea($value, $format) {
+    static $formats = array();
+
+    // Check to make sure the filter format exists; if not, we don't
+    // display anything.
+    $format = filter_resolve_format($format);
+
+    if (!array_key_exists($format, $formats)) {
+      $formats[$format] = db_result(db_query("SELECT name FROM {filter_formats} WHERE format = %d", $format));
+    }
+
+    if (!$formats[$format]) {
+      return;
+    }
+
+    if ($value) {
+      return check_markup($value, $format, FALSE);
+    }
+  }
+}
Index: includes/admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/admin.inc,v
retrieving revision 1.154.2.22
diff -u -p -r1.154.2.22 admin.inc
--- includes/admin.inc	28 Dec 2009 21:34:25 -0000	1.154.2.22
+++ includes/admin.inc	31 Dec 2009 19:25:04 -0000
@@ -1176,6 +1176,10 @@ function template_preprocess_views_ui_ed
   $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);
@@ -2382,6 +2386,11 @@ function views_ui_add_item_form(&$form_s
   $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';
@@ -2594,10 +2603,16 @@ function views_ui_config_item_form_submi
   // 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'], $form_state['type']);
+  $handler = views_get_handler($item['table'], $item['field'], $type);
 
   // This unpacks only options that are in the definition, ensuring random
   // extra stuff on the form is not sent through.
@@ -3221,7 +3236,7 @@ function views_fetch_fields($base, $type
           $bases[] = $table;
           continue;
         }
-        foreach (array('field', 'sort', 'filter', 'argument', 'relationship') as $key) {
+        foreach (array('field', 'sort', 'filter', 'argument', 'relationship', 'area') as $key) {
           if (!empty($info[$key])) {
             if ($grouping && !empty($info[$key]['no group by'])) {
               continue;
Index: includes/handlers.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/handlers.inc,v
retrieving revision 1.109.2.15
diff -u -p -r1.109.2.15 handlers.inc
--- includes/handlers.inc	24 Dec 2009 01:08:26 -0000	1.109.2.15
+++ includes/handlers.inc	31 Dec 2009 19:25:08 -0000
@@ -1310,6 +1310,14 @@ function views_views_handlers() {
       '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',
+      ),
     ),
   );
 }
Index: includes/view.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/view.inc,v
retrieving revision 1.151.2.25
diff -u -p -r1.151.2.25 view.inc
--- includes/view.inc	28 Dec 2009 21:34:25 -0000	1.151.2.25
+++ includes/view.inc	31 Dec 2009 19:25:12 -0000
@@ -64,7 +64,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');
   }
 
   /**
@@ -1419,7 +1419,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', 'exposed_widgets', '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');
     foreach ($keys as $key) {
       if (isset($clone->$key)) {
         unset($clone->$key);
@@ -1484,7 +1484,7 @@ class view extends views_db_object {
         unset($this->query);
       }
 
-      $keys = array('current_display', 'display_handler', 'build_info', 'built', 'executed', 'attachment_before', 'attachment_after', 'field', 'argument', 'filter', 'sort', 'relationship', 'query', 'result', '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', '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);
@@ -1806,7 +1806,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);
@@ -1949,6 +1956,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: modules/views.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/modules/views.views.inc,v
retrieving revision 1.6.2.1
diff -u -p -r1.6.2.1 views.views.inc
--- modules/views.views.inc	2 Jun 2009 17:29:21 -0000	1.6.2.1
+++ modules/views.views.inc	31 Dec 2009 19:25:19 -0000
@@ -52,6 +52,14 @@ 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',
+    ),
+  );
+
   return $data;
 }
 
Index: plugins/views_plugin_display.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_display.inc,v
retrieving revision 1.20.2.26
diff -u -p -r1.20.2.26 views_plugin_display.inc
--- plugins/views_plugin_display.inc	24 Dec 2009 00:41:17 -0000	1.20.2.26
+++ plugins/views_plugin_display.inc	31 Dec 2009 19:25:22 -0000
@@ -44,7 +44,7 @@ class views_plugin_display extends views
 
     // Translate changed settings:
     // Check if any of the previous values now managed by
-    // pluggable pagers have been changed. 
+    // pluggable pagers have been changed.
     // If yes, perform the conversion
     $items_per_page = $this->get_option('items_per_page');
     $offset = $this->get_option('offset');
@@ -79,6 +79,27 @@ class views_plugin_display extends views
       $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) {
+      $options = array();
+
+      $content = $this->get_option($area);
+      if (!empty($content) && !is_array($content)) {
+        $format = $this->get_option($area . '_format');
+        $options = array(
+          '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->view->add_item($this->id, $area, 'views', 'area', $options);
+      }
+    }
   }
 
   function destroy() {
@@ -215,9 +236,6 @@ 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'),
       'use_ajax' => array('use_ajax'),
       'items_per_page' => array('items_per_page', 'offset', 'use_pager', 'pager_element'),
       'pager' => array('pager'),
@@ -234,6 +252,9 @@ 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('empty'),
+      'empty' => array('empty'),
       'relationships' => array('relationships'),
       'fields' => array('fields'),
       'sorts' => array('sorts'),
@@ -281,14 +302,6 @@ 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,
 
           'use_ajax' => TRUE,
           'items_per_page' => TRUE,
@@ -310,6 +323,10 @@ class views_plugin_display extends views
           'row_plugin' => TRUE,
           'row_options' => TRUE,
 
+          'header' => TRUE,
+          'footer' => TRUE,
+          'empty' => TRUE,
+
           'relationships' => TRUE,
           'fields' => TRUE,
           'sorts' => TRUE,
@@ -323,33 +340,6 @@ class views_plugin_display extends views
         'default' => '',
         'translatable' => TRUE,
       ),
-      'header' => 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,
-      ),
       'use_ajax' => array(
         'default' => FALSE,
         'bool' => TRUE,
@@ -443,6 +433,19 @@ class views_plugin_display extends views
         '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(
@@ -656,7 +659,14 @@ class views_plugin_display extends views
           }
         }
 
-        $handler = views_get_handler($info['table'], $info['field'], $type, $override);
+        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;
@@ -944,34 +954,6 @@ class views_plugin_display extends views
       $options['exposed_form']['links']['exposed_form_options'] = t('Exposed form settings for this exposed form style.');
     }
 
-    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');
-        }
-      }
-
-      $options[$type] = array(
-        'category' => 'style',
-        'title' => $name,
-        'value' => $field,
-        'desc' => t("Change this display's !name.", array('!name' => strtolower($name))),
-      );
-    }
-
     $options['analyze-theme'] = array(
       'category' => 'style',
       'title' => t('Theme'),
@@ -1165,49 +1147,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';
@@ -1806,15 +1745,6 @@ 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;
@@ -1987,52 +1917,6 @@ class views_plugin_display extends views
   }
 
   /**
-   * Render a text area, using the proper format.
-   */
-  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'));
-
-    if (!array_key_exists($format, $formats)) {
-      $formats[$format] = db_result(db_query("SELECT name FROM {filter_formats} WHERE format = %d", $format));
-    }
-
-    if (!$formats[$format]) {
-      return;
-    }
-
-    if ($value) {
-      return check_markup($value, $format, FALSE);
-    }
-  }
-
-  /**
-   * Render the header of the view.
-   */
-  function render_header() {
-    if (!empty($this->view->result) || $this->get_option('header_empty')) {
-      return $this->render_textarea('header');
-    }
-  }
-
-  /**
-   * Render the footer of the view.
-   */
-  function render_footer() {
-    if (!empty($this->view->result) || $this->get_option('footer_empty')) {
-      return $this->render_textarea('footer');
-    }
-  }
-
-  /**
-   * 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(); }
@@ -2049,6 +1933,14 @@ class views_plugin_display extends views
     return theme($this->theme_functions(), $this->view);
   }
 
+  function render_area($area, $empty = FALSE) {
+    $return = '';
+    foreach ($this->get_handlers($area) as $area) {
+      $return .= $area->render($empty);
+    }
+    return $return;
+  }
+
   /**
    * Determine if the user has access to this display of the view.
    */
@@ -2249,10 +2141,21 @@ class views_plugin_display extends views
 
     // 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. :(
-    $type = substr($option, 0, -1);
+    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) {
-      $handler = views_get_handler($info['table'], $info['field'], $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);
       if ($handler) {
         $handler->init($this->view, $info);
         $output .= $indent . '/* ' . $types[$type]['stitle'] . ': ' . $handler->ui_name() . " */\n";
Index: theme/theme.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/theme/theme.inc,v
retrieving revision 1.73.2.20
diff -u -p -r1.73.2.20 theme.inc
--- theme/theme.inc	24 Dec 2009 01:08:26 -0000	1.73.2.20
+++ theme/theme.inc	31 Dec 2009 19:25:23 -0000
@@ -49,27 +49,15 @@ 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;
+  $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();
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	31 Dec 2009 19:25:23 -0000
@@ -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>
