Index: skinr.api.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/skinr.api.php,v
retrieving revision 1.5
diff -u -p -r1.5 skinr.api.php
--- skinr.api.php	16 Jan 2011 19:13:32 -0000	1.5
+++ skinr.api.php	28 Jan 2011 19:21:06 -0000
@@ -199,6 +199,9 @@ function hook_skinr_api_VERSION() {
  *   enable skins which are required to make the theme work properly by default.
  *   Setting this property to 1 will cause it to be enabled by default for all
  *   installed themes.
+ * - status: (optional) An associative array whose keys are theme names and
+ *   whose corresponding values denote the desired default status for the
+ *   particular theme.
  *
  * The "hook" prefix is substituted with the name of the module or theme
  * implementing it.
@@ -253,6 +256,21 @@ function hook_skinr_skin_info() {
         ),
       ),
     ),
+    // Optional: Specify a global default status for this skin, making it
+    // available or unavailable to all themes.
+    'default status' => 0,
+    // Optional: Specify a default status for a particular theme. This mainly
+    // makes sense for skins provided by themes only.
+    'status' => array(
+      'bartik' => 1,
+      'garland' => 0,
+      // In case you are registering a skin for your base theme, then you likely
+      // do not know which sub themes are going to use your base theme. By
+      // setting the global default status to 0 (as above) and enabling the skin
+      // for your base theme itself, the skin's status will be automatically
+      // inherited to all sub themes of your base theme.
+      'mybasetheme' => 1,
+    ),
   );
   return $skins;
 }
