Index: INSTALL.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/INSTALL.txt,v
retrieving revision 1.10
diff -u -p -u -p -r1.10 INSTALL.txt
--- INSTALL.txt	11 Dec 2007 03:41:42 -0000	1.10
+++ INSTALL.txt	11 Oct 2008 03:48:13 -0000
@@ -97,5 +97,34 @@ the Drupal package and read the online d
    'current signups' view to restrict it to events that have not
    started yet.
 
+8. (Optional) Configure if and how you want a list of users signed up
+   for each node to appear.  Under the 'Advanced settings' at
+   admin/settings/signup, if the signup form and related information
+   is being displayed on the node itself or on a separate tab, you
+   will find a setting to control how you want the list of signed up
+   users to appear.  You can either use the built-in listing, no
+   listing at all, or if you have enabled the views module on your
+   site (see step #7 above), you can also embed a view for this.
 
-8. Start signing up!
+   There is a default view included called 'signup_user_list' which is
+   disabled by default.  If you enable this view to customize it at
+   all, you should be careful about two things:
+
+   A) Be sure to restrict access to this view to roles that have the
+      'view all signups' permission to avoid information disclosure.
+
+   B) If you continue to embed the view on the signup nodes, be sure
+      to disable the menu items for the view, so that you don't get a
+      duplicate tab with the same information.
+
+   Note that if you just use it in its default (disabled) form, it
+   will still work as an embedded view under the signup form, and you
+   do not need to worry about these two things.
+
+   Of course, instead of embedding the view under the signup form, you
+   can also disable the setting entirely, then enable the default
+   'signup_user_list' view to provide the information on a separate
+   tab or in a block.
+
+
+9. Start signing up!
Index: UPGRADE.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/UPGRADE.txt,v
retrieving revision 1.1
diff -u -p -u -p -r1.1 UPGRADE.txt
--- UPGRADE.txt	13 Oct 2007 23:24:36 -0000	1.1
+++ UPGRADE.txt	11 Oct 2008 03:48:13 -0000
@@ -7,6 +7,19 @@ this file when you download a new versio
 specific things you need to know about a certain upgrade.
 ======================================================================
 
+* Upgrading to 5.x-2.5 (from any earlier version)
+
+  The 5.x-2.5 release greatly improves themeability of this module, so
+be sure to search the code for "function theme_" to find all the
+things you can now override in your theme.
+
+  Furthermore, 5.x-2.5 adds new functionality regarding the list of
+users who have signed up for a given node.  There is now a default
+view for this listing (if your site is running the views module from
+http://drupal.org/project/views).  Furthermore, there are some new
+advanced settings to control if and where you want the list of signed
+up users to appear.  See the new step #8 in the INSTALL.txt file.
+
 
 * Upgrading to 5.x-2.3 (from any earlier version)
 
Index: signup.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/signup.module,v
retrieving revision 1.153
diff -u -p -u -p -r1.153 signup.module
--- signup.module	10 Oct 2008 20:17:11 -0000	1.153
+++ signup.module	11 Oct 2008 03:48:15 -0000
@@ -810,25 +810,62 @@ function _signup_node_output($node, $typ
     }
   }
 
