Index: modules/hs_views_taxonomy.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/modules/hs_views_taxonomy.module,v
retrieving revision 1.3
diff -u -F^f -r1.3 hs_views_taxonomy.module
--- modules/hs_views_taxonomy.module	18 May 2008 19:17:23 -0000	1.3
+++ modules/hs_views_taxonomy.module	18 May 2008 23:22:05 -0000
@@ -5,56 +5,33 @@
 //----------------------------------------------------------------------------
 // Core hooks.
 
+
 /**
- * Implementation of hook_requirements().
+ * Implementation of hook_menu().
  */
-function hs_views_taxonomy_requirements($phase) {
-  $requirements = array();
-
-  if ($phase == 'runtime') {
-    $pattern = <<<EOT
-function _views_build_filters_form(\$view) {
-  // When the form is retrieved through an AJAX callback, the cache hasn't
-  // been loaded yet. The cache is necesssary for _views_get_filters().
-  views_load_cache();
-EOT;
-    $views_with_patch_257004 = preg_match('#'. preg_quote($pattern) .'#m', file_get_contents(drupal_get_path('module', 'views') .'/views.module'));
-
-    if ($views_with_patch_257004) {
-      $value = t('The Views module is new enough.');
-      $description = '';
-      $severity = REQUIREMENT_OK;
-    }
-    else {
-      $value = t('The Views module is outdated.');
-      $description = t("The version of Views that you have installed is either
-        older than May 11, 2008, or doesn't have the obligatory patch applied.
-        Please apply the <a href=\"!patch_url\">patch</a> or update to a newer
-        version of the Views module!",
-        array('!patch_url' => 'http://drupal.org/files/issues/hs_compatibility.patch')
-      );
-      $severity = REQUIREMENT_ERROR;      
-    }
+function hs_views_taxonomy_menu($may_cache) {
+  $items = array();
 
-    $requirements['hs_views_taxonomy'] = array(
-      'title'       => t('Hierarchical Select Views Taxonomy'),
-      'value'       => $value,
-      'description' => $description,
-      'severity'    => $severity,
+  if (!$may_cache && arg(0) == 'admin' && arg(1) == 'build' && arg(2) == 'views' && is_string(arg(3)) && arg(4) == 'hs_config' && is_numeric(arg(5))) {
+    $view_name = arg(3);
+    $vid = arg(5); // Vocabulary ID, not View ID!
+
+    $items[] = array(
+      'path' => "admin/build/views/$view_name/hs_config/$vid",
+      'title' => t('Hierarchical Select configuration for !view', array('!view' => $view_name)),
+      'callback' => 'drupal_get_form',
+      'callback arguments' => array('hs_views_taxonomy_config_form', $view_name, $vid),
+      'access' => user_access('administer views'),
+      'type' => MENU_NORMAL_ITEM,
     );
   }
-
-  return $requirements;
+  return $items;
 }
 
-
-//----------------------------------------------------------------------------
-// Hierarchical Select hooks.
-
 /**
- * Implementation of hook_hierarchical_select_form_alter().
+ * Implementation of hook_form_alter().
  */
-function hs_views_taxonomy_hierarchical_select_form_alter($form_id, &$form) {
+function hs_views_taxonomy_form_alter($form_id, &$form) {
   // Change the exposed filters of Views. Only affects hierarchical vocabulary
   // filters.
   if (in_array($form_id, array('views_filters', 'views_filterblock'))) {
@@ -74,8 +51,13 @@ function hs_views_taxonomy_hierarchical_
           // Hierarchical Select only makes sense if there's a hierarchy.
           if ($vocabulary->hierarchy > 0) {
             // Make it use a hierarchical select.
+            require_once(drupal_get_path('module', 'hierarchical_select') .'/includes/common.inc');
+
+            unset($form["filter$id"]['#options']);
+            unset($form["filter$id"]['#theme']);
+
             $form["filter$id"]['#type'] = 'hierarchical_select';
-            $form["filter$id"]['#config'] = array(
+            $defaults_override = array(
               'module' => 'hs_views_taxonomy',
               'params' => array(
                 'vid' => $vid,
@@ -85,7 +67,7 @@ function hs_views_taxonomy_hierarchical_
               // This is a GET form, so also render the flat select.
               'render_flat_select' => 1,
             );
-            taxonomy_hierarchical_select_update_form_item($form["filter$id"], $vid);
+            hierarchical_select_common_config_apply($form["filter$id"], "views-taxonomy-$view->name-$vid", $defaults_override);
             
             // Inherit #config['dropbox']['status'] from the exposed filter
             // settings.
@@ -93,12 +75,8 @@ function hs_views_taxonomy_hierarchical_
             
             // Inherit #required from the exposed filter settings.
             $form["filter$id"]['#required'] = !((bool) $view->exposed_filter[$id]['optional']);
-          
-            // Remove the dropbox limit.
-            unset($form["filter$id"]['#config']['dropbox']['limit']);
 
             // Put the altered exposed filters in a separate table row.
-            require_once(drupal_get_path('module', 'hierarchical_select') .'/includes/common.inc');
             hierarchical_select_common_views_exposed_filters_reposition();
           }
         }
@@ -111,9 +89,143 @@ function hs_views_taxonomy_hierarchical_
       $form['copy_of_form_id'] = $form['form_id'] + array('#parents' => array('form_id'));
     }
   }
+
+  // Alter the edit view form: add a link to the Hierarchical Select
+  // configuration when appropriate.
+  if ($form_id == 'views_edit_view') {
+    foreach ($form['exposed_filter'] as $filter_id => $filter) {
+      if (is_numeric($filter_id)) {
+        $id = $form['exposed_filter'][$filter_id]['id']['#default_value'];
+        if (preg_match("/term_node_(\d+)\.tid/", $id, $matches)) {
+          $vid  = $matches[1];
+          if (variable_get("taxonomy_hierarchical_select_$vid", 0)) {
+            $view = $form['#parameters'][1];
+
+            $link = l(t('Configure Hierarchical Select'), "admin/build/views/$view->name/hs_config/$vid");
+            $form['exposed_filter'][$filter_id]['name']['#value'] .= '<br />'. $link;
+          }
+        }
+      }
+    }
+  }
 }
 
 /**
+ * Implementation of hook_requirements().
+ */
+function hs_views_taxonomy_requirements($phase) {
+  $requirements = array();
+
+  if ($phase == 'runtime') {
+    $pattern = <<<EOT
+function _views_build_filters_form(\$view) {
+  // When the form is retrieved through an AJAX callback, the cache hasn't
+  // been loaded yet. The cache is necesssary for _views_get_filters().
+  views_load_cache();
+EOT;
+    $views_with_patch_257004 = preg_match('#'. preg_quote($pattern) .'#m', file_get_contents(drupal_get_path('module', 'views') .'/views.module'));
+
+    if ($views_with_patch_257004) {
+      $value = t('The Views module is new enough.');
+      $description = '';
+      $severity = REQUIREMENT_OK;
+    }
+    else {
+      $value = t('The Views module is outdated.');
+      $description = t("The version of Views that you have installed is either
+        older than May 11, 2008, or doesn't have the obligatory patch applied.
+        Please apply the <a href=\"!patch_url\">patch</a> or update to a newer
+        version of the Views module!",
+        array('!patch_url' => 'http://drupal.org/files/issues/hs_compatibility.patch')
+      );
+      $severity = REQUIREMENT_ERROR;      
+    }
+
+    $requirements['hs_views_taxonomy'] = array(
+      'title'       => t('Hierarchical Select Views Taxonomy'),
+      'value'       => $value,
+      'description' => $description,
+      'severity'    => $severity,
+    );
+  }
+
+  return $requirements;
+}
+
+
+//----------------------------------------------------------------------------
+// Forms API callbacks.
+
+/**
+ * Form definition; configuration form for Hierarchical Select as the widget
+ * for a Taxonomy exposed filter.
+ *
+ * @param $view_name
+ *   Name of a view. Provides necessary context.
+ * @param $vid
+ *   A vocabulary id. Provides necessary context.
+ */
+function hs_views_taxonomy_config_form($view_name, $vid) {
+  // Find the exposed filter, we need this to set the default value of
+  // $config['dropbox']['status'].
+  $view = views_get_view($view_name);
+  foreach ($view->exposed_filter as $filter) {
+    if ($filter['id'] == "term_node_$vid.tid") {
+      $exposed_filter = $filter;
+      break;
+    }
+  }
+
+  // Add the Hierarchical Select config form.
+  $module = 'hs_views_taxonomy';
+  $params = array('vid' => $vid);
+  $config_id = "views-taxonomy-$view_name-$vid";
+  $vocabulary = taxonomy_get_vocabulary($vid);
+  $defaults = array(
+    // Enable the save_lineage setting by default if the multiple parents
+    // vocabulary option is enabled.
+    'save_lineage' => (int) ($vocabulary->hierarchy == 2),
+    'dropbox' => array(
+      'status' => !$exposed_filter['single'],
+    ),
+    'editability' => array(
+      'max_levels' => _taxonomy_hierarchical_select_get_depth($vid),
+    ),
+  );
+  $strings = array(
+    'hierarchy'   => t('vocabulary'),
+    'hierarchies' => t('vocabularies'),
+    'item'        => t('term'),
+    'items'       => t('terms'),
+    'item_type'   => t('term type'),
+  );
+  $max_hierarchy_depth = _taxonomy_hierarchical_select_get_depth($vid);
+  $form['hierarchical_select_config'] = hierarchical_select_common_config_form($module, $params, $config_id, $defaults, $strings, $max_hierarchy_depth);
+
+  $form['link'] = array(
+    '#value' => l('Back to the view configuration', "admin/build/views/$view_name/edit"),
+    '#prefix' => '<div class="hierarchical-select-config-back-link">',
+    '#suffix' => '</div>',
+    '#weight' => -5,
+  );
+  
+  $form['save'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save'),
+  );
+
+  // Add the the submit handler for the Hierarchical Select config form.
+  $parents = array('hierarchical_select_config');
+  $form['#submit']['hierarchical_select_common_config_form_submit'] = array($parents);
+  
+  return $form;
+}
+
+
+//----------------------------------------------------------------------------
+// Hierarchical Select hooks.
+
+/**
  * Implementation of hook_hierarchical_select_params().
  */
 function hs_views_taxonomy_hierarchical_select_params() {
@@ -155,7 +267,6 @@ function hs_views_taxonomy_hierarchical_
   return ($item == '**ALL**') ? '<'. t('all') .'>' : taxonomy_hierarchical_select_item_get_label($item, $params);
 }
 
-
 /**
  * Implementation of hook_hierarchical_select_create_item().
  */
@@ -168,9 +279,60 @@ function hs_views_taxonomy_hierarchical_
  */
 function hs_views_taxonomy_hierarchical_select_node_count($item, $params) {
   if ($item == '**ALL**') {
-    return db_result(db_query('SELECT COUNT(DISTINCT(nid)) FROM {term_node}'));
+    return db_result(db_query('SELECT COUNT(DISTINCT(t.nid)) FROM {term_node} t INNER JOIN {node} n ON t.nid = n.nid WHERE n.status = 1'));
   }
   else {
     return taxonomy_hierarchical_select_node_count($item, $params);
   }
 }
+
+/**
+ * Implementation of hook_hierarchical_select_config_info().
+ */
+function hs_views_taxonomy_hierarchical_select_config_info() {
+  static $config_info;
+
+  if (!isset($config_info)) {
+    $config_info = array();
+
+    views_load_cache();
+    $result = db_query("SELECT vid, name FROM {view_view} ORDER BY name");
+    while ($view = db_fetch_object($result)) {
+      $view = views_get_view($view->name);
+
+      foreach ($view->exposed_filter as $filter_id => $filter) {
+        $vid = _hs_views_taxonomy_parse_vocabulary_id_from_id($filter['id']);
+        if ($vid) {
+          $vocabulary = taxonomy_get_vocabulary($vid);
+
+          $config_id = "views-taxonomy-$view->name-$vid";
+          $config_info[$config_id] = array(
+            'config_id' => $config_id,
+            'hierarchy type' => t('Taxonomy'),
+            'hierarchy' => t($vocabulary->name),
+            'entity type' => t('view'),
+            'entity' => t($view->name),
+            'edit link' => "admin/build/views/$view->name/hs_config/$vid",
+          );
+        }
+      }
+    }
+  }
+
+  return  $config_info;
+}
+
+/**
+ * Given an id of the form "term_node_1.tid", with 1 the vid, get the vid.
+ *
+ * @return
+ *   When no valid id was given, FALSE, otherwise the vid.
+ */
+function _hs_views_taxonomy_parse_vocabulary_id_from_id($id) {
+  $vid = FALSE;
+
+  if (preg_match("/term_node_(\d+)\.tid/", $id, $matches)) {
+    $vid = $matches[1];
+  }
+  return $vid;
+}
