Index: typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php
===================================================================
--- typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php	(copie de travail)
@@ -567,7 +567,7 @@
 			bar, formattext, bold,  strong, italic, emphasis, big, small, insertedtext, deletedtext, citation, code, definition, keyboard, monospaced, quotation, sample, variable, bidioverride, strikethrough, subscript, superscript, underline, span,
 			bar, fontstyle, space, fontsize, bar, formatblock, insertparagraphbefore, insertparagraphafter, blockquote,
 			bar, left, center, right, justifyfull,
-			bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent,  bar, lefttoright, righttoleft,
+			bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent,  bar, lefttoright, righttoleft, language, showlanguagemarks,
 			bar, textcolor, bgcolor, textindicator,
 			bar, emoticon, insertcharacter, line, link, unlink, image, table,' . (($this->thisConfig['hideTableOperationsInToolbar'] && is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.']['toggleborders.']) && $this->thisConfig['buttons.']['toggleborders.']['keepInToolbar']) ? ' toggleborders,': '') . ' user, acronym, bar, findreplace, spellcheck,
 			bar, chMode, inserttag, removeformat, bar, copy, cut, paste, bar, undo, redo, bar, showhelp, about, linebreak,
@@ -579,7 +579,7 @@
 		if($this->client['BROWSER'] == 'gecko' && $this->client['VERSION'] == '1.3')  {
 			$this->defaultToolbarOrder = $this->TCEform->docLarge ? 'bar, blockstylelabel, blockstyle, space, textstylelabel, textstyle, linebreak,
 				bar, fontstyle, space, fontsize, space, formatblock, insertparagraphbefore, insertparagraphafter, blockquote, bar, bold, italic, underline, strikethrough,
-				subscript, superscript, lefttoright, righttoleft, bar, left, center, right, justifyfull, linebreak,
+				subscript, superscript, lefttoright, righttoleft, language, showlanguagemarks, bar, left, center, right, justifyfull, linebreak,
 				bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent, bar, textcolor, bgcolor, textindicator, bar, emoticon,
 				insertcharacter, line, link, unlink, image, table, user, acronym, bar, findreplace, spellcheck, bar, chMode, inserttag,
 				removeformat, bar, copy, cut, paste, bar, undo, redo, bar, showhelp, about, linebreak,
@@ -588,7 +588,7 @@
 				cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge'
 				: 'bar, blockstylelabel, blockstyle, space, textstylelabel, textstyle, linebreak,
 				bar, fontstyle, space, fontsize, space, formatblock, insertparagraphbefore, insertparagraphafter, blockquote, bar, bold, italic, underline, strikethrough,
-				subscript, superscript, linebreak, bar, lefttoright, righttoleft, bar, left, center, right, justifyfull,
+				subscript, superscript, linebreak, bar, lefttoright, righttoleft, language, showlanguagemarks, bar, left, center, right, justifyfull,
 				orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent, bar, textcolor, bgcolor, textindicator, bar, emoticon,
 				insertcharacter, line, link, unlink, image, table, user, acronym, linebreak, bar, findreplace, spellcheck, bar, chMode, inserttag,
 				removeformat, bar, copy, cut, paste, bar, undo, redo, bar, showhelp, about, linebreak,
Index: typo3/sysext/rtehtmlarea/ext_tables.sql
===================================================================
--- typo3/sysext/rtehtmlarea/ext_tables.sql	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/ext_tables.sql	(copie de travail)
@@ -14,6 +14,7 @@
   type tinyint(3) unsigned DEFAULT '1' NOT NULL,
   term varchar(255) DEFAULT '' NOT NULL,
   acronym varchar(255) DEFAULT '' NOT NULL,
+  static_lang_isocode int(11) unsigned DEFAULT '0' NOT NULL,
 
   PRIMARY KEY (uid),
   KEY parent (pid)
Index: typo3/sysext/rtehtmlarea/extensions/Acronym/class.tx_rtehtmlarea_acronym.php
===================================================================
--- typo3/sysext/rtehtmlarea/extensions/Acronym/class.tx_rtehtmlarea_acronym.php	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/extensions/Acronym/class.tx_rtehtmlarea_acronym.php	(copie de travail)
@@ -48,8 +48,13 @@
 		'acronym'	=> 'Acronym',
 		);
 	protected $acronymIndex = 0;
-	protected $abbraviationIndex = 0;
+	protected $abbreviationIndex = 0;
 
+	public function main($parentObject) {
+
+		return parent::main($parentObject) && t3lib_extMgm::isLoaded('static_info_tables');
+	}
+
 	/**
 	 * Return tranformed content
 	 *
@@ -94,11 +99,11 @@
 
 				// <abbr> was not supported by IE before version 7
 			if ($this->htmlAreaRTE->client['BROWSER'] == 'msie' && $this->htmlAreaRTE->client['VERSION'] < 7) {
-				$this->AbbreviationIndex = 0;
+				$this->abbreviationIndex = 0;
 			}
 			$registerRTEinJavascriptString .= '
 			RTEarea['.$RTEcounter.'].buttons.'. $button .'.noAcronym = ' . ($this->acronymIndex ? 'false' : 'true') . ';
-			RTEarea['.$RTEcounter.'].buttons.'. $button .'.noAbbr =  ' . ($this->AbbreviationIndex ? 'false' : 'true') . ';';
+			RTEarea['.$RTEcounter.'].buttons.'. $button .'.noAbbr =  ' . ($this->abbreviationIndex ? 'false' : 'true') . ';';
 		}
 
 		return $registerRTEinJavascriptString;
@@ -110,42 +115,57 @@
 	 * @return	string		acronym Javascript array
 	 */
 	function buildJSAcronymArray($languageUid) {
-		global $TYPO3_DB;
 
 		$charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] ? $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] : 'iso-8859-1';
-
 		$button = 'acronym';
 		$PIDList = 0;
-		if (is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.'][$button.'.']) && trim($this->thisConfig['buttons.'][$button.'.']['PIDList'])) {
+		if (is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.'][$button.'.']) && isset($this->thisConfig['buttons.'][$button.'.']['PIDList'])) {
 			$PIDList = implode(',', t3lib_div::trimExplode(',', $this->thisConfig['buttons.'][$button.'.']['PIDList']));
 		}
 		$linebreak = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->htmlAreaRTE->ID]['enableCompressedScripts'] ? '' : chr(10);
 		$JSAcronymArray .= 'acronyms = { ' . $linebreak;
+		$JSAcronymLanguageArray .= 'acronymLanguage = { ' . $linebreak;
 		$JSAbbreviationArray .= 'abbreviations = { ' . $linebreak;
-		$table = 'tx_rtehtmlarea_acronym';
+		$JSAbbreviationLanguageArray .= 'abbreviationLanguage = { ' . $linebreak;
+		$tableA = 'tx_rtehtmlarea_acronym';
+		$tableB = 'static_languages';
+		$fields = $tableA.'.type,' . $tableA . '.term,' . $tableA . '.acronym,' . $tableB . '.lg_iso_2';
+		$tableAB = $tableA . ' LEFT JOIN ' . $tableB . ' ON ' . $tableA . '.static_lang_isocode=' . $tableB . '.uid';
 		if ($languageUid > -1) {
-			$whereClause = '(sys_language_uid=' . $languageUid . ' OR sys_language_uid=-1) ';
+			$whereClause = '(' . $tableA . '.sys_language_uid=' . $languageUid . ' OR ' . $tableA . '.sys_language_uid=-1) ';
 		} else {
 			$whereClause = '1 = 1 ';
 		}