-  // If the user has the view signups perm, display the current signups.
-  // Pull all users signed up for this event, and start table creation.
+  // How should the list of signed-up users be displayed, if at all?
+  $display_list = variable_get('signup_display_signup_user_list', 'signup');
+  
+  // If the user has the view signups perm and the admin decides to display
+  // the list at the bottom of the page, display the current signups.
   if (user_access('view all signups')) {
-    $registered_signups = db_query("SELECT u.uid, u.name, s.signup_time, s.form_data FROM {signup_log} s INNER JOIN {users} u ON u.uid = s.uid WHERE s.nid = %d AND u.uid <> 0", $node->nid);
-    $anon_signups = db_num_rows(db_query("SELECT anon_mail FROM {signup_log} WHERE nid = %d AND uid = 0", $node->nid));
-    $header = array(array('data' => t('!users signed up', array('!users' => format_plural((db_num_rows($registered_signups) + $anon_signups), '1 individual', '@count individuals')))));
-    $rows = array();
-    while ($signed_up_user = db_fetch_object($registered_signups)) {
-      $rows[] = array(theme('username', $signed_up_user));
+    if ($display_list == 'signup') {
+      // Admin wants the hard-coded signup listing.
+      $registered_query = db_query("SELECT u.uid, u.name, s.signup_time, s.form_data FROM {signup_log} s INNER JOIN {users} u ON u.uid = s.uid WHERE s.nid = %d AND u.uid <> 0", $node->nid);
+      $registered_signups = array();
+      while ($signed_up_user = db_fetch_object($registered_query)) {
+        $registered_signups[] = $signed_up_user;
+      }
+      $anon_query = db_query("SELECT * FROM {signup_log} WHERE nid = %d AND uid = 0", $node->nid);
+      $anon_signups = array();
+      while ($signed_up_user = db_fetch_object($anon_query)) {
+        $anon_signups[] = $signed_up_user;
+      }
+      $output .= theme('signup_user_list', $node, $registered_signups, $anon_signups);
     }
-    if ($anon_signups) {
-      $rows[] = array(t('!count anonymous', array('!count' => $anon_signups)));
+    elseif ($display_list == 'embed-view' && module_exists('views')) {
+      $view_name = variable_get('signup_user_list_view_name', 'signup_user_list');
+      $view_type = variable_get('signup_user_list_view_type', 'embed');
+      $view = views_get_view($view_name);
+      $args = array($node->nid);
+      $output .= views_build_view($view_type, $view, $args);
     }
-    $output .= theme('table', $header, $rows);
+    // Otherwise, they're on their own, and either don't want it displayed at
+    // all, or they want to handle where/how it's displayed via views.
   }
   return $output;
 }
 
 /**
+ * Formats the list of users signed up for a particular node.
+ *
+ * @param $node
+ *   The node object that users have signed up for.
+ * @param $registered_signups
+ *   Array of objects with data for each registered user signed up.
+ * @param $anon_signups
+ *   Array of objects with data for each anonymous user signed up.
+ */
+function theme_signup_user_list($node, $registered_signups, $anon_signups) {
+  $header = array(array('data' => t('!users signed up', array('!users' => format_plural((count($registered_signups) + count($anon_signups)), '1 individual', '@count individuals')))));
+  $rows = array();
+  foreach ($registered_signups as $signup) {
+    $rows[] = array(theme('username', $signup));
+  }
+  if (!empty($anon_signups)) {
+    $rows[] = array(t('!count anonymous', array('!count' => count($anon_signups))));
+  }
+  return theme('table', $header, $rows);
+}
+
+/**
  * Helper function that determines if a given node should have any
  * signup-related output.
  *
@@ -1278,16 +1315,102 @@ function signup_settings_page() {
     ),
     '#default_value' => variable_get('signup_form_location', 'node'),
     '#description' => t('On every signup-enabled node, users with permission to
- sign up will be presented with a form. Additionally, users the %view_signups permission will see a list of all users who have signed up. This setting controls where this information should be displayed: either directly on the node itself, or on a separate tab.', array('%view_signups' => t('view all signups'))),
-  );
+ sign up can be presented with a form and additional signup-related information. This setting controls where this information should be displayed: either directly on the node itself, on a separate tab, or not at all.'),
+    '#prefix' => '<div class="signup-form-location-radios">',
+    '#suffix' => '</div>',
+  );
+
+  // The rest of the advanced settings are conditional on if/where the signup
+  // form is being displayed.  We use jQuery to hide settings when they're not
+  // relevant.
+  drupal_add_js(SIGNUP_PATH . '/signup.settings.js');
+  drupal_add_css(SIGNUP_PATH . '/signup.css');
+
+  // For each setting that should be hidden, signup.css will hide all the
+  // settings on page load if.
+
+  $class = 'signup-fieldset_collapsed-setting';
+  if (variable_get('signup_form_location', 'node') != 'node') {
+    $class .= ' js-hide';
+  }
   $form['adv_settings']['signup_fieldset_collapsed'] = array(
     '#title' => t('Default fieldset behavior for per-node signup form'),
     '#type' => 'radios',
     '#options' => array(1 => t('Collapsed'), 0 => t('Expanded')),
     '#default_value' => variable_get('signup_fieldset_collapsed', 1),
     '#description' => t('If the signup form is included at the bottom of each node, the signup form will be encapsulated in a collapsible fieldset. This setting controls if that fieldset is expanded or collapsed by default.'),
+    '#prefix' => '<div class="' . $class . '">',
+    '#suffix' => '</div>'
   );
 
+  // If views.module is enabled provide the option to display the list 
+  // of signed-up users in a tab and/or at the bottom of the node.
+  $display_options = array();
+  $display_options['signup'] = t('Use the built-in listing');
+  $views_help_text = '';
+  if (module_exists('views')) {
+    $display_options['embed-view'] = t('Embed a view');
+    $views_help_text = t('If you choose to embed a view, you will be able to select which view you want to use below. The view you select will have a single argument passed in, the node id (nid) of the signup-enabled node being viewed. You can also use views to display this listing on its own tab or in a block if you disable this setting.');
+  }
+  else {
+    $views_help_text = t('If you enable the !views_url, you will be able to embed a view directly onto the page for this listing.', array('!views_url' => l(t('Views module'), 'http://drupal.org/project/views', array(), NULL, NULL, TRUE)));
+  }
+  $display_options['none'] = t('Do not display a listing at all');
+
+  $class = 'signup-display-signup-user-list-setting';
+  if (variable_get('signup_form_location', 'node') == 'none') {
+    $class .= ' js-hide';
+  }
+  $form['adv_settings']['signup_display_signup_user_list'] = array(
+    '#title' => t('How to display the list of signed-up users'),
+    '#type' => 'radios',
+    '#options' => $display_options,
+    '#default_value' => variable_get('signup_display_signup_user_list', 'signup'),
+    '#description' => t('If the signup form is being displayed, users with the %view_signups permission can see a list of all users who have signed up. This setting controls if and how that list should be generated. !views_help_text', array('%view_signups' => t('view all signups'), '!views_help_text' => $views_help_text)),
+    '#prefix' => '<div class="' . $class . '">',
+    '#suffix' => '</div>'
+  );
+ 
+  if (module_exists('views')) {
+    $class = 'signup-user-list-view-settings';
+    if (variable_get('signup_form_location', 'node') == 'none' || variable_get('signup_display_signup_user_list', 'signup') != 'embed-view') {
+      $class .= ' js-hide';
+    }
+    $form['adv_settings']['view_settings'] = array(
+      '#prefix' => '<div class="' . $class . '">',
+      '#suffix' => '</div>'
+    );
+
+    $views = array();
+    $result = db_query("SELECT name, description FROM {view_view}");
+    while ($view = db_fetch_object($result)) {
+      $views[$view->name] = check_plain($view->name . ': ' . $view->description);
+    }
+    views_load_cache();  // Necessary for _views_get_default_views().
+    $default_views = _views_get_default_views();
+    foreach ($default_views as $view) {
+      if (!$views[$view->name]) {
+        $views[$view->name] = check_plain($view->name . ': ' . $view->description);
+      }
+    }
+    $form['adv_settings']['view_settings']['signup_user_list_view_name'] = array(
+      '#title' => t('View to embed for the signup user list'),
+      '#type' => 'select',
+      '#options' => $views,
+      '#default_value' => variable_get('signup_user_list_view_name', 'signup_user_list'),
+      '#description' => t("If the signup user list is being generated by embedding a view, this selects which view should be used. NOTE: if you enable or customize the view being used for this, you should strongly consider disabling the view's menu items to prevent a duplicate tab showing the same information."),
+    );
+    $form['adv_settings']['view_settings']['signup_user_list_view_type'] = array(
+      '#title' => t('Type of view to embed for the signup user list'),
+      '#type' => 'radios',
+      '#options' => array(
+        'embed' => t('Page'),
+        'block' => t('Block'),
+      ),
+      '#default_value' => variable_get('signup_user_list_view_type', 'embed'),
+    );
+  }
+
   // Use our own submit handler, so we can do some processing before
   // we hand control to system_settings_form_submit.
   $form['#submit']['signup_settings_page_submit'] = array();
Index: signup_views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/signup_views.inc,v
retrieving revision 1.10
diff -u -p -u -p -r1.10 signup_views.inc
--- signup_views.inc	18 Sep 2008 17:47:45 -0000	1.10
+++ signup_views.inc	11 Oct 2008 03:48:16 -0000
@@ -528,5 +528,98 @@ print l(t("View signup schedule"), "user
   $view->requires = array(node, signup);
   $views[$view->name] = $view;
 
+  $view = new stdClass();
+  $view->name = 'signup_user_list';
+  $view->description = 'List all users signed up for a node';
+  $view->disabled = TRUE;
+  $view->access = array ();
+  $view->view_args_php = '';
+  $view->page = TRUE;
+  $view->page_title = '';
+  $view->page_header = '';
+  $view->page_header_format = '1';
+  $view->page_footer = '';
+  $view->page_footer_format = '1';
+  $view->page_empty = '';
+  $view->page_empty_format = '1';
+  $view->page_type = 'table';
+  $view->url = 'node/$signup/signup-list';
+  $view->use_pager = TRUE;
+  $view->nodes_per_page = '200';
+  $view->menu = TRUE;
+  $view->menu_title = 'Signup list';
+  $view->menu_tab = TRUE;
+  $view->menu_tab_weight = '0';
+  $view->menu_tab_default = FALSE;
+  $view->menu_tab_default_parent = NULL;
+  $view->menu_tab_default_parent_type = 'tab';
+  $view->menu_parent_tab_weight = '0';
+  $view->menu_parent_title = '';
+  $view->sort = array ();
+  $view->argument = array (
+    array (
+      'type' => 'nid',
+      'argdefault' => '1',
+      'title' => '%1',
+      'options' => '0',
+      'wildcard' => '',
+      'wildcard_substitution' => '',
+    ),
+  );
+  $view->field = array (
+    array (
+      'tablename' => 'signup_log',
+      'field' => 'uid',
+      'label' => 'Username',
+      'sortable' => '1',
+    ),
+    array (
+      'tablename' => 'signup_log',
+      'field' => 'signup_time',
+      'label' => 'Time signed up',
+      'handler' => 'views_handler_field_since',
+      'sortable' => '1',
+      'defaultsort' => 'DESC',
+    ),
+  );
+  $view->filter = array ();
+  $view->exposed_filter = array ();
+  $view->requires = array(signup_log);
+  $views[$view->name] = $view;
+
   return $views;
 }
+
+/**
+ * Implementation of hook_views_url_tokens().
+ */
+function signup_views_url_tokens() {
+  return array(
+    '$signup' => 'signup_url_node',
+  );
+}
+
+/**
+ * Views URL token handler for $signup that works for signup-enabled nodes.
+ *
+ * @param $token
+ *   Ignored.
+ * @param $argument
+ *   Ignored.
+ * @param $arg
+ *   The corresponding element of the URL that the token is holding.
+ *
+ * @return
+ *   TRUE if the path element this token represents is the node ID (nid) of a
+ *   signup-enabled node, otherwise FALSE.
+ */
+function signup_url_node($token, $argument, $arg) {
+  if (!is_numeric($arg)) {
+    return FALSE;
+  }
+  $node = node_load($arg);
+  if (!$node) {
+    return FALSE;
+  }
+  return $node->signup ? TRUE : FALSE;
+}
Index: signup.settings.js
===================================================================
RCS file: signup.settings.js
diff -N signup.settings.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ signup.settings.js	11 Oct 2008 03:48:16 -0000
@@ -0,0 +1,81 @@
+/* $Id: signup.js,v 1.3 2007/07/13 07:54:58 dww Exp $ */
+
+/**
+ * Conditionally show/hide settings based on the signup form location.
+ *
+ * If the signup form is being show on the node itself, it's wrapped
+ * in a fieldset and there's a setting to control if that fieldset
+ * should be collapsed.  Only show this setting if the form is going
+ * to be displayed on the node itself.
+ *
+ * Furthermore, if the signup form is being shown at all, we need to
+ * display the setting to control if/how the signup list is generated.
+ *
+ * Finally, we have to do some complicated logic to hide/show the
+ * views-related settings.  If the signup form is being shown at all,
+ * and the signup user list is being rendered by an embedded view,
+ * show the views settings, otherwise, hide them.
+ */
+Drupal.signupFormLocationSettingAutoAttach = function () {
+  $('div.signup-form-location-radios input.form-radio').click(function () {
+    // Simple part: Depending on the form location, hide/show the
+    // collapsible fieldset setting.
+    if (this.value == 'node') {
+      $('div.signup-fieldset_collapsed-setting').show();
+    }
+    else {
+      $('div.signup-fieldset_collapsed-setting').hide();
+    }
+
+    // Harder part: All the other settings that are inter-related.
+    if (this.value == 'none') {
+      // If the signup form is not used, hide everything else.
+      $('div.signup-display-signup-user-list-setting').hide();
+      $('div.signup-user-list-view-settings').hide();
+    }
+    else {
+      // Signup form is used, so show the user list setting.
+      $('div.signup-display-signup-user-list-setting').show();
+
+      // Now, see if the 'embed a view' radio is selected, and use
+      // that to show/hide all the view-related settings.
+      var embedView = false;
+      $('div.signup-display-signup-user-list-setting input.form-radio').each(function() {
+        if (this.value == 'embed-view' && this.checked) {
+          embedView = true;
+        }
+      });
+      if (embedView) {
+        $('div.signup-user-list-view-settings').show();
+      }
+      else {
+        $('div.signup-user-list-view-settings').hide();
+      }
+    }
+  });
+};
+
+/**
+ * Conditionally show/hide settings based on the signup user list setting.
+ *
+ * If the signup user list is going to be an embedded view, show the
+ * view-related settings, otherwise, hide them.
+ */
+Drupal.signupUserListSettingAutoAttach = function () {
+  $('div.signup-display-signup-user-list-setting input.form-radio').click(function () {
+    if (this.value == 'embed-view') {
+      $('div.signup-user-list-view-settings').show();
+    }
+    else {
+      $('div.signup-user-list-view-settings').hide();
+    }
+  });
+};
+
+// Global killswitch
+if (Drupal.jsEnabled) {
+  $(function() {
+    Drupal.signupFormLocationSettingAutoAttach();
+    Drupal.signupUserListSettingAutoAttach();
+  });
+}
