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	20 Oct 2008 00:14:45 -0000
@@ -251,21 +251,39 @@
       if (isset($node->flag)) {
         foreach ($node->flag as $name => $state) {
           $flag = flag_get_flag($name);
+          $id = $flag->get_content_id($node);
           // Flagging may trigger actions. We want actions to get the current
           // node, not a stale database-loaded one:
           if (!$remembered) {
-            $flag->remember_content($node->nid, $node);
+            $flag->remember_content($id, $node);
             // Actions may modify a node, and we don't want to overwrite this
             // modification:
             $remembered = TRUE;
           }
-          flag($state ? 'flag' : 'unflag', $name, $node->nid);
+          flag($state ? 'flag' : 'unflag', $name, $id);
         }
       }
       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 +550,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 +565,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 +574,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 +583,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.18
diff -u -r1.2.2.18 flag.install
--- flag.install	17 Oct 2008 12:17:01 -0000	1.2.2.18
+++ flag.install	20 Oct 2008 00:14:45 -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	20 Oct 2008 00:14:45 -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'),
@@ -773,7 +786,7 @@
   }
 
   function get_content_id($node) {
-    return $node->nid;
+    return ($this->i18n && !empty($node->tnid)) ? $node->tnid : $node->nid;
   }
 
   function uses_hook_link($teaser) {