-		$whereClause .= ($PIDList ? ' AND '. $table . '.pid IN (' . $TYPO3_DB->fullQuoteStr($PIDList, $table) . ') ' : '');
-		$whereClause .= t3lib_BEfunc::BEenableFields($table);
-		$whereClause .= t3lib_BEfunc::deleteClause($table);
-		$res = $TYPO3_DB->exec_SELECTquery('type,term,acronym', $table, $whereClause);
-		while($acronymRow = $TYPO3_DB->sql_fetch_assoc($res))    {
-			if( $acronymRow['type'] == 1) $JSAcronymArray .= (($this->acronymIndex++)?',':'') . '"' . $GLOBALS['LANG']->csConvObj->utf8_encode($acronymRow['term'], $charset) . '":"' . $GLOBALS['LANG']->csConvObj->utf8_encode($acronymRow['acronym'], $charset) . '"' . $linebreak;
-			if ($acronymRow['type'] == 2) $JSAbbreviationArray .= (($this->AbbreviationIndex++)?',':'') . '"' . $GLOBALS['LANG']->csConvObj->utf8_encode($acronymRow['term'], $charset) . '":"' . $GLOBALS['LANG']->csConvObj->utf8_encode($acronymRow['acronym'], $charset) . '"' . $linebreak;
+		$whereClause .= ' AND '. $tableA . '.pid IN (' . $GLOBALS['TYPO3_DB']->fullQuoteStr($PIDList, $tableA) . ') ';
+		if (is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.']['language.']) && isset($this->thisConfig['buttons.']['language.']['items'])) {
+			$languageList = implode("','", t3lib_div::trimExplode(',', $GLOBALS['TYPO3_DB']->fullQuoteStr(strtoupper($this->thisConfig['buttons.']['language.']['items']), $tableB)));
+			$whereClause .= ' AND '. $tableB . '.lg_iso_2 IN (' . $languageList . ') ';
 		}
+		$whereClause .= t3lib_BEfunc::BEenableFields($tableA);
+		$whereClause .= t3lib_BEfunc::deleteClause($tableA);
+		$whereClause .= t3lib_BEfunc::BEenableFields($tableB);
+		$whereClause .= t3lib_BEfunc::deleteClause($tableB);
+		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, $tableAB, $whereClause);
+		while ($acronymRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
+			if( $acronymRow['type'] == 1) {
+				$JSAcronymArray .= (($this->acronymIndex++)?',':'') . '"' . $GLOBALS['LANG']->csConvObj->utf8_encode($acronymRow['term'], $charset) . '":"' . $GLOBALS['LANG']->csConvObj->utf8_encode($acronymRow['acronym'], $charset) . '"' . $linebreak;
+				$JSAcronymLanguageArray .= (($this->acronymIndex-1)?',':'') . '"' . $GLOBALS['LANG']->csConvObj->utf8_encode($acronymRow['term'], $charset) . '":"' . $GLOBALS['LANG']->csConvObj->utf8_encode(strtolower($acronymRow['lg_iso_2']), $charset) . '"' . $linebreak;
+			}
+			if ($acronymRow['type'] == 2) {
+				$JSAbbreviationArray .= (($this->abbreviationIndex++)?',':'') . '"' . $GLOBALS['LANG']->csConvObj->utf8_encode($acronymRow['term'], $charset) . '":"' . $GLOBALS['LANG']->csConvObj->utf8_encode($acronymRow['acronym'], $charset) . '"' . $linebreak;
+				$JSAbbreviationLanguageArray .= (($this->abbreviationIndex-1)?',':'') . '"' . $GLOBALS['LANG']->csConvObj->utf8_encode($acronymRow['term'], $charset) . '":"' . $GLOBALS['LANG']->csConvObj->utf8_encode(strtolower($acronymRow['lg_iso_2']), $charset) . '"' . $linebreak;
+			}
+		}
 		$JSAcronymArray .= '};' . $linebreak;
+		$JSAcronymLanguageArray .= '};' . $linebreak;
 		$JSAbbreviationArray .= '};' . $linebreak;
+		$JSAbbreviationLanguageArray .= '};' . $linebreak;
 
-		return $JSAcronymArray . $JSAbbreviationArray;
+		return $JSAcronymArray . $JSAcronymLanguageArray . $JSAbbreviationArray . $JSAbbreviationLanguageArray;
 	}
+}
 
-} // end of class
-
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/extensions/Acronym/class.tx_rtehtmlarea_acronym.php']) {
 	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/extensions/Acronym/class.tx_rtehtmlarea_acronym.php']);
 }
-
 ?>
\ No newline at end of file
Index: typo3/sysext/rtehtmlarea/extensions/Language/class.tx_rtehtmlarea_language.php
===================================================================
--- typo3/sysext/rtehtmlarea/extensions/Language/class.tx_rtehtmlarea_language.php	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/extensions/Language/class.tx_rtehtmlarea_language.php	(copie de travail)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 2008 Stanislas Rolland <stanislas.rolland(arobas)fructifor.ca>
+*  (c) 2008-2009 Stanislas Rolland <typo3(arobas)sjbr.ca>
 *  All rights reserved
 *
 *  This script is part of the Typo3 project. The Typo3 project is
@@ -24,7 +24,7 @@
 /**
  * Language plugin for htmlArea RTE
  *
- * @author Stanislas Rolland <stanislas.rolland(arobas)fructifor.ca>
+ * @author Stanislas Rolland <typo3(arobas)sjbr.ca>
  *
  * TYPO3 SVN ID: $Id$
  *
@@ -36,19 +36,30 @@
 
 	protected $extensionKey = 'rtehtmlarea';	// The key of the extension that is extending htmlArea RTE
 	protected $pluginName = 'Language';		// The name of the plugin registered by the extension
-	protected $relativePathToLocallangFile = '';	// Path to this main locallang file of the extension relative to the extension dir.
+	protected $relativePathToLocallangFile = 'extensions/Language/locallang.xml';	// Path to this main locallang file of the extension relative to the extension dir.
 	protected $relativePathToSkin = 'extensions/Language/skin/htmlarea.css';		// Path to the skin (css) file relative to the extension dir.
 	protected $htmlAreaRTE;				// Reference to the invoking object
 	protected $thisConfig;				// Reference to RTE PageTSConfig
 	protected $toolbar;				// Reference to RTE toolbar array
 	protected $LOCAL_LANG; 				// Frontend language array
-	
-	protected $pluginButtons = 'lefttoright,righttoleft';
+
+	protected $pluginButtons = 'lefttoright,righttoleft,language,showlanguagemarks';
 	protected $convertToolbarForHtmlAreaArray = array (
-		'lefttoright'		=> 'LeftToRight',
-		'righttoleft'		=> 'RightToLeft',
+		'lefttoright'			=> 'LeftToRight',
+		'righttoleft'			=> 'RightToLeft',
+		'language'			=> 'Language',
+		'showlanguagemarks'		=> 'ShowLanguageMarks',
 		);
-	
+
+	public function main($parentObject) {
+		if (!t3lib_extMgm::isLoaded('static_info_tables')) {
+			$this->pluginButtons = t3lib_div::rmFromList('language', $this->pluginButtons);
+		} else {
+			require_once(t3lib_extMgm::extPath('static_info_tables').'class.tx_staticinfotables_div.php');
+		}
+		return parent::main($parentObject);
+	}
+
 	/**
 	 * Return JS configuration of the htmlArea plugins registered by the extension
 	 *
@@ -64,8 +75,68 @@
 		global $TSFE, $LANG;
 		
 		$registerRTEinJavascriptString = '';
+		if (in_array('language', $this->toolbar)) {
+			if (!is_array( $this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.']['language.'])) {
+				$registerRTEinJavascriptString .= '
+			RTEarea['.$RTEcounter.'].buttons.language = new Object();';
+			}
+			$prefixLabelWithCode = !$this->thisConfig['buttons.']['language.']['prefixLabelWithCode'] ? false : true;
+			$postfixLabelWithCode = !$this->thisConfig['buttons.']['language.']['postfixLabelWithCode'] ? false : true;
+			$languageCodes = t3lib_div::trimExplode(',', $this->thisConfig['buttons.']['language.']['items'] ? $this->thisConfig['buttons.']['language.']['items'] : 'en', 1);
+			$labelsArray = $this->getStaticInfoName(implode(',', $languageCodes));
+			if ($this->htmlAreaRTE->is_FE()) {
+				$first = $GLOBALS['TSFE']->getLLL('No language mark',$this->LOCAL_LANG);
+			} else {
+				$first = $GLOBALS['LANG']->getLL('No language mark');
+			}
+				// Generating the JavaScript options
+			$languageOptions = '{
+			"'. $first.'" : "none"';
+			foreach ($languageCodes as $index => $code) {
+				$label = ($prefixLabelWithCode ? ($code . ' - ') : '') . $labelsArray[$index] . ($postfixLabelWithCode ? (' - ' . $code) : '');
+				$label = (!$this->htmlAreaRTE->is_FE() && $this->htmlAreaRTE->TCEform->inline->isAjaxCall) ? $GLOBALS['LANG']->csConvObj->utf8_encode($label, $GLOBALS['LANG']->charSet) : $label;
+				$languageOptions .= ',
+			"' . $label . '" : "' . $code . '"';
+			}
+			$languageOptions .= '};';
+
+			$registerRTEinJavascriptString .= '
+			RTEarea['.$RTEcounter.'].buttons.language.dropDownOptions = '. $languageOptions;
+		}
 		return $registerRTEinJavascriptString;
 	}
+	
+	/**
+	 * Getting the name of a language
+	 * We assume that the Static Info Tables are in 
+	 *
+	 * @param	string		$code: the ISO alpha-2 code of a language; or a comma-separated list of such
+	 * @param	boolean		$local: local name only - if set local title is returned
+	 * @return	array		names of the language(s) in the current language
+	 */
+	function getStaticInfoName($code, $local=FALSE) {
+		$table = 'static_languages';
+		$lang = tx_staticinfotables_div::getCurrentLanguage();
+		if (!t3lib_extMgm::isLoaded('static_info_tables_'.strtolower($lang))) {
+			$lang = '';
+		}
+		$codeArray = t3lib_div::trimExplode(',', $code);
+		$namesArray = array();
+		foreach ($codeArray as $isoCode){
+			$isoCodeArray = t3lib_div::trimExplode( '_', $isoCode, 1);
+			$name = tx_staticinfotables_div::getTitleFromIsoCode($table, $isoCodeArray, $lang, $local);
+			if (!$name && $lang != 'EN') {
+					// use the default English name if there is not text in another language
+				$name = tx_staticinfotables_div::getTitleFromIsoCode($table, $isoCodeArray, '', $local);
+			}
+			if ($this->htmlAreaRTE->is_FE()) {
+				$namesArray[] = $GLOBALS['TSFE']->csConvObj->conv($name, 'utf-8', $this->htmlAreaRTE->OutputCharset);
+			} else {
+				$namesArray[] = $GLOBALS['LANG']->csConvObj->conv($name, 'utf-8', $this->htmlAreaRTE->OutputCharset);
+			}
+		}
+		return $namesArray;
+	}
 
 } // end of class
 
