Index: API.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/API.txt,v
retrieving revision 1.56
diff -u -F^f -r1.56 API.txt
--- API.txt	1 Dec 2008 02:21:17 -0000	1.56
+++ API.txt	25 Jul 2009 10:24:58 -0000
@@ -14,6 +14,8 @@
          An example: in the case of taxonomy, this is the actual term.
 - item type: a per-level, human-readable name that describes what kind of
              items that level contains.
+- entity: an item is often associated with an entity. E.g. a term is usually
+          associated with a node.
 - form element: a form element allows the developer to assign a new value to
                 a #type property in a form item. Examples of form elements
                 supported by Drupal core are: select, checkboxes, textfield.
@@ -46,6 +48,7 @@
       'save_lineage'    => 0,
       'enforce_deepest' => 0,
       'entity_count'    => 0,
+      'require_entity'  => 0,
       'resizable'       => 1,
       'level_labels' => array(
         'status' => 0,
@@ -107,9 +110,13 @@
    selection will always be a single value.
 
  - entity_count (optional, defaults to 0)
-   Enables the display of entity (most of the time the entity type is 'node')
-   counts, between parentheses, for each item in the hierarchy.
+   Enables the display of entity counts, between parentheses, for each item in
+   the hierarchy.
 
+ - require_entity (optional, defaults to 0)
+   Whether an item should only be displayed if it has at least one associated
+   entity.
+ 
  - level_labels['status'] (optional, defaults to 0)
    Whether level labels should be enabled or not. When save_lineage is
    enabled, this will result in *empty* level labels.
@@ -323,9 +330,11 @@ for the HS_DEVELOPER_MODE constant to TR
 
 8) hook_hierarchical_select_entity_count($item, $params);
    Given a item, get the number of entities (most of the time the entity type
-   is 'node') that are related to the given item.
+   is 'node') that are related to the given item. Used for the entity_count
+   and require_entity settings.
    Optional hook. When this hook is not implemented, this functionality will
-   never be used, even when you configure it that way.
+   never be used, even when you configure it that way (i.e. when you enable
+   the entity_count and require_entity settings).
 
 9) hook_hierarchical_select_implementation_info();
    Return metadata about this implementation.
Index: README.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/README.txt,v
retrieving revision 1.35
diff -u -F^f -r1.35 README.txt
--- README.txt	18 Jul 2009 11:25:14 -0000	1.35
+++ README.txt	25 Jul 2009 10:24:58 -0000
@@ -168,6 +168,8 @@ function zen_views_filters($form) {
    Mr Bidster Inc.
 * Ability to create new items/levels:
    The Worx Company, http://www.worxco.com.
+* Ability to only show items that are associated with at least one entity:
+   Merge, http://merge.nl.
 
 
 Author
Index: hierarchical_select.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/hierarchical_select.admin.inc,v
retrieving revision 1.21
diff -u -F^f -r1.21 hierarchical_select.admin.inc
--- hierarchical_select.admin.inc	21 Mar 2009 20:07:46 -0000	1.21
+++ hierarchical_select.admin.inc	25 Jul 2009 10:24:58 -0000
@@ -251,6 +251,7 @@ function _hierarchical_select_create_exp
   $output .= "  'save_lineage'    => ". $config['save_lineage'] .",\n";
   $output .= "  'enforce_deepest' => ". $config['enforce_deepest'] .",\n";
   $output .= "  'entity_count'    => ". $config['entity_count'] .",\n";
+  $output .= "  'require_entity'  => ". $config['require_entity'] .",\n";
   $output .= "  'resizable'       => ". $config['resizable'] .",\n";
   $output .= "  'level_labels' => array(\n";
   $output .= "    'status' => ". $config['level_labels']['status'] .",\n";
Index: hierarchical_select.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/hierarchical_select.module,v
retrieving revision 1.161
diff -u -F^f -r1.161 hierarchical_select.module
--- hierarchical_select.module	6 Apr 2009 14:45:32 -0000	1.161
+++ hierarchical_select.module	25 Jul 2009 10:25:01 -0000
@@ -1591,6 +1591,7 @@ function _hierarchical_select_hierarchy_
 
   // Start building the levels, initialize with the root level.
   $hierarchy->levels[0] = module_invoke($config['module'], 'hierarchical_select_root_level', $config['params']);
+  $hierarchy->levels[0] = _hierarchical_select_apply_entity_settings($hierarchy->levels[0], $config);
 
   // Prepend a "<create new item>" option to the root level when:
   // - the editability setting is enabled, and
@@ -1625,6 +1626,7 @@ function _hierarchical_select_hierarchy_
   // Build all sublevels, based on the lineage.
   for ($depth = 1; $depth <= $max_depth; $depth++) {
     $hierarchy->levels[$depth] = module_invoke($config['module'], 'hierarchical_select_children', $hierarchy->lineage[$depth - 1], $config['params']);
+    $hierarchy->levels[$depth] = _hierarchical_select_apply_entity_settings($hierarchy->levels[$depth], $config);
   }
 
   if ($config['enforce_deepest']) {
@@ -1712,20 +1714,8 @@ function _hierarchical_select_hierarchy_
         $hierarchy->lineage[$depth] = 'label_'. $depth;
         $label = ($config['level_labels']['status']) ? t($config['level_labels']['labels'][$depth]) : '';
         $hierarchy->levels[$depth] = array('label_'. $depth => $label) + $hierarchy->levels[$depth] + $children;
-      }
-    }
-  }
 
