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	20 May 2007 21:42:33 -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.126
diff -u -p -r1.126 locale.inc
--- includes/locale.inc	17 May 2007 08:34:43 -0000	1.126
+++ includes/locale.inc	20 May 2007 21:42:34 -0000
@@ -2098,7 +2098,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.
@@ -2118,68 +2118,78 @@ 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 installing modules or enabling themes.
+ * This batch will import translations for the newly added components
+ * in all the languages already set up on the site.
+ *
+ * @param $components
+ *   An array of component (theme and/or module) names to import
+ *   translations for.
+ */
+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.
+    $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	20 May 2007 21:42:37 -0000
@@ -424,3 +424,39 @@ 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 $components
+ *   An array of component (theme and/or module) names to import
+ *   translations for.
+ */
+function locale_system_update($components) {
+  include_once 'includes/locale.inc';
+  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';
+  // The filename is either {langcode}.po or {prefix}.{langcode}.po, so
+  // we can extract the language code to use for the import from the end.
+  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.478
diff -u -p -r1.478 system.module
--- modules/system/system.module	17 May 2007 07:28:42 -0000	1.478
+++ modules/system/system.module	20 May 2007 21:42:38 -0000
@@ -1404,6 +1404,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')) {
@@ -1412,6 +1419,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);
         }
       }
@@ -1426,14 +1434,22 @@ 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.
+  module_invoke('locale', 'system_update', array_diff($new_theme_list, $old_theme_list));
+ 
   return;
 }
 
@@ -1588,12 +1604,27 @@ function system_modules_disable($form, $
   return $form;
 }
 
-function system_modules_confirm_form($modules, $dependencies) {
+/**
+ * Display confirmation form for dependencies.
+ *
+ * @param $modules
+ *   Array of module file objects as returned from module_rebuild_cache().
+ * @param $storage
+ *   The contents of $form_state['storage']; an array with two
+ *   elements: the list of dependencies and the list of status
+ *   form field values from the previous screen.
+ */
+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) {
@@ -1670,8 +1701,31 @@ 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);
+    }
+  }
+
   // Temporarily disable menu module while it's broken.
   unset($form_values['status']['menu']);
+
+  // 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) {
@@ -1706,13 +1760,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();
     node_types_rebuild();
@@ -1720,17 +1767,15 @@ 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.
+  module_invoke('locale', 'system_update', $new_modules);
+
   return;
 }
 
