Index: modules/locale/locale.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v
retrieving revision 1.181
diff -u -p -r1.181 locale.module
--- modules/locale/locale.module	30 Jun 2007 19:46:56 -0000	1.181
+++ modules/locale/locale.module	30 Jun 2007 20:08:27 -0000
@@ -53,6 +53,12 @@ function locale_help($path, $arg) {
       return '<p>'. t("This page allows you to export Drupal strings. The first option is to export a translation so it can be shared. The second option generates a translation template, which contains all Drupal strings, but without their translations. You can use this template to start a new translation using various software packages designed for this task.") .'</p>';
     case 'admin/build/translate/search':
       return '<p>'. t("It is often convenient to get the strings from your setup on the <a href=\"@export\">export page</a>, and use a desktop Gettext translation editor to edit the translations. On this page you can search in the translated and untranslated strings, and the default English texts provided by Drupal.", array("@export" => url("admin/build/translate/export"))) .'</p>';
+    
+    case 'admin/build/block/configure':
+      if ($arg[4] == 'locale' && $arg[5] == 0) {
+        return '<p>'. t("This block is only shown if you have <a href=\"@languages\">at least two languages enabled</a> and you have a <a href=\"@configuration\">language negotiation setting</a> different from 'none', so you have different web addresses for different language versions.", array('@languages' => url('admin/settings/language'), '@configuration' => url('admin/settings/language/configure'))) .'</p>';
+      }
+      break;
   }
 }
 
@@ -491,3 +497,42 @@ function _locale_batch_import($filepath,
     $context['results'][] = $filepath;
   }
 }
+
+// ---------------------------------------------------------------------------------
+// Language switcher block
+
+/**
+ * Implementation of hook_block().
+ * Displays a language switcher. Translation links may be provided by other modules.
+ */
+function locale_block($op = 'list', $delta = 0) {
+  if ($op == 'list') {
+    $block[0]['info'] = t('Language switcher');
+    return $block;
+  }
+
+  // Only show if we have at least two languages and language dependent
+  // web addresses, so we can actually link to other language versions.
+  elseif ($op == 'view' && variable_get('language_count', 1) > 1 && variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE) != LANGUAGE_NEGOTIATION_NONE) {
+    $languages = language_list('enabled');
+    $links = array();
+    foreach ($languages[1] as $language) {
+      $links[$language->language] = array(
+        'href'       => $_GET['q'],
+        'title'      => $language->native,
+        'language'   => $language,
+        'attributes' => array('class' => 'language-link'),
+      );
+    }
+    
+    // Allow modules to provide translations for specific links.
+    // A translation link may need to point to a different path or use
+    // a translated link text before going through l(), which will just
+    // handle the path aliases.
+    drupal_alter('translation_link', $links, $_GET['q']);
+    
+    $block['subject'] = t('Languages');
+    $block['content'] = theme('links', $links, array());
+    return $block;
+  }
+}
Index: modules/translation/translation.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/translation/translation.module,v
retrieving revision 1.2
diff -u -p -r1.2 translation.module
--- modules/translation/translation.module	30 Jun 2007 19:46:58 -0000	1.2
+++ modules/translation/translation.module	30 Jun 2007 20:08:30 -0000
@@ -336,3 +336,44 @@ function translation_node_get_translatio
 function translation_supported_type($type) {
   return variable_get('language_' . $type, 0) == TRANSLATION_ENABLED;
 }
+
+/**
+ * Return paths of all translations of a node, based on
+ * its Drupal path. 
+ *
+ * @param $path
+ *   A Drupal path, for example node/432.
+ * @return
+ *   An array of paths of translations of the node accessible 
+ *   to the current user keyed with language codes.
+ */
+function translation_path_get_translations($path) {
+  $paths = array();
+  // Check for a node related path, and for its translations.
+  if ((preg_match("!^node/([0-9]+)(/.+|)$!", $path, $matches)) && ($node = node_load((int)$matches[1])) && !empty($node->tnid)) {
+    foreach (translation_node_get_translations($node->tnid) as $language => $translation_node) {
+      $paths[$language] = 'node/'. $translation_node->nid . $matches[2];
+    }
+  }
+  return $paths;
+}
+
+/**
+ * Implementation of hook_alter_translation_link().
+ *
+ * Replaces links with pointers to translated versions of the content.
+ */
+function translation_translation_link_alter(&$links, $path) {
+  if ($paths = translation_path_get_translations($path)) {
+    foreach ($links as $langcode => $link) {
+      if (isset($paths[$langcode])) {
+        // Translation in a different node.
+        $links[$langcode]['href'] = $paths[$langcode];
+      }
+      else {
+        // No translation in this language, or no permission to view.
+        unset($links[$langcode]);
+      }
+    }
+  }
+}