Index: typo3/sysext/rtehtmlarea/extensions/Language/locallang.xml
===================================================================
--- typo3/sysext/rtehtmlarea/extensions/Language/locallang.xml	(r�vision 0)
+++ typo3/sysext/rtehtmlarea/extensions/Language/locallang.xml	(r�vision 0)
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- TYPO3 SVN ID: $Id: locallang.xml 3135 2008-02-08 16:08:16Z stan $ -->
+<T3locallang>
+	<meta type="array">
+		<description>Labels for LanguageMarks extension of htmlArea RTE</description>
+		<type>module</type>
+	</meta>
+	<data type="array">
+		<languageKey index="default" type="array">
+			<label index="No language mark">No language mark</label>
+		</languageKey>
+	</data>
+	<orig_hash type="array">
+		<languageKey index="default" type="array">
+		</languageKey>
+	</orig_hash>
+	<orig_text type="array">
+		<languageKey index="default" type="array">
+		</languageKey>
+	</orig_text>
+</T3locallang>
\ No newline at end of file
Index: typo3/sysext/rtehtmlarea/extensions/Language/skin/htmlarea.css
===================================================================
--- typo3/sysext/rtehtmlarea/extensions/Language/skin/htmlarea.css	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/extensions/Language/skin/htmlarea.css	(copie de travail)
@@ -1,4 +1,12 @@
-/* Selectors for the Language plugin of htmlArea RTE */
+/* Selectors for the LanguageMarks plugin of htmlArea RTE */
 /* TYPO3 SVN ID: $Id: htmlarea.css 2862 2008-01-05 19:32:58Z stanrolland $ */
-.htmlarea .toolbar .LeftToRight {background-image:url("images/left_to_right.gif");}
-.htmlarea .toolbar .RightToLeft {background-image:url("images/right_to_left.gif");}
+
+.htmlarea .toolbar .LeftToRight {
+	background-image:url("images/left_to_right.gif");
+}
+.htmlarea .toolbar .RightToLeft {
+	background-image:url("images/right_to_left.gif");
+}
+.htmlarea .toolbar .ShowLanguageMarks {
+	background-image:url("images/show-language-marks.gif");
+}
Index: typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js	(copie de travail)
@@ -2785,6 +2785,16 @@
 	},
 
 	/**
+	 * Returns a plugin object
+	 *
+	 * @param	string		pluinName: the name of some plugin
+	 * @return	object		the plugin object or null
+	 */
+	getPluginInstance : function(pluginName) {
+		return this.editor.getPluginInstance(pluginName);
+	},
+
+	/**
 	 * Returns true if the button is enabled in the toolbar configuration
 	 *
 	 * @param	string		buttonId: identification of the button
Index: typo3/sysext/rtehtmlarea/htmlarea/locallang_dialogs.xml
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/locallang_dialogs.xml	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/htmlarea/locallang_dialogs.xml	(copie de travail)
@@ -101,6 +101,14 @@
 			<label index="style">Paragraph:</label>
 			<label index="Block style label">Block style:</label>
 			<label index="text_style">Text style:</label>
+			<label index="LeftToRight">Left to right1</label>
+			<label index="RightToLeft">Right to left1</label>
+			<label index="Language">Language</label>
+			<label index="Text direction">Text direction</label>
+			<label index="Language:">Language:</label>
+			<label index="Text direction:">Text direction:</label>
+			<label index="No language mark">No language</label>
+			<label index="Remove language mark">Remove language</label>
 		</languageKey>
 	</data>
 	<orig_hash type="array">
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/Acronym/acronym.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/Acronym/acronym.js	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/Acronym/acronym.js	(copie de travail)
@@ -48,12 +48,12 @@
 		 * Registering plugin "About" information
 		 */
 		var pluginInformation = {
-			version		: "1.6",
+			version		: "1.7",
 			developer	: "Stanislas Rolland",
-			developerUrl	: "http://www.fructifor.ca/",
+			developerUrl	: "http://www.sjbr.ca/",
 			copyrightOwner	: "Stanislas Rolland",
-			sponsor		: "Fructifor Inc.",
-			sponsorUrl	: "http://www.fructifor.ca/",
+			sponsor		: "SJBR",
+			sponsorUrl	: "http://www.sjbr.ca/",
 			license		: "GPL"
 		};
 		this.registerPluginInformation(pluginInformation);
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/Language/language.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/Language/language.js	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/Language/language.js	(copie de travail)
@@ -1,7 +1,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 2008 Stanislas Rolland <stanislas.rolland(arobas)fructifor.ca>
+*  (c) 2008-2009 Stanislas Rolland <typo3(arobas)sjbr.ca>
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -30,30 +30,55 @@
  * TYPO3 SVN ID: $Id: language.js 2862 2008-01-05 19:32:58Z stanrolland $
  */
 Language = HTMLArea.Plugin.extend({
-		
+
 	constructor : function(editor, pluginName) {
 		this.base(editor, pluginName);
 	},
-	
+
 	/*
 	 * This function gets called by the class constructor
 	 */
 	configurePlugin : function (editor) {
-		
+
 		/*
+		 * Setting up some properties from PageTSConfig
+		 */
+		this.buttonsConfiguration = this.editorConfiguration.buttons;
+		this.useAttribute = {};
+		this.useAttribute.lang = (this.buttonsConfiguration.language && this.buttonsConfiguration.language.useLangAttribute) ? this.buttonsConfiguration.language.useLangAttribute : true;
+		this.useAttribute.xmlLang = (this.buttonsConfiguration.language && this.buttonsConfiguration.language.useXmlLangAttribute) ? this.buttonsConfiguration.language.useXmlLangAttribute : false;
+		if (!this.useAttribute.lang && !this.useAttribute.xmlLang) {
+			this.useAttribute.lang = true;
+		}
+
+			// Importing list of allowed attributes
+		if (this.editor.getPluginInstance("TextStyle")) {
+			this.allowedAttributes = this.editor.getPluginInstance("TextStyle").allowedAttributes;
+		}			
+		if (!this.allowedAttributes && this.editor.getPluginInstance("InlineElements")) {
+			this.allowedAttributes = this.editor.getPluginInstance("InlineElements").allowedAttributes;
+		}
+		if (!this.allowedAttributes && this.editor.getPluginInstance("BlockElements")) {
+			this.allowedAttributes = this.editor.getPluginInstance("BlockElements").allowedAttributes;
+		}
+		if (!this.allowedAttributes) {
+			this.allowedAttributes = new Array("id", "title", "lang", "xml:lang", "dir", (HTMLArea.is_gecko?"class":"className"));
+		}
+
+		/*
 		 * Registering plugin "About" information
 		 */
 		var pluginInformation = {
-			version		: "1.0",
+			version		: "0.1",
 			developer	: "Stanislas Rolland",
-			developerUrl	: "http://www.fructifor.ca/",
+			developerUrl	: "http://www.sjbr.ca/",
 			copyrightOwner	: "Stanislas Rolland",
-			sponsor		: "Fructifor Inc.",
-			sponsorUrl	: "http://www.fructifor.ca/",
+			sponsor		: this.localize("Technische Universitat Ilmenau"),
+			sponsorUrl	: "http://www.tu-ilmenau.de/",
 			license		: "GPL"
 		};
 		this.registerPluginInformation(pluginInformation);
-		
+
 		/*
 		 * Registering the buttons
 		 */
@@ -69,17 +94,59 @@
 			};
 			this.registerButton(buttonConfiguration);
 		}
-		
+
+		/*
+		 * Registering the dropdown list
+		 */
+		var buttonId = "Language";
+		var dropDownConfiguration = {
+			id		: buttonId,
+			tooltip		: this.localize(buttonId + "-Tooltip"),
+			options		: ((this.buttonsConfiguration.language && this.buttonsConfiguration.language.dropDownOptions) ? this.buttonsConfiguration.language.dropDownOptions : null),
+			action		: "onChange",
+			refresh		: null,
+			context		: null
+		};
+		this.registerDropDown(dropDownConfiguration);
+
 		return true;
 	 },
