Index: API.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/API.txt,v
retrieving revision 1.53
diff -u -F^f -r1.53 API.txt
--- API.txt	21 Sep 2008 22:25:44 -0000	1.53
+++ API.txt	23 Sep 2008 18:32:00 -0000
@@ -274,13 +274,17 @@ for the HS_DEVELOPER_MODE constant to TR
    Returns an array with the names of all parameters that are necessary for
    this implementation to work.
 
-2) hook_hierarchical_select_root_level($params);
+2) hook_hierarchical_select_root_level($params, $dropbox = FALSE);
    Returns the root level of the hierarchy: an array of (item, label) pairs.
+   The $dropbox parameter can is optional and can even ommitted, as it's only
+   necessary if you need the dropbox to influence your hierarchy.
 
-3) hook_hierarchical_select_children($parent, $params);
+3) hook_hierarchical_select_children($parent, $params, $dropbox = FALSE);
    Gets the children of $parent ($parent is an item in the hierarchy) and
    returns them: an array of (item, label) pairs, or the empty array if the
    given $parent has no children.
+   The $dropbox parameter can is optional and can even ommitted, as it's only
+   necessary if you need the dropbox to influence your hierarchy.
 
 4) hook_hierarchical_select_lineage($item, $params);
    Calculates the lineage of $item (array of items, with $item the last) and
Index: hierarchical_select.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/hierarchical_select.module,v
retrieving revision 1.135
diff -u -F^f -r1.135 hierarchical_select.module
--- hierarchical_select.module	21 Sep 2008 22:25:44 -0000	1.135
+++ hierarchical_select.module	23 Sep 2008 18:32:01 -0000
@@ -839,13 +839,13 @@ function _hierarchical_select_process_ca
   $db_selection = array(); // dropbox selection
 
   $config = $element['#config'];
