Add better hiliting to the UI; now possible to tell what items are overridden as...
authorEarl Miles
Fri, 15 Feb 2008 04:11:48 +0000 (04:11 +0000)
committerEarl Miles
Fri, 15 Feb 2008 04:11:48 +0000 (04:11 +0000)
13 files changed:
css/admin.css
includes/admin.inc
includes/ajax.inc
includes/plugins.inc
includes/view.inc
js/ajax.js
modules/node.views.inc
theme/views-ui-edit-view.tpl.php [new file with mode: 0644]
theme/views-view-list.tpl.php [new file with mode: 0644]
theme/views-view-unformatted.tpl.php
theme/views-view.tpl.php
views.module
views_ui.module

index 6d7b364..227b570 100644 (file)
@@ -344,10 +344,23 @@ html.js a.views-button-remove {
   padding: 0;
 }
 
-div.views-basic-info div.view-changed {
-  float: right;
+div.changed {
+  background: #ffd;
 }
 
-div.views-basic-info div.view-hide {
+div.view-changed {
   display: none;
+  float: right;
+}
+
+div.changed div.view-changed {
+  display: block;
+}
+
+.hilited {
+  background: #ffd;
+}
+
+.overridden {
+  font-style: italic;
 }
index fa271e6..7b1f138 100644 (file)
@@ -224,40 +224,24 @@ function views_ui_edit_view_form_cancel($form, &$form_state) {
 }
 
 /**
- * Display the edit view form.
- *
- * Since this form is more of a summary than a form, there's a lot more work
- * here than you might find in most forms.
+ * Preprocess the view edit page.
  */
-function theme_views_ui_edit_view($view) {
-  $output = '';
-  $save_button = drupal_get_form('views_ui_edit_view_form', $view);
+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);
-  $base_table = !empty($table['table']['base']['title']) ?
+  $vars['base_table'] = !empty($table['table']['base']['title']) ?
     $table['table']['base']['title'] : t('Unknown or missing table name');
 
-  $output .= '<div class="views-basic-info">';
-  if (!empty($view->changed)) {
-    if (!is_numeric($view->vid)) {
-      $output .= '<div class="view-changed view-new">' . t('New view') . '</div>';
-    }
-    else {
-      $output .= '<div class="view-changed">' . t('Changed view') . '</div>';
-    }
-  }
-  else {
-    $output .= '<div class="view-changed view-hide">' . t('Changed view') . '</div>';
-  }
-  $output .= t('View %name, displaying items of type <b>@base</b>.',
-    array('%name' => $view->name, '@base' => $base_table));
-  $output .= '</div>';
-
   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')) {
-    views_ajax_render(t('Invalid display id'));
+    drupal_set_message(t('This view has a broken default display and cannot be used.'), 'error');
   }
 
   foreach ($view->display as $display) {
@@ -270,18 +254,7 @@ function theme_views_ui_edit_view($view) {
   $display_button = drupal_get_form('views_ui_add_display_form', $view);
   $tabs->add_extra($display_button);
 
-  $output .= $tabs->render();
-
-  $message = '<div class="message">' . t("Click on an item to edit that item's details.") . '</div>';
-  $output .= '<div id="views-ajax-form">';
-  $output .= '<div id="views-ajax-title"></div>';
-  $output .= '<div id="views-ajax-pad">';
-  $output .= $message;
-  $output .= '</div>';
-  $output .= '</div>';
-
-  // Render the actual form here
-  $output .= $save_button;
+  $vars['tabs'] = $tabs->render();
 
   views_add_css('admin');
   views_add_js('ajax');
@@ -302,11 +275,10 @@ function theme_views_ui_edit_view($view) {
   $settings = array('views' => array('ajax' => array(
     'id' => '#views-ajax-pad',
     'title' => '#views-ajax-title',
-    'defaultForm' => $message,
+    'defaultForm' => $vars['message'],
   )));
-  drupal_add_js($settings, 'setting');
 
-  return $output;
+  drupal_add_js($settings, 'setting');
 }
 
 /**
@@ -343,7 +315,7 @@ function views_ui_display_tab($view, &$display) {
   if ($display->id == 'default') {
     $tag = empty($view->tag) ? t('None') : $view->tag;
     $left .= '<dt>' . t('View settings') . '</dt>';
-    $left .= '<dd class="views-item-details">' . t('Tag') . ': ' . l($tag, "admin/build/views/nojs/details/$view->name", array('attributes' => array('class' => 'views-ajax-link'))) . '</dd>';
+    $left .= '<dd class="' . views_ui_item_css('details') . '">' . t('Tag') . ': ' . l($tag, "admin/build/views/nojs/details/$view->name", array('attributes' => array('class' => 'views-ajax-link'))) . '</dd>';
   }
 
   $options = $categories = array();
@@ -377,7 +349,17 @@ function views_ui_display_tab($view, &$display) {
     $left .= '<dt class="views-category-' . $id . '">' . $category['title'] . '</dt>';
     if (!empty($category['data'])) {
       foreach ($category['data'] as $cid => $cdata) {
-        $left .= '<dd class="views-item-' . $cid . '">' . $cdata . '</dd>';
+        $override = '';
+        if (!empty($display->display_options['defaults'][$cid])) {
+          $display_id = 'default';
+        }
+        else {
+          $display_id = $display->id;
+          if ($display->handler->defaultable_sections($cid) && !$display->handler->is_default_display()) {
+            $override = ' overridden';
+          }
+        }
+        $left .= '<dd class="' . views_ui_item_css($display_id . '-' . $cid) . $override . '">' . $cdata . '</dd>';
       }
     }
   }
@@ -413,6 +395,55 @@ function views_ui_display_tab($view, &$display) {
   return array($display->display_title, $body);
 }
 
+/**
+ * Add information about a section to a display.
+ */
+function views_ui_add_info($type, $view, $display) {
+  $types = views_object_types();
+
+  $output = '';
+  $output .= 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'), 'html' => true));
+  $output .= 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'), 'html' => true));
+
+  $overridden = '';
+  if (!$display->handler->is_default_display() && empty($display->display_options['defaults'][$types[$type]['plural']])) {
+    $overridden = ' class="overridden"';
+  }
+
+  $title = l($types[$type]['title'], "admin/build/views/nojs/rearrange/$view->name/$display->id/$type", array('attributes' => array('class' => 'views-ajax-link')));
+
+  $output .= "<dt$overridden>" . $title . '</dt>';
+
+  $fields = '';
+  foreach ($display->handler->get_option($types[$type]['plural']) as $field) {
+    $handler = views_get_handler($field->table, $field->field, $type);
+    if (empty($handler)) {
+      $output .= t("Error: handler for @table > @field doesn't exist!", array('@table' => $field->table, '@field' => $field->field)) . '<br/>';
+      continue;
+    }
+    $handler->init($view, $field);
+
+    $f = t('@group: @title', array('@group' => $handler->definition['group'], '@title' => $handler->definition['title']));
+    $f = l($f, "admin/build/views/nojs/config-item/$view->name/$display->id/$type/$field->id", array('attributes' => array('class' => 'views-ajax-link')));
+
+    $fields .=  '<dd class="' . views_ui_item_css($display->id . '-' . $type . '-' . $field->id) . '">' . $f . ' ' . $handler->admin_summary() . '</dt>';
+
+    if ($handler->needs_style_plugin()) {
+      $style_plugin = views_fetch_plugin_data('style', $handler->data->style_plugin);
+      $style_title = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin['title'];
+
+      if (!empty($style_plugin['uses options'])) {
+        $fields .= l('<span>' . t('Settings') . '</span>', "admin/build/views/nojs/config-style/$view->name/$display->id/$type/$field->id", array('attributes' => array('class' => 'views-button-configure views-ajax-link'), 'html' => true));
+      }
+
+      $fields .= '<dd class="' . views_ui_item_css($display->id . '-' . $type . '-' . $field->id . '-style-plugin') . '">' . t(' &nbsp; Style: !style', array('!style' => l($style_title, "admin/build/views/nojs/change-style/$view->name/$display->id/$type/$field->id", array('attributes' => array('class' => 'views-ajax-link'))))) . '</dd>';
+    }
+  }
+
+  $output .= empty($fields) ? ('<dd>' . t('None defined.') . '</dd>') : $fields;
+  return $output;
+}
+
 function views_ui_regenerate_tabs($view, $display_id = NULL, $object = NULL) {
   if (empty($display_id)) {
     $displays = array_keys($view->display);
@@ -441,6 +472,11 @@ function views_ui_regenerate_tabs($view, $display_id = NULL, $object = NULL) {
     $object->replace['#views-tab-' . $id] = $body;
     $object->replace['#views-tab-title-' . $id] = $title;
   }
+
+  if ($view->changed) {
+    $object->changed = TRUE;
+  }
+
   views_ajax_render($object);
 }
 
@@ -449,7 +485,7 @@ function views_ui_regenerate_tabs($view, $display_id = NULL, $object = NULL) {
  * 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_id, $name = NULL) {
+function views_ui_standard_form_buttons(&$form, $form_id, $name = NULL, $third = NULL, $submit = NULL) {
   $form['buttons'] = array(
     '#prefix' => '<div class="clear-block"><div class="form-buttons">',
     '#suffix' => '</div></div>',
@@ -470,6 +506,19 @@ function views_ui_standard_form_buttons(&$form, $form_id, $name = NULL) {
     '#value' => t('Cancel'),
     '#submit' => array($cancel_submit),
   );
+
+  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' => t($third),
+      '#submit' => array($third_submit),
+    );
+  }
 }
 
 function views_ui_standard_cancel($form, &$form_state) {
@@ -644,6 +693,8 @@ function views_ui_edit_details($js, $view) {
  */
 function views_ui_edit_details_form(&$form_state, $view) {
   $form['#title'] = t('View details');
+  $form['#section'] = 'details';
+
   $form['description'] = array(
     '#type' => 'textfield',
     '#title' => t('View description'),
@@ -774,6 +825,8 @@ function views_ui_rearrange_type($js, $view, $display_id, $type) {
 function views_ui_rearrange_form(&$form_state, $view, $display_id, $type) {
   $types = views_object_types();
   $form['#title'] = t('Rearrange @type', array('@type' => $types[$type]['title']));
+  $form['#section'] = $display_id . 'rearrange-item';
+
   $types = views_object_types();
   if (!$view->set_display($display_id)) {
     views_ajax_render(t('Invalid display id'));
@@ -906,8 +959,9 @@ function views_ui_add_item($js, $view, $display_id, $type) {
     views_include('ajax');
     $form_state = views_ajax_form('views_ui_add_item_form', $view, $display_id, $type);
     // regenerate the tabset, set it to replace
+    $object = NULL;
     if (!empty($form_state['id'])) {
-      $object = views_render_ajax_form('views_ui_config_item_form', $form_state['view'], $display_id, $type, $form_state['id']);
+      $object = views_render_ajax_form('views_ui_config_item_form', $form_state['view'], $display_id, $type, $form_state['id'], TRUE);
       // This form is at a different URL than $_GET['q'] so we have to pass via the object.
       $object->url = url("admin/build/views/ajax/config-item/$view->name/$display_id/$type/$form_state[id]");
     }
@@ -926,6 +980,7 @@ function views_ui_add_item_form(&$form_state, $view, $display_id, $type) {
 
   $types = views_object_types();
   $form['#title'] = t('Add @type', array('@type' => $types[$type]['title']));
+  $form['#section'] = $display_id . 'add-item';
 
   $form_state['view'] = &$view;
   $form_state['display_id'] = $display_id;
@@ -940,14 +995,13 @@ function views_ui_add_item_form(&$form_state, $view, $display_id, $type) {
       '#type' => 'checkboxes',
       '#options' => $options,
     );
-
-    views_ui_standard_form_buttons($form, 'views_ui_add_item_form', t('Add'));
   }
   else {
     $form['markup'] = array(
-      '#value' => t('There are no @types available to add.', array('@types' =>  strtolower($types[$type]['title']))),
+      '#value' => '<div>' . t('There are no @types available to add.', array('@types' =>  strtolower($types[$type]['title']))) . '</div>',
     );
   }
+  views_ui_standard_form_buttons($form, 'views_ui_add_item_form', t('Add'));
 
   return $form;
 }
@@ -959,6 +1013,8 @@ function views_ui_add_item_form_submit($form, &$form_state) {
   $type = $form_state['type'];
   $types = views_object_types();
 
+  $form_state['view']->stack = array();
+
   // 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);
@@ -966,6 +1022,9 @@ function views_ui_add_item_form_submit($form, &$form_state) {
     if (empty($form_state['id'])) {
       $form_state['id'] = $id;
     }
+    else {
+      $form_state['view']->stack[] = $id;
+    }
   }
 
   // Store in cache
@@ -986,14 +1045,21 @@ function views_ui_config_item($js, $view, $display_id, $type, $id) {
     views_include('ajax');
     $form_state = views_ajax_form('views_ui_config_item_form', $view, $display_id, $type, $id);
     // regenerate the tabset, set it to replace
-    return views_ui_regenerate_tabs($form_state['view'], $display_id);
+    $object = NULL;
+    // If we're editing several in a row, go to the next one. Setting $stack to TRUE.
+    if (!empty($form_state['next'])) {
+      $object = views_render_ajax_form('views_ui_config_item_form', $form_state['view'], $display_id, $type, $form_state['next'], TRUE);
+      // This form is at a different URL than $_GET['q'] so we have to pass via the object.
+      $object->url = url("admin/build/views/ajax/config-item/$view->name/$display_id/$type/$form_state[next]");
+    }
+    return views_ui_regenerate_tabs($form_state['view'], $display_id, $object);
   }
 }
 
 /**
  * Form to config_item items in the views UI.
  */
-function views_ui_config_item_form(&$form_state, $view, $display_id, $type, $id) {
+function views_ui_config_item_form(&$form_state, $view, $display_id, $type, $id, $stack = FALSE) {
   $form = array('options' => array('#tree' => TRUE));
   if (!$view->set_display($display_id)) {
     views_ajax_render(t('Invalid display id'));
@@ -1008,8 +1074,11 @@ function views_ui_config_item_form(&$form_state, $view, $display_id, $type, $id)
     }
     $handler->init($view, $item);
     $types = views_object_types();
+
     $form['#title'] = t('Configure @type "@group: @title"', array('@type' => strtolower($types[$type]['stitle']), '@group' => $handler->definition['group'], '@title' => $handler->definition['title']));
 
+    $form['#section'] = $display_id . '-' . $type . '-' . $id;
+
     // Get form from the handler.
     $handler->options_form($form['options'], $form_state);
     $form_state['view'] = &$view;
@@ -1018,7 +1087,17 @@ function views_ui_config_item_form(&$form_state, $view, $display_id, $type, $id)
     $form_state['id'] = $id;
     $form_state['handler'] = &$handler;
 
-    views_ui_standard_form_buttons($form, 'views_ui_config_item_form');
+    // Set this hidden field so that when we come back, our stacking state
+    // will be retained.
+    $form['stack'] = array(
+      '#type' => 'hidden',
+      // default value means that what we receive in $_POST is more important.
+      '#default_value' => $stack,
+    );
+
+    $form_state['stack'] = $stack;
+
+    views_ui_standard_form_buttons($form, 'views_ui_config_item_form', NULL, t('Remove'), 'remove');
   }
   return $form;
 }
@@ -1031,6 +1110,24 @@ function views_ui_config_item_form_validate($form, &$form_state) {
 }
 
 /**
+ * Check to see if there is another config item on the 'stack' that should
+ * be displayed next.
+ */
+function views_ui_check_stack(&$form_state) {
+  if (!empty($form_state['view']->stack)) {
+    // If we came in through a 'stack' system, advance to the next.
+    if ($form_state['stack'] || $form_state['values']['stack']) {
+      $form_state['next'] = array_shift($form_state['view']->stack);
+    }
+    else {
+      // Otherwise, the user has clicked elsewhere and come back; our stack needs
+      // to be removed.
+      unset($form_state['view']->stack);
+    }
+  }
+}
+
+/**
  * Submit handler for configing new item(s) to a view.
  */
 function views_ui_config_item_form_submit($form, &$form_state) {
@@ -1046,12 +1143,29 @@ function views_ui_config_item_form_submit($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'], $item);
 
+  views_ui_check_stack($form_state);
+
   // Write to cache
   views_ui_cache_set($form_state['view']);
   $form_state['redirect'] = 'admin/build/views/edit/' . $form_state['view']->name;
 }
 
 /**
+ * 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);
+
+  views_ui_check_stack($form_state);
+
+  // Write to cache
+  views_ui_cache_set($form_state['view']);
+  $form_state['redirect'] = 'admin/build/views/edit/' . $form_state['view']->name;
+}
+
+
+/**
  * Page callback to change the summary style of an argument
  */
 function views_ui_change_style($js, $view, $display_id, $type, $id) {
@@ -1087,6 +1201,8 @@ function views_ui_change_style_form(&$form_state, $view, $display_id, $type, $id
     $types = views_object_types();
     $form['#title'] = t('Change summary style for @type "@group: @title"', array('@type' => strtolower($types[$type]['stitle']), '@group' => $handler->definition['group'], '@title' => $handler->definition['title']));
 
+    $form['#section'] = $display_id . '-' . $type . '-' . $id .'-style-plugin';
+
     $form['style_plugin'] =  array(
       '#type' => 'radios',
       '#options' => views_fetch_plugin_names('style', 'summary', TRUE),
@@ -1159,6 +1275,8 @@ function views_ui_config_style_form(&$form_state, $view, $display_id, $type, $id
     $types = views_object_types();
     $form['#title'] = t('Configure summary style for @type "@group: @title"', array('@type' => strtolower($types[$type]['stitle']), '@group' => $handler->definition['group'], '@title' => $handler->definition['title']));
 
+    $form['#section'] = $display_id . '-' . $type . '-style-options';
+
     $plugin = views_get_plugin('style', $item->style_plugin);
     if ($plugin) {
       $form['style_options'] = array(
@@ -1200,52 +1318,6 @@ function views_ui_config_style_form_submit($form, &$form_state) {
 }
 
 /**
- * Add information about a section to a display.
- */
-function views_ui_add_info($type, $view, $display) {
-  $types = views_object_types();
-
-  $output = '';
-  $output .= 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'), 'html' => true));
-  $output .= 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'), 'html' => true));
-
-
-  $output .= '<dt>' . $types[$type]['title'] . '</dt>';
-
-  $fields = '';
-  foreach ($display->handler->get_option($types[$type]['plural']) as $field) {
-    $handler = views_get_handler($field->table, $field->field, $type);
-    if (empty($handler)) {
-      $output .= t("Error: handler for @table > @field doesn't exist!", array('@table' => $field->table, '@field' => $field->field)) . '<br/>';
-      continue;
-    }
-    $handler->init($view, $field);
-
-    $f = t('@group: @title', array('@group' => $handler->definition['group'], '@title' => $handler->definition['title']));
-    $form = $form_state = array();
-    $handler->options_form($form, $form_state);
-    if (!empty($form)) {
-      $f = l($f, "admin/build/views/nojs/config-item/$view->name/$display->id/$type/$field->id", array('attributes' => array('class' => 'views-ajax-link')));
-    }
-    $fields .=  '<dd class="views-item-' . $type . '-' . $field->id . '">' . $f . ' ' . $handler->admin_summary() . '</dt>';
-
-    if ($handler->needs_style_plugin()) {
-      $style_plugin = views_fetch_plugin_data('style', $handler->data->style_plugin);
-      $style_title = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin['title'];
-
-      if (!empty($style_plugin['uses options'])) {
-        $fields .= l('<span>' . t('Settings') . '</span>', "admin/build/views/nojs/config-style/$view->name/$display->id/$type/$field->id", array('attributes' => array('class' => 'views-button-configure views-ajax-link'), 'html' => true));
-      }
-
-      $fields .= '<dd class="views-item-style-plugin">' . t(' &nbsp; Style: !style', array('!style' => l($style_title, "admin/build/views/nojs/change-style/$view->name/$display->id/$type/$field->id", array('attributes' => array('class' => 'views-ajax-link'))))) . '</dd>';
-    }
-  }
-
-  $output .= empty($fields) ? ('<dd>' . t('None defined.') . '</dd>') : $fields;
-  return $output;
-}
-
-/**
  * Get a list of roles in the system.
  */
 function views_ui_get_roles() {
@@ -1259,4 +1331,11 @@ function views_ui_get_roles() {
   }
 
   return $roles;
+}
+
+/**
+ * Get a css safe id for a particular section.
+ */
+function views_ui_item_css($item) {
+  return views_css_safe('views-item-' . $item);
 }
\ No newline at end of file
index 10f559b..2bc8ab3 100644 (file)
@@ -89,13 +89,17 @@ function views_ajax_form($form_id) {
   }
 
   // If the form wasn't submitted successfully, render the form.
-  $output = theme('status_messages');
-  $output .= drupal_render_form($form_id, $form);
-  $title = empty($form['#title']) ? '' : $form['#title'];
-  $url = empty($form['#url']) ? url($_GET['q'], array('absolute' => TRUE)) : $form['#url'];
-  $js = empty($form['#js']) ? NULL : $form['#js'];
+  $object = new stdClass();
+  $object->display = theme('status_messages');
+  $object->display .= drupal_render_form($form_id, $form);
+  $object->title = empty($form['#title']) ? '' : $form['#title'];
+  $object->url = empty($form['#url']) ? url($_GET['q'], array('absolute' => TRUE)) : $form['#url'];
+  $object->js = empty($form['#js']) ? NULL : $form['#js'];
+  if (!empty($form['#section'])) {
+    $object->hilite = '.' . views_ui_item_css($form['#section']);
+  }
 
-  views_ajax_render($output, $title, $url, $js);
+  views_ajax_render($object);
 }
 
 /**
@@ -133,6 +137,10 @@ function views_render_ajax_form($form_id) {
   $output->display .= drupal_render_form($form_id, $form);
   $output->title = empty($form['#title']) ? '' : $form['#title'];
   $output->url = empty($form['#url']) ? url($_GET['q'], array('absolute' => TRUE)) : $form['#url'];
+  if ($form['#section']) {
+    $output->hilite = '.' . views_ui_item_css($form['#section']);
+  }
+
   return $output;
 }
 
index 1447196..ff99a42 100644 (file)
@@ -401,6 +401,16 @@ class views_display_plugin extends views_object {
     }
     $form['#title'] = check_plain($this->display->display_title) . ': ';
 
+    // Set the 'section' to hilite on the form.
+    // If it's the item we're looking at is pulling from the default display,
+    // reflect that.
+    if (!empty($this->display->display_options['defaults'][$form_state['section']])) {
+      $form['#section'] = 'default-' . $form_state['section'];
+    }
+    else {
+      $form['#section'] = $this->display->id . '-' . $form_state['section'];
+    }
+
     switch ($form_state['section']) {
       case 'display_title':
         $form['#title'] .= t('The name of this display');
@@ -562,6 +572,11 @@ class views_display_plugin extends views_object {
           $plugin->options_validate($form[$form_state['section']], $form_state);
         }
         break;
+      case 'access':
+        $access = $form_state['values']['access'];
+        if ($access['type'] == 'role' && !array_filter($access['role'])) {
+          form_error($form, t('You must select at least one role if type is "by role"'));
+        }
     }
   }
 
@@ -577,6 +592,8 @@ class views_display_plugin extends views_object {
         break;
       case 'title':
       case 'access':
+        $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.
@@ -955,10 +972,15 @@ class views_display_plugin_block extends views_display_plugin {
    * but extended block handlers might be able to do interesting
    * stuff with it.
    */
-  function hook_block($op = 'list', $delta = 0, $edit = array()) {
+  function execute_hook_block($op = 'list', $delta = 0, $edit = array()) {
     if ($op == 'list') {
       $delta = $this->view->name . '-' . $this->display->id;
-      return array($delta => array('info' => $this->get_option('block_description')));
+      $desc = $this->get_option('block_description');
+
+      if (empty($desc)) {
+        $desc = $this->view->name;
+      }
+      return array($delta => array('info' => $desc));
     }
   }
 
@@ -1162,10 +1184,10 @@ class views_style_plugin_default extends views_style_plugin {
     // @todo: This needs to be able to support either a database resource OR
     // an array, because our input format doesn't actually have to be from
     // a query.
-    $rows = '';
+    $rows = array();
     while ($row = db_fetch_object($this->view->result)) {
       // @todo: Include separator as an option.
-      $rows .= $this->row_plugin->render($row);
+      $rows[] = $this->row_plugin->render($row);
     }
     return theme(array('views_view_unformatted__' . $this->view->name, 'views_view_unformatted'), $this->view, $this->options, $rows);
   }
@@ -1204,10 +1226,9 @@ class views_style_plugin_list extends views_style_plugin {
     // @todo: This needs to be able to support either a database resource OR
     // an array, because our input format doesn't actually have to be from
     // a query.
-    $rows = '';
+    $rows = array();
     while ($row = db_fetch_object($this->view->result)) {
-      // @todo: Include separator as an option.
-      $rows .= $this->row_plugin->render($row);
+      $rows[] = $this->row_plugin->render($row);
     }
     return theme(array('views_view_list__' . $this->view->name, 'views_view_list'), $this->view, $this->options, $rows);
   }
index 7dfcc00..83817db 100644 (file)
@@ -145,10 +145,21 @@ class view extends views_db_object {
    * @param $display_id
    *   The id of the display to mark as current.
    */
-  function set_display($display_id = 'default') {
+  function set_display($display_id = NULL) {
     // If we have not already initialized the display, do so. But be careful.
     if (empty($this->current_display)) {
       $this->init_display();
+
+      // If handlers were not initialized, and no argument was sent, set up
+      // to the default display.
+      if (empty($display_id)) {
+        $display_id = 'default';
+      }
+    }
+
+    // If no display id sent in and one wasn't chosen above, we're finished.
+    if (empty($display_id)) {
+      return TRUE;
     }
 
     // Ensure the requested display exists.
@@ -441,6 +452,24 @@ class view extends views_db_object {
   }
 
   /**
+   * Called to get hook_block information from the view and the
+   * named display handler.
+   */
+  function execute_hook_block($display_id = NULL) {
+    // Prepare the view with the information we have.
+
+    // This was probably already called, but it's good to be safe.
+    if (!$this->set_display($display_id)) {
+      return FALSE;
+    }
+
+    // Execute the view
+    if (isset($this->display_handler)) {
+      return $this->display_handler->execute_hook_block();
+    }
+  }
+
+  /**
    * Determine if the given user has access to the view. Note that
    * this sets the display handler if it hasn't been.
    */
@@ -958,7 +987,12 @@ class views_db_object {
 
     // Get the existing configuration
     $fields = $this->display[$display_id]->handler->get_option($types[$type]['plural']);
-    $fields[$id] = $item;
+    if (isset($item)) {
+      $fields[$id] = $item;
+    }
+    else {
+      unset($fields[$id]);
+    }
 
     // Store.
     $this->display[$display_id]->handler->set_option($types[$type]['plural'], $fields);
index 7592d5d..47451c1 100644 (file)
@@ -107,7 +107,15 @@ Drupal.Views.Ajax.ajaxResponse = function(data) {
       $('#views-tabset').clickTab(instance.$tabs.length);
     }
   }
+  
+  if (data.hilite) {
+    $('.hilited').removeClass('hilited');
+    $(data.hilite).addClass('hilited');
+  }
 
+  if (data.changed) {
+    $('div.views-basic-info').addClass('changed');
+  }
 }
 
 Drupal.behaviors.ViewsAjaxLinks = function() {
index 8cfedb9..65f1657 100644 (file)
@@ -166,7 +166,7 @@ function node_views_data() {
     'title' => t('Created year + month'),
     'help' => t('In the form of YYYYMM'),
     'argument' => array(
-      'handler' => 'views_handler_argument_date_year_month',
+      'handler' => 'views_handler_argument_node_created_year_month',
       'arguments' => array(), // this is required to make sure construct is called.
     ),
   );
@@ -175,7 +175,7 @@ function node_views_data() {
     'title' => t('Created year'),
     'help' => t('In the form of YYYY'),
     'argument' => array(
-      'handler' => 'views_handler_argument_date_year',
+      'handler' => 'views_handler_argument_node_created_year',
       'arguments' => array(), // this is required to make sure construct is called.
     ),
   );
@@ -184,7 +184,7 @@ function node_views_data() {
     'title' => t('Created month'),
     'help' => t('In the form of MM 01 - 12'),
     'argument' => array(
-      'handler' => 'views_handler_argument_date_month',
+      'handler' => 'views_handler_argument_node_created_month',
       'arguments' => array(), // this is required to make sure construct is called.
     ),
   );
@@ -356,7 +356,7 @@ class views_handler_argument_node_nid extends views_handler_argument {
 /**
  * Argument handler for a year (CCYY)
  */
-class views_handler_argument_node_date_year extends views_handler_argument_formula {
+class views_handler_argument_node_created_year extends views_handler_argument_formula {
   /**
    * Constructor implementation
    *
@@ -380,7 +380,7 @@ class views_handler_argument_node_date_year extends views_handler_argument_formu
 /**
  * Argument handler for a year plus month (CCYYMM)
  */
-class views_handler_argument_date_year_month extends views_handler_argument_formula {
+class views_handler_argument_node_created_year_month extends views_handler_argument_formula {
   /**
    * Constructor implementation
    */
@@ -409,7 +409,7 @@ class views_handler_argument_date_year_month extends views_handler_argument_form
 /**
  * Argument handler for a month (MM)
  */
-class views_handler_argument_date_month extends views_handler_argument_formula {
+class views_handler_argument_node_created_month extends views_handler_argument_formula {
   /**
    * Constructor implementation
    */
diff --git a/theme/views-ui-edit-view.tpl.php b/theme/views-ui-edit-view.tpl.php
new file mode 100644 (file)
index 0000000..f361190
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+// $Id$
+/**
+ * @file views-ui-edit-view.tpl.php
+ * Template for the primary view editing window.
+ */
+?>
+
+<div class="views-basic-info<?php if (!empty($view->changed)) { print " changed"; }?>">
+  <?php if (!is_numeric($view->vid)): ?>
+    <div class="view-changed view-new"><?php print t('New view'); ?></div>
+  <?php else: ?>
+    <div class="view-changed"><?php print t('Changed view'); ?></div>
+  <?php endif; ?>
+  <?php print t('View %name, displaying items of type <b>@base</b>.',
+      array('%name' => $view->name, '@base' => $base_table)); ?>
+</div>
+
+<?php print $tabs; ?>
+
+<div id="views-ajax-form">
+  <div id="views-ajax-title">
+    <?php // This is initially empty ?>
+  </div>
+  <div id="views-ajax-pad">
+    <?php /* This is sent in because it is also sent out through settings and
+    needs to be consistent. */ ?>
+    <?php print $message; ?>
+  </div>
+</div>
+
+<?php print $save_button ?>
diff --git a/theme/views-view-list.tpl.php b/theme/views-view-list.tpl.php
new file mode 100644 (file)
index 0000000..7897191
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+// $Id$
+/**
+ * @file views-view-list.tpl.php
+ * Default simple view template to display a list of rows.
+ *
+ * - $options['type'] will either be ul or ol.
+ * @ingroup views_templates
+ */
+?>
+<div class="item-list">
+  <<?php print $options['type']; ?>>
+    <?php foreach ($rows as $row): ?>
+      <li><?php print $row ?></li>
+    <?php endforeach; ?>
+  </<?php print $options['type']; ?>>
+</div>
\ No newline at end of file
index 0d481f1..4efe153 100644 (file)
@@ -7,4 +7,6 @@
  * @ingroup views_templates
  */
 ?>
-<?php print $rows ?>
\ No newline at end of file
+<?php foreach ($rows as $row): ?>
+  <?php print $row ?>
+<?php endforeach; ?>
\ No newline at end of file
index dc60796..6ea2dea 100644 (file)
@@ -30,7 +30,7 @@
   <?php endif; ?>
 
   <?php if ($rows): ?>
-    <div class="content">
+    <div class="view-content">
       <?php print $rows; ?>
     </div>
   <?php elseif ($empty): ?>
index 3c5abd0..74f9bd8 100644 (file)
@@ -141,12 +141,7 @@ function views_block($op = 'list', $delta = 0, $edit = array()) {
       list($name, $display_id) = explode('-', $delta);
       // Load the view
       if ($view = views_get_view($name)) {
-        if ($op == 'view') {
-          return $view->execute_display($display_id, $args);
-        }
-        else {
-          return $view->execute_hook_block($display_id, $op, $delta, $edit);
-        }
+        return $view->execute_display($display_id);
       }
       break;
   }
index 03be679..bbf39cd 100644 (file)
@@ -114,21 +114,25 @@ function views_ui_perm() {
 }
 
 function views_ui_theme() {
+  $path = drupal_get_path('module', 'views');
+  include_once "$path/includes/admin.inc";
+
   return array(
     'views_ui_edit_view' => array(
-      'arguments' => array('form'),
-      'file' => '/includes/admin.inc',
+      'arguments' => array('view' => NULL),
+      'template' => 'views-ui-edit-view',
+      'path' => "$path/theme",
     ),
     'views_ui_rearrange_form' => array(
-      'arguments' => array('form'),
+      'arguments' => array('form' => NULL),
       'file' => '/includes/admin.inc',
     ),
     'views_tabset' => array(
-      'arguments' => array('tabs'),
+      'arguments' => array('tabs' => NULL),
       'file' => '/includes/tabs.inc',
     ),
     'views_tab' => array(
-      'arguments' => array('body'),
+      'arguments' => array('body' => NULL),
       'file' => '/includes/tabs.inc',
     ),
   );