? .DS_Store
? edit-shortcuts.patch
? head.db
? install_drupal.php
? includes/.DS_Store
? modules/.DS_Store
? modules/node/.DS_Store
? modules/toolbar/.DS_Store
? sites/default/files
? sites/default/private
? sites/default/settings.php
Index: modules/node/content_types.js
===================================================================
RCS file: modules/node/content_types.js
diff -N modules/node/content_types.js
--- modules/node/content_types.js	4 Jul 2009 14:57:23 -0000	1.5
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,29 +0,0 @@
-// $Id: content_types.js,v 1.5 2009/07/04 14:57:23 dries Exp $
-(function ($) {
-
-Drupal.behaviors.contentTypes = {
-  attach: function () {
-    if ($('#edit-type').val() == $('#edit-name').val().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/_+/g, '_') || $('#edit-type').val() == '') {
-      $('.form-item-type-wrapper').hide();
-      $('#edit-name').keyup(function () {
-        var machine = $(this).val().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/_+/g, '_');
-        if (machine != '_' && machine != '') {
-          $('#edit-type').val(machine);
-          $('#node-type-name-suffix').empty().append(' Machine name: ' + machine + ' [').append($('<a href="#">' + Drupal.t('Edit') + '</a>').click(function () {
-            $('.form-item-type-wrapper').show();
-            $('#node-type-name-suffix').hide();
-            $('#edit-name').unbind('keyup');
-            return false;
-          })).append(']');
-        }
-        else {
-          $('#edit-type').val(machine);
-          $('#node-type-name-suffix').text('');
-        }
-      });
-      $('#edit-name').keyup();
-    }
-  }
-};
-
-})(jQuery);
Index: modules/toolbar/toolbar.admin.css
===================================================================
RCS file: modules/toolbar/toolbar.admin.css
diff -N modules/toolbar/toolbar.admin.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/toolbar/toolbar.admin.css	28 Aug 2009 06:54:45 -0000
@@ -0,0 +1,7 @@
+h4.shortcuts-set,
+div.shortcuts-change-set {
+  display: inline;
+}
+.toolbar-slot-hidden {
+  display: none;
+}
\ No newline at end of file
Index: modules/toolbar/toolbar.admin.inc
===================================================================
RCS file: modules/toolbar/toolbar.admin.inc
diff -N modules/toolbar/toolbar.admin.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/toolbar/toolbar.admin.inc	28 Aug 2009 06:54:45 -0000
@@ -0,0 +1,132 @@
+<?php
+// $Id$
+
+/**
+ * Add a new link to the current set.
+ */
+function toolbar_admin_shortcut_add_link() {
+  toolbar_shortcut_save(array(
+    'sid'    => toolbar_current_set(),
+    'weight' => -8,
+    'path'   => $_GET['link'],
+    'title'  => $_GET['title'],
+    'status' => 1,
+  ));
+  drupal_goto('admin/settings/shortcuts');
+}
+
+/**
+ * @file Administrative items for the toolbar module.
+ */
+function toolbar_admin_shortcuts() {
+  $set = toolbar_set_load(toolbar_current_set());
+  $form = array();
+  $form['set'] = array(
+    '#markup' => t('Using set "@set"', array('@set' => $set['name'])),
+    '#prefix' => '<h4 class="shortcuts-set">',
+    '#suffix' => '</h4>',
+    '#weight' => -100,
+  );
+
+  $form['change_set'] = array(
+    '#markup' => l('Change set', 'admin/settings/shortcuts/switch-set'),
+    '#prefix' => ' <div class="shortcuts-change-set">(',
+    '#suffix' => ')</div>',
+    '#weight' => -99,
+  );
+
+  $form['shortcuts']['#tree'] = TRUE;
+
+  foreach ($set['shortcuts'] as $shortcut) {
+    $scid = $shortcut['scid'];
+    $status = ($shortcut['status'] ? 'enabled' : 'disabled');
+    $form['shortcuts'][$status][$scid]['name']['#markup'] = l($shortcut['title'], $shortcut['path']);
+    $form['shortcuts'][$status][$scid]['weight'] = array(
+      '#type' => 'weight',
+      '#title' => t('Weight'),
+      '#delta' => 50,
+      '#default_value' => $shortcut['weight'],
+      '#attributes' => array('class' => array('shortcut-weight')),
+    );
+    $form['shortcuts'][$status][$scid]['status'] = array(
+      '#type' => 'select',
+      '#title' => t('Status'),
+      '#options' => array('disabled' => t('Disabled'), 'enabled' => t('Enabled')),
+      '#default_value' => $status,
+      '#attributes' => array('class' => array('shortcut-status-select')),
+    );
+    
+    $form['shortcuts'][$status][$scid]['edit']['#markup'] = l(t('edit'), 'admin/settings/shortcuts/shortcut/' . $scid);
+    $form['shortcuts'][$status][$scid]['delete']['#markup'] = l(t('delete'), 'admin/settings/shortcuts/shortcut/' . $scid . '/delete');
+  }
+
+  $form['submit'] = array(
+    '#type' => 'submit', 
+    '#value' => t('Save Changes'),
+  );
+  
+
+  return $form;
+}
+
+/**
+ * Theme function for the main shortcut administration page.
+ * 
+ * @see toolbar_admin_shortcuts
+ * @ingroup themable
+ */
+function theme_toolbar_admin_shortcuts($form) {
+  drupal_add_css(drupal_get_path('module', 'toolbar') . '/toolbar.admin.css');
+  drupal_add_js(drupal_get_path('module', 'toolbar') . '/toolbar.admin.js');
+  $map = array('disabled' => t('Disabled'), 'enabled' => t('Enabled'));
+
+  $output = drupal_render($form['set']);
+  $output .= drupal_render($form['change_set']);
+  $rows = array();
+  foreach (array('enabled', 'disabled') as $status) {
+    drupal_add_tabledrag('shortcuts', 'match', 'sibling', 'shortcut-status-select');
+    drupal_add_tabledrag('shortcuts', 'order', 'sibling', 'shortcut-weight');
+    $rows[] = array(
+      'data' => array(array(
+        'colspan' => 5,
+        'data' => '<strong>' . $map[$status] . '</strong>',
+      )),
+      'class' => array('toolbar-status', 'toolbar-status-' . $status),
+    );
+    foreach (element_children($form['shortcuts'][$status]) as $key) {
+      $shortcut = &$form['shortcuts'][$status][$key];
+      $row = array();
+      $row[] = drupal_render($shortcut['name']);
+      $row[] = drupal_render($shortcut['weight']);
+      $row[] = drupal_render($shortcut['status']);
+      $row[] = drupal_render($shortcut['edit']);
+      $row[] = drupal_render($shortcut['delete']);
+      $rows[] = array(
+        'data' => $row,
+        'class' => array('draggable'),
+      );
+    }
+    if ($status == 'enabled') {
+      for ($i = 0; $i < TOOLBAR_MAX_SLOTS; $i++) {
+        $rows['empty-' . $i] = array(
+          'data' => array(array(
+            'colspan' => 5,
+            'data' => '<em>' . t('Empty') . '</em>',
+          )),
+          'class' => array('toolbar-slot-empty'),
+        );
+      }
+      $count_shortcuts = count(element_children($form['shortcuts'][$status]));
+      if ($count_shortcuts < TOOLBAR_MAX_SLOTS) {
+        for ($i = 0; $i < $count_shortcuts; $i++) {
+          $rows['empty-' . $i]['class'][] = 'toolbar-slot-hidden';
+        }
+      }
+    }
+  }
+  $header = array(t('Name'), t('Weight'), t('Status'), array('data' => t('Operations'), 'colspan' => 2));
+  $output .= theme('table', $header, $rows, array('id' => 'shortcuts'));
+  unset($form['#theme']);
+  $output .= drupal_render($form);
+  return $output;
+}
Index: modules/toolbar/toolbar.admin.js
===================================================================
RCS file: modules/toolbar/toolbar.admin.js
diff -N modules/toolbar/toolbar.admin.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/toolbar/toolbar.admin.js	28 Aug 2009 06:54:45 -0000
@@ -0,0 +1,84 @@
+// $Id: toolbar.js,v 1.10 2009/08/04 06:26:52 webchick Exp $
+(function ($) {
+
+/**
+ * Move a toolbar in the toolbars table from one region to another via select list.
+ *
+ * This behavior is dependent on the tableDrag behavior, since it uses the
+ * objects initialized in that behavior to update the row.
+ */
+Drupal.behaviors.toolbarDrag = {
+  attach: function (context, settings) {
+    var table = $('table#shortcuts');
+    var tableDrag = Drupal.tableDrag.shortcuts; // Get the toolbars tableDrag object.
+    $('> tbody > tr:visible, > tr:visible', table)
+      .filter(':odd').filter('.odd')
+        .removeClass('odd').addClass('even')
+      .end().end()
+      .filter(':even').filter('.even')
+        .removeClass('even').addClass('odd');
+    var visibleSlots = [],
+      hiddenSlots = [],
+      visibleLength = 0,
+      slots = 0;
+    $(table).find('.toolbar-slot-empty').each(function(index) {
+      if ($(this).is(':visible')) {
+        visibleSlots.push($(this));
+        visibleLength++;
+      }
+      else {
+        hiddenSlots.push($(this));
+      }
+      slots++;
+    });
+     
+
+    // Add a handler for when a row is swapped, update empty regions.
+    tableDrag.row.prototype.onSwap = function (swappedRow) {
+      var disabledIndex = $(table).find('tr').index($(table).find('tr.toolbar-status-disabled')) - slots - 2,
+        count = 0;
+      $(table).find('tr.toolbar-status-enabled').nextAll().filter(':not(.toolbar-slot-empty)').each(function(index) {
+        if (index < disabledIndex) {
+          count++;
+        }
+      });
+      var total = slots - count;
+      if (total != visibleLength) {
+        if (total > visibleLength) {
+          // Less slots on screen than needed.
+          visibleSlots.push(hiddenSlots.pop().show());
+          visibleLength++;
+        }
+        else {
+          // More slots on screen than needed.
+          hiddenSlots.push(visibleSlots.pop().hide());
+          visibleLength--;
+        }
+      }
+    };
+
+    // Add a handler so when a row is dropped, update fields dropped into new regions.
+    tableDrag.onDrop = function () {
+      // Use "status-message" row instead of "status" row because
+      // "status-{status_name}-message" is less prone to regexp match errors.
+      var statusRow = $(this.rowObject.element).prevAll('tr.toolbar-status').get(0);
+      var statusName = statusRow.className.replace(/([^ ]+[ ]+)*toolbar-status-([^ ]+)([ ]+[^ ]+)*/, '$2');
+      var statusField = $('select.shortcut-status-select', this.rowObject.element);
+      statusField.val(statusName);
+      return true;
+    };
+    tableDrag.restripeTable = function () {
+      // :even and :odd are reversed because jQuery counts from 0 and
+      // we count from 1, so we're out of sync.
+      // Match immediate children of the parent element to allow nesting.
+      $('> tbody > tr:visible, > tr:visible', this.table)
+        .filter(':odd').filter('.odd')
+          .removeClass('odd').addClass('even')
+        .end().end()
+        .filter(':even').filter('.even')
+          .removeClass('even').addClass('odd');
+    };
+  }
+};
+
+})(jQuery);
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	28 Aug 2009 06:54:45 -0000
@@ -123,6 +123,7 @@ div#toolbar div.toolbar-menu ul li a.act
 div#toolbar div.toolbar-shortcuts {
   position: relative;
   padding: 0 10px;