-  $dropbox = (bool) $config['dropbox']['status'];
+  $has_dropbox = (bool) $config['dropbox']['status'];
   $op = $element['#post']['op'];
 
   if (empty($element['#post'])) {
     $value = (isset($element['#value'])) ? $element['#value'] : $element['#default_value'];
     $value = (is_array($value)) ? $value : array($value);
-    if ($dropbox) {
+    if ($has_dropbox) {
       $db_selection = $value;
     }
     else {
@@ -853,9 +853,10 @@ function _hierarchical_select_process_ca
     }
   }
   else {
-    if ($dropbox && $op == t('Add')) {
-      $hs_selection = _hierarchical_select_process_get_hs_selection($element);
+    if ($has_dropbox && $op == t('Add')) {
       $db_selection = _hierarchical_select_process_get_db_selection($element);
+      $dropbox = _hierarchical_select_dropbox_generate($config, $db_selection);
+      $hs_selection = _hierarchical_select_process_get_hs_selection($element, $dropbox);
 
       // Add $hs_selection to $db_selection (automatically filters to keep
       // only the unique ones).
@@ -886,7 +887,7 @@ function _hierarchical_select_process_ca
       // Ensure that this new item will not violate the max_levels and
       // allowed_levels settings.
       else if (
-        (count(module_invoke($config['module'], 'hierarchical_select_children', $parent, $config['params']))
+        (count(module_invoke($config['module'], 'hierarchical_select_children', $parent, $config['params'], FALSE))
           || $config['editability']['max_levels'] == 0
           || $depth < $config['editability']['max_levels']
         )
@@ -904,20 +905,24 @@ function _hierarchical_select_process_ca
         }
       }
 
-      $hs_selection = _hierarchical_select_process_get_hs_selection($element);
-      if ($dropbox) {
+      $dropbox = FALSE;
+      if ($has_dropbox) {
         $db_selection = _hierarchical_select_process_get_db_selection($element);
+        $dropbox = _hierarchical_select_dropbox_generate($config, $db_selection);
       }
+      $hs_selection = _hierarchical_select_process_get_hs_selection($element, $dropbox);      
     }
     else {
       // This handles the cases of:
       // - $op == t('Update')
       // - $op == t('Cancel') (used when creating a new item or a new level)
       // - any other submit button, e.g. the "Preview" button
-      $hs_selection = _hierarchical_select_process_get_hs_selection($element);
-      if ($dropbox) {
+      $dropbox = FALSE;
+      if ($has_dropbox) {
         $db_selection = _hierarchical_select_process_get_db_selection($element);
+        $dropbox = _hierarchical_select_dropbox_generate($config, $db_selection);
       }
+      $hs_selection = _hierarchical_select_process_get_hs_selection($element, $dropbox);
     }
   }
 
@@ -1119,7 +1124,7 @@ function _hierarchical_select_process_re
  */
 function _hierarchical_select_process_calculate_return_value($hierarchy, $dropbox = FALSE, $module, $params, $save_lineage) {
   if (!$dropbox) {
-    $return_value = _hierarchical_select_hierarchy_validate($hierarchy->lineage, $module, $params);
+    $return_value = _hierarchical_select_hierarchy_validate($hierarchy->lineage, $module, $params, $dropbox);
     // If the save_lineage setting is disabled, keep only the deepest item.
     if (!$save_lineage) {
       $return_value = (is_array($return_value)) ? end($return_value) : NULL;
@@ -1142,7 +1147,7 @@ function _hierarchical_select_process_ca
         // An entry in the dropbox when the save_lineage setting is enabled is
         // the entire generated lineage, if it's valid (i.e. if the user has
         // not tampered with it).
-        $lineage = _hierarchical_select_hierarchy_validate($selection, $module, $params);
+        $lineage = _hierarchical_select_hierarchy_validate($selection, $module, $params, $dropbox);
         $return_value = array_merge($return_value, $lineage);
       }
     }
@@ -1455,7 +1460,7 @@ function _hierarchical_select_hierarchy_
   // lexicography, rather than by hierarchy.
   if ($config['save_lineage'] && is_array($selection) && count($selection) >= 2) {
     // Ensure the item in the root level is the first item in the selection.
-    $root_level = array_keys(module_invoke($config['module'], 'hierarchical_select_root_level', $config['params']));
+    $root_level = array_keys(module_invoke($config['module'], 'hierarchical_select_root_level', $config['params'], $dropbox));
 
     for ($i = 0; $i < count($selection); $i++) {
       if (in_array($selection[$i], $root_level)) {
@@ -1467,7 +1472,7 @@ function _hierarchical_select_hierarchy_
     }
     // Reconstruct all sublevels.
     for ($i = 0; $i < count($selection); $i++) {
-      $children = array_keys(module_invoke($config['module'], 'hierarchical_select_children', $selection[$i], $config['params']));
+      $children = array_keys(module_invoke($config['module'], 'hierarchical_select_children', $selection[$i], $config['params'], $dropbox));
 
       // Ensure the next item in the selection is a child of the current item.
       for ($j = $i + 1; $j < count($selection); $j++) {
@@ -1479,7 +1484,7 @@ function _hierarchical_select_hierarchy_
   }
 
   // Validate the hierarchy.
-  $selection = _hierarchical_select_hierarchy_validate($selection, $config['module'], $config['params']);
+  $selection = _hierarchical_select_hierarchy_validate($selection, $config['module'], $config['params'], $dropbox);
 
   // When nothing is currently selected, set the root level to:
   // - "<none>" when:
@@ -1491,7 +1496,7 @@ function _hierarchical_select_hierarchy_
   //   enforce_deepest is enabled *and* the root level is not empty
   // - "label_0" (the root level label) in all other cases.
   if ($selection == -1) {
-    $root_level = module_invoke($config['module'], 'hierarchical_select_root_level', $config['params']);
+    $root_level = module_invoke($config['module'], 'hierarchical_select_root_level', $config['params'], $dropbox);
 
     $first_case  = $config['enforce_deepest'] && $config['level_labels']['status'] && !isset($config['level_labels']['labels'][0]);
     $second_case = $dropbox && count($dropbox->lineages) > 0;
@@ -1524,7 +1529,7 @@ function _hierarchical_select_hierarchy_
   // If enforce_deepest is enabled, ensure that the lineage goes as deep as
   // possible: append values of items that will be selected by default.
   if ($config['enforce_deepest'] && !in_array($hierarchy->lineage[0], array('none', 'label_0'))) {
-    $hierarchy->lineage = _hierarchical_select_hierarchy_enforce_deepest($hierarchy->lineage, $hierarchy->levels[0], $config['module'], $config['params']);
+    $hierarchy->lineage = _hierarchical_select_hierarchy_enforce_deepest($hierarchy->lineage, $hierarchy->levels[0], $config['module'], $config['params'], $dropbox);
   }
 
   $end_lineage = microtime();  
@@ -1537,7 +1542,7 @@ function _hierarchical_select_hierarchy_
   $start_levels = microtime();
 
   // 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] = module_invoke($config['module'], 'hierarchical_select_root_level', $config['params'], $dropbox);
 
   // Prepend a "<create new item>" option to the root level when:
   // - the editability setting is enabled, and
@@ -1570,7 +1575,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] = module_invoke($config['module'], 'hierarchical_select_children', $hierarchy->lineage[$depth - 1], $config['params'], $dropbox);
   }
 
   if ($config['enforce_deepest']) {
@@ -1624,7 +1629,7 @@ function _hierarchical_select_hierarchy_
     // Add one more level if appropriate.
     $parent = $hierarchy->lineage[$max_depth];
     if (module_invoke($config['module'], 'hierarchical_select_valid_item', $parent, $config['params'])) {
-      $children = module_invoke($config['module'], 'hierarchical_select_children', $parent, $config['params']);
+      $children = module_invoke($config['module'], 'hierarchical_select_children', $parent, $config['params'], $dropbox);
       if (count($children)) {
         // We're good, let's add one level!
         $depth = $max_depth + 1;
@@ -1701,7 +1706,7 @@ function _hierarchical_select_hierarchy_
 
   // Add child information.
   $start_childinfo = microtime();
-  $hierarchy = _hierarchical_select_hierarchy_add_childinfo($hierarchy, $config);
+  $hierarchy = _hierarchical_select_hierarchy_add_childinfo($hierarchy, $config, $dropbox);
   $end_childinfo = microtime();
 
   // Calculate the time it took to build the hierarchy object.
@@ -1724,14 +1729,16 @@ function _hierarchical_select_hierarchy_
  *   A config array with at least the following settings:
  *   - module
  *   - params
+ * @param $dropbox
+ *   A dropbox object. Necessary when the dropbox can influence the hierarchy.
  * @return
  *   An updated hierarchy object with the "childinfo" property set.
  */
-function _hierarchical_select_hierarchy_add_childinfo($hierarchy, $config) {
+function _hierarchical_select_hierarchy_add_childinfo($hierarchy, $config, $dropbox = FALSE) {
   foreach ($hierarchy->levels as $depth => $level) {
     foreach (array_keys($level) as $item) {
       if (!preg_match('/(none|label_\d+|create_new_item)/', $item)) {
-        $hierarchy->childinfo[$depth][$item] = count(module_invoke($config['module'], 'hierarchical_select_children', $item, $config['params']));
+        $hierarchy->childinfo[$depth][$item] = count(module_invoke($config['module'], 'hierarchical_select_children', $item, $config['params'], $dropbox));
       }
     }
   }
@@ -1751,10 +1758,12 @@ function _hierarchical_select_hierarchy_
  *   The module that should be used for HS hooks.
  * @param $params
  *   The module that should be passed to HS hooks.
+ * @param $dropbox
+ *   A dropbox object. Necessary when the dropbox can influence the hierarchy.
  * @return
  *   The updated selection.
  */
-function _hierarchical_select_hierarchy_validate($selection, $module, $params) {
+function _hierarchical_select_hierarchy_validate($selection, $module, $params, $dropbox) {
   $valid = TRUE;
   $selection_levels = count($selection);
   for ($i = 0; $i < $selection_levels; $i++) {
@@ -1765,7 +1774,7 @@ function _hierarchical_select_hierarchy_
       if ($i > 0) {
         $parent = $selection[$i - 1];
         $child = $selection[$i];
-        $children = array_keys(module_invoke($module, 'hierarchical_select_children', $parent, $params));
+        $children = array_keys(module_invoke($module, 'hierarchical_select_children', $parent, $params, $dropbox));
         $valid = $valid && in_array($child, $children);
       }
     }
@@ -1793,22 +1802,24 @@ function _hierarchical_select_hierarchy_
  *   The module that should be used for HS hooks.
  * @param $params
  *   The params that should be passed to HS hooks.
+ * @param $dropbox
+ *   A dropbox object. Necessary when the dropbox can influence the hierarchy.
  * @return
  *   The updated lineage.
  */
-function _hierarchical_select_hierarchy_enforce_deepest($lineage, $root_level, $module, $params) {
+function _hierarchical_select_hierarchy_enforce_deepest($lineage, $root_level, $module, $params, $dropbox) {
   // Use the deepest item as the first parent. Then apply this algorithm:
   // 1) get the parent's children, stop if no children
   // 2) choose the first child as the option that is selected by default, by
   //    adding it to the lineage of the hierarchy
   // 3) make this child the parent, go to step 1.
   $parent = end($lineage); // The last item in the lineage is the deepest one.
-  $children = module_invoke($module, 'hierarchical_select_children', $parent, $params);
+  $children = module_invoke($module, 'hierarchical_select_children', $parent, $params, $dropbox);
   while (count($children)) {
     $first_child = reset(array_keys($children));
     $lineage[] = $first_child;
     $parent = $first_child;
-    $children = module_invoke($module, 'hierarchical_select_children', $parent, $params);
+    $children = module_invoke($module, 'hierarchical_select_children', $parent, $params, $dropbox);
   }
 
   return $lineage;
@@ -1852,7 +1863,7 @@ function _hierarchical_select_dropbox_ge
     // Store the "save lineage" setting, needed in the rendering layer.
     $dropbox->save_lineage = $config['save_lineage'];
     if ($config['save_lineage']) {
-      $dropbox->lineages = _hierarchical_select_dropbox_reconstruct_lineages_save_lineage_enabled($config['module'], $selection, $config['params']);
+      $dropbox->lineages = _hierarchical_select_dropbox_reconstruct_lineages_save_lineage_enabled($config['module'], $selection, $config['params'], FALSE);
     }
     else {
       // Retrieve the lineage of each item.
@@ -1915,7 +1926,7 @@ function _hierarchical_select_dropbox_re
   // We have to reconstruct all lineages from the given set of selected items.
   // That means: we have to reconstruct every possible combination!
   $lineages = array();
-  $root_level = module_invoke($module, 'hierarchical_select_root_level', $params);
+  $root_level = module_invoke($module, 'hierarchical_select_root_level', $params, FALSE);
 
   foreach ($selection as $key => $item) {
     // Create new lineage if the item can be found in the root level.
@@ -1934,7 +1945,7 @@ function _hierarchical_select_dropbox_re
     // Try to improve every lineage. Make sure we don't iterate over
     // possibly new lineages.
     for ($id = 0; $id < $num; $id++) {
-      $children = module_invoke($module, 'hierarchical_select_children', $lineages[$id][$i]['value'], $params);
+      $children = module_invoke($module, 'hierarchical_select_children', $lineages[$id][$i]['value'], $params, FALSE);
 
       $child_added_to_lineage = FALSE;
       foreach (array_keys($children) as $child) {
