Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.184
diff -u -p -r1.184 system.admin.inc
--- modules/system/system.admin.inc	22 Aug 2009 09:44:56 -0000	1.184
+++ modules/system/system.admin.inc	22 Aug 2009 14:33:37 -0000
@@ -192,6 +192,119 @@ function system_settings_overview() {
   return $output;
 }
 
+function system_admin_theme_form() {
+  drupal_add_js(drupal_get_path('module', 'system') . '/system.js');
+  
+  $themes = system_get_theme_data();
+  uasort($themes, 'system_sort_modules_by_info_name');
+  
+  foreach ($themes as $theme) {
+    $options[$theme->name] = $theme->info['name'];
+  }
+  
+  $form['theme'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Choose a theme'),
+    '#collapsible' => FALSE,
+  );
+  $form['theme']['admin_theme'] = array(
+    '#type' => 'select',
+    '#options' => array(0 => t('Default theme')) + $options,
+    '#title' => t('Administration theme'),
+    '#description' => t('Choose "Default theme" to always use the same theme as the rest of the site.'),
+    '#default_value' => variable_get('admin_theme', 0),
+  );
+  
+   // Visibility
+  $form['block_vis_settings'] = array(
+    '#type' => 'vertical_tabs',
+  );
+
+  $form['page_vis_settings'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Page visibility'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#group' => 'block_vis_settings',
+  );
+
+  $access = user_access('use PHP for settings');
+  if (variable_get('admin_theme_visibility', 0) == 2 && !$access) {
+    $form['page_vis_settings'] = array();
+    $form['page_vis_settings']['visibility'] = array('#type' => 'value', '#value' => 2);
+    $form['page_vis_settings']['pages'] = array('#type' => 'value', '#value' => $edit['pages']);
+  }
+  else {
+    $options = array(t('Every page except those specified below.'), t('Only the pages specified below.'));
+    $description = t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array('%blog' => 'blog', '%blog-wildcard' => 'blog/*', '%front' => '<front>'));
+
+    if (module_exists('php') && $access) {
+      $options[] = t('Show if the following PHP code returns <code>TRUE</code> (PHP-mode, experts only).');
+      $description .= ' ' . t('If the PHP-mode is chosen, enter PHP code between %php. Note that executing incorrect PHP-code can break your Drupal site.', array('%php' => '<?php ?>'));
+    }
+    $form['page_vis_settings']['visibility'] = array(
+      '#type' => 'radios',
+      '#title' => t('Show administration theme on specific pages'),
+      '#options' => $options,
+      '#default_value' => variable_get('admin_theme_visibility', 0),
+    );
+    $form['page_vis_settings']['pages'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Pages'),
+      '#description' => $description,
+      '#default_value' => variable_get('admin_theme_pages', ''),
+    );
+  }
+
+  // Role-based visibility settings.
+  $role_options = db_query('SELECT rid, name FROM {role} ORDER BY name')->fetchAllKeyed();
+  $form['role_vis_settings'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Role visibility'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#group' => 'block_vis_settings',
+  );
+  $form['role_vis_settings']['roles'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Show administration theme for specific roles'),
+    '#options' => $role_options,
+    '#description' => t('Show administration theme only for the selected role(s). If you select no roles, the administration theme will be visible to all users.'),
+    '#default_value' => variable_get('admin_theme_roles', array()),
+  );
+
+  // Submit button
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save configuration'),
+  );
+  
+  return $form;
+}
+
+/**
+ * Process system_themes_form form submissions.
+ */
+function system_admin_theme_form_submit($form, &$form_state) {
+  if ($form_state['values']['admin_theme'] && $form_state['values']['admin_theme'] != variable_get('theme_default', 'garland')) {
+    drupal_set_message(t('Please note that the <a href="!admin_theme_page">administration theme</a> is still set to the %admin_theme theme; consequently, the theme on this page remains unchanged. All non-administrative sections of the site, however, will show the selected %selected_theme theme by default.', array(
+      '!admin_theme_page' => url('admin/settings/admin'),
+      '%admin_theme' => $form_state['values']['admin_theme'],
+      '%selected_theme' => variable_get('theme_default', 'garland'),
+    )));
+    variable_set('admin_theme', $form_state['values']['admin_theme']);
+    variable_set('admin_theme_visibility', $form_state['values']['visibility']);
+    variable_set('admin_theme_pages', $form_state['values']['pages']);
+    variable_set('admin_theme_roles', array_filter($form_state['values']['roles']));
+  }
+  else {
+    variable_del('admin_theme');
+    variable_del('admin_theme_visibility');
+    variable_del('admin_theme_pages');
+    variable_del('admin_theme_roles');
+  }
+}
+
 /**
  * Menu callback; displays a listing of all themes.
  *
@@ -268,26 +381,6 @@ function system_themes_form() {
     '#default_value' => variable_get('theme_default', 'garland'),
   );
 
-  // Administration theme settings.
-  $form['admin_theme'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Administration theme'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-  );
-  $form['admin_theme']['admin_theme'] = array(
-    '#type' => 'select',
-    '#options' => array(0 => t('Default theme')) + $options,
-    '#title' => t('Administration theme'),
-    '#description' => t('Choose "Default theme" to always use the same theme as the rest of the site.'),
-    '#default_value' => variable_get('admin_theme', 0),
-  );
-  $form['admin_theme']['node_admin_theme'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Use the administration theme when editing or creating content'),
-    '#default_value' => variable_get('node_admin_theme', '0'),
-  );
-
   $form['buttons']['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Save configuration'),
@@ -328,24 +421,13 @@ function system_themes_form_submit($form
         }
       }
     }
-    if ($form_state['values']['admin_theme'] && $form_state['values']['admin_theme'] != $form_state['values']['theme_default']) {
-      drupal_set_message(t('Please note that the <a href="!admin_theme_page">administration theme</a> is still set to the %admin_theme theme; consequently, the theme on this page remains unchanged. All non-administrative sections of the site, however, will show the selected %selected_theme theme by default.', array(
-        '!admin_theme_page' => url('admin/settings/admin'),
-        '%admin_theme' => $form_state['values']['admin_theme'],
-        '%selected_theme' => $form_state['values']['theme_default'],
-      )));
-    }
 
     // Save the variables.
     variable_set('theme_default', $form_state['values']['theme_default']);
-    variable_set('admin_theme', $form_state['values']['admin_theme']);
-    variable_set('node_admin_theme', $form_state['values']['node_admin_theme']);
   }
   else {
     // Revert to defaults: only Garland is enabled.
     variable_del('theme_default');
-    variable_del('admin_theme');
-    variable_del('node_admin_theme');
     db_update('system')
       ->fields(array('status' => 1))
       ->condition('type', 'theme')
Index: modules/system/system.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.js,v
retrieving revision 1.30
diff -u -p -r1.30 system.js
--- modules/system/system.js	12 Aug 2009 11:43:10 -0000	1.30
+++ modules/system/system.js	22 Aug 2009 14:33:37 -0000
@@ -1,6 +1,29 @@
 // $Id: system.js,v 1.30 2009/08/12 11:43:10 dries Exp $
 (function ($) {
 
+Drupal.behaviors.adminThemeVisibility = {
+  attach: function (context) {
+    // Provide the vertical tab summaries.
+    $('fieldset#edit-page-vis-settings', context).setSummary(function(context) {
+      var vals = [];
+      if ($('#edit-visibility-0', context).is(':checked')) {
+        vals.unshift(Drupal.t("Every page expect those listed."));
+      }
+      if ($('#edit-visibility-1', context).is(':checked')) {
+        vals.unshift(Drupal.t("Only the pages specified."));
+      }
+      return vals.join(', ');
+    });
+    $('fieldset#edit-role-vis-settings', context).setSummary(function(context) {
+      var vals = [];
+      $("input[type^='checkbox']:checked", context).parent().each(function() {
+        vals.push(Drupal.checkPlain($(this).text()));
+      });
+      return vals.join(', ');
+    });
+  }
+};
+
 /**
  * Show/hide the 'Email site administrator when updates are available' checkbox
  * on the install page.
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.759
diff -u -p -r1.759 system.module
--- modules/system/system.module	22 Aug 2009 09:44:56 -0000	1.759
+++ modules/system/system.module	22 Aug 2009 14:33:40 -0000
@@ -580,6 +580,16 @@ function system_menu() {
       'access arguments' => array($theme),
     );
   }
+  
+  $items['admin/appearance/admin'] = array(
+    'title' => 'Administration theme',
+    'description' => 'Select and configure an administration theme.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('system_admin_theme_form'),
+    'access arguments' => array('administer site configuration'),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 1,
+  );
 
   // Configuration and modules.
   $items['admin/config'] = array(
@@ -1351,12 +1361,57 @@ function _system_filetransfer_backend_fo
   return $form;
 }
 
+function system_show_admin_theme() {
+  global $user;
+  
+  // No admin theme set or admin theme is same as default theme.
+  if (!variable_get('admin_theme', 'garland') || variable_get('admin_theme', 'garland') == variable_get('theme_default', 'garland')) {
+    return FALSE;
+  }
+  
+  // role visibility
+  $roles = variable_get('admin_theme_roles', array());
+
+  if (!empty($roles) && !array_intersect(variable_get('admin_theme_roles', array()), array_keys($user->roles))) {
+    if (!$user->uid == 1) {
+      return FALSE;
+    }
+  }
+  
+  // page visibility
+  $pages = variable_get('admin_theme_pages', '');
+  $visibility = variable_get('admin_theme_visibility', 0);
+
+  if (!empty($pages)) {
+    if ($visibility < 2) {
+      $path = drupal_get_path_alias($_GET['q']);
+      // Compare with the internal and path alias (if any).
+      $page_match = drupal_match_path($path, $pages);
+      if ($path != $_GET['q']) {
+        $page_match = $page_match || drupal_match_path($_GET['q'], $pages);
+      }
+      // When variable admin_theme_visibility has a value of 0, the block is displayed on
+      // all pages except those listed in variable admin_theme_pages. When set to 1, it
+      // is displayed only on those pages listed in variable admin_theme_pages.
+      return !(variable_get('admin_theme_visibility', '') xor $page_match);
+    }
+    elseif (module_exists('php')) {
+      return php_eval($pages);
+    }
+    else {
+      return FALSE;
+    }
+  }
+  
+  return FALSE;
+}
+
 /**
  * Implement hook_init().
  */
 function system_init() {
   // Use the administrative theme if the user is looking at a page in the admin/* path.
-  if (arg(0) == 'admin' || (variable_get('node_admin_theme', '0') && arg(0) == 'node' && (arg(1) == 'add' || arg(2) == 'edit'))) {
+  if (system_show_admin_theme()) {
     global $custom_theme;
     $custom_theme = variable_get('admin_theme', 0);
     drupal_add_css(drupal_get_path('module', 'system') . '/admin.css', array('weight' => CSS_SYSTEM));
Index: modules/system/system.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.test,v
retrieving revision 1.68
diff -u -p -r1.68 system.test
--- modules/system/system.test	22 Aug 2009 09:44:56 -0000	1.68
+++ modules/system/system.test	22 Aug 2009 14:33:42 -0000
@@ -923,10 +923,15 @@ class SystemThemeFunctionalTest extends 
     // Enable an administration theme and show it on the node admin pages.
     $edit = array(
       'theme_default' => 'stark',
-      'admin_theme' => 'garland',
-      'node_admin_theme' => TRUE,
     );
     $this->drupalPost('admin/appearance', $edit, t('Save configuration'));
+    
+    $edit = array(      
+      'admin_theme' => 'garland',
+      'visibility' => 1,
+      'pages' => "node/add*\nnode/*/edit\nadmin*",
+    );
+    $this->drupalPost('admin/appearance/admin', $edit, t('Save configuration'));
 
     $this->drupalGet('admin');
     $this->assertRaw('themes/garland', t('Administration theme used on an administration page.'));
@@ -940,25 +945,18 @@ class SystemThemeFunctionalTest extends 
     $this->drupalGet('node/' . $this->node->nid . '/edit');
     $this->assertRaw('themes/garland', t('Administration theme used on the edit content page.'));
 
-    // Disable the admin theme on the node admin pages.
-    $edit = array(
-      'node_admin_theme' => FALSE,
-    );
-    $this->drupalPost('admin/appearance', $edit, t('Save configuration'));
-
-    $this->drupalGet('admin');
-    $this->assertRaw('themes/garland', t('Administration theme used on an administration page.'));
-
-    $this->drupalGet('node/add');
-    $this->assertRaw('themes/stark', t('Site default theme used on the add content page.'));
-
     // Reset to the default theme settings.
     $edit = array(
       'theme_default' => 'garland',
-      'admin_theme' => '0',
-      'node_admin_theme' => FALSE,
     );
     $this->drupalPost('admin/appearance', $edit, t('Save configuration'));
+    
+    $edit = array(      
+      'admin_theme' => 0,
+      'visibility' => 0,
+      'pages' => '',
+    );
+    $this->drupalPost('admin/appearance/admin', $edit, t('Save configuration'));
 
     $this->drupalGet('admin');
     $this->assertRaw('themes/garland', t('Site default theme used on administration page.'));
Index: profiles/default/default.install
===================================================================
RCS file: /cvs/drupal/drupal/profiles/default/default.install,v
retrieving revision 1.1
diff -u -p -r1.1 default.install
--- profiles/default/default.install	21 Aug 2009 07:50:08 -0000	1.1
+++ profiles/default/default.install	22 Aug 2009 14:33:42 -0000
@@ -212,5 +212,7 @@ function default_install() {
     ->condition('name', 'seven')
     ->execute();
   variable_set('admin_theme', 'seven');
-  variable_set('node_admin_theme', '1');
+  variable_set('admin_theme_visibility', '1');
+  variable_set('admin_theme_pages', "admin*\nnode/add/*\nnode/*/edit\nbatch*");
+  variable_set('admin_theme_roles', array($rid => $rid));
 }
Index: modules/block/block.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.admin.inc,v
retrieving revision 1.48
diff -u -p -r1.48 block.admin.inc
--- modules/block/block.admin.inc	12 Aug 2009 11:43:09 -0000	1.48
+++ modules/block/block.admin.inc	22 Aug 2009 14:33:43 -0000
@@ -180,6 +180,8 @@ function _block_compare($a, $b) {
  * Menu callback; displays the block configuration form.
  */
 function block_admin_configure(&$form_state, $module = NULL, $delta = 0) {
+  drupal_add_js(drupal_get_path('module', 'block') . '/block.js');
+
   $form['module'] = array(
     '#type' => 'value',
     '#value' => $module,
@@ -220,12 +222,18 @@ function block_admin_configure(&$form_st
   if (isset($info[$delta])) {
     drupal_set_title(t("'%name' block", array('%name' => $info[$delta]['info'])), PASS_THROUGH);
   }
+  
+  // Visibility
+  $form['block_vis_settings'] = array(
+    '#type' => 'vertical_tabs',
+  );
 
   $form['page_vis_settings'] = array(
     '#type' => 'fieldset',
-    '#title' => t('Page specific visibility settings'),
+    '#title' => t('Page visibility'),
     '#collapsible' => TRUE,
     '#collapsed' => TRUE,
+    '#group' => 'block_vis_settings',
   );
 
   $access = user_access('use PHP for settings');
@@ -264,9 +272,10 @@ function block_admin_configure(&$form_st
   $role_options = db_query('SELECT rid, name FROM {role} ORDER BY name')->fetchAllKeyed();
   $form['role_vis_settings'] = array(
     '#type' => 'fieldset',
-    '#title' => t('Role specific visibility settings'),
+    '#title' => t('Role visibility'),
     '#collapsible' => TRUE,
     '#collapsed' => TRUE,
+    '#group' => 'block_vis_settings',
   );
   $form['role_vis_settings']['roles'] = array(
     '#type' => 'checkboxes',
@@ -283,9 +292,10 @@ function block_admin_configure(&$form_st
   ))->fetchCol();
   $form['content_type_vis_settings'] = array(
     '#type' => 'fieldset',
-    '#title' => t('Content type specific visibility settings'),
+    '#title' => t('Content type visibility'),
     '#collapsible' => TRUE,
     '#collapsed' => TRUE,
+    '#group' => 'block_vis_settings',
   );
   $form['content_type_vis_settings']['types'] = array(
     '#type' => 'checkboxes',
@@ -298,9 +308,10 @@ function block_admin_configure(&$form_st
   // Standard block configurations.
   $form['user_vis_settings'] = array(
     '#type' => 'fieldset',
-    '#title' => t('User specific visibility settings'),
+    '#title' => t('User visibility'),
     '#collapsible' => TRUE,
     '#collapsed' => TRUE,
+    '#group' => 'block_vis_settings',
   );
   $form['user_vis_settings']['custom'] = array(
     '#type' => 'radios',
Index: modules/block/block.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.js,v
retrieving revision 1.10
diff -u -p -r1.10 block.js
--- modules/block/block.js	4 Aug 2009 06:26:52 -0000	1.10
+++ modules/block/block.js	22 Aug 2009 14:33:43 -0000
@@ -1,6 +1,43 @@
 // $Id: block.js,v 1.10 2009/08/04 06:26:52 webchick Exp $
 (function ($) {
 
+Drupal.behaviors.blockVisibility = {
+  attach: function (context) {
+    // Provide the vertical tab summaries.
+    $('fieldset#edit-page-vis-settings', context).setSummary(function(context) {
+      var vals = [];
+      if ($('#edit-visibility-0', context).is(':checked')) {
+        vals.unshift(Drupal.t("Every page expect those listed."));
+      }
+      if ($('#edit-visibility-1', context).is(':checked')) {
+        vals.unshift(Drupal.t("Only the pages specified."));
+      }
+      return vals.join(', ');
+    });
+    $('fieldset#edit-role-vis-settings', context).setSummary(function(context) {
+      var vals = [];
+      $("input[type^='checkbox']:checked", context).parent().each(function() {
+        vals.push(Drupal.checkPlain($(this).text()));
+      });
+      return vals.join(', ');
+    });
+    $('fieldset#edit-content-type-vis-settings', context).setSummary(function(context) {
+      var vals = [];
+      $("input[type^='checkbox']:checked", context).parent().each(function() {
+        vals.push(Drupal.checkPlain($(this).text()));
+      });
+      return vals.join(', ');
+    });
+    $('fieldset#edit-user-vis-settings', context).setSummary(function(context) {
+      var vals = [];
+      $("input[type^='radio']:checked", context).parent().each(function() {
+        vals.push(Drupal.checkPlain($(this).text()));
+      });
+      return vals.join(', ');
+    });
+  }
+};
+
 /**
  * Move a block in the blocks table from one region to another via select list.
  *
Index: modules/block/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.module,v
retrieving revision 1.360
diff -u -p -r1.360 block.module
--- modules/block/block.module	20 Aug 2009 10:56:33 -0000	1.360
+++ modules/block/block.module	22 Aug 2009 14:33:45 -0000
@@ -464,11 +464,16 @@ function block_user_validate(&$edit, $ac
 /**
  * Implement hook_form_FORM_ID_alter().
  */
-function block_form_system_themes_form_alter(&$form, &$form_state) {
+function block_form_alter(&$form, &$form_state, $form_id) {
   // This function needs to fire before the theme changes are recorded in the
   // database, otherwise it will populate the default list of blocks from the
   // new theme, which is empty.
-  array_unshift($form['#submit'], 'block_system_themes_form_submit');
+  if ($form_id == 'system_themes_form') {
+    array_unshift($form['#submit'], 'block_system_themes_form_submit');
+  }
+  elseif ($form_id == 'system_admin_theme_form') {
+    array_unshift($form['#submit'], 'block_system_admin_theme_form_submit');  
+  }
 }
 
 /**
@@ -483,6 +488,14 @@ function block_system_themes_form_submit
         }
       }
     }
+  }
+}
+
+/**
+ * Initialize blocks for admin theme.
+ */
+function block_system_admin_theme_form_submit(&$form, &$form_state) {
+  if ($form_state['values']['op'] == t('Save configuration')) {
     if ($form_state['values']['admin_theme'] && $form_state['values']['admin_theme'] !== variable_get('admin_theme', 0)) {
       // If we're changing themes, make sure the theme has its blocks initialized.
       $has_blocks = (bool) db_query_range('SELECT 1 FROM {block} WHERE theme = :theme', array(':theme' => $form_state['values']['admin_theme']), 0, 1)->fetchField();
Index: modules/block/block.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.test,v
retrieving revision 1.25
diff -u -p -r1.25 block.test
--- modules/block/block.test	3 Aug 2009 03:04:33 -0000	1.25
+++ modules/block/block.test	22 Aug 2009 14:33:45 -0000
@@ -293,7 +293,7 @@ class BlockAdminThemeTestCase extends Dr
 
     // Enable admin theme and confirm that tab is accessible.
     $edit['admin_theme'] = 'stark';
-    $this->drupalPost('admin/appearance', $edit, t('Save configuration'));
+    $this->drupalPost('admin/appearance/admin', $edit, t('Save configuration'));
     $this->drupalGet('admin/structure/block/list/stark');
     $this->assertResponse(200, t('The block admin page for the admin theme can be accessed'));
   }
