Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.301
diff -u -r1.301 system.admin.inc
--- modules/system/system.admin.inc	5 Sep 2010 15:38:16 -0000	1.301
+++ modules/system/system.admin.inc	8 Sep 2010 11:19:57 -0000
@@ -869,6 +869,7 @@
     }
 
     // If this module requires other modules, add them to the array.
+    $extra['states']['requires'] = array();
     foreach ($module->requires as $requires => $v) {
       if (!isset($files[$requires])) {
         $extra['requires'][$requires] = t('@module (<span class="admin-missing">missing</span>)', array('@module' => drupal_ucfirst($requires)));
@@ -891,6 +892,7 @@
           $extra['requires'][$requires] = t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $requires_name));
         }
       }
+      $extra['states']['requires'][] = array('package' => $files[$requires]->info['package'], 'filename' => $requires);
     }
     // Generate link for module's help page, if there is one.
     if ($help_arg && $module->status && in_array($filename, module_implements('help'))) {
@@ -926,10 +928,9 @@
       }
     }
 
-    // Mark dependents disabled so the user cannot remove required modules.
-    $dependents = array();
     // If this module is required by other modules, list those, and then make it
     // impossible to disable this one.
+    $extra['states']['required_by'] = array();
     foreach ($module->required_by as $required_by => $v) {
       // Hidden modules are unset already.
       if (isset($visible_files[$required_by])) {
@@ -940,6 +941,7 @@
         else {
           $extra['required_by'][] = t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $files[$required_by]->info['name']));
         }
+        $extra['states']['required_by'][] = array('package' => $files[$required_by]->info['package'], 'filename' => $required_by);
       }
     }
     $form['modules'][$module->info['package']][$filename] = _system_modules_build_row($module->info, $extra);
@@ -1047,6 +1049,20 @@
     $status_long .= t('This module requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $php_required, '!php_version' => phpversion()));
   }
 
+  // Fill the form API #states array to dynamically enable/disable the module
+  // checkboxes depending on the state of the related modules.
+  $states = array();
+  if (empty($info['required'])) {
+    // The module checkbox is enabled if all the modules that it requires are enabled.
+    foreach ($extra['states']['requires'] as $requires) {
+      $states[':input[name="modules[' . $requires['package'] . '][' . $requires['filename'] . '][enable]"]'] = array('checked' => TRUE);
+    }
+    // The module checkbox is disabled if any of the modules that require it are enabled.
+    foreach ($extra['states']['required_by'] as $required_by) {
+      $states[':input[name="modules[' . $required_by['package'] . '][' . $required_by['filename'] . '][enable]"]'] = array('checked' => FALSE);
+    }
+  }
+
   // If this module is compatible, present a checkbox indicating
   // this module may be installed. Otherwise, show a big red X.
   if ($compatible) {
@@ -1054,6 +1070,9 @@
       '#type' => 'checkbox',
       '#title' => t('Enable'),
       '#default_value' => $extra['enabled'],
+      '#states' => array(
+        'enabled' => $states,
+      ),
     );
     if ($extra['disabled']) {
       $form['enable']['#disabled'] = TRUE;
@@ -1130,7 +1149,6 @@
 
   // Builds list of modules.
   $modules = array();
-  // If we're not coming from the confirmation form, build the list of modules.
   if (empty($form_state['storage'])) {
     // If we're not coming from the confirmation form, build the module list.
     foreach ($form_state['values']['modules'] as $group_name => $group) {