-	 
+
 	/* The list of buttons added by this plugin */
 	buttonList : [
 		["LeftToRight", null],
-		["RightToLeft", null]
+		["RightToLeft", null],
+		["ShowLanguageMarks", null]
 	],
-	 
+
 	/*
+	 * This function gets called when the editor is generated
+	 */
+	onGenerate : function () {
+			// Add rules to the stylesheet for language mark highlighting
+			// Model: body.htmlarea-show-language-marks *[lang=en]:before { content: "en: "; }
+			// Such rule is not supported by Internet Explorer
+		if (HTMLArea.is_gecko) {
+			var obj = this.getDropDownConfiguration("Language");
+			if ((typeof(obj) !== "undefined") && (typeof(this.editor._toolbarObjects[obj.id]) !== "undefined")) {
+				var styleSheet = this.editor._doc.styleSheets[0];
+				var select = document.getElementById(this.editor._toolbarObjects[obj.id].elementId);
+				var options = select.options;
+				var rule;
+				for (var i = options.length; --i >= 0;) {
+					if (this.useAttribute.lang) {
+						rule = 'body.htmlarea-show-language-marks *[lang=' + options[i].value + ']:before { content: "' + options[i].value + ': "; }';
+						styleSheet.insertRule(rule, styleSheet.cssRules.length);
+					} else if (this.useAttribute.xmlLang) {
+						rule = 'body.htmlarea-show-language-marks *[xml:lang=' + options[i].value + ']:before { content: "' + options[i].value + ': "; }';
+						styleSheet.insertRule(rule, styleSheet.cssRules.length);
+					}
+				}
+			}
+		}
+	},
+
+	/*
 	 * This function gets called when a button was pressed.
 	 *
 	 * @param	object		editor: the editor instance
@@ -92,37 +159,302 @@
 		var buttonId = this.translateHotKey(id);
 		buttonId = buttonId ? buttonId : id;
 		
+		switch (buttonId) {
+			case "RightToLeft" :
+			case "LeftToRight" :
+				this.setDirAttribute(buttonId);
+				break;
+			case "ShowLanguageMarks":
+				this.toggleLanguageMarks();
+				break;
+			default	:
+				break;
+		}
+		return false;
+	},
+	
+	/*
+	 * Sets the dir attribute
+	 *
+	 * @param	string		buttonId: the button id
+	 *
+	 * @return	void
+	 */
+	setDirAttribute : function (buttonId) {
 		var direction = (buttonId == "RightToLeft") ? "rtl" : "ltr";
-		var el = this.editor.getParentElement();
-		if (el) {
-			if (el.nodeName.toLowerCase() === "bdo") {
-				el.dir = direction;
+		var element = this.editor.getParentElement();
+		if (element) {
+			if (element.nodeName.toLowerCase() === "bdo") {
+				element.dir = direction;
 			} else {
-				el.dir = (el.dir == direction || el.style.direction == direction) ? "" : direction;
+				element.dir = (element.dir == direction || element.style.direction == direction) ? "" : direction;
 			}
-			el.style.direction = "";
+			element.style.direction = "";
 		}
-		
-		return false;
+	 },
+	
+	/*
+	 * Toggles the display of language marks
+	 *
+	 * @param	boolean		forceLanguageMarks: if set, language marks are displayed whatever the current state
+	 *
+	 * @return	void
+	 */
+	toggleLanguageMarks : function (forceLanguageMarks) {
+		var body = this.editor._doc.body;
+		if (!HTMLArea._hasClass(body, 'htmlarea-show-language-marks')) {
+			HTMLArea._addClass(body,'htmlarea-show-language-marks');
+		} else if (!forceLanguageMarks) {
+			HTMLArea._removeClass(body,'htmlarea-show-language-marks');
+		}
 	},
+
+	/*
+	 * This function gets called when some language was selected in the drop-down list
+	 */
+	onChange : function (editor, buttonId) {
+		var tbobj = this.editor._toolbarObjects[buttonId];
+		var language = document.getElementById(tbobj.elementId).value;
+		this.applyLanguageMark(language);
+	},
+
+	/*
+	 * This function applies the langauge mark to the selection
+	 */
+	applyLanguageMark : function (language) {
+		var selection = this.editor._getSelection();
+		var statusBarSelection = this.editor.getPluginInstance("StatusBar") ? this.editor.getPluginInstance("StatusBar").getSelection() : null;
+		var range = this.editor._createRange(selection);
+		var parent = this.editor.getParentElement(selection, range);
+		var selectionEmpty = this.editor._selectionEmpty(selection);
+		var endPointsInSameBlock = this.editor.endPointsInSameBlock();
+		var fullNodeSelected = false;
+		if (!selectionEmpty) {
+			if (endPointsInSameBlock) {
+				var ancestors = this.editor.getAllAncestors();
+				for (var i = 0; i < ancestors.length; ++i) {
+					fullNodeSelected = (statusBarSelection === ancestors[i])
+						&& ((HTMLArea.is_gecko && ancestors[i].textContent === range.toString()) || (HTMLArea.is_ie && ((selection.type !== "Control" && ancestors[i].innerText === range.text) || (selection.type === "Control" && ancestors[i].innerText === range.item(0).text))));
+					if (fullNodeSelected) {
+						parent = ancestors[i];
+						break;
+					}
+				}
+					// Working around bug in Safari selectNodeContents
+				if (!fullNodeSelected && HTMLArea.is_safari && statusBarSelection && statusBarSelection.textContent === range.toString()) {
+					fullNodeSelected = true;
+					parent = statusBarSelection;
+				}
+			}
+		}
+		if (selectionEmpty || fullNodeSelected) {
+				// Selection is empty or parent is selected in the status bar
+			if (parent) {
+					// Set language attributes
+				this.setLanguageAttributes(parent, language);
+			}
+		} else if (endPointsInSameBlock) {
+				// The selection is not empty, nor full element
+			if (language != "none") {
+					// Add span element with lang attribute(s)
+				var newElement = this.editor._doc.createElement("span");
+				this.setLanguageAttributes(newElement, language);
+				this.editor.wrapWithInlineElement(newElement, selection, range);
+				if (HTMLArea.is_gecko) {
+					range.detach();
+				}
+			}
+		} else {
+			this.setLanguageAttributeOnBlockElements(language);
+		}
+	},
+
+	/*
+	 * This function gets the language attribute on the given element
+	 *
+	 * @param	object		element: the element from which to retrieve the attribute value
+	 *
+	 * @return	string		value of the lang attribute, or of the xml:lang attribute
+	 */
+	getLanguageAttribute : function (element) {
+		return element.getAttribute("lang") ? element.getAttribute("lang") : (element.getAttribute("xml:lang") ? element.getAttribute("xml:lang") : "none");
+	},
 	
 	/*
+	 * This function sets the language attributes on the given element
+	 *
+	 * @param	object		element: the element on which to set the value of the lang and/or xml:lang attribute
+	 * @param	string		language: value of the lang attributes, or "none", in which case, the attribute(s) is(are) removed
+	 *
+	 * @return	void
+	 */
+	setLanguageAttributes : function (element, language) {
+		if (language == "none") {
+				// Remove language mark, if any
+			element.removeAttribute("lang");
+			element.removeAttribute("xml:lang");
+				// Remove the span tag if it has no more attribute
+			if ((element.nodeName.toLowerCase() == "span") && !HTMLArea.hasAllowedAttributes(element, this.allowedAttributes)) {
+				this.editor.removeMarkup(element);
+			}
+		} else {
+			if (this.useAttribute.lang) {
+				element.setAttribute("lang", language);
+			}
+			if (this.useAttribute.xmlLang) {
+				element.setAttribute("xml:lang", language);
+			}
+		}
+	},
+
+	/*
+	 * This function gets the language attributes from blocks sibling of the block containing the start container of the selection
+	 *
+	 * @return	string		value of the lang attribute, or of the xml:lang attribute, or "none", if all blocks sibling do not have the same attribute value as the block containing the start container
+	 */
+	getLanguageAttributeFromBlockElements : function() {
+		var selection = this.editor._getSelection();
+		var endBlocks = this.editor.getEndBlocks(selection);
+		var startAncestors = this.editor.getBlockAncestors(endBlocks.start);
+		var endAncestors = this.editor.getBlockAncestors(endBlocks.end);
+		var index = 0;
+		while (index < startAncestors.length && index < endAncestors.length && startAncestors[index] === endAncestors[index]) {
+			++index;
+		}
+		if (endBlocks.start === endBlocks.end) {
+			--index;
+		}
+		var language = this.getLanguageAttribute(startAncestors[index]);
+		for (var block = startAncestors[index]; block; block = block.nextSibling) {
+			if (HTMLArea.isBlockElement(block)) {
+				if (this.getLanguageAttribute(block) != language || this.getLanguageAttribute(block) == "none") {
+					language = "none";
+					break;
+				}
+			}
+			if (block == endAncestors[index]) {
+				break;
+			}
+		}
+		return language;
+	},
+
+	/*
+	 * This function sets the language attributes on blocks sibling of the block containing the start container of the selection
+	 */
+	setLanguageAttributeOnBlockElements : function(language) {
+		var selection = this.editor._getSelection();
+		var endBlocks = this.editor.getEndBlocks(selection);
+		var startAncestors = this.editor.getBlockAncestors(endBlocks.start);
+		var endAncestors = this.editor.getBlockAncestors(endBlocks.end);
+		var index = 0;
+		while (index < startAncestors.length && index < endAncestors.length && startAncestors[index] === endAncestors[index]) {
+			++index;
+		}
+		if (endBlocks.start === endBlocks.end) {
+			--index;
+		}
+		for (var block = startAncestors[index]; block; block = block.nextSibling) {
+			if (HTMLArea.isBlockElement(block)) {
+				this.setLanguageAttributes(block, language);
+			}
+			if (block == endAncestors[index]) {
+				break;
+			}
+		}
+	},
+
+	/*
 	 * This function gets called when the toolbar is updated
 	 */
 	onUpdateToolbar : function () {
 		if (this.editor.getMode() === "wysiwyg" && this.editor.isEditable()) {
+			var selection = this.editor._getSelection();
+			var statusBarSelection = this.editor.getPluginInstance("StatusBar") ? this.editor.getPluginInstance("StatusBar").getSelection() : null;
+			var range = this.editor._createRange(selection);
+			var parent = this.editor.getParentElement(selection);
+				// Updating the direction buttons
 			var buttonList = this.buttonList, buttonId;
 			for (var i = 0, n = buttonList.length; i < n; ++i) {
 				buttonId = buttonList[i][0];
 				if (this.isButtonInToolbar(buttonId)) {
-					var el = this.editor.getParentElement();
-					if (el) {
-						var direction = (buttonId === "RightToLeft") ? "rtl" : "ltr";
-						this.editor._toolbarObjects[buttonId].state("active",(el.dir == direction || el.style.direction == direction));
+					switch (buttonId) {
+						case "RightToLeft" :
+						case "LeftToRight" :
+							if (parent) {
+								var direction = (buttonId === "RightToLeft") ? "rtl" : "ltr";
+								this.editor._toolbarObjects[buttonId].state("active",(parent.dir == direction || parent.style.direction == direction));
+							}
+							break;
+						case "ShowLanguageMarks":
+							this.editor._toolbarObjects[buttonId].state("active", HTMLArea._hasClass(this.editor._doc.body, 'htmlarea-show-language-marks'));
+							break;
+						default	:
+							break;
 					}
 				}
 			}
+				// Updating the language drop-down
+			var fullNodeSelected = false;
+			var language = this.getLanguageAttribute(parent);
+			var selectionEmpty = this.editor._selectionEmpty(selection);
+			var endPointsInSameBlock = this.editor.endPointsInSameBlock();
+			if (!selectionEmpty) {
+				if (endPointsInSameBlock) {
+					var ancestors = this.editor.getAllAncestors();
+					for (var i = 0; i < ancestors.length; ++i) {
+						fullNodeSelected = (statusBarSelection === ancestors[i])
+							&& ((HTMLArea.is_gecko && ancestors[i].textContent === range.toString()) || (HTMLArea.is_ie && ((selection.type !== "Control" && ancestors[i].innerText === range.text) || (selection.type === "Control" && ancestors[i].innerText === range.item(0).text))));
+						if (fullNodeSelected) {
+							parent = ancestors[i];
+							break;
+						}
+					}
+						// Working around bug in Safari selectNodeContents
+					if (!fullNodeSelected && HTMLArea.is_safari && statusBarSelection && statusBarSelection.textContent === range.toString()) {
+						fullNodeSelected = true;
+						parent = statusBarSelection;
+					}
+					language = this.getLanguageAttribute(parent);
+				} else {
+					language = this.getLanguageAttributeFromBlockElements();
+				}
+			}
+			var obj = this.getDropDownConfiguration("Language");
+			if ((typeof(obj) !== "undefined") && (typeof(this.editor._toolbarObjects[obj.id]) !== "undefined")) {
+				this.updateValue(obj, language, selectionEmpty, fullNodeSelected, endPointsInSameBlock);
+			}
 		}
+	},
+
+	/*
+	* This function updates the language drop-down list
+	*/
+	updateValue : function (obj, language, selectionEmpty, fullNodeSelected, endPointsInSameBlock) {
+		var select = document.getElementById(this.editor._toolbarObjects[obj.id]["elementId"]);
+		var options = select.options;
+		for (var i = options.length; --i >= 0;) {
+			options[i].selected = false;
+		}
+		select.selectedIndex = 0;
+		options[0].selected = true;
+		select.options[0].text = this.localize("No language mark");
+		if (language != "none") {
+			for (i = options.length; --i >= 0;) {
+				if (language == options[i].value) {
+					if (selectionEmpty || fullNodeSelected || !endPointsInSameBlock) {
+						options[i].selected = true;
+						select.selectedIndex = i;
+						select.options[0].text = this.localize("Remove language mark");
+					}
+					break;
+				}
+			}
+		}
+		select.disabled = !(options.length>1) || (selectionEmpty && this.editor.getParentElement().nodeName.toLowerCase() === "body");
+		select.className = "";
+		if (select.disabled) {
+			select.className = "buttonDisabled";
+		}
 	}
 });
-
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/Language/locallang.xml
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/Language/locallang.xml	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/Language/locallang.xml	(copie de travail)
@@ -9,6 +9,9 @@
 		<languageKey index="default" type="array">
 			<label index="LeftToRight-Tooltip">Direction left to right</label>
 			<label index="RightToLeft-Tooltip">Direction right to left</label>
+			<label index="Language-Tooltip">Language</label>
+			<label index="ShowLanguageMarks-Tooltip">Show language marks</label>
+			<label index="Technische Universitat Ilmenau">Technische Universität Ilmenau</label>
 		</languageKey>
 	</data>
 	<orig_hash type="array">
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/TableOperations/table-operations.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/TableOperations/table-operations.js	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/TableOperations/table-operations.js	(copie de travail)
@@ -3,7 +3,7 @@
 *
 *  (c) 2002 interactivetools.com, inc. Authored by Mihai Bazon, sponsored by http://www.bloki.com.
 *  (c) 2005 Xinha, http://xinha.gogo.co.nz/ for the original toggle borders function.
-*  (c) 2004-2008 Stanislas Rolland <typo3(arobas)sjbr.ca>
+*  (c) 2004-2009 Stanislas Rolland <typo3(arobas)sjbr.ca>
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -200,6 +200,7 @@
 				TableOperations.insertSpace(doc, content);
 			}
 		}
