Index: i18nmenu/i18nmenu.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/i18n/i18nmenu/i18nmenu.module,v
retrieving revision 1.2.2.9
diff -u -p -r1.2.2.9 i18nmenu.module
--- i18nmenu/i18nmenu.module	3 Oct 2008 11:32:24 -0000	1.2.2.9
+++ i18nmenu/i18nmenu.module	16 Dec 2008 18:07:36 -0000
@@ -28,16 +28,18 @@ function i18nmenu_locale($op = 'groups',
  * Refresh locale strings.
  */
 function i18nmenu_locale_refresh() {
+  // Rebuild menus to ensure all items are altered by i18nmenu_menu_link_alter.
+  menu_rebuild();
   foreach (menu_get_menus() as $name => $title) {
     $tree = menu_tree_all_data($name);
-    i18nmenu_localize_tree($tree);
+    i18nmenu_localize_tree($tree, TRUE);
   }
 }
 
 /**
  * Implementation of hook_menu_link_alter().
  *
- * Catch changed links, update language and refresh texts
+ * Catch changed links, update language and set alter option.
  */
 function i18nmenu_menu_link_alter(&$item, $menu) {
   // If we set option to language it causes an error with the link system
@@ -48,11 +50,42 @@ function i18nmenu_menu_link_alter(&$item
   elseif (isset($item['language'])) {
     unset($item['options']['langcode']);
   }
-  // @ TO DO: Refresh texts
-  //dsm($item);
-  //$original = $item['original_item'];
-  //$item['router_path'] = _menu_find_router_path($menu, $item['link_path']);
-  //i18nmenu_make_translatable($item);
+  // If we are handling the menu module custom menu items and a language
+  // is not set, invoke translation via the i18nstrings module.
+  if (empty($item['language']) && $item['module'] == 'menu') {
+    // Because the menu item is not passed to the callback, we cannot
+    // use this method to translate the item. Still, we want to avoid calls
+    // to t(), which add rows to the default interface group (which clutter
+    // that group and in any case won't be used). So we use a function that
+    // simply returns the title.
+    // Don't set title_arguments, to ensure that the title itself is passed
+    // to the title_callback.
+    $item['title_callback'] = 'i18nmenu_title_callback';
+    // Setting the alter option to true ensures that
+    // hook_translated_menu_link_alter() will be called.
+    $item['options']['alter'] = TRUE;
+  }
+}
+
+/**
+ * Callback to provide a menu item title.
+ *
+ * Simply return the title, as translation will be done in
+ * hook_translated_menu_link_alter().
+ */
+function i18nmenu_title_callback($title) {
+  return $title;
+}
+
+/**
+ * Implementation of hook_translated_menu_link_alter().
+ *
+ * Translate menu links on the fly.
+ */
+function i18nmenu_translated_menu_link_alter(&$item, $map) {
+  if ($item['module'] == 'menu') {
+    $item['title'] = _i18nmenu_get_item($item);
+  }
 }
 
 /**
@@ -88,7 +121,7 @@ function i18nmenu_translated_tree($menu_
 /**
  * Localize menu tree.
  */
-function i18nmenu_localize_tree(&$tree) {
+function i18nmenu_localize_tree(&$tree, $update = FALSE) {
   global $language;
   foreach ($tree as $index => $item) {
     $link = $item['link'];
@@ -105,12 +138,11 @@ function i18nmenu_localize_tree(&$tree) 
         $router = i18nmenu_get_router($link['router_path']);
         // If the title is the same it will be localized by the menu system.
         if ($link['link_title'] != $router['title']) {
-          //$tree[$index]['link']['title'] = 'Translated';
-          $tree[$index]['link']['title'] = tt('menu:item:'. $link['mlid'] .':title', $link['link_title'], NULL, TRUE);
+          $tree[$index]['link']['title'] = _i18nmenu_get_item($link, $update);
         }
         // Localize subtree.
         if ($item['below'] !== FALSE) {
-          i18nmenu_localize_tree($tree[$index]['below']);
+          i18nmenu_localize_tree($tree[$index]['below'], $update);
         }
       }
     }
@@ -118,6 +150,14 @@ function i18nmenu_localize_tree(&$tree) 
 }
 
 /**
+ * Optionally insert/update and return the localized version of a menu item
+ * string.
+ */
+function _i18nmenu_get_item($link, $update = FALSE) {
+  return tt('menu:item:'. $link['mlid'] .':title', $link['link_title'], NULL, $update);
+}
+
+/**
  * Get the menu router for this router path.
  *
  * We need the untranslated title to compare, and this will be fast.
@@ -132,22 +172,61 @@ function i18nmenu_get_router($path) {
 }
 
 /**
- * Implementation of hook_form_alter().
+ * Implementation of hook_form_form_id_alter().
+ *
+ * Add translate links to menu items in the menu overview form.
  */
-function i18nmenu_form_alter(&$form, $form_state, $form_id) {
-  if ($form_id == 'menu_edit_item') {
-    //dsm ($form);
-    if ($form['menu']['#item'] && isset($form['menu']['#item']['options']['langcode'])) {
-      $language = $form['menu']['#item']['options']['langcode'];
-    }
-    else {
-      $language = '';
+function i18nmenu_form_menu_overview_form_alter(&$form, $form_state) {
+  $destination = drupal_get_destination();
+  foreach (element_children($form) as $mlid) {
+    if (isset($form[$mlid]['hidden'])) {
+      $context = i18nstrings_context('menu:item:'. $form[$mlid]['#item']['mlid'] .':title');
+      // Check if we have a source string.
+      $source = i18nstrings_get_source($context);
+      // If so, add a translate link.
+      if ($source->lid) {
+        $form[$mlid]['operations']['translate'] = array('#value' => l(t('translate'), 'admin/build/translate/edit/'. $source->lid, array('query' => $destination)));
+      }
     }
-    $form['menu']['language'] = array(
-      '#type' => 'select',
-      '#title' => t('Language'),
-      '#options' => array('' => t('All languages')) + locale_language_list('name'),
-      '#default_value' => $language,
-    );
   }
-}
\ No newline at end of file
+}
+
+/**
+ * Implementation of hook_form_form_id_alter().
+ *
+ * Add a language selector to the menu_edit_item form and register a submit
+ * callback to process items.
+ */
+function i18nmenu_form_menu_edit_item_alter(&$form, $form_state) {
+  if ($form['menu']['#item'] && isset($form['menu']['#item']['options']['langcode'])) {
+    $language = $form['menu']['#item']['options']['langcode'];
+  }
+  else {
+    $language = '';
+  }
+  $form['menu']['language'] = array(
+    '#type' => 'select',
+    '#title' => t('Language'),
+    '#description' => t('Select a language for this menu item. Choose "All languages" to make the menu item translatable into different languages.'),
+    '#options' => array('' => t('All languages')) + locale_language_list('name'),
+    '#default_value' => $language,
+  );
+  $form['#submit'][] = 'i18nmenu_menu_item_update';
+}
+
+/**
+ * Submit handler for the menu_edit_item form.
+ *
+ * On menu item insert or update, save a translation record.
+ */
+function i18nmenu_menu_item_update($form, &$form_state) {
+  $item = $form_state['values']['menu'];
+  list($item['menu_name'], $item['plid']) = explode(':', $item['parent']);
+  // If this was an insert, determine the ID that was set.
+  if (!isset($link['mlid'])) {
+    $item['mlid'] = db_result(db_query("SELECT mlid FROM {menu_links} WHERE link_path = '%s' AND menu_name = '%s' AND module = 'menu' AND plid = %d AND link_title = '%s'", $item['link_path'], $item['menu_name'], $item['plid'], $item['link_title']));
+  }
+  if (!empty($item['mlid'])) {
+    _i18nmenu_get_item($item, TRUE);
+  }
+}
