Index: flag.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/Attic/flag.module,v
retrieving revision 1.11.2.48
diff -u -r1.11.2.48 flag.module
--- flag.module	13 Oct 2008 11:29:01 -0000	1.11.2.48
+++ flag.module	12 Nov 2008 23:26:33 -0000
@@ -264,8 +264,25 @@
       }
       break;
     case 'delete':
-      db_query("DELETE FROM {flag_content} WHERE content_type = 'node' AND content_id = %d", $node->nid);
-      db_query("DELETE FROM {flag_counts} WHERE content_type = 'node' AND content_id = %d", $node->nid);
+      $flags = flag_get_flags();
+      foreach ($flags as $flag) {
+        // If the flag is being tracked by translation set and the node is part
+        // of a translation set, don't delete the flagging record.
+        // Instead, data will be updated in the 'translation_change' op, below.
+        if ($flag->applies_to_content_id($node->nid) && (!$flag->i18n || empty($node->tnid))) {
+          db_query("DELETE FROM {flag_content} WHERE fid = %d AND content_type = 'node' AND content_id = %d", $flag->fid, $node->nid);
+          db_query("DELETE FROM {flag_counts} WHERE fid = %d AND content_type = 'node' AND content_id = %d", $flag->fid, $node->nid);
+        }
+      }
+      break;
+    case 'translation_change':
+      if (isset($node->translation_change)) {
+        // If there is only one node remaining, track by nid rather than tnid.
+        // Otherwise, use the new tnid.
+        $content_id = $node->translation_change['new_tnid'] == 0 ? $node->translation_change['remaining_nid'] : $node->translation_change['new_tnid'];
+        db_query("UPDATE {flag_content} SET content_id = %d WHERE content_type = 'node' AND content_id = %d", $content_id, $node->translation_change['old_tnid']);
+        db_query("UPDATE {flag_counts} SET content_id = %d WHERE content_type = 'node' AND content_id = %d", $content_id, $node->translation_change['old_tnid']);
+      }
       break;
   }
 }
@@ -532,6 +549,14 @@
     );
   }
 
+  $form['global'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Global flag'),
+    '#default_value' => $flag->global,
+    '#description' => t('If checked, flag is considered "global" and each node is either flagged or not. If unchecked, each user has individual flags on content.'),
+    '#weight' => 1,
+  );
+
   $form['roles'] = array(
     '#type' => 'checkboxes',
     '#title' => t('Roles that may use this flag'),
@@ -539,13 +564,7 @@
     '#default_value' => $flag->roles,
     '#required' => TRUE,
     '#description' => t('Checking <em>authenticated user</em> will allow all logged-in users to flag content with this flag. Anonymous users may not flag content.'),
-  );
-
-  $form['global'] = array(
-    '#type' => 'checkbox',
-    '#title' => t("Global flag"),
-    '#default_value' => $flag->global,
-    '#description' => t('If checked, flag is considered "global" and each node is either flagged or not. If unchecked, each user has individual flags on content.'),
+    '#weight' => 5,
   );
 
   $form['types'] = array(
@@ -554,7 +573,8 @@
     '#options' => node_get_types('names'),
     '#default_value' => $flag->types,
     '#description' => t('Check any node types that this flag may be used on. You must check at least one node type.'),
-    '#required' => TRUE
+    '#required' => TRUE,
+    '#weight' => 10,
   );
 
   $form['display'] = array(
@@ -562,6 +582,7 @@
     '#title' => t('Display options'),
     '#description' => t('Flags are usually controlled through links that allow users to toggle their behavior. You can choose how users interact with flags by changing options here. It is legitimate to have none of the following checkboxes ticked, if, for some reason, you wish <a href="@placement-url">to place the the links on the page yourself</a>.', array('@placement-url' => 'http://drupal.org/node/295383')),
     '#tree' => FALSE,
+    '#weight' => 20,
   );
 
   $form['submit'] = array(
Index: flag.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/Attic/flag.install,v
retrieving revision 1.2.2.20
diff -u -r1.2.2.20 flag.install
--- flag.install	22 Oct 2008 21:50:20 -0000	1.2.2.20
+++ flag.install	12 Nov 2008 23:26:32 -0000
@@ -75,6 +75,12 @@
       $requirements['flag_content_clash']['description'] = _flag_flag_content_message();
     }
   }
+
+  if (module_exists('translation') && !module_exists('translation_helpers')) {
+    $requirements['flag_translation']['title'] = $t('Flag');
+    $requirements['flag_translation']['severity'] = REQUIREMENT_ERROR;
+    $requirements['flag_translation']['description'] = $t('To have the flag module work with translations, you need to install and enable the <a href="http://drupal.org/project/translation_helpers">Translation helpers</a> module.');
+  }
   return $requirements;
 }
 
Index: flag.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/Attic/flag.inc,v
retrieving revision 1.1.2.19
diff -u -r1.1.2.19 flag.inc
--- flag.inc	16 Oct 2008 16:13:00 -0000	1.1.2.19
+++ flag.inc	12 Nov 2008 23:26:32 -0000
@@ -737,12 +737,25 @@
       'show_on_page' => TRUE,
       'show_on_teaser' => TRUE,
       'show_on_form' => FALSE,
+      'i18n' => 0,
     );
     return $options;
   }
   
   function options_form(&$form) {
     parent::options_form($form);
+    $form['i18n'] = array(
+      '#type' => 'radios',
+      '#title' => t('Internationalization'),
+      '#options' => array(
+        '1' => t('Flag translations of content as a group'),
+        '0' => t('Flag each translation of content separately'),
+      ),
+      '#default_value' => empty($form['#flag']->fid) && module_exists('translation_helpers') ? 1 : $this->i18n,
+      '#description' => t('Flagging translations as a group effectively allows users to flag the original piece of content regardless of the translation they are viewing. Changing this setting will <strong>not</strong> update content that has been flagged already.'),
+      '#access' => module_exists('translation_helpers'),
+      '#weight' => 5,
+    );
     $form['display']['show_on_teaser'] = array(
       '#type' => 'checkbox',
       '#title' => t('Display link on node teaser'),
@@ -776,6 +789,24 @@
     return $node->nid;
   }
 
+  /**
+   * Adjust the Content ID to find the translation parent if i18n-enabled.
+   *
+   * @param $content_id
+   *   The nid for the content.
+   * @return
+   *   The tnid if available, the nid otherwise.
+   */
+  function get_translation_id($content_id) {
+    if ($this->i18n) {
+      $node = $this->fetch_content($content_id);
+      if (!empty($node->tnid)) {
+        $content_id = $node->tnid;
+      }
+    }
+    return $content_id;
+  }
+
   function uses_hook_link($teaser) {
     if ($teaser && $this->show_on_teaser || !$teaser && $this->show_on_page) {
       return TRUE;
@@ -783,6 +814,17 @@
     return FALSE;
   }
 
+  function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE) {
+    $content_id = $this->get_translation_id($content_id);
+    return parent::flag($action, $content_id, $account, $skip_permission_check);
+  }
+
+
+  function is_flagged($content_id, $uid = NULL) {
+    $content_id = $this->get_translation_id($content_id);
+    return parent::is_flagged($content_id, $uid);
+  }
+
   function get_labels_token_types() {
     return array('node');
   }