+		this.buildLanguageFieldset(doc, table, content, "floating");
 		if (this.removedFieldsets.indexOf("layout") == -1) this.buildLayoutFieldset(doc, table, content, "floating");
 		if (this.removedFieldsets.indexOf("alignment") == -1) this.buildAlignmentFieldset(doc, table, content);
 		TableOperations.insertSpace(doc, content);
@@ -340,6 +341,12 @@
 						this.editor.plugins.BlockStyle.instance.applyClassChange(tpart, val);
 					}
 					break;
+				    case "f_lang":
+					this.getPluginInstance("Language").setLanguageAttributes(table, val);
+					break;
+				    case "f_dir":
+					table.dir = (val != "not set") ? val : "";
+					break;
 				}
 			}
 		}
@@ -416,6 +423,7 @@
 		} else {
 			TableOperations.insertSpace(doc, content);
 		}
+		this.buildLanguageFieldset(doc, element, content, "floating");
 		if (this.removedFieldsets.indexOf("layout") == -1) this.buildLayoutFieldset(doc, element, content, "floating");
 		if (this.removedFieldsets.indexOf("alignment") == -1) this.buildAlignmentFieldset(doc, element, content);
 		if (this.removedFieldsets.indexOf("borders") == -1) this.buildBordersFieldset(dialog.dialogWindow, doc, dialog.editor, element, content);