+  height: 50px;
 }
 
 div#toolbar div.toolbar-shortcuts ul {
@@ -161,6 +162,10 @@ div#toolbar div.toolbar-shortcuts span.i
   -webkit-border-radius: 5px;
 }
 
+div#toolbar a#toolbar-customize {
+  float: right;
+}
+
 /**
  * IE 6 Fixes.
  *
Index: modules/toolbar/toolbar.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.info,v
retrieving revision 1.2
diff -u -p -r1.2 toolbar.info
--- modules/toolbar/toolbar.info	6 Jul 2009 13:54:21 -0000	1.2
+++ modules/toolbar/toolbar.info	28 Aug 2009 06:54:45 -0000
@@ -1,9 +1,9 @@
 ; $Id: toolbar.info,v 1.2 2009/07/06 13:54:21 dries Exp $
 name = Toolbar
-description = Toolbar exposing the top level administration menu items
+description = Toolbar exposing the top level administration menu items.
 core = 7.x
 package = Core
 version = VERSION
 files[] = toolbar.install
 files[] = toolbar.module
-dependencies[] = menu
+files[] = toolbar.admin.inc
Index: modules/toolbar/toolbar.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.install,v
retrieving revision 1.3
diff -u -p -r1.3 toolbar.install
--- modules/toolbar/toolbar.install	30 Jul 2009 19:24:21 -0000	1.3
+++ modules/toolbar/toolbar.install	28 Aug 2009 06:54:45 -0000
@@ -7,51 +7,177 @@
  */
 
 /**
- * Implementation of hook_install().
- *
- * @todo
- *   Implement role based shortcut bars. 
+ * Implement hook_install().
  */
 function toolbar_install() {
-  $t = get_t();
-  $query = db_insert('menu_custom')
-    ->fields(array(
-      'menu_name' => 'admin_shortcuts',
-      'title' => $t('Administration shortcuts'),
-      'description' => $t('The <em>Admininstration shortcuts</em> menu contains commonly used links for administrative tasks.')
-    ))
-    ->execute();
-
-  // Add starter convenience shortcuts.
-  menu_rebuild();
-  $items = array(
-    'node/add' => 'Add',
-    'admin/content' => 'Find content',
-    'admin' => 'Dashboard',
+  drupal_install_schema('toolbar');
+  include_once DRUPAL_ROOT . '/modules/toolbar/toolbar.module';
+  $sid = toolbar_set_save(array('name' => t('Default')));
+  toolbar_shortcut_save(array(
+    'sid'    => $sid,
+    'weight' => -10,
+    'path'   => 'node/add',
+    'title'  => t('Add'),
+    'status' => 1,
+  ));
+  toolbar_shortcut_save(array(
+    'sid'    => $sid,
+    'weight' => -9,
+    'path'   => 'admin/content',
+    'title'  => t('Find Content'),
+    'status' => 1,
+  ));
+  toolbar_shortcut_save(array(
+    'sid'    => $sid,
+    'weight' => -8,
+    'path'   => 'admin',
+    'title'  => t('Dashboard'),
+    'status' => 1,
+  ));
+}
+
+/**
+ * Implement hook_uninstall().
+ */
+function toolbar_uninstall() {
+  drupal_uninstall_schema('toolbar');
+}
+
+/**
+ * Implement hook_schema().
+ */
+function toolbar_schema() {
+  $schema = array();
+
+  $schema['toolbar_sets'] = array(
+    'description' => 'Stores configuration options for toolbar shortcut sets.',
+    'fields' => array(
+      'sid' => array(
+        'description' => 'The primary identifier for the set.',
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'description' => 'The set name.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+      ),
+    ),
+    'primary key' => array('sid'),
+    'indexes' => array(
+      'name' => array('name'),
+    ),
   );
-  $weight = -20;
-  foreach ($items as $path => $title) {
-    $link = array(
-      'mlid' => 0,
-      'link_title' => $title,
-      'link_path' => $path,
-      'router_path' => $path,
-      'menu_name' => 'admin_shortcuts',
-      'module' => 'menu',
-      'weight' => $weight,
-    );
-
-    // Check for an existing menu item before attempting to create a new one.
-    $menu_link = db_query("SELECT mlid FROM {menu_links} WHERE link_path = :path AND menu_name = :menu_name", array(
-      ':path' => $link['link_path'],
-      ':menu_name' => $link['menu_name']
-    ))
-    ->fetchField();
-    if (!$menu_link) {
-      menu_link_save($link);
-    }
-
-    // Increment weight so items can be displayed in desired order.
-    $weight++;
-  }
+
+  $schema['toolbar_shortcuts'] = array(
+    'description' => 'Stores shortcuts in toolbar sets.',
+    'fields' => array(
+      'scid' => array(
+        'description' => 'The primary identifier for the shortcut.',
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'sid' => array(
+        'description' => 'The {toolbar_sets}.sid for this shortcut.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'weight' => array(
+        'description' => 'The weight of the set in the shortcut.',
+        'type' => 'int',
+        'unsigned' => FALSE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'path' => array(
+        'description' => 'The path of the shortcut.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+      ),
+      'title' => array(
+        'description' => 'The name of the shortcut.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+      ),
+      'status' => array(
+        'description' => 'Boolean indicating whether or not this shortcut is enabled.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'primary key' => array('scid'),
+    'indexes' => array(
+      'sid' => array('sid'),
+      'weight' => array('weight'),
+    ),
+    'foreign keys' => array(
+      'sid' => array('toolbar_sets' => 'sid'),
+    ),
+  );
+
+  $schema['toolbar_set_users'] = array(
+    'description' => 'Maps users to toolbar sets.',
+    'fields' => array(
+      'uid' => array(
+        'description' => 'The {user}.uid for this set.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'sid' => array(
+        'description' => 'The {toolbar_sets}.sid for this user.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'primary key' => array('uid'),
+    'indexes' => array(
+      'sid' => array('sid'),
+    ),
+    'foreign keys' => array(
+      'sid' => array('toolbar_sets' => 'sid'),
+      'uid' => array('users' => 'uid'),
+    ),
+  );
+
+  $schema['toolbar_set_roles'] = array(
+    'description' => 'Maps roles to toolbar sets.',
+    'fields' => array(
+      'rid' => array(
+        'description' => 'The {role}.rid for this set.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'sid' => array(
+        'description' => 'The {toolbar_sets}.sid for this role.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'primary key' => array('rid'),
+    'indexes' => array(
+      'sid' => array('sid'),
+    ),
+    'foreign keys' => array(
+      'sid' => array('toolbar_sets' => 'sid'),
+      'rid' => array('role' => 'rid'),
+    ),
+  );
+
+  return $schema;
 }
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	28 Aug 2009 06:54:45 -0000
@@ -7,7 +7,12 @@
  */
 
 /**
- * Implementation of hook_permission().
+ * @TODO Document this.
+ */
+define('TOOLBAR_MAX_SLOTS', 7);
+
+/**
+ * Implement hook_permission().
  */
 function toolbar_permission() {
   return array(
@@ -15,6 +20,14 @@ function toolbar_permission() {
       'title' => t('Access administration toolbar'),
       'description' => t('Access the persistent administration toolbar displayed on all pages.'),
     ),
+    'customize toolbar shortcuts' => array(
+      'title' => t('Customize toolbar shortcuts'),
+      'description' => t('Customize the shortcuts in the toolbar displayed on all pages.')
+    ),
+    'choose toolbar shortcut set' => array(
+      'title' => t('Choose toolbar shortcut set'),
+      'description' => t('Choose which set of toolbar shortcuts appear in the user\'s toolbar.')
+    ),
   );
 }
 
@@ -27,6 +40,70 @@ function toolbar_theme($existing, $type,
     'template' => 'toolbar',
     'path' => drupal_get_path('module', 'toolbar'),
   );
+  $items['toolbar_admin_shortcuts'] = array(
+    'arguments' => array('form' => NULL),
+    'file' => 'toolbar.admin.inc',
+  );
+  return $items;
+}
+
+/**
+ * Implement hook_menu().
+ */
+
+function toolbar_menu() {
+  $items = array();
+
+  $items['admin/settings/shortcuts'] = array(
+    'title' => 'Shortcuts',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('toolbar_admin_shortcuts'),
+    'access arguments' => array('customize toolbar shortcuts'),
+    'type' => MENU_NORMAL_ITEM,
+    'file' => 'toolbar.admin.inc',
+  );
+
+  $items['admin/settings/shortcuts/add-link'] = array(
+    'title' => 'Add link',
+    'page callback' => 'toolbar_admin_shortcut_add_link',
+    'access arguments' => array('customize toolbar shortcuts'),
+    'type' => MENU_NORMAL_ITEM,
+    'file' => 'toolbar.admin.inc',
+  );
+
+  $items['admin/settings/shortcuts/switch-set'] = array(
+    'title' => 'Switch set',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('toolbar_admin_shortcuts_switch_set'),
+    'access arguments' => array('customize toolbar shortcuts'),
+    'type' => MENU_NORMAL_ITEM,
+    'file' => 'toolbar.admin.inc',
+  );
+
+  $items['admin/settings/shortcuts/shortcut/%toolbar_shortcut'] = array(
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('toolbar_admin_shortcut_edit', 4),
+    'access arguments' => array('customize toolbar shortcuts'),
+    'type' => MENU_CALLBACK,
+    'file' => 'toolbar.admin.inc',
+  );
+
+  $items['admin/settings/shortcuts/shortcut/%toolbar_shortcut/edit'] = array(
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('toolbar_admin_shortcut_edit', 4),
+    'access arguments' => array('customize toolbar shortcuts'),
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'file' => 'toolbar.admin.inc',
+  );
+
+  $items['admin/settings/shortcuts/shortcut/%toolbar_shortcut/delete'] = array(
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('toolbar_admin_shortcut_delete', 4),
+    'access arguments' => array('customize toolbar shortcuts'),
+    'type' => MENU_LOCAL_TASK,
+    'file' => 'toolbar.admin.inc',
+  );
+
   return $items;
 }
 
@@ -39,6 +116,19 @@ function toolbar_page_alter(&$page) {
   if (user_access('access toolbar')) {
     $page['page_top']['toolbar'] = toolbar_build();
   }
+  if (user_access('customize toolbar shortcuts')) {
+    $get = $_GET;
+    unset($get['q']);
+    $link = $_GET['q'];
+    if (!empty($get)) {
+      $link .= '?' . http_build_query($get);
+    }
+    $query = array(
+      'link' => $link,
+      'title' => drupal_get_title(),
+    );
+    $page['content']['foo']['#markup'] = l('+ Add shortcut', 'admin/settings/shortcuts/add-link', array('query' => http_build_query($query)));
+  }
 }
 
 /**
@@ -53,6 +143,89 @@ function toolbar_preprocess_page(&$vars)
 }
 
 /**
+ * Find the set for the current user.
+ *
+ * @todo
+ *   Implement this.
+ */
+function toolbar_current_set($account = NULL) {
+  if (!isset($account)) {
+    global $user;
+    $account = $user;
+  }
+  // Magic here.
+  return 1;
+}
+
+/**
+ * Load a toolbar shortcut by ID.
+ */
+function toolbar_shortcut_load($scid) {
+  return db_select('toolbar_shortcuts')
+    ->fields('toolbar_shortcuts')
+    ->condition('scid', $scid)
+    ->execute()
+    ->fetchAssoc();
+}
+
+/**
+ * Save a toolbar shortcut.
+ */
+function toolbar_shortcut_save($shortcut) {
+  if (isset($shortcut['scid'])) {
+    $scid = $shortcut['scid'];
+    unset($shortcut['scid']);
+    db_update('toolbar_shortcuts')
+      ->fields($shortcut)
+      ->condition('scid', $scid)
+      ->execute;
+    return $scid;
+  }
+  else {
+    return db_insert('toolbar_shortcuts')
+      ->fields($shortcut)
+      ->execute();
+  }
+}
+
+/**
+ * Load a toolbar set by ID.
+ */
+function toolbar_set_load($sid) {
+  $set = db_select('toolbar_sets')
+    ->fields('toolbar_sets')
+    ->condition('sid', $sid)
+    ->execute()
+    ->fetchAssoc();
+  $set['shortcuts'] = db_select('toolbar_shortcuts')
+    ->fields('toolbar_shortcuts')
+    ->condition('sid', $sid)
+    ->execute()
+    ->fetchAllAssoc('scid', PDO::FETCH_ASSOC);
+  return $set;
+}
+
+/**
+ * Save a toolbar set.
+ */
+function toolbar_set_save($set) {
+  if (isset($set['sid'])) {
+    $sid = $set['sid'];
+    unset($set['sid']);
+    db_update('toolbar_sets')
+      ->fields($set)
+      ->condition('sid', $sid)
+      ->execute;
+    return $sid;
+  }
+  else {
+    return db_insert('toolbar_sets')
+      ->fields($set)
+      ->execute();
+  }
+}
+
+/**
  * Build the admin menu as a structured array ready for drupal_render().
  */
 function toolbar_build() {
@@ -96,12 +269,33 @@ function toolbar_build() {
   );
 
   // Add convenience shortcut links.
-  $shortcuts = menu_tree_all_data('admin_shortcuts');
-  $shortcuts = toolbar_menu_navigation_links($shortcuts);
+  $set = toolbar_set_load(toolbar_current_set());
+  $shortcuts = array();
+  foreach ($set['shortcuts'] as $shortcut) {
+    $class = '';
+    // Make sure we have a path specific ID in place, so we can attach icons
+    // and behaviors to the items.
+    $id = str_replace(array('/', '<', '>'), array('-', '', ''), $shortcut['path']);
+    $class = ' path-' . $id;
+    if (toolbar_in_active_trail($shortcut['path'])) {
+      $class .= ' active-trail';
+    }
+    $shortcuts[$shortcut['scid']] = array(
+      'href' => $shortcut['path'],
+      'title' => '<span class="icon"></span>' . $shortcut['title'],
+      'html' => TRUE,
+      'attributes' => array('id' => 'toolbar-link-' . $id, 'class' => array('to-overlay')),
+    );
+  }
   $build['toolbar_shortcuts'] = array(
-    '#theme' => 'links',
-    '#links' => $shortcuts,
-    '#attributes' => array('id' => 'toolbar-shortcuts'),
+    'shortcuts' => array(
+      '#theme' => 'links',
+      '#links' => $shortcuts,
+      '#attributes' => array('id' => 'toolbar-shortcuts'),
+    ),
+    'configure' => array(
+      '#markup' => l(t('edit shortcuts'), 'admin/settings/shortcuts', array('attributes' => array('id' => 'toolbar-customize'))),
+    ),
   );
 
   return $build;
@@ -153,7 +347,7 @@ function toolbar_menu_navigation_links($
       if (toolbar_in_active_trail($item['link']['href'])) {
         $class .= ' active-trail';
       }
-      $links['menu-' . $item['link']['mlid'] . $class] = $link;
+      $links[$item['link']['mlid']] = $link;
     }
   }
   return $links;
