Index: install.php
===================================================================
RCS file: /cvs/drupal/drupal/install.php,v
retrieving revision 1.87
diff -u -p -r1.87 install.php
--- install.php	11 Nov 2007 06:56:44 -0000	1.87
+++ install.php	11 Nov 2007 21:47:56 -0000
@@ -27,6 +27,9 @@ function install_main() {
   // Ensure correct page headers are sent (e.g. caching)
   drupal_page_header();
 
+  // Set up $language, so t() caller functions will still work.
+  drupal_init_language();
+
   // Check existing settings.php.
   $verify = install_verify_settings();
 
@@ -544,6 +547,19 @@ function install_select_locale($profilen
     return FALSE;
   }
   else {
+    // Allow profile to pre-select the language, skipping the selection.
+    $function = $profilename .'_profile_details';
+    if (function_exists($function)) {
+      $details = $function();
+      if (isset($details['language'])) {
+        foreach ($locales as $locale) {
+          if ($details['language'] == $locale->name) {
+            return $locale->name;
+          }
+        }
+      }
+    }
+
     foreach ($locales as $locale) {
       if ($_POST['locale'] == $locale->name) {
         return $locale->name;
@@ -631,16 +647,47 @@ function install_tasks($profile, $task) 
   drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
   $_SESSION['messages'] = $messages;
 
-  // Build a page for a final task.
+  // Build a page for final tasks.
   drupal_maintenance_theme();
   if (empty($task)) {
-    variable_set('install_task', 'configure');
-    $task = 'configure';
+    variable_set('install_task', 'locale-import');
+    $task = 'locale-import';
   }
 
   // We are using a list of if constructs here to allow for
   // passing from one task to the other in the same request.
 
+  // Import interface translations for the enabled modules.
+  if ($task == 'locale-import') {
+    if (!empty($install_locale) && ($install_locale != 'en')) {
+      include_once 'includes/locale.inc';
+      // Enable installation language as default site language.
+      locale_add_language($install_locale, NULL, NULL, NULL, NULL, NULL, 1, TRUE);
+      // Collect files to import for this language.
+      $batch = locale_batch_by_language($install_locale);
+      if (!empty($batch)) {
+        // Start a batch, switch to 'locale-batch' task. We need to
+        // set the variable here, because batch_process() redirects.
+        variable_set('install_task', 'locale-batch');
+        batch_set($batch);
+        $path = $base_url .'/install.php?locale='. $install_locale .'&profile='. $profile;
+        batch_process($path, $path);
+      }
+    }
+    // Found nothing to import or not foreign language, go to next task.
+    $task = 'configure';
+  }
+
+  // We are running a batch import of interface translation files.
+  // This might run in multiple HTTP requests, constantly redirecting
+  // to the same address, until the batch finished callback is invoked
+  // and the task advances to 'configure'.
+  if ($task == 'locale-batch') {
+    include_once 'includes/batch.inc';
+    include_once 'includes/locale.inc';
+    $output = _batch_page();
+  }
+
   if ($task == 'configure') {
     drupal_set_title(st('Configure site'));
 
@@ -681,49 +728,22 @@ function install_tasks($profile, $task) 
     if (function_exists($function)) {
       // The profile needs to run more code, maybe even more tasks.
       // $task is sent through as a reference and may be changed!
-      $output = $function($task);
+      $output = $function($task, $base_url .'/install.php?locale='. $install_locale .'&profile='. $profile);
     }
 
     // If the profile doesn't move on to a new task we assume
-    // that it is done: we let the installer regain control and
-    // proceed with the locale import.
+    // that it is done.
     if ($task == 'profile') {
-      $task = 'locale-import';
-    }
-  }
-
-  // Import interface translations for the enabled modules, after
-  // any changes made by the profile through the profile forms.
-  if ($task == 'locale-import') {
-    if (!empty($install_locale) && ($install_locale != 'en')) {
-      include_once 'includes/locale.inc';
-      // Enable installation language as default site language.
-      locale_add_language($install_locale, NULL, NULL, NULL, NULL, NULL, 1, TRUE);
-      // Collect files to import for this language.
-      $batch = locale_batch_by_language($install_locale);
-      if (!empty($batch)) {
-        // Start a batch, switch to 'locale-batch' task. We need to
-        // set the variable here, because batch_process() redirects.
-        variable_set('install_task', 'locale-batch');
-        batch_set($batch);
-        $path = $base_url .'/install.php?locale='. $install_locale .'&profile='. $profile;
-        batch_process($path, $path);
-      }
+      $task = 'profile-finished';
     }
-    // Found nothing to import or not foreign language, go to next task.
-    $task = 'finished';
-  }
-
-  // We are running a batch import of interface translation files.
-  // This might run in multiple HTTP requests, constantly redirecting
-  // to the same address, until the batch finished callback is invoked
-  // and the task advances to 'finished'.
-  if ($task == 'locale-batch') {
-    include_once 'includes/batch.inc';
-    include_once 'includes/locale.inc';
-    $output = _batch_page();
   }
 
+  // Profile custom tasks are done, so let the installer regain
+  // control and proceed with the final page.
+  if ($task == 'profile-finished') {
+     $task = 'finished';
+   }
+   
   // Display a 'finished' page to user.
   if ($task == 'finished') {
     drupal_set_title(st('@drupal installation complete', array('@drupal' => drupal_install_profile_name())));
@@ -760,7 +780,7 @@ function install_tasks($profile, $task) 
  * The list of reserved tasks to run in the installer.
  */
 function install_reserved_tasks() {
-  return array('configure', 'locale-import', 'locale-batch', 'finished', 'done');
+  return array('configure', 'locale-import', 'locale-batch', 'profile-finished', 'finished', 'done');
 }
 
 /**
@@ -797,6 +817,7 @@ function install_task_list($active = NUL
     'locale-select'  => st('Choose language'),
     'requirements'   => st('Verify requirements'),
     'database'       => st('Setup database'),
+    'locale-batch'   => st('Import translations'),
     'configure'      => st('Configure site'),
   );
 
@@ -820,11 +841,9 @@ function install_task_list($active = NUL
     }
   }
 
-  // If necessary, add translation import to the task list.
-  if (count($locales) > 1 && !empty($_GET['locale']) && $_GET['locale'] != 'en') {
-    $tasks += array(
-      'locale-batch' => st('Import translations'),
-    );
+  // If not required, remove translation import from the task list.
+  if (count($locales) < 2 || empty($_GET['locale']) || $_GET['locale'] == 'en') {
+    unset($tasks['locale-batch']);
   }
 
   // Add finished step as the last task.
Index: includes/locale.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/locale.inc,v
retrieving revision 1.157
diff -u -p -r1.157 locale.inc
--- includes/locale.inc	11 Nov 2007 16:14:45 -0000	1.157
+++ includes/locale.inc	11 Nov 2007 21:47:58 -0000
@@ -2542,7 +2542,7 @@ function _locale_batch_language_finished
  * Advance installer task to the finished screen.
  */
 function _locale_batch_installer_finished($success, $results) {
-  variable_set('install_task', 'finished');
+  variable_set('install_task', 'configure');
 }
 
 /**
Index: profiles/default/default.profile
===================================================================
RCS file: /cvs/drupal/drupal/profiles/default/default.profile,v
retrieving revision 1.19
diff -u -p -r1.19 default.profile
--- profiles/default/default.profile	6 Nov 2007 09:00:31 -0000	1.19
+++ profiles/default/default.profile	11 Nov 2007 21:47:58 -0000
@@ -5,7 +5,7 @@
  * Return an array of the modules to be enabled when this profile is installed.
  *
  * @return
- *  An array of modules to be enabled.
+ *   An array of modules to enable.
  */
 function default_profile_modules() {
   return array('color', 'comment', 'help', 'menu', 'taxonomy', 'dblog');
@@ -15,7 +15,9 @@ function default_profile_modules() {
  * Return a description of the profile for the initial installation screen.
  *
  * @return
- *   An array with keys 'name' and 'description' describing this profile.
+ *   An array with keys 'name' and 'description' describing this profile,
+ *   and optional 'language' to override the language selection for
+ *   language-specific profiles.
  */
 function default_profile_details() {
   return array(
@@ -39,23 +41,29 @@ function default_profile_task_list() {
 /**
  * Perform any final installation tasks for this profile.
  *
- * The installer goes through the configure -> locale-import ->
- * locale-batch -> finished -> done tasks in this order, if you
+ * The installer goes through the locale-import -> locale-batch
+ * -> configure -> finished -> done tasks in this order, if you
  * don't implement this function in your profile.
  *
  * If this function is implemented, you can have any number of
- * custom tasks to perform, implementing a state machine here to
- * walk the user through those tasks, by setting $task to something
- * other then the reserved tasks listed in install_reserved_tasks()
- * and the 'profile' task this function gets called with for first
- * time. If you implement your custom tasks, this function will get called
- * in every HTTP request (for form processing, printing your
- * information screens and so on) until you advance to the
- * 'locale-import' task, with which you hand control back to the
- * installer.
+ * custom tasks to perform after 'configure', implementing a state
+ * machine here to walk the user through those tasks. First time,
+ * this function gets called with $task set to 'profile', and you
+ * can advance to further tasks by setting $task to your tasks'
+ * identifiers, used as array keys in the hook_profile_task_list()
+ * above. You must avoid the reserved tasks listed in
+ * install_reserved_tasks(). If you implement your custom tasks,
+ * this function will get called in every HTTP request (for form
+ * processing, printing your information screens and so on) until
+ * you advance to the 'profile-finished' task, with which you
+ * hand control back to the installer. Each custom page you
+ * return needs to provide a way to continue, such as a form
+ * submission or a link. You should also set custom page titles,
+ * if the default "Configure site" title is not appropriate.
  *
  * You should define the list of custom tasks you implement by
- * returning an array of them in hook_profile_task_list().
+ * returning an array of them in hook_profile_task_list(), as these
+ * show up in the list of tasks on the installer user interface.
  *
  * Should a profile want to display a form here, it can; it should set
  * the task using variable_set('install_task', 'new_task') and use
@@ -65,12 +73,15 @@ function default_profile_task_list() {
  * @param $task
  *   The current $task of the install system. When hook_profile_tasks()
  *   is first called, this is 'profile'.
+ * @param $url
+ *   Complete URL to be used for a link or form action on a custom page,
+ *   if providing any, to allow the user to proceed with the installation.
  *
  * @return
  *   An optional HTML string to display to the user. Only used if you
  *   modify the $task, otherwise discarded.
  */
-function default_profile_tasks(&$task) {
+function default_profile_tasks(&$task, $url) {
 
   // Insert default user-defined node types into the database. For a complete
   // list of available node type attributes, refer to the node type API