@@ -479,6 +487,12 @@
 				    case "f_class":
 					this.editor.plugins.BlockStyle.instance.applyClassChange(element, val);
 					break;
+				    case "f_lang":
+					this.getPluginInstance("Language").setLanguageAttributes(element, val);
+					break;
+				    case "f_dir":
+					element.dir = (val != "not set") ? val : "";
+					break;
 				}
 			}
 		}
@@ -1646,6 +1660,48 @@
 		content.appendChild(fieldset);
 	},
 	
+	buildLanguageFieldset : function (doc, el, content, fieldsetClass) {
+		if (this.removedFieldsets.indexOf("language") == -1 && (this.removedProperties.indexOf("language") == -1 || this.removedProperties.indexOf("direction") == -1) && this.getPluginInstance("Language") && (this.isButtonInToolbar("Language") || this.isButtonInToolbar("LeftToRight") || this.isButtonInToolbar("RightToLeft"))) {
+			var languageObject = this.getPluginInstance("Language");
+			var fieldset = doc.createElement("fieldset");
+			if (fieldsetClass) {
+				fieldset.className = fieldsetClass;
+			}
+			TableOperations.insertLegend(doc, fieldset, "Language");
+			var ul = doc.createElement("ul");
+			fieldset.appendChild(ul);
+			if (this.removedProperties.indexOf("language") == -1 && this.isButtonInToolbar("Language")) {
+				var languageOptions = this.getDropDownConfiguration("Language").options;
+				var select,
+					selected = "",
+					options = new Array(),
+					values = new Array();
+				for (var option in languageOptions) {
+					if (languageOptions.hasOwnProperty(option)) {
+						options.push(option);
+						values.push(languageOptions[option]);
+					}
+				}
+				selected = el ? languageObject.getLanguageAttribute(el) : "none";
+				if (selected != "none") {
+					options[0] = languageObject.localize("Remove language mark");
+				}
+				(selected.match(/([^\s]*)\s/)) && (selected = RegExp.$1);
+				var li = doc.createElement("li");
+				ul.appendChild(li);
+				select = TableOperations.buildSelectField(doc, li, "f_lang", "Language:", "fr", "", "Language", options, values, new RegExp((selected ? selected : "none"), "i"));
+			}
+			if (this.removedProperties.indexOf("direction") == -1 && (this.isButtonInToolbar("LeftToRight") || this.isButtonInToolbar("RightToLeft"))) {
+				var li = doc.createElement("li");
+				ul.appendChild(li);
+				selected = el ? el.dir : "";
+				(selected.match(/([^\s]*)\s/)) && (selected = RegExp.$1);
+				select = TableOperations.buildSelectField(doc, li, "f_dir", "Text direction:", "fr", "", "Text direction", ["Not set", "Right to left", "Left to right"], ["not set", "rtl", "ltr"], new RegExp((selected ? selected : "not set"), "i"));
+			}
+			content.appendChild(fieldset);
+		}
+	},
+	
 	buildCellTypeFieldset : function (doc, el, content, column, fieldsetClass) {
 		var fieldset = doc.createElement("fieldset");
 		if (fieldsetClass) fieldset.className = fieldsetClass;
Index: typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea-edited-content.css
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea-edited-content.css	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea-edited-content.css	(copie de travail)
@@ -14,6 +14,14 @@
 	padding: 3px; border:1px dashed #316ac5 ! important;
 }
 
+/* Make language marks visible */
+body.htmlarea-show-language-marks *[lang] {
+	background: url("images/language-marker.gif") left bottom no-repeat; padding-left: 14px; text-decoration: underline;
+}
+body.htmlarea-show-language-marks *[xml:lang] {
+	background-image: url("images/language-marker.gif"); background-position: left bottom; background-repeat: no-repeat; padding-left: 14px; text-decoration: underline;
+}
+
 /* Selectors for the Abbreviation plugin */
 body.htmlarea-content-body abbr, body.htmlarea-content-body acronym {
 	border-bottom:1px dashed #000;
Index: typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css	(copie de travail)
@@ -83,6 +83,7 @@
 .htmlarea .toolbar .Variable {background-image:url("images/InlineElements/variable.gif");}
 .htmlarea .toolbar .LeftToRight {background-image:url("images/ed_left_to_right.gif");}
 .htmlarea .toolbar .RightToLeft {background-image:url("images/ed_right_to_left.gif");}
+.htmlarea .toolbar .ShowLanguageMarks {background-image:url("images/show-language-marks.gif");}
 .htmlarea .toolbar .Indent {background-image:url("images/BlockElements/indent.gif");}
 .htmlarea .toolbar .Outdent {background-image:url("images/BlockElements/outdent.gif");}
 .htmlarea .toolbar .Blockquote {background-image:url("images/BlockElements/blockquote.gif");}
Index: typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/language-marker.gif
===================================================================
Impossible d'afficher : fichier consid�r� comme binaire.
svn:mime-type = application/octet-stream

Modification de propri�t�s sur typo3\sysext\rtehtmlarea\htmlarea\skins\default\images\language-marker.gif
___________________________________________________________________
Ajout� : svn:mime-type
   + application/octet-stream

Index: typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/show-language-marks.gif
===================================================================
Impossible d'afficher : fichier consid�r� comme binaire.
svn:mime-type = application/octet-stream

Modification de propri�t�s sur typo3\sysext\rtehtmlarea\htmlarea\skins\default\images\show-language-marks.gif
___________________________________________________________________
Ajout� : svn:mime-type
   + application/octet-stream

Index: typo3/sysext/rtehtmlarea/locallang_db.xml
===================================================================
--- typo3/sysext/rtehtmlarea/locallang_db.xml	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/locallang_db.xml	(copie de travail)
@@ -12,6 +12,7 @@
 			<label index="tx_rtehtmlarea_acronym.type.I.1">Abbreviation</label>
 			<label index="tx_rtehtmlarea_acronym.term">Term</label>
 			<label index="tx_rtehtmlarea_acronym.acronym">Abridged form</label>
+			<label index="tx_rtehtmlarea_acronym.static_lang_isocode">Language of term</label>
 		</languageKey>
 	</data>
 	<orig_hash type="array">
Index: typo3/sysext/rtehtmlarea/mod2/class.tx_rtehtmlarea_acronym_mod.php
===================================================================
--- typo3/sysext/rtehtmlarea/mod2/class.tx_rtehtmlarea_acronym_mod.php	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/mod2/class.tx_rtehtmlarea_acronym_mod.php	(copie de travail)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 2005-2008 Stanislas Rolland <typo3(arobas)sjbr.ca>
+*  (c) 2005-2009 Stanislas Rolland <typo3(arobas)sjbr.ca>
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -57,6 +57,7 @@
 		$this->doc->form = '<form action="" id="content" name="content" method="POST">';
 		$JScode='
 			var dialog = window.opener.HTMLArea.Dialog.Acronym;
+			var plugin = dialog.plugin;
 			var editor = dialog.plugin.editor;
 			var param = null;
 			var html = editor.getSelectedHTML();
@@ -64,8 +65,8 @@
 			var range = editor._createRange(sel);
 			var abbr = editor._activeElement(sel);
 				// Working around Safari issue
-			if (!abbr && editor._statusBarTree.selected) {
-				abbr = editor._statusBarTree.selected;
+			if (!abbr && plugin.getPluginInstance("StatusBar") && plugin.getPluginInstance("StatusBar").getSelection()) {
+				abbr = plugin.getPluginInstance("StatusBar").getSelection();
 			}
 			var abbrType = null;
 			var acronyms = new Object();
@@ -81,7 +82,7 @@
 			}
 
 			function setType() {
-				if(document.content.acronym.checked) {
+				if (document.content.acronym.checked) {
 					abbrType = "acronym";
 					document.getElementById("abbrType").innerHTML = "' . $LANG->getLL('Acronym') . '";
 				} else {
@@ -89,6 +90,7 @@
 					document.getElementById("abbrType").innerHTML = "' . $LANG->getLL('Abbreviation') . '";
 				}
 				document.getElementById("title").value = param["title"];
+				rtehtmlareaAcronymFillLanguage();
 				fillSelect(param);
 				dialog.resize();
 			}
@@ -150,6 +152,7 @@
 							}
 							if (selectedOption == i) {
 								document.content.title.value = i;
+								rtehtmlareaAcronymSelectedLanguage(i);
 							}
 						}
 					}
