Index: includes/install.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/install.inc,v
retrieving revision 1.39
diff -u -p -r1.39 install.inc
--- includes/install.inc	15 May 2007 15:29:47 -0000	1.39
+++ includes/install.inc	16 May 2007 13:16:15 -0000
@@ -273,7 +273,7 @@ function drupal_verify_profile($profile,
 
   // Get a list of modules required by this profile.
   $function = $profile .'_profile_modules';
-  $module_list = array_merge(drupal_required_modules(), $function(), ($locale ? array('locale') : array()));
+  $module_list = array_merge(drupal_required_modules(), $function(), ($locale != 'en' ? array('locale') : array()));
 
   // Get a list of modules that exist in Drupal's assorted subdirectories.
   $present_modules = array();
Index: includes/locale.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/locale.inc,v
retrieving revision 1.124
diff -u -p -r1.124 locale.inc
--- includes/locale.inc	15 May 2007 15:29:47 -0000	1.124
+++ includes/locale.inc	16 May 2007 13:16:17 -0000
@@ -2100,7 +2100,7 @@ function _locale_get_predefined_list() {
  */
 
 /**
- * Prepare a batch to use to import translations.
+ * Prepare a batch to use to import translations on install time.
  *
  * @param $langcode
  *   Language code to import translations for.
@@ -2120,68 +2120,72 @@ function locale_batch_installer($langcod
     $files = array_merge($files, file_scan_directory(dirname($component->filename) .'/po/', '(^|\.)'. $langcode .'\.po$', array('.', '..', 'CVS'), 0, FALSE));
   }
 
-  if (count($files)) {
-    $$operations = array();
-    foreach($files as $file) {
-      // We call _locale_batch_import for every batch operation
-      // with the file name and language code.
-      $operations[] = array('_locale_batch_import', array($file->filename, $langcode));
-    }
-    return _locale_batch_build($operations, '_locale_batch_installer_finished');
-  }
-
-  // Found nothing to import.
-  return FALSE;
+  return _locale_batch_build($files, '_locale_batch_installer_finished');
 }
 
 /**
  * Build a locale batch from an array of files.
  *
- * @param $operations
- *   Array of operations to perform
+ * @param $files
+ *   Array of files to import
  * @param $finished
  *   A finished callback to use for the batch
  * @return
  *   A batch structure
  */
-function _locale_batch_build($operations, $finished) {
+function _locale_batch_build($files, $finished = NULL) {
   $t = get_t();
-  if (count($operations)) {
-    $batch = array(
-      'operations'    => $operations,
-      'title'         => $t('Importing interface translations'),
-      'init_message'  => $t('Starting import'),
-      'error_message' => $t('Error importing interface translations'),
-      'finished'      => $finished,
-    );
+  if (count($files)) {
+    $operations = array();
+    foreach($files as $file) {
+      // We call _locale_batch_import for every batch operation.
+      $operations[] = array('_locale_batch_import', array($file->filename));    }
+      $batch = array(
+        'operations'    => $operations,
+        'title'         => $t('Importing interface translations'),
+        'init_message'  => $t('Starting import'),
+        'error_message' => $t('Error importing interface translations'),
+      );
+      if (isset($finished)) {
+        $batch['finished'] = $finished;
+      }
     return $batch;
   }
   return FALSE;
 }
 
 /**
- * Perform interface translation import as a batch step.
- *
- * @param $filepath
- *   Path to a file to import.
- * @param $langcode
- *   Language to import file into.
- * @param $results
- *   Contains a list of files imported.
- */
-function _locale_batch_import($filepath, $langcode, &$context) {
-  $file = (object) array('filename' => basename($filepath), 'filepath' => $filepath);
-  _locale_import_read_po('db-store', $file, 'keep', $langcode);
-  $context['results'][] = $filepath;
-}
-
-/**
  * Batch callback invoked when installer import processing finishes.
  * Advance installer task to the finished screen.
  */
 function _locale_batch_installer_finished($success, $results) {
   variable_set('install_task', 'finished');
 }
+
+/**
+ * Prepare a batch to run when enabling modules and themes
+ */
+function locale_batch_system($components) {
+  $files = array();
+  $languages = language_list('enabled');
+  unset($languages[1]['en']);
+  if (count($languages[1])) {
+    $language_list = join('|', array_keys($languages[1]));
+    // Collect all files to import for all $components (modules or themes).
+    $result = db_query("SELECT name, filename FROM {system} WHERE status = 1");
+    while ($component = db_fetch_object($result)) {
+      if (in_array($component->name, $components)) {
+        // Collect all files for this component in all enabled languages, named
+        // as $langcode.po or with names ending with $langcode.po. This allows
+        // for filenames like node-module.de.po to let translators use small
+        // files and be able to import in smaller chunks.
+        $files = array_merge($files, file_scan_directory(dirname($component->filename) .'/po/', '(^|\.)('. $language_list .')\.po$', array('.', '..', 'CVS'), 0, FALSE));
+      }
+    }
+    return _locale_batch_build($files);
+  }
+  return FALSE;
+}
 /**
  * @} End of "locale-autoimport"
  */
Index: modules/locale/locale.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v
retrieving revision 1.172
diff -u -p -r1.172 locale.module
--- modules/locale/locale.module	15 May 2007 20:19:47 -0000	1.172
+++ modules/locale/locale.module	16 May 2007 13:16:21 -0000
@@ -424,3 +424,55 @@ function locale_language_list($field = '
   }
   return $list;
 }
+
+/**
+ * Imports translations when new modules or themes are
+ * installed or enabled. This function will either import
+ * translation for the component change right away, or
+ * start a batch if more files need to be imported.
+ *
+ * @param $type
+ *   Either 'module' or 'theme', depending on the type of system change.
+ * @param $disabled
+ *   A list of the names of disabled components.
+ * @param $enabled
+ *   A list of the names of enabled components.
+ * @param $new
+ *   A list of the names of new components, if applicable.
+ */
+function locale_system_update($type, $disabled, $enabled, $new = array()) {
+  include_once 'includes/locale.inc';
+  switch ($type) {
+    case 'module':
+      // Import files for newly installed modules.
+      $components = $new;
+      break;
+    case 'theme':
+      // Import files for enabled themes (we don't know whether
+      // these were enabled anytime before)
+      $components = $enabled;
+      break;
+    default:
+      $components = array();
+  }
+  if ($batch = locale_batch_system($components)) {
+    batch_set($batch);
+  }
+}
+
+/**
+ * Perform interface translation import as a batch step.
+ *
+ * @param $filepath
+ *   Path to a file to import.
+ * @param $results
+ *   Contains a list of files imported.
+ */
+function _locale_batch_import($filepath, &$context) {
+  include_once 'includes/locale.inc';
+  if (preg_match('!(/|\.)([^\.]+)\.po$!', $filepath, $langcode)) {
+    $file = (object) array('filename' => basename($filepath), 'filepath' => $filepath);
+    _locale_import_read_po('db-store', $file, 'keep', $langcode[2]);
+    $context['results'][] = $filepath;
+  }
+}
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.476
diff -u -p -r1.476 system.module
--- modules/system/system.module	14 May 2007 16:22:26 -0000	1.476
+++ modules/system/system.module	16 May 2007 13:16:22 -0000
@@ -1391,6 +1391,13 @@ function theme_system_themes_form($form)
 
 function system_themes_form_submit($form_values, $form, &$form_state) {
 
+  // Store list of previously enabled themes and disable all themes
+  $old_theme_list = $new_theme_list = array();
+  foreach (list_themes() as $theme) {
+    if ($theme->status) {
+      $old_theme_list[] = $theme->name;
+    }
+  }
   db_query("UPDATE {system} SET status = 0 WHERE type = 'theme'");
 
   if ($form_values['op'] == t('Save configuration')) {
@@ -1399,6 +1406,7 @@ function system_themes_form_submit($form
         // Always enable the default theme, despite its status checkbox being checked:
         if ($choice || $form_values['theme_default'] == $key) {
           system_initialize_theme_blocks($key);
+          $new_theme_list[] = $key;
           db_query("UPDATE {system} SET status = 1 WHERE type = 'theme' and name = '%s'", $key);
         }
       }
@@ -1413,14 +1421,24 @@ function system_themes_form_submit($form
     variable_set('theme_default', $form_values['theme_default']);
   }
   else {
+    // Revert to defaults: only Garland is enabled.
     variable_del('theme_default');
     db_query("UPDATE {system} SET status = 1 WHERE type = 'theme' AND name = 'garland'");
+    $new_theme_list = array('garland');
   }
 
   list_themes(TRUE);
   menu_rebuild();
   drupal_set_message(t('The configuration options have been saved.'));
   $form_state['redirect'] = 'admin/build/themes';
+  
+  // Notify locale module about new themes being enabled, so translations can
+  // be imported. This might start a batch, and only return to the redirect
+  // path after that.
+  if (module_exists('locale')) {
+    locale_system_update('theme', array_diff($old_theme_list, $new_theme_list), array_diff($new_theme_list, $old_theme_list));
+  }
+ 
   return;
 }
 
@@ -1575,12 +1593,17 @@ function system_modules_disable($form, $
   return $form;
 }
 
-function system_modules_confirm_form($modules, $dependencies) {
+function system_modules_confirm_form($modules, $storage) {
   $form = array();
   $items = array();
 
+  list($dependencies, $status) = $storage;
   $form['validation_modules'] = array('#type' => 'value', '#value' => $modules);
   $form['status']['#tree'] = TRUE;
+  // Remember list of modules selected on the module listing page already.
+  foreach ($status as $key => $choice) {
+    $form['status'][$key] = array('#type' => 'value', '#value' => $choice);
+  }
   foreach ($dependencies as $name => $missing_dependencies) {
     $form['status'][$name] = array('#type' => 'hidden', '#value' => 1);
     foreach ($missing_dependencies as $k => $dependency) {
@@ -1657,6 +1680,28 @@ function system_modules_submit($form_val
     $dependencies = NULL;
   }
 
+  // Update throttle settings, if present
+  if (isset($form_values['throttle'])) {
+    foreach ($form_values['throttle'] as $key => $choice) {
+      db_query("UPDATE {system} SET throttle = %d WHERE type = 'module' and name = '%s'", $choice ? 1 : 0, $key);
+    }
+  }
+
+  // If there where unmet dependencies and they haven't confirmed don't process
+  // the submission yet. Store the form submission data needed later.
+  if ($dependencies) {
+    if (!isset($form_values['confirm'])) {
+      $form_state['storage'] = array($dependencies, $form_values['status']);
+      return;
+    }
+    else {
+      $form_values['status'] = array_merge($form_values['status'], $form_storage[1]);
+    }
+  }
+  // If we have no dependencies, or the dependencies are confirmed
+  // to be installed, we don't need the temporary storage anymore.
+  unset($form_state['storage']);
+
   $enable_modules = array();
   $disable_modules = array();
   foreach ($form_values['status'] as $key => $choice) {
@@ -1691,13 +1736,6 @@ function system_modules_submit($form_val
   drupal_install_modules($new_modules);
 
   $current_module_list = module_list(TRUE, FALSE);
-
-  if (isset($form_values['throttle'])) {
-    foreach ($form_values['throttle'] as $key => $choice) {
-      db_query("UPDATE {system} SET throttle = %d WHERE type = 'module' and name = '%s'", $choice ? 1 : 0, $key);
-    }
-  }
-
   if ($old_module_list != $current_module_list) {
     drupal_rebuild_theme_registry();
     menu_rebuild();
@@ -1705,17 +1743,19 @@ function system_modules_submit($form_val
     drupal_set_message(t('The configuration options have been saved.'));
   }
 
-  // If there where unmet dependencies and they haven't confirmed don't redirect.
-  if ($dependencies && !isset($form_values['confirm'])) {
-    $form_state['storage'] = $dependencies;
-    return;
-  }
-
   drupal_clear_css_cache();
 
   // Unset storage to indicate this form cycle is over.
-  unset($form_state['storage']);
   $form_state['redirect'] = 'admin/build/modules';
+  
+  // Notify locale module about module changes, so translations can be
+  // imported. This might start a batch, and only return to the redirect
+  // path after that.
+  if (module_exists('locale')) {
+    $old_module_names = array_keys($old_module_list);
+    locale_system_update('module', array_diff($old_module_names, $enable_modules), array_diff($enable_modules, $old_module_names), $new_modules);
+  }
+  
   return;
 }
 