Index: skinr.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/skinr.module,v
retrieving revision 1.42
diff -u -p -r1.42 skinr.module
--- skinr.module	16 Jan 2011 19:13:32 -0000	1.42
+++ skinr.module	27 Jan 2011 06:12:08 -0000
@@ -41,6 +41,13 @@ function skinr_hook_info() {
 }
 
 /**
+ * Clears cached Skinr information.
+ */
+function skinr_cache_reset() {
+  cache_clear_all('skinr_', 'cache', TRUE);
+}
+
+/**
  * Implements hook_module_implements_alter().
  */
 function skinr_module_implements_alter(&$implementations, $hook) {
@@ -450,6 +457,8 @@ function skinr_rule_visible($rid) {
  *   - path: The path to the extension.
  *   - directory: (optional) The sub-directory holding Skinr plugin files.
  *   - ...: Any other properties defined by the module or theme.
+ *
+ * @todo Cache this.
  */
 function skinr_implements() {
   $cache = &drupal_static(__FUNCTION__);
@@ -459,11 +468,13 @@ function skinr_implements() {
     // Collect hook_skinr_api_VERSION() module implementations. This will also
     // auto-load $module.skinr.inc files, which may contain skin/group hook
     // implementations (when not using the plugin system).
+    $module_info = system_get_info('module');
     foreach (module_implements('skinr_api_' . SKINR_VERSION) as $module) {
       // Ensure that $module and the extension type is registered.
       $cache[$module] = array(
         'type' => 'module',
         'name' => $module,
+        'version' => isset($module_info[$module]['version']) ? $module_info[$module]['version'] : NULL,
       );
       // Check whether the hook returns any information.
       $function = $module . '_skinr_api_' . SKINR_VERSION;
@@ -499,15 +510,30 @@ function skinr_implements() {
     // regardless of whether base themes are enabled.
     $all_themes = list_themes();
     $themes = array();
+    // Additionally record the base themes and sub themes of each theme, in
+    // order to apply inheritance rules elsewhere. Do not assign these variables
+    // as properties on the theme objects themselves, since all objects are
+    // pointers (much like references) in PHP 5, so our properties would be
+    // visible for everyone else who calls list_themes().
+    $base_themes = array();
+    $sub_themes = array();
     foreach ($all_themes as $name => $theme) {
       // If the theme is enabled, add it to the stack.
       if (!empty($theme->status)) {
         $themes[$name] = $theme;
         // Find and add all base themes of the enabled theme to the stack.
         // @see drupal_theme_initialize()
+        $sub_theme_name = $name;
         while ($name && isset($all_themes[$name]->base_theme)) {
+          // Record the sub theme for the base theme.
+          $sub_themes[$all_themes[$name]->base_theme][$name] = $name;
+
+          // Add the base theme to the stack.
           $name = $all_themes[$name]->base_theme;
           $themes[$name] = $all_themes[$name];
+
+          // Record the base theme for the original sub theme.
+          $base_themes[$sub_theme_name][$name] = $name;
         }
       }
     }
@@ -517,6 +543,9 @@ function skinr_implements() {
         $cache[$name] = array(
           'type' => 'theme',
           'name' => $name,
+          'version' => isset($theme->info['version']) ? $theme->info['version'] : NULL,
+          'base themes' => isset($base_themes[$name]) ? $base_themes[$name] : array(),
+          'sub themes' => isset($sub_themes[$name]) ? $sub_themes[$name] : array(),
         );
         // Add any additional information that has been registered.
         $cache[$name] += $theme->info['skinr'];
@@ -692,20 +721,19 @@ function skinr_skin_delete_multiple($arg
 }
 
 /**
- * Retrieves the desired skinr object.
+ * Retrieves a stored skin from the database.
  *
  * @param $theme
- *   The theme these settings apply to. If no theme name is provided, the
- *   current theme will be used.
+ *   The theme of the skin. Defaults to the current theme.
  * @param $module
- *   The module these settings apply to.
+ *   The module of the skin.
  * @param $sid
- *   The element ID these settings apply to.
+ *   The element ID of the skin.
  *
  * @return
- *   A skin object if both $module and $sid are specified. An array of skin
- *   objects if only $module is specified. An array of all skin objects for a
- *   theme if neither $module nor $sid is specified. FALSE on failure.
+ *   A skin object if both $module and $sid are specified. An array of skins
+ *   if only $module is specified. An array of all skins for a theme if neither
+ *   $module nor $sid is specified. FALSE on failure.
  *
  * @todo Rename $skin->skins to $skin->options throughout the module.
  */
@@ -716,55 +744,44 @@ function skinr_skin_load($theme = NULL, 
     $theme = skinr_current_theme();
   }
 
+  // @todo This condition is always FALSE when no $sid is passed.
   if (!isset($skins[$theme][$module][$sid])) {
-    if (!isset($skins[$theme])) {
-      $skins[$theme] = array();
-    }
-    if (isset($module) && !isset($skins[$theme][$module])) {
-      $skins[$theme][$module] = array();
+    $skins += array($theme => array());
+    if (isset($module)) {
+      $skins[$theme] += array($module => array());
     }
 
-    if (isset($module) && isset($sid)) {
-      // Fetch just this sid.
-      $result = db_query("SELECT theme, module, sid, settings, skins FROM {skinr} WHERE theme = :theme AND module = :module AND sid = :sid", array(
-        ':theme' => $theme,
-        ':module' => $module,
-        ':sid' => $sid,
-      ));
-    }
-    elseif (isset($module)) {
-      // Fetch all settings for this theme and module.
-      $result = db_query("SELECT theme, module, sid, settings, skins FROM {skinr} WHERE theme = :theme AND module = :module", array(
-        ':theme' => $theme,
-        ':module' => $module,
-      ));
+    $query = db_select('skinr', 's')
+      ->fields('s', array('theme', 'module', 'sid', 'settings', 'skins'));
+    if (isset($theme)) {
+      $query->condition('theme', $theme);
     }
-    else {
-      // Fetch all settings for this theme.
-      $result = db_query("SELECT theme, module, sid, settings, skins FROM {skinr} WHERE theme = :theme", array(
-        ':theme' => $theme,
-      ));
+    if (isset($module)) {
+      $query->condition('module', $module);
     }
-
-    foreach ($result as $skin) {
+    if (isset($sid)) {
+      $query->condition('sid', $sid);
+    }
+    foreach ($query->execute() as $skin) {
       $skin->settings = unserialize($skin->settings);
       $skin->skins = unserialize($skin->skins);
       $skins[$skin->theme][$skin->module][$skin->sid] = $skin;
     }
   }
 
-  if (!isset($sid) && isset($module)) {
-    // Return all the skinrs for the theme.
+  // Return all skins for the passed theme.
+  if (!isset($module) && !isset($sid)) {
     if (isset($skins[$theme])) {
       return $skins[$theme];
     }
   }
+  // Return all skins for the passed module.
   elseif (!isset($sid)) {
-    // Return all the skinrs for the module.
     if (isset($skins[$theme][$module])) {
       return $skins[$theme][$module];
     }
   }
+  // Return the requested skin.
   elseif (isset($skins[$theme][$module][$sid])) {
     return $skins[$theme][$module][$sid];
   }
@@ -840,46 +857,44 @@ function skinr_current_theme($exclude_ad
 }
 
 /**
- * Prepare defaults for skins.
- *
- * @return
- *   An array of default skin settings.
- *
- * @todo Merge into skinr_get_skin_info() and remove this function.
- */
-function skinr_skin_info_default() {
-  return array(
-    'name' => '',
-    'title' => '',
-    'type' => 'checkboxes',
-    'description' => '',
-    'group' => '',
-    'theme hooks' => array('*'),
-    'attached' => array(),
-    'options' => array(),
-    'weight' => NULL,
-    'default status' => 0,
-    'status' => array(),
-  );
-}
-
-/**
  * Prepare the default status for a skin.
  *
- * @param $default_status
- *   The default status for all themes for a skin.
+ * @param $skin_info
+ *   Information about a registered skin.
  *
  * @return
  *   An array of default statuses for each enabled theme.
  */
-function skinr_skin_info_status_default($default_status = 0) {
+function skinr_skin_info_status_default($skin_info) {
   $status = array();
-  foreach (list_themes() as $theme_name => $theme) {
+  // Retrieve the explicit default status of the registering theme for itself.
+  $base_theme_status = NULL;
+  if (isset($skin_info['status'][$skin_info['source']['name']])) {
+    $base_theme_status = $skin_info['status'][$skin_info['source']['name']];
+  }
+  // Retrieve the sub themes of the base theme that registered the skin.
+  $sub_themes = array();
+  if (isset($skin_info['source']['sub themes'])) {
+    $sub_themes = $skin_info['source']['sub themes'];
+  }
+  $themes = list_themes();
+  foreach ($themes as $name => $theme) {
     if (!$theme->status) {
       continue;
     }
-    $status[$theme_name] = $default_status;
+    // If this theme is a sub theme of the theme that registered the skin, check
+    // whether we need to inherit the status of the base theme to the sub theme.
+    // This is the case when a skin of a base theme enables itself for the base
+    // theme (not knowing about potential sub themes).
+    if (isset($base_theme_status) && isset($sub_themes[$name])) {
+      $status[$name] = $base_theme_status;
+    }
+    // Apply global default.
+    $status += array($name => $skin_info['default status']);
   }
+  // Lastly, apply all explicit defaults.
+  $status = array_merge($status, $skin_info['status']);
+
   return $status;
 }
 
@@ -928,8 +943,20 @@ function _skinr_add_path_to_files(&$file
  */
 function skinr_skin_info_process(&$skin_infos, $source) {
   foreach ($skin_infos as $skin_name => $skin_info) {
-    // Merge in defaults.
-    $skin_infos[$skin_name] = array_merge(skinr_skin_info_default(), $skin_infos[$skin_name]);
+    // Populate default properties.
+    $skin_infos[$skin_name] += array(
+      'name' => '',
+      'title' => '',
+      'type' => 'checkboxes',
+      'description' => '',
+      'group' => '',
+      'theme hooks' => array('*'),
+      'attached' => array(),
+      'options' => array(),
+      'weight' => NULL,
+      'default status' => 0,
+      'status' => array(),
+    );
 
     // Merge in name.
     $skin_infos[$skin_name]['name'] = $skin_name;
@@ -937,8 +964,8 @@ function skinr_skin_info_process(&$skin_
     // Merge in source information.
     $skin_infos[$skin_name]['source'] = $source;
 
-    // Merge in default statuses for all themes.
-    $skin_infos[$skin_name]['status'] = array_merge(skinr_skin_info_status_default($skin_infos[$skin_name]['default status']), $skin_infos[$skin_name]['status']);
+    // Merge in default status for all themes.
+    $skin_infos[$skin_name]['status'] = skinr_skin_info_status_default($skin_infos[$skin_name]);
 
     // Add path to stylesheets.
     if (isset($skin_infos[$skin_name]['attached']['css'])) {
@@ -1217,4 +1244,33 @@ function skinr_handler($type, $op, $hand
         return $handler($op, $a3, $a4);
     }
   }
-}
\ No newline at end of file
+}
+
+/**
+ * Implements hook_modules_enabled().
+ */
+function skinr_modules_enabled() {
+  skinr_cache_reset();
+}
+
+/**
+ * Implements hook_modules_disabled().
+ */
+function skinr_modules_disabled() {
+  skinr_cache_reset();
+}
+
+/**
+ * Implements hook_themes_enabled().
+ */
+function skinr_themes_enabled() {
+  skinr_cache_reset();
+}
+
+/**
+ * Implements hook_themes_disabled().
+ */
+function skinr_themes_disabled() {
+  skinr_cache_reset();
+}
+
Index: skinr_ui.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/skinr_ui.admin.inc,v
retrieving revision 1.22
diff -u -p -r1.22 skinr_ui.admin.inc
--- skinr_ui.admin.inc	13 Jan 2011 06:46:55 -0000	1.22
+++ skinr_ui.admin.inc	27 Jan 2011 04:17:31 -0000
@@ -420,8 +420,6 @@ function skinr_ui_multiple_delete_confir
  * @see skinr_ui_admin_skin_infos_submit()
  */
 function skinr_ui_admin_skin_infos($form, $form_state) {
-  $form = array();
-
   $skins = skinr_get_skin_info();
   if (empty($skins)) {
     $form['skins_empty'] = array(
@@ -436,19 +434,14 @@ function skinr_ui_admin_skin_infos($form
   // Iterate through each of the skins.
   foreach ($skins as $name => $skin) {
     $extra = array();
-    // @todo Status for skins is now per theme; either figure out a better way to display, or delete the status row.
-    $extra['enabled'] = TRUE;
 
     // Generate link for skin's configuration page
-    $configure_link = menu_get_item('admin/appearance/skinr/skins/settings/'. $name);
-    if ($configure_link['access']) {
-      $extra['links']['configure'] = array(
-        '#type' => 'link',
-        '#title' => t('Configure'),
-        '#href' => $configure_link['href'],
-        '#options' => array('attributes' => array('class' => array('skin-link', 'skin-link-configure'), 'title' => $configure_link['description'])),
-      );
-    }
+    $extra['links']['configure'] = array(
+      '#type' => 'link',
+      '#title' => t('Configure'),
+      '#href' => 'admin/appearance/skinr/skins/settings/' . $name,
+      '#options' => array('attributes' => array('class' => array('skin-link', 'skin-link-configure'))),
+    );
 
     // Create a row entry for this skin.
     $form['skins'][$skin['group']][$name] = _skinr_ui_admin_skin_infos_build_row($skin, $extra);
@@ -513,10 +506,10 @@ function _skinr_ui_admin_skin_infos_buil
     '#markup' => $skin['source']['type'],
   );
   $form['source name'] = array(
-    '#markup' => $info['name'],
+    '#markup' => $skin['source']['name'],
   );
   $form['source version'] = array(
-    '#markup' => $info['version'],
+    '#markup' => $skin['source']['version'],
   );
   $form['source plugin'] = array(
     '#markup' => '', //$skin['source']['plugin'],
@@ -530,31 +523,13 @@ function _skinr_ui_admin_skin_infos_buil
     '#markup' => implode('<br />', $theme_hooks),
   );
 
-  // Check the compatibilities.
-  $compatible = TRUE;
-  $status_short = '';
-  $status_long = '';
-
-  // @todo Check for Skinr API compatibility.
-  $compatible = TRUE;
-
-  // If this skin is compatible, present a checkbox indicating
-  // this skin may be installed. Otherwise, show a big red X.
-  if ($compatible) {
-    $form['enable'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Enable'),
-      '#default_value' => $extra['enabled'],
-    );
-    if ($extra['disabled']) {
-      $form['enable']['#disabled'] = TRUE;
-    }
-  }
-  else {
-    $form['enable'] = array(
-      '#markup' =>  theme('image', array('path' => 'misc/watchdog-error.png', 'alt' => t('incompatible'), 'title' => $status_short)),
-    );
-    $form['name']['#markup'] .= theme('theme_skinr_ui_admin_skin_infos_incompatible', array('message' => $status_long));
+  $form['enable'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable'),
+    '#default_value' => $extra['enabled'],
+  );
+  if ($extra['disabled']) {
+    $form['enable']['#disabled'] = TRUE;
   }
 
   // Build operation links.
@@ -699,47 +674,35 @@ function theme_skinr_ui_admin_skin_infos
  * @ingroup forms
  * @see skinr_ui_admin_skin_infos_settings_submit()
  */
-function skinr_ui_admin_skin_infos_settings($form, $form_state, $skinset_name) {
-  $form = array();
-
-  $skin_infos = skinr_get_skin_info();
-  if (!empty($skin_infos[$skinset_name])) {
-    $skin_info = $skin_infos;
-
-    $themes = list_themes();
-    ksort($themes);
-
-    $form['skins'] = array('#tree' => TRUE);
+function skinr_ui_admin_skin_infos_settings($form, &$form_state, $skin_info) {
+  $themes = list_themes();
+  ksort($themes);
 
-    // Iterate through each of the skinsets.
-    foreach ($skin_info as $name => $skin) {
-      foreach ($themes as $theme) {
-        if (!$theme->status) {
-          continue;
-        }
+  $form['skins'] = array('#tree' => TRUE);
 
-        // Create a row entry for this skinset.
-        $form['skins'][$theme->name][$name] = _skinr_ui_admin_skin_infos_settings_build_row($skin, $theme->name);
-      }
+  foreach ($themes as $theme) {
+    if ($theme->status) {
+      // Create a row entry for this skinset.
+      $form['skins'][$theme->name][$skin_info['name']] = _skinr_ui_admin_skin_infos_settings_build_row($skin_info, $theme->name);
     }
+  }
 
-    // Add basic information to the fieldsets.
-    $current_theme = skinr_current_theme(TRUE);
-    foreach (element_children($form['skins']) as $theme_name) {
-      $form['skins'][$theme_name] += array(
-        '#type' => 'fieldset',
-        '#title' => t($themes[$theme_name]->info['name']),
-        '#collapsible' => TRUE,
-        '#collapsed' => ($theme_name != $current_theme),
-        '#theme' => 'skinr_ui_admin_skin_infos_settings_fieldset',
-        '#header' => array(
-          t('Enabled'),
-          t('Name'),
-        ),
-      );
-    }
+  // Add basic information to the fieldsets.
+  $current_theme = skinr_current_theme(TRUE);
+  foreach (element_children($form['skins']) as $theme_name) {
+    $form['skins'][$theme_name] += array(
+      '#type' => 'fieldset',
+      '#title' => t($themes[$theme_name]->info['name']),
+      '#collapsible' => TRUE,
+      '#collapsed' => ($theme_name != $current_theme),
+      '#theme' => 'skinr_ui_admin_skin_infos_settings_fieldset',
+      '#header' => array(
+        t('Enabled'),
+        t('Name'),
+      ),
+    );
   }
-  $form_state['skin_info'] = $skin_infos;
+  $form_state['skin_info'] = $skin_info;
 
   $form['actions'] = array('#type' => 'actions');
   $form['actions']['submit'] = array(
@@ -761,7 +724,7 @@ function _skinr_ui_admin_skin_infos_sett
   $form['enable'] = array(
     '#type' => 'checkbox',
     '#title' => t('Enable'),
-    '#default_value' => !empty($skin['status'][$theme_name]),
+    '#default_value' => (int) !empty($skin['status'][$theme_name]),
   );
 
   // The hooks this skin is working with.
@@ -854,7 +817,7 @@ function skinr_ui_admin_skin_infos_setti
 
     foreach ($statuses as $name => $status) {
       $skinr_skin = new StdClass();
-      $skinr_skin->name = $form_state['skin_info'][$name]['source']['name'];
+      $skinr_skin->name = $form_state['skin_info']['source']['name'];
       $skinr_skin->type = 'skinset';
       $skinr_skin->skin = $name;
       $skinr_skin->status = $status;
@@ -882,8 +845,6 @@ function skinr_ui_admin_skin_infos_setti
 
   drupal_set_message(t('The configuration options have been saved.'));
   $form_state['redirect'] = 'admin/appearance/skinr/skins';
-
-  return;
 }
 
 /**
Index: skinr_ui.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/skinr_ui.module,v
retrieving revision 1.24
diff -u -p -r1.24 skinr_ui.module
--- skinr_ui.module	20 Dec 2010 21:42:29 -0000	1.24
+++ skinr_ui.module	27 Jan 2011 03:49:15 -0000
@@ -41,7 +41,6 @@ function skinr_ui_menu() {
     'title' => 'List',
     'description' => t('Manage Skinr settings.'),
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'parent' => 'admin/appearance/skinr',
     'weight' => -10,
   );
 
@@ -51,41 +50,27 @@ function skinr_ui_menu() {
     'description' => 'Manage which skins are available when changing Skinr settings.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('skinr_ui_admin_skin_infos'),
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer skinr'),
     'file' => 'skinr_ui.admin.inc',
     'type' => MENU_LOCAL_TASK,
-    'parent' => 'admin/appearance/skinr',
   );
   $items['admin/appearance/skinr/skins/select'] = array(
     'title' => 'List',
     'description' => 'Manage your skins.',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'parent' => 'admin/appearance/skinr/skins',
     'weight' => -1,
   );
-  // drupal_uninstall_modules() invokes hook_menu() in disabled modules and does
-  // not respect module dependencies. Therefore, uninstalling both Skinr UI and
-  // Skinr at the same time is leading to a database error, since
-  // skinr_get_skin_info() tries to load data from tables that have been deleted
-  // already.
-  // @see http://drupal.org/node/151452
-  // @see http://drupal.org/node/320303
-  $skin_infos = array();
-  if (in_array('skinr', module_list())) {
-    $skin_infos = skinr_get_skin_info();
-  }
-  foreach ($skin_infos as $skin_info) {
-    $items['admin/appearance/skinr/skins/settings/' . $skin_info['name']] = array(
-      'title' => $skin_info['title'],
-      'description' => 'Manage which options are available for each Skin when changing Skinr settings.',
-      'page callback' => 'drupal_get_form',
-      'page arguments' => array('skinr_ui_admin_skin_infos_settings', $skin_info['name']),
-      'access arguments' => array('administer site configuration'),
-      'file' => 'skinr_ui.admin.inc',
-      'type' => MENU_LOCAL_TASK,
-      'parent' => 'admin/appearance/skinr/skins',
-    );
-  }
+  $items['admin/appearance/skinr/skins/settings/%skinr_ui_skin_info'] = array(
+    'title' => 'Skin settings',
+    'title callback' => 'skinr_ui_skin_info_title',
+    'title arguments' => array(5),
+    'description' => 'Manage which options are available for each Skin when changing Skinr settings.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('skinr_ui_admin_skin_infos_settings', 5),
+    'access arguments' => array('administer skinr'),
+    'file' => 'skinr_ui.admin.inc',
+    'type' => MENU_LOCAL_TASK,
+  );
 
   // Rules.
   $items['admin/appearance/skinr/rules'] = array(
@@ -93,7 +78,6 @@ function skinr_ui_menu() {
     'page callback' => 'skinr_rules',
     'type' => MENU_LOCAL_TASK,
     'access arguments' => array('administer skinr'),
-    'parent' => 'admin/appearance/skinr',
     'weight' => 1,
     'description' => t('Configure region and page level Skinr rules.'),
     'file' => 'skinr_ui.rules.inc',
@@ -130,7 +114,6 @@ function skinr_ui_menu() {
     'page arguments' => array('skinr_ui_import_form'),
     'type' => MENU_LOCAL_TASK,
     'access arguments' => array('administer skinr'),
-    'parent' => 'admin/appearance/skinr',
     'weight' => 2,
     'description' => t('Import Skinr settings.'),
     'file' => 'skinr_ui.admin.inc',
@@ -141,7 +124,6 @@ function skinr_ui_menu() {
     'page arguments' => array('skinr_ui_export_form'),
     'type' => MENU_LOCAL_TASK,
     'access arguments' => array('administer skinr'),
-    'parent' => 'admin/appearance/skinr',
     'weight' => 3,
     'description' => t('Export Skinr settings.'),
     'file' => 'skinr_ui.admin.inc',
@@ -189,6 +171,24 @@ function skinr_ui_menu() {
 }
 
 /**
+ * Menu argument loader; Retrieves skin information for a single skin.
+ */
+function skinr_ui_skin_info_load($name) {
+  $skin_info = skinr_get_skin_info();
+  if (isset($skin_info[$name])) {
+    return $skin_info[$name];
+  }
+  return FALSE;
+}
+
+/**
+ * Menu title callback; Returns the title of a skin.
+ */
+function skinr_ui_skin_info_title($skin_info) {
+  return check_plain($skin_info['title']);
+}
+
+/**
  * Helper function to determine if ajax is used to call a function.
  */
 function skinr_js_load($js = 'nojs') {
Index: tests/skinr.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/tests/skinr.test,v
retrieving revision 1.10
diff -u -p -r1.10 skinr.test
--- tests/skinr.test	16 Jan 2011 20:40:31 -0000	1.10
+++ tests/skinr.test	28 Jan 2011 19:22:06 -0000
@@ -116,6 +116,7 @@ class SkinrApiTestCase extends DrupalWeb
       'skinr' => array(),
       // Node is a required core module, so always expected.
       'node' => array(
+        'version' => VERSION,
         'path' => drupal_get_path('module', 'skinr') . '/modules',
       ),
       // skinr_test has been installed.
@@ -126,18 +127,28 @@ class SkinrApiTestCase extends DrupalWeb
         'type' => 'theme',
         'api' => 2,
         'directory' => 'skins',
+        'base themes' => array(),
+        'sub themes' => drupal_map_assoc(array('skinr_test_subtheme')),
       ),
       'skinr_test_subtheme' => array(
         'type' => 'theme',
         'api' => 2,
         'directory' => 'skins',
+        'base themes' => drupal_map_assoc(array('skinr_test_basetheme')),
+        'sub themes' => array(),
       ),
     );
+    // When running tests on Skinr code packaged by drupal.org, all 'version'
+    // properties will have the version of the Skinr module. When running on a
+    // repository checkout, the version is NULL (undefined).
+    $skinr_module_info = system_get_info('module', 'skinr');
+    $skinr_module_version = (!empty($skinr_module_info['version']) ? $skinr_module_info['version'] : NULL);
     foreach ($all_expected as $name => $expected) {
       // Populate defaults.
       $expected += array(
         'type' => 'module',
         'name' => $name,
+        'version' => $skinr_module_version,
       );
       $expected += array(
         'path' => drupal_get_path($expected['type'], $name),
@@ -188,6 +199,9 @@ class SkinrApiTestCase extends DrupalWeb
     $this->assertEqual($skin_info['skinr_test_basetheme']['source']['path'], $path . '/tests/themes/skinr_test_basetheme', t('Skin path points to basetheme directory: @path', array(
       '@path' => $skin_info['skinr_test_basetheme']['source']['path'],
     )));
+    $default_theme = variable_get('theme_default', 'bartik');
+    $this->assertEqual($skin_info['skinr_test_basetheme']['status'][$default_theme], 0, 'Basetheme skin is disabled for default theme.');
+    $this->assertEqual($skin_info['skinr_test_basetheme']['status']['skinr_test_basetheme'], 1, 'Basetheme skin is enabled for Skinr test basetheme.');
     unset($skin_info['skinr_test_basetheme']);
 
     // skinr_test_subtheme is registered via hook_skinr_skin_info() in
Index: tests/skinr_ui.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/tests/skinr_ui.test,v
retrieving revision 1.1
diff -u -p -r1.1 skinr_ui.test
--- tests/skinr_ui.test	16 Jan 2011 21:08:33 -0000	1.1
+++ tests/skinr_ui.test	27 Jan 2011 05:58:21 -0000
@@ -120,4 +120,27 @@ class SkinrUIBasicTestCase extends Drupa
     $class = (string) $elements[0]['class'];
     $this->assertTrue(strpos($class, ' font-1 '), 'CSS class of configured skin option found.');
   }
+
+  /**
+   * Tests default status of skins.
+   *
+   * @todo Add assertions for 'default status' itself.
+   */
+  function testSkinAdminDefaultStatus() {
+    // The skinr_test_basetheme skin defined by the skinr_test_basetheme theme
+    // specifies a default status for itself. Enable its subtheme (only) to test
+    // that the status of the basetheme is inherited to the subtheme.
+    theme_enable(array('garland', 'skinr_test_subtheme'));
+
+    // Verify that the skin appears on the skin overview page.
+    $this->drupalGet('admin/appearance/skinr/skins');
+    $this->assertLinkByHref('admin/appearance/skinr/skins/settings/skinr_test_basetheme');
+    $this->drupalGet('admin/appearance/skinr/skins/settings/skinr_test_basetheme');
+
+    // Verify that it is enabled for the skinr_test_subtheme, and disabled for
+    // Bartik and Garland by default.
+    $this->assertFieldChecked('edit-skins-skinr-test-subtheme-skinr-test-basetheme-enable', 'skinr_test_basetheme skin is enabled for skinr_test_subtheme.');
+    $this->assertNoFieldChecked('edit-skins-bartik-skinr-test-basetheme-enable', 'skinr_test_basetheme skin is disabled for Bartik.');
+    $this->assertNoFieldChecked('edit-skins-garland-skinr-test-basetheme-enable', 'skinr_test_basetheme skin is disabled for Garland.');
+  }
 }
Index: tests/themes/skinr_test_basetheme/skinr_test_basetheme.skinr.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/tests/themes/skinr_test_basetheme/skinr_test_basetheme.skinr.inc,v
retrieving revision 1.2
diff -u -p -r1.2 skinr_test_basetheme.skinr.inc
--- tests/themes/skinr_test_basetheme/skinr_test_basetheme.skinr.inc	16 Jan 2011 19:13:32 -0000	1.2
+++ tests/themes/skinr_test_basetheme/skinr_test_basetheme.skinr.inc	21 Jan 2011 02:59:08 -0000
@@ -7,7 +7,10 @@
 function skinr_test_basetheme_skinr_skin_info() {
   $skins['skinr_test_basetheme'] = array(
     'title' => 'Base theme skin',
-    'default status' => 1,
+    'default status' => 0,
+    'status' => array(
+      'skinr_test_basetheme' => 1,
+    ),
   );
   return $skins;
 }