-  // If the entity_count setting is enabled, add entity counts.
-  // NOTE: this is an optional hook, so we also check if it's implemented.
-  if ($config['entity_count'] && module_hook($config['module'], 'hierarchical_select_entity_count')) {
-    foreach (array_keys($hierarchy->levels) as $depth) {
-      foreach ($hierarchy->levels[$depth] as $value => $label) {
-        $is_valid_item = module_invoke($config['module'], 'hierarchical_select_valid_item', $value, $config['params']);
-        if ($is_valid_item) {
-          $entity_count = module_invoke($config['module'], 'hierarchical_select_entity_count', $value, $config['params']);
-          $hierarchy->levels[$depth][$value] = "$label ($entity_count)";
-        }
+        $hierarchy->levels[$depth] = _hierarchical_select_apply_entity_settings($hierarchy->levels[$depth], $config);
       }
     }
   }
@@ -1779,6 +1769,49 @@ function _hierarchical_select_hierarchy_
 }
 
 /**
+ * Given a level, apply the entity_count and require_entity settings.
+ *
+ * @param $level
+ *   A level in the hierarchy.
+ * @param $config
+ *   A config array with at least the following settings:
+ *   - module
+ *   - params
+ *   - entity_count
+ *   - require_entity
+ * @return
+ *   The updated level
+ */
+function _hierarchical_select_apply_entity_settings($level, $config) {
+  // Only do something when the entity_count or the require_entity (or both)
+  // settings are enabled.
+  // NOTE: this uses the optional "hierarchical_selectentity_count" hook, so
+  // we also check if it's implemented.
+  if (($config['entity_count'] || $config['require_entity']) && module_hook($config['module'], 'hierarchical_select_entity_count')) {
+    foreach ($level as $item => $label) {
+      // We don't want to alter special items.
+      if (!preg_match('/(none|label_\d+|create_new_item)/', $item)) {
+        $entity_count = module_invoke($config['module'], 'hierarchical_select_entity_count', $item, $config['params']);
+
+        // When the require_entity setting is enabled and the entity count is
+        // zero, then remove the item from the level.
+        // When the item is not removed from the level due to the above and
+        // the entity_count setting is enabled, update the label of the item
+        // to include the entity count.
+        if ($config['require_entity'] && $entity_count == 0) {
+          unset($level[$item]);
+        }
+        elseif ($config['entity_count']) {
+          $level[$item] = "$label ($entity_count)";
+        }
+      }
+    }
+  }
+
+  return $level;
+}
+
+/**
  * Extends a hierarchy object with child information: for each item in the
  * hierarchy, the child count will be retrieved and stored in the hierarchy
  * object, in the "childinfo" property. Items are grouped per level.
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/includes/common.inc,v
retrieving revision 1.23
diff -u -F^f -r1.23 common.inc
--- includes/common.inc	1 Dec 2008 02:21:17 -0000	1.23
+++ includes/common.inc	25 Jul 2009 10:25:01 -0000
@@ -25,6 +25,7 @@ function hierarchical_select_common_conf
     'save_lineage'    => 0,
     'enforce_deepest' => 0,
     'entity_count'    => 0,
+    'require_entity'  => 0,
     'resizable'       => 1,
     'level_labels' => array(
       'status' => 0,
@@ -98,6 +99,14 @@ function hierarchical_select_common_conf
   }
 
   $config = hierarchical_select_common_config_get($config_id, $defaults_override);
+  $args = array(
+    '!item' => $strings['item'],
+    '!items' => $strings['items'],
+    '!entity' => $strings['entity'],
+    '!entities' => $strings['entities'],
+    '!hierarchy' => $strings['hierarchy'],
+    '!hierarchies' => $strings['hierarchies']
+  );
 
   $form = array(
     '#tree' => TRUE,
@@ -135,14 +144,14 @@ function hierarchical_select_common_conf
     '#type' => 'radios',
     '#title' => t('Save lineage'),
     '#options' => array(
-      1 => t('Save !item lineage', array('!item' => $strings['item'])),
-      0 => t('Save only the deepest !item', array('!item' => $strings['item'])),
+      1 => t('Save !item lineage', $args),
+      0 => t('Save only the deepest !item', $args),
     ),
     '#default_value' => $config['save_lineage'],
     '#description' => t(
       'Saving the !item lineage means saving the <em>the !item itself and all
       its ancestors</em>.',
-      array('!item' => $strings['item'], '!hierarchy' => $strings['hierarchy'])
+      $args
     ),
   );
 
@@ -150,14 +159,14 @@ function hierarchical_select_common_conf
     '#type' => 'radios',
     '#title' => t('Level choice'),
     '#options' => array(
-      1 => t('Force the user to choose a !item from a <em>deepest level</em>', array('!item' => $strings['item'])),
-      0 => t('Allow the user to choose a !item from <em>any level</em>', array('!item' => $strings['item'])),
+      1 => t('Force the user to choose a !item from a <em>deepest level</em>', $args),
+      0 => t('Allow the user to choose a !item from <em>any level</em>', $args),
     ),
     '#default_value' => $config['enforce_deepest'],
     '#description' => t(
       'This setting determines from which level in the !hierarchy tree a
       user can select a !item.',
-      array('!item' => $strings['item'], '!hierarchy' => $strings['hierarchy'])
+      $args
     ),
     '#attributes' => array('class' => 'enforce-deepest'),
   );
@@ -165,11 +174,11 @@ function hierarchical_select_common_conf
   if (module_hook($module, 'hierarchical_select_entity_count')) {
     $form['entity_count'] = array(
       '#type' => 'radios',
-      '#title' => t('Display the !entity count', array('!entity' => $strings['entity'])),
+      '#title' => t('Display the !entity count', $args),
       '#description' => t(
         'When enabled, the user will see the number of !entities that match
         the current !item listed between brackets.',
-        array('!entities' => $strings['entities'], '!item' => $strings['item'])
+        $args
       ),
       '#options' => array(
         0 => t('Disabled'),
@@ -178,6 +187,23 @@ function hierarchical_select_common_conf
       '#default_value' => $config['entity_count'],
       '#attributes' => array('class' => 'entity-count'),
     );
+
+    $form['require_entity'] = array(
+      '#type' => 'radios',
+      '#title' => t('Require associated !entity', $args),
+      '#description' => t(
+        'When enabled, !items will only be displayed when they are associated
+        with at least one !entity, or if one of their child !items are
+        associated with at least one !entity.',
+        $args
+      ),
+      '#options' => array(
+        0 => t('Disabled'),
+        1 => t('Enabled'),
+      ),
+      '#default_value' => $config['require_entity'],
+      '#attributes' => array('class' => 'require-entity'),
+    );
   }
 
   $form['resizable'] = array(
@@ -207,7 +233,7 @@ function hierarchical_select_common_conf
       However, when the user is only allowed to choose a !item from the
       deepest level, then you can only enter a label for the <em>root</em>
       level.',
-      array('!item' => $strings['item'])
+      $args
     ),
     '#collapsible' => TRUE,
   );
@@ -258,7 +284,7 @@ function hierarchical_select_common_conf
       Note: the "Save !item lineage" option has no effect on this, even if
       a lineage consists of 3 !items, this will count as only one selection
       in the dropbox.',
-      array('!item' => $strings['item'], '!items' => $strings['items'])
+      $args
     ),
     '#size' => 5,
     '#maxlength' => 5,
@@ -287,13 +313,13 @@ function hierarchical_select_common_conf
       '#description' => t(
         'You can allow the user to <strong>add new !items to this
         !hierarchy</strong> <em>through</em> Hierarchical Select.',
-        array('!hierarchy' => $strings['hierarchy'], '!items' => $strings['items'])
+        $args
       ),
       '#collapsible' => TRUE,
     );
     $form['editability']['status'] = array(
       '#type' => 'checkbox',
-      '#title' => t('Allow creation of new !items', array('!items' => $strings['items'])),
+      '#title' => t('Allow creation of new !items', $args),
       '#options' => array(
         0 => t('Disabled'),
         1 => t('Enabled'),
@@ -323,7 +349,7 @@ function hierarchical_select_common_conf
       '#description' => t(
         'Allow the user to create child !items for !items that do not yet have
         children.',
-        array('!items' => $strings['items'])
+        $args
       ),
       '#attributes' => array('class' => 'editability-allow-new-levels'),
     );
@@ -337,7 +363,7 @@ function hierarchical_select_common_conf
       '#description' => t(
         'When the user is allowed to create new levels, this option prevents
         the user from creating extremely deep !hierarchies.',
-        array('!hierarchies' => $strings['hierarchies'])
+        $args
       ),
       '#attributes' => array('class' => 'editability-max-levels'),
     );
Index: tests/internals.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/tests/internals.test,v
retrieving revision 1.2
diff -u -F^f -r1.2 internals.test
--- tests/internals.test	21 Mar 2009 20:07:46 -0000	1.2
+++ tests/internals.test	25 Jul 2009 10:25:02 -0000
@@ -114,6 +114,7 @@
         'save_lineage'    => 0,
         'enforce_deepest' => 0,
         'entity_count'    => 0,
+        'require_entity'  => 0,
         'resizable'       => 1,
         'level_labels' => array(
           'status' => 0,
@@ -260,6 +261,7 @@
         'save_lineage'    => 0,
         'enforce_deepest' => 1,
         'entity_count'    => 0,
+        'require_entity'  => 0,
         'resizable'       => 1,
         'level_labels' => array(
           'status' => 0,
