diff -ur moodle-original/admin/lang.php moodle/admin/lang.php
--- moodle-original/admin/lang.php	2009-11-27 02:02:50.000000000 +0200
+++ moodle/admin/lang.php	2010-03-21 12:49:17.468347861 +0200
@@ -34,6 +34,9 @@
         $currentfile = optional_param('currentfile', LANG_DEFAULT_HELPFILE, PARAM_PATH);
     } else {
         $currentfile = optional_param('currentfile', LANG_DEFAULT_FILE, PARAM_FILE);
+        // some language files are really big (ie. moodle.php) and take long to load
+        // we use this parameter to allow quick single string editing
+        $currentstr = optional_param('currentstr', '', PARAM_TEXT);
     }
     $uselocal = optional_param('uselocal', -1, PARAM_INT);
 
@@ -443,6 +446,39 @@
             }
 
             $newstrings = array();
+            // if one particular string was edited, then we will use the
+            // existing strings (with English version) as default values, to 
+            // avoid them being marked as ORPHANED strings
+            if($currentstr) {
+                unset($string);
+                include($enfilepath);
+                $enstring = isset($string) ? $string : array();
+                unset($string);
+                ksort($enstring);
+
+                @include($lcfilepath);
+                $localstring = isset($string) ? $string : array();
+                unset($string);
+                ksort($localstring);
+
+                @include($trfilepath);
+                $string = isset($string) ? $string : array();
+                ksort($string);
+                foreach($enstring as $key => $value) {
+                    $stringkey = 'stringXXX' . lang_form_string_key($key);
+                    if ($uselocal) {
+                        if(isset($localstring[$key])) {
+                            $value = lang_fix_value_from_file($localstring[$key]);
+                        } else {
+                            $value = lang_fix_value_from_file($string[$key]);
+                        }
+                    } else {
+                        $value = lang_fix_value_from_file($string[$key]);
+                    }
+                    $value = html_entity_decode($value);
+                    $newstrings[$stringkey] = $value;
+                }
+            }
 
             foreach ($_POST as $postkey => $postval) {
                 $stringkey = lang_file_string_key($postkey);
@@ -524,6 +560,11 @@
             unset($string);
             include($enfilepath);
             $enstring = isset($string) ? $string : array();
+            // if a particular string was requested, then we will show/edit only
+            // that string to make working with large files (like moodle.php) faster 
+            if ($currentstr) {
+                $enstring = array($currentstr => $enstring[$currentstr]);
+            }            
             //
             // Following strings have moved into langconfig.php, but keep the here for backward compatibility
             //
@@ -672,6 +713,7 @@
                 $o .= '<tr><td>&nbsp;</td><td><br />';
                 $o .= '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
                 $o .= '<input type="hidden" name="currentfile" value="'.$currentfile.'" />';
+                $o .= '<input type="hidden" name="currentstr" value="'.$currentstr.'" />';
                 $o .= '<input type="hidden" name="mode" value="compare" />';
                 $o .= '<input type="submit" name="update" tabindex="'.$missingcounter.'" value="'.get_string('savechanges').': '.$currentfile.'" />';
                 $o .= '</td></tr>';
diff -ur moodle-original/lib/moodlelib.php moodle/lib/moodlelib.php
--- moodle-original/lib/moodlelib.php	2010-02-25 02:03:05.000000000 +0200
+++ moodle/lib/moodlelib.php	2010-03-20 23:13:33.604544639 +0200
@@ -5297,6 +5297,36 @@
 }
 
 /**
+ * Caches results of get_string for click-to-translate actions.
+ * 
+ * If the current user has moodle/site:langeditlocal or moodle/site:langeditmaster 
+ * capabilities then the function caches the parameters and result of get_string 
+ * in order to be used for click-to-translate actions.
+ *
+ * @param string $identifier The key identifier for the localized string
+ * @param string $langfile The language file (including .php) where the key 
+ * identifier is stored.
+ * @param string $result The output of get_string call (including $a variable 
+ * substitutions)
+ * @return null on normal call (stores data); or the cached data (sorted string 
+ * length) if $identifier or $langfile are null
+ */
+function store_get_string_result($identifier, $langfile, $result) {
+    static $strings;
+    $context = get_system_context();
+    if (!has_capability('moodle/site:langeditlocal', $context, 0, false) &&
+		    !has_capability('moodle/site:langeditmaster', $context, 0, false)) {
+       return;
+	  }
+	
+    if(is_null($identifier) && is_null($langfile)) {
+        uasort($strings, create_function('$a,$b', 'return strlen($b) - strlen($a)'));
+        return $strings;
+    }
+    $strings["$langfile#$identifier"] = $result;
+}
+
+/**
  * Returns a localized string.
  *
  * Returns the translated string specified by $identifier as
@@ -5464,6 +5494,7 @@
                 if (eval($result) === FALSE) {
                     trigger_error('Lang error: '.$identifier.':'.$locallangfile, E_USER_NOTICE);
                 }
+                store_get_string_result($identifier, $module . '.php', $resultstring);
                 return $resultstring;
             }
         }
@@ -5474,6 +5505,7 @@
                 if (eval($result) === FALSE) {
                     trigger_error('Lang error: '.$identifier.':'.$langfile, E_USER_NOTICE);
                 }
+                store_get_string_result($identifier, $module . '.php', $resultstring);
                 return $resultstring;
             }
        }
@@ -5503,6 +5535,7 @@
                             if (eval($result) === FALSE) {
                                 trigger_error('Lang error: '.$identifier.':'.$locallangfile, E_USER_NOTICE);
                             }
+                            store_get_string_result($identifier, $module . '.php', $resultstring);
                             return $resultstring;
                         }
                     }
@@ -5512,6 +5545,7 @@
                     if (file_exists($langfile)) {
                         if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
                             eval($result);
+                            store_get_string_result($identifier, $module . '.php', $resultstring);
                             return $resultstring;
                         }
                     }
@@ -5527,6 +5561,7 @@
         if (file_exists($locallangfile)) {
             if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
                 eval($result);
+                store_get_string_result($identifier, $module . '.php', $resultstring);
                 return $resultstring;
             }
         }
@@ -5537,6 +5572,7 @@
         if (file_exists($langfile)) {
             if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
                 eval($result);
+                store_get_string_result($identifier, $module . '.php', $resultstring);
                 return $resultstring;
             }
         }
@@ -5551,6 +5587,7 @@
             if (file_exists($locallangfile)) {
                 if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
                     eval($result);
+                    store_get_string_result($identifier, $module . '.php', $resultstring);
                     return $resultstring;
                 }
             }
@@ -5561,6 +5598,7 @@
             if (file_exists($langfile)) {
                 if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
                     eval($result);
+                    store_get_string_result($identifier, $module . '.php', $resultstring);
                     return $resultstring;
                 }
             }
diff -ur moodle-original/lib/weblib.php moodle/lib/weblib.php
--- moodle-original/lib/weblib.php	2010-03-11 02:03:24.000000000 +0200
+++ moodle/lib/weblib.php	2010-03-20 23:47:55.792543396 +0200
@@ -3066,6 +3066,89 @@
 /// Include the actual footer file
 
     ob_start();
+    // if we cached the results of get_string, then it means we can edit the 
+    // language files; therefore, we enable the click-to-translate feature
+    if($strings = store_get_string_result(NULL, NULL, NULL)) {
+        // FOR PHP 4:
+        // PHP 4 does not have json_encode. A add-on function can be found 
+        // here: http://www.php.net/manual/en/function.json-encode.php#82904
+        // save it into the json_encode.php file in the moodle lib directory
+        // and uncomment the following line
+        // include_once(dirname(__FILE__) . '/json_encode.php');
+        echo '
+<script type="text/javascript" src="http://www.google.com/jsapi"></script>
+<script type="text/javascript">
+  google.load("jquery", "1.4.1")
+  // this array contains translatable strings an their source (language file 
+  // and key identifier used)
+  var langdict = ', json_encode($strings) , '
+  var wwwroot = "', $CFG->wwwroot , '"
+</script>';
+        echo <<<JS
+<script type="text/javascript">
+$(function() {
+  // create a place to display translatable strings options
+  $('<div id="translation_console">')
+    .hide()
+    .css({
+      position: 'absolute',
+      zIndex: 1000,
+      background: 'white',
+      color: 'black',
+      width: '300px',
+      height: '300px',
+      overflow: 'scroll'
+    })
+    .mouseleave(function() { $(this).fadeOut(1000) })
+    .appendTo('body')
+})
+
+// when the user right-click on a element while pressing the control key
+// we will display the translateable texts from that element's HTML instead of 
+// the element contextual menu
+$(document).mousedown(function(e){
+  if(e.ctrlKey && e.which == 3) {
+    // take control over the next display of the contextual menu
+    $(e.target).one('contextmenu',function(event){
+      // clear the translation console
+      var console = $('#translation_console').html('')
+      // read the full HTML of the target element
+      var targetHtml = $('<div>').append($(event.target).clone()).html()
+      // find translatable string withing the target element's HTML
+      for(var key in langdict) {
+        if (targetHtml.indexOf(langdict[key]) != -1) {
+          // parse the file and string identifier
+          var data = key.split('#', 2)
+          // find the editing form URL (including current string and page fragment)
+          var formurl = wwwroot + '/admin/lang.php?mode=compare&currentfile=' + data[0] + '&currentstr=' + data[1] + '#' + data[1]
+          // add a link into the translation console that opens the editing form
+          // in a new frame with a name based on the string key and file
+          $('<a>')
+            .css('display', 'block')
+            .attr('href', formurl)
+            .attr('target', key)
+            .text(langdict[key])
+            .appendTo(console)
+        }
+      }
+      
+      // try to center the translation console around the mouse position, 
+      // but without puting it outside the window boundaries
+      var left = event.pageX - console.width() / 2
+      var top = event.pageY - console.height() / 2
+      left = Math.max(0, Math.min(left, $(document).width() - console.width() / 2))
+      top = Math.max(0, Math.min(top, $(document).height() - console.height() / 2))
+      // display the console
+      console.css({left: left, top: top}).show()
+      // prevent the real contextual menu to show up
+      return false;
+    });
+  }
+})
+</script>
+JS
+;
+	}
     include($CFG->footer);
     $output = ob_get_contents();
     ob_end_clean();