@@ -168,6 +171,11 @@
 					}
 				} else {
 					var doc = editor._doc;
+					var languageObject = plugin.getPluginInstance("Language");
+					if (plugin.isButtonInToolbar("Language")) {
+						var select = document.getElementById("termLanguageSelector");
+						var language = select.options[select.selectedIndex].value;
+					}
 					if (!abbr) {
 						abbr = doc.createElement(abbrType);
 						abbr.title = title;
@@ -175,15 +183,69 @@
 							html = document.content.acronymSelector.options[document.content.acronymSelector.selectedIndex].value;
 						}
 						abbr.innerHTML = html;
+						if (languageObject && plugin.isButtonInToolbar("Language")) {
+							languageObject.setLanguageAttributes(abbr, language);
+						}
 						if (HTMLArea.is_ie) range.pasteHTML(abbr.outerHTML);
 							else editor.insertNodeAtSelection(abbr);
 					} else {
 						abbr.title = title;
-						if(document.content.acronymSelector.options.length != 1 && document.content.termSelector.selectedIndex > 0 && document.content.termSelector.options[document.content.termSelector.selectedIndex].value == title) abbr.innerHTML = document.content.acronymSelector.options[document.content.acronymSelector.selectedIndex].value;
+						if (languageObject && plugin.isButtonInToolbar("Language")) {
+							languageObject.setLanguageAttributes(abbr, language);
+						}
+						if (document.content.acronymSelector.options.length != 1 && document.content.termSelector.selectedIndex > 0 && document.content.termSelector.options[document.content.termSelector.selectedIndex].value == title) {
+							abbr.innerHTML = document.content.acronymSelector.options[document.content.acronymSelector.selectedIndex].value;
+						}
 					}
 				}
 			};
 
+			function rtehtmlareaAcronymFillLanguage() {
+				if (plugin.isButtonInToolbar("Language")) {
+					var languageOptions = plugin.getDropDownConfiguration("Language").options;
+					var select = document.getElementById("termLanguageSelector");
+					while (select.options.length > 0) {
+						select.options[select.length-1] = null;
+					}
+					for (var option in languageOptions) {
+						if (languageOptions.hasOwnProperty(option)) {
+							var addOption = document.createElement("option");
+							addOption.innerHTML = option;
+							addOption.value = languageOptions[option];
+							select.appendChild(addOption);
+						}
+					}
+				} else {
+					document.getElementById("languageSelector").style.display = "none";
+				}
+			};
+
+			function rtehtmlareaAcronymSelectedLanguage(term) {
+				if (abbrType == "acronym") {
+					var languages = acronymLanguage;
+				} else {
+					var languages = abbreviationLanguage;
+				}
+				if (document.getElementById("languageSelector").style.display != "none") {
+					var select = document.getElementById("termLanguageSelector");
+					var options = select.options;
+					for (var i = options.length; --i >= 0;) {
+						options[i].selected = false;
+					}
+					select.selectedIndex = 0;
+					options[0].selected = true;
+					if (languages[term]) {
+						for (i = options.length; --i >= 0;) {
+							if (languages[term] == options[i].value) {
+								options[i].selected = true;
+								select.selectedIndex = i;
+								break;
+							}
+						}
+					}
+				}
+			}
+
 			function onOK() {
 				processAcronym(document.getElementById("title").value);
 				dialog.close();
@@ -254,17 +316,26 @@
 		<div>
 			<label class="fl" for="termSelector" id="termSelectorLabel" title="' . $LANG->getLL('Select_a_term',1) . '">' . $LANG->getLL('Unabridged_term',1) . '</label>
 			<select id="termSelector" name="termSelector"  title="' . $LANG->getLL('Select_a_term',1) . '"
-				onChange="document.content.acronymSelector.selectedIndex=document.content.termSelector.selectedIndex; document.content.title.value=document.content.termSelector.options[document.content.termSelector.selectedIndex].value;">
+				onChange="document.content.acronymSelector.selectedIndex=document.content.termSelector.selectedIndex;
+					document.content.title.value=document.content.termSelector.options[document.content.termSelector.selectedIndex].value;
+					rtehtmlareaAcronymSelectedLanguage(document.content.title.value);">
 				<option value=""></option>
 			</select>
 		</div>
 		<div>
 			<label class="fl" for="acronymSelector" id="acronymSelectorLabel" title="' . $LANG->getLL('Select_an_acronym',1) . '">' . $LANG->getLL('Abridged_term',1) . '</label>
 			<select id="acronymSelector" name="acronymSelector"  title="' . $LANG->getLL('Select_an_acronym',1) . '"
-				onChange="document.content.termSelector.selectedIndex=document.content.acronymSelector.selectedIndex; document.content.title.value=document.content.termSelector.options[document.content.termSelector.selectedIndex].value;">
+				onChange="document.content.termSelector.selectedIndex=document.content.acronymSelector.selectedIndex;
+					document.content.title.value=document.content.termSelector.options[document.content.termSelector.selectedIndex].value;
+					rtehtmlareaAcronymSelectedLanguage(document.content.title.value);">
 				<option value=""></option>
 			</select>
 		</div>
+		<div id="languageSelector">
+			<label class="fl" for="termLanguageSelector" id="termLanguageSelectorLabel" title="' . $LANG->getLL('Select_a_language',1) . '">' . $LANG->getLL('Language',1) . '</label>
+			<select id="termLanguageSelector" name="termLanguageSelector"  title="' . $LANG->getLL('Select_a_language',1) . '">
+			</select>
+		</div>
 	</fieldset>
 	<fieldset>
 		<legend>' . $LANG->getLL('Term_to_abridge',1) . '</legend>
Index: typo3/sysext/rtehtmlarea/mod2/locallang.xml
===================================================================
--- typo3/sysext/rtehtmlarea/mod2/locallang.xml	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/mod2/locallang.xml	(copie de travail)
@@ -21,6 +21,8 @@
 			<label index="OK">OK</label>
 			<label index="Delete">Delete</label>
 			<label index="Cancel">Cancel</label>
+			<label index="Language">Language:</label>
+			<label index="Select_a_language">Select a language</label>
 		</languageKey>
 	</data>
 	<orig_hash type="array">
Index: typo3/sysext/rtehtmlarea/mod4/class.tx_rtehtmlarea_select_image.php
===================================================================
--- typo3/sysext/rtehtmlarea/mod4/class.tx_rtehtmlarea_select_image.php	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/mod4/class.tx_rtehtmlarea_select_image.php	(copie de travail)
@@ -3,7 +3,7 @@
 *  Copyright notice
 *
 *  (c) 1999-2008 Kasper Skaarhoj (kasper@typo3.com)
-*  (c) 2004-2008 Stanislas Rolland <typo3(arobas)sjbr.ca>
+*  (c) 2004-2009 Stanislas Rolland <typo3(arobas)sjbr.ca>
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -494,6 +494,16 @@
 				var classesImage = ' . ($this->thisConfig['classesImage']?'true':'false') . ';
 				if (classesImage) var styleSelector=\'<select id="iClass" name="iClass" style="width:140px;">' . $classesImageJSOptions  . '</select>\';
 				var floatSelector=\'<select id="iFloat" name="iFloat"><option value="">' . $LANG->getLL('notSet') . '</option><option value="none">' . $LANG->getLL('nonFloating') . '</option><option value="left">' . $LANG->getLL('left') . '</option><option value="right">' . $LANG->getLL('right') . '</option></select>\';
+				if (plugin.isButtonInToolbar("Language")) {
+					var languageOptions = plugin.getDropDownConfiguration("Language").options;
+					var languageSelector = \'<select id="iLang" name="iLang">\';
+					for (var option in languageOptions) {
+						if (languageOptions.hasOwnProperty(option)) {
+							languageSelector +=\'<option value="\' + languageOptions[option] + \'">\' + option + \'</option>\';
+						}
+					}
+					languageSelector += \'</select>\';
+				}
 				var bgColor=\' class="bgColor4"\';
 				var sz="";
 				sz+=\'<table border=0 cellpadding=1 cellspacing=1><form action="" name="imageData">\';
@@ -525,6 +535,10 @@
 				sz+=\'<tr><td\'+bgColor+\'><label for="iTitle">'.$LANG->getLL('title').': </label></td><td><input type="text" id="iTitle" name="iTitle"'.$GLOBALS['TBE_TEMPLATE']->formWidth(20).' /></td></tr>\';')
 				.(in_array('alt', $removedProperties)?'':'
 				sz+=\'<tr><td\'+bgColor+\'><label for="iAlt">'.$LANG->getLL('alt').': </label></td><td><input type="text" id="iAlt" name="iAlt"'.$GLOBALS['TBE_TEMPLATE']->formWidth(20).' /></td></tr>\';')
