Index: modules/menu/menu.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.admin.inc,v
retrieving revision 1.56
diff -u -p -r1.56 menu.admin.inc
--- modules/menu/menu.admin.inc	24 Aug 2009 01:49:41 -0000	1.56
+++ modules/menu/menu.admin.inc	31 Aug 2009 14:49:24 -0000
@@ -10,7 +10,7 @@
  * Menu callback which shows an overview page of all the custom menus and their descriptions.
  */
 function menu_overview_page() {
-  $result = db_query("SELECT * FROM {menu_custom} ORDER BY title", array(), array('fetch' => PDO::FETCH_ASSOC));
+  $result = db_query("SELECT * FROM {menu_custom} WHERE uid = 0 ORDER BY title", array(), array('fetch' => PDO::FETCH_ASSOC));
   $header = array(t('Title'), array('data' => t('Operations'), 'colspan' => '3'));
   $rows = array();
   foreach ($result as $menu) {
@@ -40,7 +40,7 @@ function theme_menu_admin_overview($titl
  * Shows for one menu the menu links accessible to the current user and
  * relevant operations.
  */
-function menu_overview_form(&$form_state, $menu) {
+function menu_overview_form(&$form_state, $menu, $advanced_mode = FALSE) {
   global $menu_admin;
   $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, m.description, ml.*
@@ -60,7 +60,8 @@ function menu_overview_form(&$form_state
   menu_tree_check_access($tree, $node_links);
   $menu_admin = FALSE;
 
-  $form = _menu_overview_tree_form($tree);
+  $form = _menu_overview_tree_form($tree, $advanced_mode);
+  $form['#advanced_mode'] = $advanced_mode;
   $form['#menu'] =  $menu;
   if (element_children($form)) {
     $form['submit'] = array(
@@ -77,7 +78,7 @@ function menu_overview_form(&$form_state
 /**
  * Recursive helper function for menu_overview_form().
  */
-function _menu_overview_tree_form($tree) {
+function _menu_overview_tree_form($tree, $advanced_mode = FALSE) {
   $form = &drupal_static(__FUNCTION__, array('#tree' => TRUE));
   foreach ($tree as $data) {
     $title = '';
@@ -89,11 +90,11 @@ function _menu_overview_tree_form($tree)
       $form[$mlid]['#attributes'] = $item['hidden'] ? array('class' => array('menu-disabled')) : array('class' => array('menu-enabled'));
       $form[$mlid]['title']['#markup'] = l($item['title'], $item['href'], $item['localized_options']) . ($item['hidden'] ? ' (' . t('disabled') . ')' : '');
       $form[$mlid]['hidden'] = array(
-        '#type' => 'checkbox',
+        '#type' => $advanced_mode ? 'checkbox' : 'value',
         '#default_value' => !$item['hidden'],
       );
       $form[$mlid]['expanded'] = array(
-        '#type' => 'checkbox',
+        '#type' => $advanced_mode ? 'checkbox' : 'value',
         '#default_value' => $item['expanded'],
       );
       $form[$mlid]['weight'] = array(
@@ -128,8 +129,9 @@ function _menu_overview_tree_form($tree)
       }
     }
 
-    if ($data['below']) {
-      _menu_overview_tree_form($data['below']);
+    // Only show the full menu tree if we are in advanced mode.
+    if ($advanced_mode && $data['below']) {
+      _menu_overview_tree_form($data['below'], $advanced_mode);
     }
   }
   return $form;
@@ -187,16 +189,18 @@ function menu_overview_form_submit($form
  * @ingroup themeable
  */
 function theme_menu_overview_form($form) {
-  drupal_add_tabledrag('menu-overview', 'match', 'parent', 'menu-plid', 'menu-plid', 'menu-mlid', TRUE, MENU_MAX_DEPTH - 1);
+  if ($form['#advanced_mode']) {
+    drupal_add_tabledrag('menu-overview', 'match', 'parent', 'menu-plid', 'menu-plid', 'menu-mlid', TRUE, MENU_MAX_DEPTH - 1);
+  }
   drupal_add_tabledrag('menu-overview', 'order', 'sibling', 'menu-weight');
 
-  $header = array(
-    t('Menu link'),
-    array('data' => t('Enabled'), 'class' => array('checkbox')),
-    array('data' => t('Show as expanded'), 'class' => array('checkbox')),
-    t('Weight'),
-    array('data' => t('Operations'), 'colspan' => '3'),
-  );
+  $header = array(t('Menu link'));
+  if ($form['#advanced_mode']) {
+    $header[] = array('data' => t('Enabled'), 'class' => array('checkbox'));
+    $header[] = array('data' => t('Show as expanded'), 'class' => array('checkbox'));
+  }
+  $header[] = t('Weight');
+  $header[] = array('data' => t('Operations'), 'colspan' => '3');
 
   $rows = array();
   foreach (element_children($form) as $mlid) {
@@ -221,8 +225,10 @@ function theme_menu_overview_form($form)
 
       $row = array();
       $row[] = theme('indentation', $element['#item']['depth'] - 1) . drupal_render($element['title']);
-      $row[] = array('data' => drupal_render($element['hidden']), 'class' => array('checkbox'));
-      $row[] = array('data' => drupal_render($element['expanded']), 'class' => array('checkbox'));
+      if ($form['#advanced_mode']) {
+        $row[] = array('data' => drupal_render($element['hidden']), 'class' => array('checkbox'));
+        $row[] = array('data' => drupal_render($element['expanded']), 'class' => array('checkbox'));
+      }
       $row[] = drupal_render($element['weight']) . drupal_render($element['plid']) . drupal_render($element['mlid']);
       $row = array_merge($row, $operations);
 
@@ -233,7 +239,7 @@ function theme_menu_overview_form($form)
   }
   $output = '';
   if (empty($rows)) {
-    $rows[] = array(array('data' => $form['#empty_text'], 'colspan' => '7'));
+    $rows[] = array(array('data' => $form['#empty_text'], 'colspan' => $form['#advanced_mode'] ? 7 : 5));
   }
   $output .= theme('table', $header, $rows, array('id' => 'menu-overview'));
   $output .= drupal_render_children($form);
Index: modules/menu/menu.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.install,v
retrieving revision 1.19
diff -u -p -r1.19 menu.install
--- modules/menu/menu.install	20 Jul 2009 18:51:33 -0000	1.19
+++ modules/menu/menu.install	31 Aug 2009 14:49:24 -0000
@@ -50,6 +50,19 @@ function menu_schema() {
         'default' => '',
         'description' => 'Primary Key: Unique key for menu. This is used as a block delta so length is 32.',
       ),
+      'uid' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'description' => 'The {users}.uid that this menu is specific to; if set to 0, then the menu is available to all users.',
+      ),
+      'parent_menu' => array(
+        'type' => 'varchar',
+        'length' => 32,
+        'not null' => TRUE,
+        'default' => '',
+        'description' => 'The name of the menu that this menu was cloned from, if there is one.',
+      ),
       'title' => array(
         'type' => 'varchar',
         'length' => 255,
@@ -63,9 +76,35 @@ function menu_schema() {
         'description' => 'Menu description.',
       ),
     ),
+    'indexes' => array(
+      'uid' => array('uid'),
+    ),
+    'foreign keys' => array(
+      'uid' => array('users' => 'uid'),
+    ),
     'primary key' => array('menu_name'),
   );
 
   return $schema;
 }
 
+/**
+ * @defgroup updates-6.x-to-7.x System updates from 6.x to 7.x
+ * @{
+ */
+
+/**
+ * Add columns to the {menu_custom} table to allow per-user menus.
+ */
+function menu_update_7000() {
+  $ret = array();
+  db_add_field($ret, 'menu_custom', 'uid', array('type' => 'int', 'not null' => TRUE, 'default' => 0));
+  db_add_field($ret, 'menu_custom', 'parent_menu', array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''));
+  db_add_index($ret, 'menu_custom', 'uid', array('uid'));
+  return $ret;
+}
+
+/**
+ * @} End of "defgroup updates-6.x-to-7.x"
+ * The next series of updates should start at 8000.
+ */
Index: modules/menu/menu.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.module,v
retrieving revision 1.201
diff -u -p -r1.201 menu.module
--- modules/menu/menu.module	29 Aug 2009 05:46:03 -0000	1.201
+++ modules/menu/menu.module	31 Aug 2009 14:49:24 -0000
@@ -84,7 +84,8 @@ function menu_menu() {
     'page arguments' => array('menu_overview_form', 3),
     'title callback' => 'menu_overview_title',
     'title arguments' => array(3),
-    'access arguments' => array('administer menu'),
+    'access callback' => '_menu_custom_menu_access',
+    'access arguments' => array(3),
     'type' => MENU_CALLBACK,
     'file' => 'menu.admin.inc',
   );
@@ -93,11 +94,26 @@ function menu_menu() {
     'weight' => -10,
     'type' => MENU_DEFAULT_LOCAL_TASK,
   );
-  $items['admin/structure/menu-customize/%menu/add'] = array(
+  $items['admin/structure/menu-customize/%menu/list/basic'] = array(
+    'title' => 'Basic',
+    'weight' => -10,
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+  );
+  $items['admin/structure/menu-customize/%menu/list/advanced'] = array(
+    'title' => 'Advanced',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('menu_overview_form', 3, TRUE),
+    'access callback' => '_menu_custom_menu_access',
+    'access arguments' => array(3),
+    'type' => MENU_LOCAL_TASK,
+    'file' => 'menu.admin.inc',
+  );
+  $items['admin/structure/menu-customize/%menu/list/add'] = array(
     'title' => 'Add link',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('menu_edit_item', 'add', NULL, 3),
-    'access arguments' => array('administer menu'),
+    'access callback' => '_menu_custom_menu_access',
+    'access arguments' => array(3),
     'type' => MENU_LOCAL_ACTION,
     'file' => 'menu.admin.inc',
   );
@@ -105,7 +121,8 @@ function menu_menu() {
     'title' => 'Edit menu',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('menu_edit_menu', 'edit', 3),
-    'access arguments' => array('administer menu'),
+    'access callback' => '_menu_custom_menu_access',
+    'access arguments' => array(3),
     'type' => MENU_LOCAL_TASK,
     'file' => 'menu.admin.inc',
   );
@@ -113,7 +130,8 @@ function menu_menu() {
     'title' => 'Delete menu',
     'page callback' => 'menu_delete_menu_page',
     'page arguments' => array(3),
-    'access arguments' => array('administer menu'),
+    'access callback' => '_menu_custom_menu_access',
+    'access arguments' => array(3),
     'type' => MENU_CALLBACK,
     'file' => 'menu.admin.inc',
   );
@@ -121,7 +139,8 @@ function menu_menu() {
     'title' => 'Edit menu link',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('menu_edit_item', 'edit', 4, NULL),
-    'access arguments' => array('administer menu'),
+    'access callback' => '_menu_custom_item_access',
+    'access arguments' => array(4),
     'type' => MENU_CALLBACK,
     'file' => 'menu.admin.inc',
   );
@@ -129,7 +148,8 @@ function menu_menu() {
     'title' => 'Reset menu link',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('menu_reset_item_confirm', 4),
-    'access arguments' => array('administer menu'),
+    'access callback' => '_menu_custom_item_access',
+    'access arguments' => array(4),
     'type' => MENU_CALLBACK,
     'file' => 'menu.admin.inc',
   );
@@ -137,7 +157,8 @@ function menu_menu() {
     'title' => 'Delete menu link',
     'page callback' => 'menu_item_delete_page',
     'page arguments' => array(4),
-    'access arguments' => array('administer menu'),
+    'access callback' => '_menu_custom_item_access',
+    'access arguments' => array(4),
     'type' => MENU_CALLBACK,
     'file' => 'menu.admin.inc',
   );
@@ -145,6 +166,30 @@ function menu_menu() {
 }
 
 /**
+ * Access callback for custom menus.
+ */
+function _menu_custom_menu_access($menu) {
+  global $user;
+  // Only menu administrators and the owner of the menu can access it.
+  return user_access('administer menu') || (!empty($menu['uid']) && $menu['uid'] == $user->uid);
+}
+
+/**
+ * Access callback for custom menu links.
+ */
+function _menu_custom_item_access($menu_link) {
+  global $user;
+  // Menu administrators can access all links.
+  if (user_access('administer menu')) {
+    return TRUE;
+  }
+  // Otherwise, only the owner of the menu that the link belongs to can access
+  // it.
+  $menu = menu_load($menu_link['menu_name']);
+  return !empty($menu['uid']) && $menu['uid'] == $user->uid;
+}
+
+/**
  * Implement hook_theme().
  */
 function menu_theme() {
@@ -170,7 +215,7 @@ function menu_enable() {
   $base_link = db_query("SELECT mlid AS plid, menu_name FROM {menu_links} WHERE link_path = 'admin/structure/menu' AND module = 'system'")->fetchAssoc();
   $base_link['router_path'] = 'admin/structure/menu-customize/%';
   $base_link['module'] = 'menu';
-  $result = db_query("SELECT * FROM {menu_custom}", array(), array('fetch' => PDO::FETCH_ASSOC));
+  $result = db_query("SELECT * FROM {menu_custom} WHERE uid = 0", array(), array('fetch' => PDO::FETCH_ASSOC));
   foreach ($result as $menu) {
     // $link is passed by reference to menu_link_save(), so we make a copy of $base_link.
     $link = $base_link;
@@ -204,6 +249,76 @@ function menu_load($menu_name) {
 }
 
 /**
+ * Clone a menu for the provided user account, if one doesn't already exist.
+ */
+function menu_clone_menu($menu, $account) {
+  if (!empty($account->uid) && $account->uid != $menu['uid']) {
+    // Clone the menu.
+    $original_name = $menu['menu_name'];
+    $menu['menu_name'] = menu_get_unique_name($original_name);
+    $menu['parent_menu'] = $original_name;
+    $menu['uid'] = $account->uid;
+    drupal_write_record('menu_custom', $menu);
+    // Clone each menu link.
+    $menu_links = db_query("SELECT * FROM {menu_links} WHERE menu_name = :menu", array(':menu' => $original_name))->fetchAll(PDO::FETCH_ASSOC);
+    foreach ($menu_links as $menu_link) {
+      unset($menu_link['mlid']);
+      $menu_link['menu_name'] = $menu['menu_name'];
+      $menu_link['options'] = unserialize($menu_link['options']);
+      menu_link_save($menu_link);
+    }
+  }
+  return $menu;
+}
+
+/**
+ * Returns a unique, machine-readable menu name, based on the provided name.
+ */
+function menu_get_unique_name($menu_name) {
+  $candidate_name = $menu_name;
+  while ($existing_name = db_query('SELECT menu_name FROM {menu_custom} WHERE menu_name = :menu', array(':menu' => $candidate_name))->fetchField()) {
+    // When the menu name doesn't validate, try adding a numerical index to
+    // make it unique.
+    $index = empty($index) ? 1 : $index + 1;
+    // Make sure to keep the menu name under the maximum length.
+    $candidate_name = substr($menu_name, 0, 32 - strlen((string)$index)) . $index;
+  }
+  return $candidate_name;
+}
+
+/**
+ * Returns the name of the user-customized version of a menu, or the original
+ * menu if it has not been customized.
+ */
+function menu_get_user_menu_name($menu_name, $account = NULL) {
+  global $user;
+  if (!isset($account)) {
+    $account = $user;
+  }
+  $customized_menu_name = menu_check_user_menu_name($menu_name, $account);
+  return $customized_menu_name === FALSE ? $menu_name : $customized_menu_name;
+}
+
+/**
+ * Returns the name of the user-customized version of a menu, or FALSE if there
+ * is none.
+ */
+function menu_check_user_menu_name($menu_name, $account = NULL) {
+  global $user;
+  if (!isset($account)) {
+    $account = $user;
+  }
+  // Only logged-in users can have a customized menu.
+  if (!empty($account->uid)) {
+    $customized_menu = db_query('SELECT menu_name FROM {menu_custom} WHERE uid = :uid AND parent_menu = :menu', array(':uid' => $account->uid, ':menu' => $menu_name))->fetchField();
+    if (!empty($customized_menu)) {
+      return $customized_menu;
+    }
+  }
+  return FALSE;
+}
+
+/**
  * Return a list of menu items that are valid possible parents for the given menu item.
  *
  * @param $menus
@@ -477,21 +592,27 @@ function menu_node_form_submit($form, &$
 /**
  * Return an associative array of the custom menus names.
  *
- * @param $all
+ * @param $include_system_menus
  *   If FALSE return only user-added menus, or if TRUE also include
  *   the menus defined by the system.
+ * @param $include_user_specific_menus
+ *   If FALSE return only site-wide menus that are not associated with a
+ *   particular user, or if TRUE also include the user-specific menus.
  * @return
  *   An array with the machine-readable names as the keys, and human-readable
  *   titles as the values.
  */
-function menu_get_menus($all = TRUE) {
+function menu_get_menus($include_system_menus = TRUE, $include_user_specific_menus = FALSE) {
   $system_menus = array_keys(menu_list_system_menus());
   $query = db_select('menu_custom');
   $query->addField('menu_custom', 'menu_name', 'menu_name');
   $query->addField('menu_custom', 'title', 'title');
-  if (!$all) {
+  if (!$include_system_menus) {
     $query->condition('menu_name', $system_menus, 'NOT IN');
   }
+  if (!$include_user_specific_menus) {
+    $query->condition('uid', 0);
+  }
   $query->orderBy('title');
 
   return $query->execute()->fetchAllKeyed();
Index: modules/toolbar/toolbar.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.css,v
retrieving revision 1.2
diff -u -p -r1.2 toolbar.css
--- modules/toolbar/toolbar.css	29 Jul 2009 12:28:41 -0000	1.2
+++ modules/toolbar/toolbar.css	31 Aug 2009 14:49:24 -0000
@@ -161,6 +161,49 @@ div#toolbar div.toolbar-shortcuts span.i
   -webkit-border-radius: 5px;
 }
 
+div#toolbar a#toolbar-customize {
+  float: right;
+}
+
+div.toolbar-add-to-shortcuts a {
+  min-width: 12px;
+  height: 12px;
+  background: url(toolbar.png) no-repeat -50px -60px;
+  display: block;
+  text-decoration: none;
+}
+
+div.toolbar-add-to-shortcuts a span.icon {
+  display: block;
+  width: 12px;
+  background: url(toolbar.png) no-repeat -50px -60px;
+  height: 12px;
+  float: left;
+}
+
+div.toolbar-add-to-shortcuts a:hover span.icon {
+  background-position: -50px -72px;
+}
+
+div.toolbar-add-to-shortcuts a span.text {
+  float: left;
+  display: none;
+}
+
+div.toolbar-add-to-shortcuts a:hover span.text {
+  font-size: 10px;
+  line-height: 12px;
+  color: #fff;
+  background-color: #5f605b;
+  display: block;
+  padding-right: 6px;
+  cursor: pointer;
+  -moz-border-radius-topright: 5px;
+  -moz-border-radius-bottomright: 5px;
+  -webkit-border-radius-topright: 5px;
+  -webkit-border-radius-bottomright: 5px;
+}
+
 /**
  * IE 6 Fixes.
  *
Index: modules/toolbar/toolbar.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.module,v
retrieving revision 1.6
diff -u -p -r1.6 toolbar.module
--- modules/toolbar/toolbar.module	22 Aug 2009 14:34:22 -0000	1.6
+++ modules/toolbar/toolbar.module	31 Aug 2009 14:49:24 -0000
@@ -15,6 +15,10 @@ function toolbar_permission() {
       'title' => t('Access administration toolbar'),
       'description' => t('Access the persistent administration toolbar displayed on all pages.'),
     ),
+    'create own shortcuts' => array(
+      'title' => t('Add items to the personal shortcuts menu'),
+      'description' => t('Users with this permission are able to automatically add items to their personal shortcuts menu.'),
+    ),
   );
 }
 
@@ -31,6 +35,26 @@ function toolbar_theme($existing, $type,
 }
 
 /**
+ * Implement hook_menu().
+ */
+function toolbar_menu() {
+  $items = array();
+  $items['admin/settings/shortcuts/add-link'] = array(
+    'title' => 'Add link',
+    'page callback' => 'toolbar_shortcut_add_link',
+    'access arguments' => array('create own shortcuts'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['admin/settings/shortcuts/edit'] = array(
+    'title' => 'Add link',
+    'page callback' => 'toolbar_shortcut_edit_links',
+    'access arguments' => array('create own shortcuts'),
+    'type' => MENU_CALLBACK,
+  );
+  return $items;
+}
+
+/**
  * Implement hook_page_alter().
  * 
  * Add admin toolbar to the page_top region automatically.
@@ -39,6 +63,61 @@ function toolbar_page_alter(&$page) {
   if (user_access('access toolbar')) {
     $page['page_top']['toolbar'] = toolbar_build();
   }
+  if (user_access('create own shortcuts')) {
+    // $_GET['q'] is the unaliased version.
+    $get = $_GET;
+    unset($get['q']);
+    $link = $_GET['q'];
+    if (!empty($get)) {
+      $link .= '?' . http_build_query($get);
+    }
+    $query = array(
+      'link' => $link,
+      'name' => drupal_get_title(),
+    );
+    $page['add_to_shortcuts'] = array(
+      '#prefix' => '<div class="toolbar-add-to-shortcuts">',
+      '#markup' => l('<span class="icon"></span><span class="text">' . t('Add to shortcuts') . '</span>', 'admin/settings/shortcuts/add-link', array('query' => http_build_query($query), 'html' => TRUE)),
+      '#suffix' => '</div>',
+    );
+  }
+}
+
+/**
+ * Add a link to the shortcuts menu.
+ */
+function toolbar_shortcut_add_link() {
+  global $user;
+  // Clone the menu, if we need to.
+  $menu = menu_load(toolbar_shortcuts_menu_name());
+  $original_menu = $menu['menu_name'];
+  $menu = menu_clone_menu($menu, $user);
+  // Add the requested menu link to the end of the list.
+  $path = $_GET['link'];
+  $title = $_GET['name'];
+  $weight = db_query('SELECT MAX(weight) FROM {menu_links} WHERE menu_name = :menu AND plid = 0', array(':menu' => $menu['menu_name']))->fetchField() + 1;
+  $link = array(
+    'mlid' => 0,
+    'plid' => 0,
+    'link_title' => $title,
+    'link_path' => $path,
+    'menu_name' => $menu['menu_name'],
+    'module' => 'menu',
+    'weight' => $weight,
+  );
+  menu_link_save($link);
+  drupal_set_message(t('Added a shortcut for %title.', array('%title' => $title)));
+  drupal_goto('admin/structure/menu-customize/' . $menu['menu_name']);
+}
+
+/**
+ * Edit the shortcuts menu for the current user, creating a new one if needed.
+ */
+function toolbar_shortcut_edit_links() {
+  global $user;
+  $menu = menu_load(toolbar_shortcuts_menu_name());
+  $menu = menu_clone_menu($menu, $user);
+  drupal_goto('admin/structure/menu-customize/' . $menu['menu_name']);
 }
 
 /**
@@ -50,6 +129,9 @@ function toolbar_preprocess_page(&$vars)
   if (user_access('access toolbar')) {
     $vars['classes_array'][] = 'toolbar toolbar-shortcuts';
   }
+  if (user_access('create own shortcuts')) {
+    $vars['add_to_shortcuts'] = drupal_render($vars['page']['add_to_shortcuts']);
+  }
 }
 
 /**
@@ -96,18 +178,33 @@ function toolbar_build() {
   );
 
   // Add convenience shortcut links.
-  $shortcuts = menu_tree_all_data('admin_shortcuts');
+  $shortcuts = menu_tree_all_data(toolbar_shortcuts_menu_name());
   $shortcuts = toolbar_menu_navigation_links($shortcuts);
   $build['toolbar_shortcuts'] = array(
-    '#theme' => 'links',
-    '#links' => $shortcuts,
-    '#attributes' => array('id' => 'toolbar-shortcuts'),
+    'shortcuts' => array(
+      '#theme' => 'links',
+      '#links' => $shortcuts,
+      '#attributes' => array('id' => 'toolbar-shortcuts'),
+    ),
   );
+  if (user_access('create own shortcuts')) {
+    $build['toolbar_shortcuts']['configure'] = array(
+      '#markup' => l(t('edit shortcuts'), 'admin/settings/shortcuts/edit', array('attributes' => array('id' => 'toolbar-customize'))),
+    );
+  }
 
   return $build;
 }
 
 /**
+ * Returns the name of the menu that stores toolbar shortcuts for the current
+ * user.
+ */
+function toolbar_shortcuts_menu_name() {
+  return menu_get_user_menu_name('admin_shortcuts');
+}
+
+/**
  * Get only the top level items below the 'admin' path.
  */
 function toolbar_get_menu_tree() {
Index: themes/seven/page.tpl.php
===================================================================
RCS file: /cvs/drupal/drupal/themes/seven/page.tpl.php,v
retrieving revision 1.3
diff -u -p -r1.3 page.tpl.php
--- themes/seven/page.tpl.php	22 Aug 2009 19:58:28 -0000	1.3
+++ themes/seven/page.tpl.php	31 Aug 2009 14:49:24 -0000
@@ -18,6 +18,7 @@
   <div id="branding" class="clearfix">
     <?php print $breadcrumb; ?>
     <?php if ($title): ?><h1 class="page-title"><?php print $title; ?></h1><?php endif; ?>
+    <?php if ($add_to_shortcuts): ?><?php print $add_to_shortcuts; ?><?php endif; ?>
     <?php if ($primary_local_tasks): ?><ul class="tabs primary"><?php print $primary_local_tasks; ?></ul><?php endif; ?>
   </div>
 
Index: themes/seven/style.css
===================================================================
RCS file: /cvs/drupal/drupal/themes/seven/style.css,v
retrieving revision 1.15
diff -u -p -r1.15 style.css
--- themes/seven/style.css	27 Aug 2009 20:33:05 -0000	1.15
+++ themes/seven/style.css	31 Aug 2009 14:49:24 -0000
@@ -728,3 +728,10 @@ body.overlay #page {
 body.overlay #block-system-main {
   padding: 20px;
 }
+
+/* Shortcut theming */
+div.toolbar-add-to-shortcuts {
+  float: left;
+  margin-left: 6px;
+  margin-top: 6px;
+}
