Index: includes/menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
retrieving revision 1.146
diff -u -p -r1.146 menu.inc
--- includes/menu.inc	14 Jan 2007 01:37:48 -0000	1.146
+++ includes/menu.inc	8 Mar 2007 23:33:20 -0000
@@ -83,6 +83,7 @@ define('MENU_CREATED_BY_ADMIN', 0x0040);
 define('MENU_IS_LOCAL_TASK', 0x0080);
 define('MENU_EXPANDED', 0x0100);
 define('MENU_LINKS_TO_PARENT', 0x0200);
+define('MENU_RESET', 0x0400);
 
 /**
  * @} End of "Menu flags".
@@ -1102,8 +1103,10 @@ function _menu_build() {
             unset($_menu['items'][$old_mid]);
             $_menu['path index'][$item->path] = $item->mid;
           }
-          // The new menu item gets all the custom type flags from the database
-          $_menu['items'][$item->mid]['type'] &= $item->type;
+          if (!($item->type & MENU_RESET)) {
+            // The new menu item gets all the custom type flags from the database
+            $_menu['items'][$item->mid]['type'] &= $item->type;
+          }
         }
         else {
           // It has a permanent ID. Only replace with non-custom menu items.
@@ -1127,8 +1130,16 @@ function _menu_build() {
         }
       }
 
-      // If the administrator has changed the item, reflect the change.
-      if ($item->type & MENU_MODIFIED_BY_ADMIN) {
+      if ($item->type & MENU_RESET) {
+        // Initialize the reset mids array if necessary
+        if (!isset($_menu['reset mids'])) {
+          $_menu['reset mids'] = array();
+        }
+        // Add our mid to the list of mids needing resaved in the database.
+        $_menu['reset mids'][] = $item->mid;
+      }
+      else if ($item->type & MENU_MODIFIED_BY_ADMIN) {
+        // If the administrator has changed the item, reflect the change.
         $_menu['items'][$item->mid]['title'] = $item->title;
         $_menu['items'][$item->mid]['description'] = $item->description;
         $_menu['items'][$item->mid]['pid'] = $item->pid;
@@ -1141,6 +1152,16 @@ function _menu_build() {
   // Associate parent and child menu items.
   _menu_find_parents($_menu['items']);
 
+  // Save any mids that were in the reset list.
+  if (isset($_menu['reset mids'])) {
+    foreach($_menu['reset mids'] as $mid) {
+      $t = $_menu['items'][$mid];
+      $t['mid'] = $mid;
+      menu_save_item($t);
+    }
+    unset($_menu['reset mids']);
+  }
+
   // Prepare to display trees to the user as required.
   _menu_build_visible_tree();
 }
Index: modules/menu/menu.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.module,v
retrieving revision 1.100
diff -u -p -r1.100 menu.module
--- modules/menu/menu.module	5 Jan 2007 19:05:54 -0000	1.100
+++ modules/menu/menu.module	8 Mar 2007 23:33:20 -0000
@@ -63,7 +63,7 @@ function menu_menu($may_cache) {
     $items[] = array('path' => 'admin/build/menu/item/reset',
       'title' => t('Reset menu item'),
       'callback' => 'drupal_get_form',
-      'callback arguments' => array('menu_reset_item'),
+      'callback arguments' => array('menu_item_reset_form'),
       'access' => user_access('administer menu'),
       'type' => MENU_CALLBACK);
     $items[] = array('path' => 'admin/build/menu/item/disable',
@@ -459,7 +459,7 @@ function menu_item_delete_form_submit($f
 /**
  * Menu callback; reset a single modified item.
  */
-function menu_reset_item($mid) {
+function menu_item_reset_form($mid) {
   if (isset($mid) && $title = db_result(db_query('SELECT title FROM {menu} WHERE mid = %d', $mid))) {
     $form['mid'] = array('#type' => 'value', '#value' => $mid);
     return confirm_form($form, t('Are you sure you want to reset the item %item to its default values?', array('%item' => $title)), 'admin/build/menu', t('Any customizations will be lost. This action cannot be undone.'), t('Reset'));
@@ -472,8 +472,8 @@ function menu_reset_item($mid) {
 /**
  * Process menu reset item form submissions.
  */
-function menu_reset_item_submit($form_id, $form_values) {
-  menu_delete_item($form_values['mid']);
+function menu_item_reset_form_submit($form_id, $form_values) {
+  menu_reset_item($form_values['mid']);
   drupal_set_message(t('The menu item was reset to its default settings.'));
 
   return 'admin/build/menu';
@@ -583,10 +583,46 @@ function menu_delete_item($item) {
   }
 
   if ($item['mid']) {
+    $pid = db_result(db_query('SELECT pid FROM {menu} WHERE mid = %d', $item['mid']));
     db_query('DELETE FROM {menu} WHERE mid = %d', $item['mid']);
+    // Reparent our former children to keep the tree consistent.
+    db_query('UPDATE {menu} SET pid = %d WHERE pid = %d', $pid, $item['mid']);
+  }
+  elseif ($item['path']) {
+    $result = db_query("SELECT mid FROM {menu} WHERE path = '%s'", $item['path']);
+    while ($row = db_fetch_array($result)) {
+      menu_delete_item($row);
+    }
+  }
+}
+
+/**
+ * Reset a modified menu item to default settings. If $item['mid'] is specified, then
+ * this is used to find the existing item; otherwise, $item['path'] is used.
+ * Note: This function was first available in Drupal 5.2 and Drupal 4.7.7. Prior versions
+ * use menu_delete_item() to perform resets.
+ *
+ * @param $item
+ *   The menu item to be reset.
+ */
+function menu_reset_item($item) {
+  if (!is_array($item)) {
+    $item = array('mid' => $item);
+  }
+
+  if ($item['mid']) {
+    $mid = $item['mid'];
+    // Add the MENU_RESET flag so the item gets reset the next pass through the table.
+    $item = menu_get_item($mid);
+    $item['mid'] = $mid;
+    $item['type'] |= MENU_RESET;
+    menu_save_item($item);
   }
   elseif ($item['path']) {
-    db_query("DELETE FROM {menu} WHERE path = '%s'", $item['path']);
+    $result = db_query("SELECT mid FROM {menu} WHERE path = '%s'", $item['path']);
+    while ($row = db_fetch_array($result)) {
+      menu_reset_item($row);
+    }
   }
 }
 