+				.(in_array('lang', $removedProperties)?'':'
+				if (plugin.isButtonInToolbar("Language")) {
+					sz+=\'<tr><td\'+bgColor+\'><label for="iLang">\' + plugin.getPluginInstance("Language").localize(\'Language-Tooltip\') + \': </label></td><td>\' + languageSelector + \'</td></tr>\';
+				}')
 				.(in_array('clickenlarge', $removedProperties)?'':'
 				sz+=\'<tr><td\'+bgColor+\'><label for="iClickEnlarge">'.$LANG->sL('LLL:EXT:cms/locallang_ttc.php:image_zoom',1).' </label></td><td><input type="checkbox" name="iClickEnlarge" id="iClickEnlarge" value="0" /></td></tr>\';').'
 				sz+=\'<tr><td><input type="submit" value="'.$LANG->getLL('update').'" onClick="return setImageProperties();"></td></tr>\';
@@ -580,7 +594,6 @@
 					if (document.imageData.iAlt) {
 						selectedImageRef.alt=document.imageData.iAlt.value;
 					}
-
 					if (document.imageData.iBorder) {
 						selectedImageRef.style.borderStyle = "";
 						selectedImageRef.style.borderWidth = "";
@@ -599,7 +612,6 @@
 						}
 						selectedImageRef.removeAttribute("border");
 					}
-
 					if (document.imageData.iFloat) {
 						var iFloat = document.imageData.iFloat.options[document.imageData.iFloat.selectedIndex].value;
 						if (iFloat || selectedImageRef.style.cssFloat || selectedImageRef.style.styleFloat) {
@@ -610,7 +622,6 @@
 							}
 						}
 					}
-
 					if (classesImage && document.imageData.iClass) {
 						var iClass = document.imageData.iClass.options[document.imageData.iClass.selectedIndex].value;
 						if (iClass || (selectedImageRef.attributes["class"] && selectedImageRef.attributes["class"].value)) {
@@ -619,7 +630,15 @@
 							selectedImageRef.className = "";
 						}
 					}
-
+					if (document.imageData.iLang) {
+						var iLang = document.imageData.iLang.options[document.imageData.iLang.selectedIndex].value;
+						var languageObject = plugin.getPluginInstance("Language");
+						if (iLang || languageObject.getLanguageAttribute(selectedImageRef)) {
+							languageObject.setLanguageAttributes(selectedImageRef, iLang);
+						} else {
+							languageObject.setLanguageAttributes(selectedImageRef, "none");
+						}
+					}
 					if (document.imageData.iClickEnlarge) {
 						if (document.imageData.iClickEnlarge.checked) {
 							selectedImageRef.setAttribute("clickenlarge","1");
@@ -694,17 +713,28 @@
 							}
 						}
 					}
-
 					if (classesImage && document.imageData.iClass) {
 						var fObj=document.imageData.iClass;
 						var value=selectedImageRef.className;
 						var l=fObj.length;
-						for (var a=0;a < l; a++)	{
-							if (fObj.options[a].value == value)	{
+						for (var a=0;a < l; a++) {
+							if (fObj.options[a].value == value) {
 								fObj.selectedIndex = a;
 							}
 						}
 					}
+					if (document.imageData.iLang) {
+						var fObj=document.imageData.iLang;
+						var value=plugin.getPluginInstance("Language").getLanguageAttribute(selectedImageRef);
+						for (var i = 0, n = fObj.length; i < n; i++) {
+							if (fObj.options[i].value == value) {
+								fObj.selectedIndex = i;
+								if (i) {
+									fObj.options[0].text = plugin.getPluginInstance("Language").localize("Remove language mark");
+								}
+							}
+						}
+					}
 					if (document.imageData.iClickEnlarge) {
 						if (selectedImageRef.getAttribute("clickenlarge") == "1") {
 							document.imageData.iClickEnlarge.checked = 1;
Index: typo3/sysext/rtehtmlarea/tca.php
===================================================================
--- typo3/sysext/rtehtmlarea/tca.php	(r�vision 4859)
+++ typo3/sysext/rtehtmlarea/tca.php	(copie de travail)
@@ -71,7 +71,7 @@
 		),
 		'term' => Array (		
 			'exclude' => 0,		
-			'label' => 'LLL:EXT:rtehtmlarea/locallang_db.xml:tx_rtehtmlarea_acronym.term',		
+			'label' => 'LLL:EXT:rtehtmlarea/locallang_db.xml:tx_rtehtmlarea_acronym.term',
 			'config' => Array (
 				'type' => 'input',
 				'size' => '30',
@@ -80,16 +80,36 @@
 		),
 		'acronym' => Array (		
 			'exclude' => 0,		
-			'label' => 'LLL:EXT:rtehtmlarea/locallang_db.xml:tx_rtehtmlarea_acronym.acronym',		
+			'label' => 'LLL:EXT:rtehtmlarea/locallang_db.xml:tx_rtehtmlarea_acronym.acronym',
 			'config' => Array (
 				'type' => 'input',
 				'size' => '30',
 				'eval' => 'trim,required',
 			)
 		),
+		'static_lang_isocode' => Array (		
+			'exclude' => 0,
+			'label' => 'LLL:EXT:rtehtmlarea/locallang_db.xml:tx_rtehtmlarea_acronym.static_lang_isocode',
+			'displayCond' => 'EXT:static_info_tables:LOADED:true',
+			'config' => array(
+				'type' => 'select',
+				'items' => array(
+					array('', 0),
+				),
+				'itemsProcFunc' => 'tx_staticinfotables_div->selectItemsTCA',
+				'itemsProcFunc_config' => array(
+					'table' => 'static_languages',
+					'indexField' => 'uid',
+					'prependHotlist' => 1,
+				),
+				'size' => 1,
+				'minitems' => 0,
+				'maxitems' => 1,
+			)
+		),
 	),
 	'types' => Array (
-		'0' => Array( 'showitem' => 'hidden;;1;;1-1-1, sys_language_uid, type, term, acronym')
+		'0' => Array( 'showitem' => 'hidden;;1;;1-1-1, sys_language_uid, type, term, acronym, static_lang_isocode')
 	),
 	"palettes" => Array (
 		"1" => Array("showitem" => "starttime, endtime")
Index: typo3/sysext/t3skin/rtehtmlarea/htmlarea-edited-content.css
===================================================================
--- typo3/sysext/t3skin/rtehtmlarea/htmlarea-edited-content.css	(r�vision 4859)
+++ typo3/sysext/t3skin/rtehtmlarea/htmlarea-edited-content.css	(copie de travail)
@@ -14,6 +14,14 @@
 	padding: 3px; border:1px dashed #316ac5 ! important;
 }
 
+/* Make language marks visible */
+body.htmlarea-show-language-marks *[lang] {
+	background: url("images/language-marker.gif") left bottom no-repeat; padding-left: 14px; text-decoration: underline;
+}
+body.htmlarea-show-language-marks *[xml:lang] {
+	background-image: url("images/language-marker.gif"); background-position: left bottom; background-repeat: no-repeat; padding-left: 14px; text-decoration: underline;
+}
+
 /* Selectors for the Abbreviation plugin */
 body.htmlarea-content-body abbr, body.htmlarea-content-body acronym {
 	border-bottom:1px dashed #000;
Index: typo3/sysext/t3skin/rtehtmlarea/htmlarea.css
===================================================================
--- typo3/sysext/t3skin/rtehtmlarea/htmlarea.css	(r�vision 4859)
+++ typo3/sysext/t3skin/rtehtmlarea/htmlarea.css	(copie de travail)
@@ -93,6 +93,7 @@
 .htmlarea .toolbar .Variable {background-image:url("images/InlineElements/variable.gif");}
 .htmlarea .toolbar .LeftToRight {background-image:url("images/ed_left_to_right.gif");}
 .htmlarea .toolbar .RightToLeft {background-image:url("images/ed_right_to_left.gif");}
+.htmlarea .toolbar .ShowLanguageMarks {background-image:url("images/show-language-marks.gif");}
 .htmlarea .toolbar .Indent {background-image:url("images/BlockElements/indent.gif");}
 .htmlarea .toolbar .Outdent {background-image:url("images/BlockElements/outdent.gif");}
 .htmlarea .toolbar .Blockquote {background-image:url("images/BlockElements/blockquote.gif");}
Index: typo3/sysext/t3skin/rtehtmlarea/images/language-marker.gif
===================================================================
Impossible d'afficher : fichier consid�r� comme binaire.
svn:mime-type = application/octet-stream

Modification de propri�t�s sur typo3\sysext\t3skin\rtehtmlarea\images\language-marker.gif
___________________________________________________________________
Ajout� : svn:mime-type
   + application/octet-stream

Index: typo3/sysext/t3skin/rtehtmlarea/images/show-language-marks.gif
===================================================================
Impossible d'afficher : fichier consid�r� comme binaire.
svn:mime-type = application/octet-stream

Modification de propri�t�s sur typo3\sysext\t3skin\rtehtmlarea\images\show-language-marks.gif
___________________________________________________________________
Ajout� : svn:mime-type
   + application/octet-stream

