Commit dc3ec4ee authored by merlinofchaos's avatar merlinofchaos

UI checkpoint checkin.

parent 9cb53fce
...@@ -38,41 +38,66 @@ ...@@ -38,41 +38,66 @@
margin-top: 0; margin-top: 0;
} }
.views-tabset .views-tab-area { .views-tabset .views-display {
border: 1px solid black; border: 1px solid black;
margin-left: 119px; /* 120 -1 causes borders to overlap */ margin-left: 119px; /* 120 -1 causes borders to overlap */
min-height: 300px; min-height: 300px;
_height: 300px; /* stupid IE hack */ _height: 300px; /* stupid IE hack */
} }
.views-tabset .views-display-deleted {
background-color: #eee;
}
.views-tabset .views-display .top {
padding: 2px 5px;
border-left: 1px solid black;
border-right: 1px solid black;
border-bottom: 2px solid black;
}
.views-tab-area .tab-section { .views-tabset .views-display .top .display-description {
margin-left: 1em;
font-style: italic;
overflow: hide;
white-space: nowrap;
}
.views-display .tab-section {
width: 33%; width: 33%;
padding: 0; padding: 0;
margin: 0; margin: 0;
float: left; float: left;
min-height: 300px; min-height: 273px;
_height: 300px; _height: 274px;
} }
.views-tab-area .tab-section .inside { .views-display .tab-section .inside {
margin: 0; margin: 0;
padding: 2px 5px; padding: 2px 5px;
} }
.views-tab-area .tab-section .links { .views-display .tab-section .links {
float: right; float: right;
} }
.views-tab-area .tab-section .links a { .views-display .tab-section .links a {
font-size: small; font-size: small;
} }
.views-tab-area .middle { .views-display .form-submit {
margin: 0;
}
.views-display #views-add-display-form {
float: right;
}
.views-display .middle {
width: 34%; width: 34%;
background-color: #ccc; background-color: #ccc;
} }
.views-tab-area dl { .views-display dl {
margin: 0; margin: 0;
} }
...@@ -99,3 +124,10 @@ ...@@ -99,3 +124,10 @@
float: right; float: right;
} }
#views-ajax-pad {
display: none;
}
html.js #views-ajax-pad {
display: block;
}
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Handles the server side AJAX interactions of Views. * Handles the server side AJAX interactions of Views.
* *
* @defgroup ajax * @defgroup ajax Views ajax library
* @{ * @{
*/ */
......
...@@ -13,23 +13,32 @@ function views_views_plugins() { ...@@ -13,23 +13,32 @@ function views_views_plugins() {
return array( return array(
'module' => 'views', // This just tells our themes are elsewhere. 'module' => 'views', // This just tells our themes are elsewhere.
'display' => array( 'display' => array(
'default' => array(
'title' => t('Defaults'),
'help' => t('Default settings for this view.'),
'handler' => 'views_display_plugin_default',
'no ui' => TRUE,
'no remove' => TRUE,
),
'page' => array( 'page' => array(
'title' => t('Page'), 'title' => t('Page'),
'help' => t('Creates a page with a URL, menu links, etc.'), 'help' => t('Display the view as a page, with a URL and menu links.'),
'handler' => 'views_display_plugin_page', 'handler' => 'views_display_plugin_page',
'uses_hook_menu' => TRUE, 'uses_hook_menu' => TRUE,
), ),
'block' => array( 'block' => array(
'title' => t('Block'), 'title' => t('Block'),
'help' => t('Creates a block that can be used from the block administration page.'), 'help' => t('Display the view as a block.'),
'handler' => 'views_display_plugin_block', 'handler' => 'views_display_plugin_block',
'uses_hook_block' => TRUE, 'uses_hook_block' => TRUE,
), ),
/*
'embed' => array( 'embed' => array(
'title' => t('Embedded'), 'title' => t('Embedded'),
'help' => t('Creates a view that is used from other code. By itself an embedded view does not do anything.'), 'help' => t('Creates a view that is used from other code. By itself an embedded view does not do anything.'),
'handler' => 'views_display_plugin', 'handler' => 'views_display_plugin',
), ),
*/
), ),
'style' => array( 'style' => array(
'default' => array( 'default' => array(
...@@ -132,10 +141,6 @@ function views_discover_plugins() { ...@@ -132,10 +141,6 @@ function views_discover_plugins() {
/** /**
* The default display plugin handler. Display plugins handle options and * The default display plugin handler. Display plugins handle options and
* basic mechanisms for different output methods. * basic mechanisms for different output methods.
*
* -- hook_menu
* -- hook_menu
* -- render_page
*/ */
class views_display_plugin extends views_object { class views_display_plugin extends views_object {
var $uses_hook_block = FALSE; var $uses_hook_block = FALSE;
...@@ -168,10 +173,40 @@ class views_display_plugin extends views_object { ...@@ -168,10 +173,40 @@ class views_display_plugin extends views_object {
} }
} }
/**
* Because forms may be split up into sections, this provides
* an easy URL to exactly the right section. Don't override this.
*/
function option_link($text, $section) {
return l($text, 'admin/build/views/nojs/display/' . $this->view->name . '/' . $this->display->id . '/' . $section, array('attributes' => array('class' => 'views-ajax-link')));
}
/**
* Provide the default summary for options in the views UI.
* The summary is part of a <dl> set, so be sure to put
* everything in <dt>/<dd> blocks.
*/
function options_summary() {
$output = '';
$output .= '<dt>' . t('Admin title: !title', array('!title' => $this->option_link($this->display->display_title, 'display_title'))) . '</dt>';
return $output;
}
/** /**
* Provide the default form for setting options. * Provide the default form for setting options.
*/ */
function options_form(&$form) { } function options_form(&$form, &$form_state) {
switch ($form_state['section']) {
case 'display_title':
$form['display_title'] = array(
'#type' => 'textfield',
'#title' => t('Display title'),
'#description' => t('This title will appear only in the administrative interface for the View.'),
'#default_value' => $this->display->display_title,
);
break;
}
}
/** /**
* Validate the options form. * Validate the options form.
...@@ -182,7 +217,13 @@ class views_display_plugin extends views_object { ...@@ -182,7 +217,13 @@ class views_display_plugin extends views_object {
* Perform any necessary changes to the form values prior to storage. * Perform any necessary changes to the form values prior to storage.
* There is no need for this function to actually store the data. * There is no need for this function to actually store the data.
*/ */
function options_submit($form, &$form_state) { } function options_submit($form, &$form_state) {
switch ($form_state['section']) {
case 'display_title':
$this->display->display_title = $form_state['values']['display_title'];
break;
}
}
/** /**
* Not all display plugins will support filtering * Not all display plugins will support filtering
...@@ -262,6 +303,44 @@ class views_display_plugin extends views_object { ...@@ -262,6 +303,44 @@ class views_display_plugin extends views_object {
function execute() { } function execute() { }
} }
/**
* A plugin to handle defaults on a view.
*/
class views_display_plugin_default extends views_display_plugin {
/**
* The default execute handler fully renders the view.
*
* For the simplest use:
* @code
* $output = $view->execute_display('default', $args);
* @endcode
*
* For more complex usages, a view can be partially built:
* @code
* $view->set_arguments($args);
* $view->build('default'); // Build the query
* $view->execute(); // Run the query
* $output = $view->render(); // Render the view
* @endcode
*
* If short circuited at any point, look in $view->build_info for
* information about the query. After execute, look in $view->result
* for the object returned from db_query.
*
* You can also do:
* @code
* $view->set_arguments($args);
* $output = $view->render('default'); // Render the view
* @endcode
*
* This illustrates that render is smart enough to call build and execute
* if these items have not already been accomplished.
*/
function execute() {
return $this->view->render();
}
}
/** /**
* The plugin that handles a full page. * The plugin that handles a full page.
*/ */
...@@ -329,7 +408,6 @@ class views_display_plugin_block extends views_display_plugin { ...@@ -329,7 +408,6 @@ class views_display_plugin_block extends views_display_plugin {
* The display block handler returns the structure necessary for a block. * The display block handler returns the structure necessary for a block.
*/ */
function execute() { function execute() {
drupal_set_page_view($this);
// Prior to this being called, the $view should already be set to this // Prior to this being called, the $view should already be set to this
// display, and arguments should be set on the view. // display, and arguments should be set on the view.
$info['content'] = $this->view->render(); $info['content'] = $this->view->render();
......
...@@ -92,7 +92,7 @@ function theme_views_tabset($tabs, $extra = NULL, $selected = NULL) { ...@@ -92,7 +92,7 @@ function theme_views_tabset($tabs, $extra = NULL, $selected = NULL) {
$tab_output = "<div class=\"views-tab-area\">\n"; $tab_output = "<div class=\"views-tab-area\">\n";
foreach ($tabs as $name => $tab) { foreach ($tabs as $name => $tab) {
$link_output .= '<li' . ($name == $selected ? ' class="active"': '') . '><a href="#views-tab-' . $tab->name . '">' . $tab->title . '</a></li>' . "\n"; $link_output .= '<li' . ($name == $selected ? ' class="active"': '') . '><a href="#views-tab-' . $tab->name . '" id="views-tab-title-' . $tab->name . '">' . check_plain($tab->title) . '</a></li>' . "\n";
$tab_output .= '<div id="views-tab-' . $tab->name . '" class="views-tab">' . $tab->render() . "</div>\n"; $tab_output .= '<div id="views-tab-' . $tab->name . '" class="views-tab">' . $tab->render() . "</div>\n";
} }
$link_output .= "</ul>\n"; $link_output .= "</ul>\n";
...@@ -109,15 +109,3 @@ function theme_views_tabset($tabs, $extra = NULL, $selected = NULL) { ...@@ -109,15 +109,3 @@ function theme_views_tabset($tabs, $extra = NULL, $selected = NULL) {
function theme_views_tab($body) { function theme_views_tab($body) {
return $body; return $body;
} }
function views_tabs_fieldsets($fieldsets = "") {
$tabset = new views_tabset;
foreach ($fieldsets as $fieldset) {
$title = $fieldset['#title'];
unset($fieldset['#title']);
$body = drupal_render($fieldset);
$name = preg_replace('/[^a-zA-Z0-9_]/', '_', $title);
$tabset->add(new views_tab($name, $title, $body));
}
return $tabset->render();
}
...@@ -53,10 +53,11 @@ class view extends views_db_object { ...@@ -53,10 +53,11 @@ class view extends views_db_object {
/** /**
* Returns the complete list of dependent objects in a view, including * Returns the complete list of dependent objects in a view, including
* the display which is often special. * the display which is often special and needs to be handled in a less
* generic manner.
* *
* @todo LG: special how? This needs to be doc'ed more. * Note: In PHP5 this should be static, but PHP4 doesn't support static
* @todo Convert all references to this method to be static, not dynamic. * methods.
*/ */
function objects_all() { function objects_all() {
return array('display', 'argument', 'field', 'sort', 'filter', 'relationship'); return array('display', 'argument', 'field', 'sort', 'filter', 'relationship');
...@@ -122,52 +123,43 @@ class view extends views_db_object { ...@@ -122,52 +123,43 @@ class view extends views_db_object {
} }
/** /**
* Set the display for this view, and initialize the display handler. * Set the display for this view and initialize the display handler.
*
* @todo Determine if this is meant to be called only once, and if so, document that.
*/ */
function set_display($display_id = NULL) { function init_display($display_id = 'default') {
// The default display is always the first one in the list. // The default display is always the first one in the list.
if (isset($this->current_display)) { if (isset($this->current_display)) {
return TRUE; return TRUE;
} }
$this->default_display = 0; if (empty($this->display[$display_id])) {
if (!isset($display_id)) { $display_id = 'default';
$this->current_display = 0; if (empty($this->display[$display_id])) {
} // @todo: Log an error here?
return FALSE;
foreach ($this->display as $id => $display) {
if ($display->id == $display_id) {
$this->current_display = $id;
} }
} }
// If the id was invalid, then just use the default display. $this->current_display = $display_id;
if (!isset($this->current_display)) {
$this->current_display = 0;
}
if (!isset($this->display[$this->current_display])) {
return FALSE;
}
// Fetch the display handler data and instantiate an object. // Fetch the display handler data and instantiate an object.
$display_data = $this->display[$this->current_display]; $display = &$this->display[$this->current_display];
$this->display_handler = views_get_plugin('display', $display_data->display_plugin); $display->handler = views_get_plugin('display', $display->display_plugin);
if (empty($this->display_handler)) { if (empty($display->handler)) {
return FALSE; return FALSE;
} }
// init the new display handler with data. // init the new display handler with data.
$this->display_handler->init($this, $display_data); $display->handler->init($this, $display);
// If this is NOT the default display handler, let it know which is // If this is NOT the default display handler, let it know which is
// since it may well utilize some data from the default. // since it may well utilize some data from the default.
if ($this->current_display != $this->default_display) { if ($this->current_display != 'default') {
$this->display_handler->default_display = $this->display[$this->default_display]; $display->handler->default_display = $this->display['default'];
} }
// Set a shortcut
$this->display_handler = &$display->handler;
return TRUE; return TRUE;
} }
...@@ -200,7 +192,7 @@ class view extends views_db_object { ...@@ -200,7 +192,7 @@ class view extends views_db_object {
return; return;
} }
if (!$this->set_display($display_id)) { if (!$this->init_display($display_id)) {
return FALSE; return FALSE;
} }
...@@ -245,7 +237,6 @@ class view extends views_db_object { ...@@ -245,7 +237,6 @@ class view extends views_db_object {
$argument_title = ''; $argument_title = '';
// build arguments. // build arguments.
foreach ($this->argument as $id => $arg) { foreach ($this->argument as $id => $arg) {
unset ($argument); // @todo: LG: Is this necessary, or is this because of the non-bug with reference reassignment?
$argument = &$this->argument[$id]; $argument = &$this->argument[$id];
if (!is_object($argument->handler)) { if (!is_object($argument->handler)) {
...@@ -400,12 +391,12 @@ class view extends views_db_object { ...@@ -400,12 +391,12 @@ class view extends views_db_object {
function execute_display($display_id = NULL, $args = array()) { function execute_display($display_id = NULL, $args = array()) {
// Prepare the view with the information we have. // Prepare the view with the information we have.
$this->set_arguments($args); $this->set_arguments($args);
$this->set_display($display_id); if (!$this->init_display($display_id)) {
return FALSE;
}
// Execute the view // Execute the view
if (isset($this->display_handler)) { return $this->display_handler->execute();
return $this->display_handler->execute();
}
} }
/** /**
...@@ -414,7 +405,11 @@ class view extends views_db_object { ...@@ -414,7 +405,11 @@ class view extends views_db_object {
*/ */
function execute_hook_menu($display_id = NULL) { function execute_hook_menu($display_id = NULL) {
// Prepare the view with the information we have. // Prepare the view with the information we have.
$this->set_display($display_id); // Wasn't this just done already in the menu hook in views_get_page_views()?
// This was probably already called, but it's good to be safe.
if (!$this->init_display($display_id)) {
return FALSE;
}
// Execute the view // Execute the view
if (isset($this->display_handler)) { if (isset($this->display_handler)) {
...@@ -427,7 +422,7 @@ class view extends views_db_object { ...@@ -427,7 +422,7 @@ class view extends views_db_object {
* this sets the display handler if it hasn't been. * this sets the display handler if it hasn't been.
*/ */
function access($account) { function access($account) {
if (empty($this->display_handler) && !$this->set_display()) { if (empty($this->display_handler) && !$this->init_display()) {
return FALSE; return FALSE;
} }
...@@ -537,7 +532,19 @@ class view extends views_db_object { ...@@ -537,7 +532,19 @@ class view extends views_db_object {
while ($data = db_fetch_object($result)) { while ($data = db_fetch_object($result)) {
$object = new $object_name(FALSE); $object = new $object_name(FALSE);
$object->load_row($data); $object->load_row($data);
array_push($views[$object->vid]->$key, $object);
// Because it can get complicated with this much indirection,
// make a shortcut reference.
$location = &$views[$object->vid]->$key;
// If we have a basic id field, load the item onto the view based on
// this ID, otherwise push it on.
if (!empty($object->id)) {
$location[$data->id] = $object;
}
else {
$location[] = $object;
}
} }
} }
return $views; return $views;
...@@ -821,23 +828,30 @@ class views_db_object { ...@@ -821,23 +828,30 @@ class views_db_object {
* can be easily located. * can be easily located.
*/ */
function add_display($type = 'page', $style = 'default') { function add_display($type = 'page', $style = 'default') {
// Get all existing IDs so we can feel confident that we have a unique if (empty($type)) {
// one for the new display. return FALSE;
foreach ($this->display as $d) { }
$ids[$d->id] = TRUE;
$plugin = views_fetch_plugin_data('display', $type);
if (empty($plugin)) {
return FALSE;
} }
$id = $type; $id = $type;
$title = $plugin['title'];
$count = 0; $count = 0;
// Loop through IDs based upon our style plugin name until // Loop through IDs based upon our style plugin name until
// we find one that is unused. // we find one that is unused.
while (!empty($ids[$id])) { while (!empty($this->display[$id])) {
$id = $type . '_' . ++$count; $id = $type . '_' . ++$count;
$title = $plugin['title'] . ' ' . $count;
} }
// Create the new display object // Create the new display object
$display = new views_display; $display = new views_display;
$display->display_title = $title;
$display->display_plugin = $type; $display->display_plugin = $type;
$display->style_plugin = $style; $display->style_plugin = $style;
$display->id = $id; $display->id = $id;
......
...@@ -128,7 +128,8 @@ Drupal.behaviors.ViewsAjaxLinks = function() { ...@@ -128,7 +128,8 @@ Drupal.behaviors.ViewsAjaxLinks = function() {
$('form.views-ajax-form:not(.views-processed)').addClass('views-processed').submit(function() { $('form.views-ajax-form:not(.views-processed)').addClass('views-processed').submit(function() {
// Translate the href on the link to the ajax href. That way this degrades // Translate the href on the link to the ajax href. That way this degrades
// into a nice, normal link. // into a nice, normal link.
var url = Drupal.settings.views.forms[$(this).attr('id')]; var url = $(this).attr('action');
url = url.replace('nojs', 'ajax');
$(this).ajaxSubmit({ $(this).ajaxSubmit({
url: url, url: url,
......
...@@ -82,19 +82,26 @@ function views_schema() { ...@@ -82,19 +82,26 @@ function views_schema() {
'description' => t('The view this display is attached to.'), 'description' => t('The view this display is attached to.'),
'no export' => TRUE, 'no export' => TRUE,
), ),
'display_plugin' => array( 'id' => array(
'type' => 'varchar', 'type' => 'varchar',
'length' => '64', 'length' => '64',
'default' => '', 'default' => '',
'not null' => TRUE, 'not null' => TRUE,
'description' => t('The type of the display. Usually page, block or embed, but is pluggable so may be other things.'), 'description' => t('An identifier for this display; usually generated from the display_plugin, so should be something like page or page_1 or block_2, etc.'),
), ),
'id' => array( 'display_title' => array(
'type' => 'varchar', 'type' => 'varchar',
'length' => '64', 'length' => '64',
'default' => '', 'default' => '',
'not null' => TRUE, 'not null' => TRUE,
'description' => t('An identifier for this display; usually generated from the display_plugin, so should be something like page or page_1 or block_2, etc.'), 'description' => t('The title of the display, viewable by the administrator.'),
),
'display_plugin' => array(
'type' => 'varchar',
'length' => '64',
'default' => '',
'not null' => TRUE,
'description' => t('The type of the display. Usually page, block or embed, but is pluggable so may be other things.'),
), ),
'access' => array( 'access' => array(
'type' => 'varchar', 'type' => 'varchar',
...@@ -115,7 +122,7 @@ function views_schema() { ...@@ -115,7 +122,7 @@ function views_schema() {
'length' => '255', 'length' => '255',
'default' => '', 'default' => '',
'not null' => TRUE, 'not null' => TRUE,
'description' => t('The title to use for this display.'), 'description' => t('The title of the view use for this display.'),
), ),
'header' => array( 'header' => array(
'type' => 'blob', 'type' => 'blob',
......
...@@ -178,7 +178,9 @@ function views_access($view, $account = NULL) { ...@@ -178,7 +178,9 @@ function views_access($view, $account = NULL) {
if (!$view) { if (!$view) {
return FALSE; return FALSE;
} }
$view->set_display($display_id); if (!$view->init_display($display_id)) {
return FALSE;
}
} }
if (is_string($view)) {