Index: modules/menu/menu.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.admin.inc,v
retrieving revision 1.24
diff -u -p -r1.24 menu.admin.inc
--- modules/menu/menu.admin.inc	8 Jan 2008 11:31:49 -0000	1.24
+++ modules/menu/menu.admin.inc	20 Jan 2008 01:00:00 -0000
@@ -21,24 +21,88 @@ function menu_overview_page() {
 }
 
 /**
- * Form for editing an entire menu tree at once.
+ * Similar to pager_query() but customized for menu links.
  *
- * Shows for one menu the menu items accessible to the current user and
- * relevant operations.
+ * This code will attempt to have between $lower_limit and $upper_limit links
+ * per page, but every page will display at least one top-level link (plid == 0)
+ * and all its children.
+ *
+ * @param $menu_name
+ *  The {menu_links}.menu_name whose links are to be paged.
+ * @param $lower_limit
+ *  The lower limit at which additional links will be displayed on another page.
+ * @param $upper_limit
+ *  A desired upper limit on the number of links per page.
+ * @param $element
+ *  Like page_query() is used to distinguish multiple pagers.
+ * @return
+ *  Returns a resource, typically for processing by menu_tree_data().
  */
-function menu_overview_form(&$form_state, $menu) {
+function menu_pager_query($menu_name, $lower_limit = 150, $upper_limit = 250, $element = 0) {
+  global $pager_page_array, $pager_total, $pager_total_items;
   global $menu_admin;
+  $page = isset($_GET['page']) ? $_GET['page'] : '';
+  $top_items = array();
+  $sql = "
+    SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, ml.*
+    FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path 
+    WHERE ml.menu_name = '%s' AND plid = 0 AND hidden >= %d
+    ORDER BY ml.mlid ASC";
+  $result_top = db_query($sql, $menu_name, 0);
+  // Use the menu functions so that the top-level links are sorted after being localized.
+  $tree = menu_tree_data($result_top);
+  $node_links = array();
+  menu_tree_collect_node_links($tree, $node_links);
+  // We indicate that a menu administrator is running the menu access check.
+  $menu_admin = TRUE;
+  menu_tree_check_access($tree, $node_links);
+  $menu_admin = FALSE;
+  // Count the number of links in each sub-tree of a top-level link.
+  foreach ($tree as $item) {
+    $top_items[$item['link']['mlid']] = db_result(db_query("SELECT COUNT(mlid) FROM {menu_links} WHERE p1 = %d", $item['link']['mlid']));
+  }
+  $page_parents = array();
+  $page_num = 0;
+  $sum = 0;
+  foreach($top_items as $mlid => $count) {
+    // Increment the page if we have enough items.
+    if (($sum > $lower_limit) || ($sum && ($sum + $count > $upper_limit))) {
+      $page_num++;
+      $sum = 0;
+    }
+    $page_parents[$page_num][] = $mlid;
+    $sum += $count;
+  }
+  // Convert comma-separated $page to an array, used by other functions.
+  $pager_page_array = explode(',', $page);
+
+  $pager_total_items[$element] = $page_num + 1;
+  $pager_total[$element] = $page_num + 1;
+  $pager_page_array[$element] = max(0, min((int)$pager_page_array[$element], ((int)$pager_total[$element]) - 1));
+  $page = $pager_page_array[$element];
+  
   $sql = "
     SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, ml.*
     FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path
-    WHERE ml.menu_name = '%s'
+    WHERE ml.menu_name = '%s' AND ml.hidden >= %d AND ml.p1 IN (". implode(',', $page_parents[$page]) .")
     ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC, p6 ASC, p7 ASC, p8 ASC, p9 ASC";
-  $sql_count = "SELECT COUNT(*) FROM {menu_links} ml WHERE menu_name = '%s'";
-  $result = pager_query($sql, 200, 0, $sql_count, $menu['menu_name']);
+
+  return db_query($sql, $menu_name, 0);
+}
+
+/**
+ * Form for editing an entire menu tree at once.
+ *
+ * Shows for one menu the menu items accessible to the current user and
+ * relevant operations.
+ */
+function menu_overview_form(&$form_state, $menu) {
+  global $menu_admin;
+  $result = menu_pager_query($menu['menu_name']);
   $tree = menu_tree_data($result);
   $node_links = array();
   menu_tree_collect_node_links($tree, $node_links);
-  // We indicate that a menu admintrator is running the menu access check.
+  // We indicate that a menu administrator is running the menu access check.
   $menu_admin = TRUE;
   menu_tree_check_access($tree, $node_links);
   $menu_admin = FALSE;
@@ -214,7 +278,7 @@ function theme_menu_overview_form($form)
   $output = '';
   if ($rows) {
     $output .= theme('table', $header, $rows, array('id' => 'menu-overview'));
-    $output .= theme('pager', NULL, 200, 0);
+    $output .= theme('pager', NULL, 1, 0);
   }
   $output .= drupal_render($form);
   return $output;
