Index: typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php
===================================================================
--- typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php	(r�vision 3931)
+++ typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php	(copie de travail)
@@ -70,12 +70,6 @@
 		'showhelp',		// Has no content yet
 		);
 	
-		// Hide toolbar buttons not implemented in client browsers
-	var $hideButtonsFromClient = array (
-		'safari'	=>	array('paste'),
-		'opera'		=>	array('copy', 'cut', 'paste'),
- 		);
-	
 		// Always show these toolbar buttons (TYPO3 button name)
 	var $conf_toolbar_show = array (
 		'undo',
@@ -86,24 +80,16 @@
 	
 		// The order of the toolbar: the name is the TYPO3-button name
 	var $defaultToolbarOrder;
-
-		// The default hotkeys: the name is the TYPO3-button name
-	var $defaultHotKeyList = 'selectall, cleanword, undo, redo';
-
+	
 		// Conversion array: TYPO3 button names to htmlArea button names
 	var $convertToolbarForHtmlAreaArray = array (
 		'line'			=> 'InsertHorizontalRule',
-		'cut'			=> 'Cut',
-		'copy'			=> 'Copy',
-		'paste'			=> 'Paste',
 		'chMode'		=> 'HtmlMode',
 		'showhelp'		=> 'ShowHelp',
 		'textindicator'		=> 'TextIndicator',
 		'space'			=> 'space',
 		'bar'			=> 'separator',
 		'linebreak'		=> 'linebreak',
-		'undo'			=> 'Undo',
-		'redo'			=> 'Redo',
 		);
 	
 	var $pluginList;
@@ -623,18 +609,9 @@
 			}
 		}
 		
-			// Hiding buttons not implemented in some clients
-		foreach ($this->hideButtonsFromClient as $client => $buttonArray) {
-			if ($this->client['BROWSER'] == $client) {
-				foreach($buttonArray as $buttonId) {
-					$hideButtons[] = $buttonId;
-				}
-			}
-		}
+			// Hiding buttons
+		$show = array_diff($show, $this->conf_toolbar_hide, t3lib_div::trimExplode(',',$this->thisConfig['hideButtons'],1));
 		
-			// Hiding the buttons
-		$show = array_diff($show, $this->conf_toolbar_hide, $hideButtons, t3lib_div::trimExplode(',',$this->thisConfig['hideButtons'],1));
-		
 			// Apply toolbar constraints from registered plugins
 		foreach ($this->registeredPlugins as $pluginId => $plugin) {
 			if ($this->isPluginEnabled($pluginId) && method_exists($plugin, "applyToolbarConstraints")) {
Index: typo3/sysext/rtehtmlarea/ext_localconf.php
===================================================================
--- typo3/sysext/rtehtmlarea/ext_localconf.php	(r�vision 3931)
+++ typo3/sysext/rtehtmlarea/ext_localconf.php	(copie de travail)
@@ -153,6 +153,10 @@
 $TYPO3_CONF_VARS['EXTCONF']['rtehtmlarea']['plugins']['UndoRedo']['objectReference'] = 'EXT:'.$_EXTKEY.'/extensions/UndoRedo/class.tx_rtehtmlarea_undoredo.php:&tx_rtehtmlarea_undoredo';
 $TYPO3_CONF_VARS['EXTCONF']['rtehtmlarea']['plugins']['UndoRedo']['addIconsToSkin'] = 0;
 $TYPO3_CONF_VARS['EXTCONF']['rtehtmlarea']['plugins']['UndoRedo']['disableInFE'] = 0;
+$TYPO3_CONF_VARS['EXTCONF']['rtehtmlarea']['plugins']['CopyPaste'] = array();
+$TYPO3_CONF_VARS['EXTCONF']['rtehtmlarea']['plugins']['CopyPaste']['objectReference'] = 'EXT:'.$_EXTKEY.'/extensions/CopyPaste/class.tx_rtehtmlarea_copypaste.php:&tx_rtehtmlarea_copypaste';
+$TYPO3_CONF_VARS['EXTCONF']['rtehtmlarea']['plugins']['CopyPaste']['addIconsToSkin'] = 0;
+$TYPO3_CONF_VARS['EXTCONF']['rtehtmlarea']['plugins']['CopyPaste']['disableInFE'] =  0;
 
 $_EXTCONF = unserialize($_EXTCONF);    // unserializing the configuration so we can use it here:
 
Index: typo3/sysext/rtehtmlarea/extensions/CopyPaste/class.tx_rtehtmlarea_copypaste.php
===================================================================
--- typo3/sysext/rtehtmlarea/extensions/CopyPaste/class.tx_rtehtmlarea_copypaste.php	(r�vision 0)
+++ typo3/sysext/rtehtmlarea/extensions/CopyPaste/class.tx_rtehtmlarea_copypaste.php	(r�vision 0)
@@ -0,0 +1,89 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2008 Stanislas Rolland <typo3(arobas)sjbr.ca>
+*  All rights reserved
+*
+*  This script is part of the Typo3 project. The Typo3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/**
+ * Copy Paste plugin for htmlArea RTE
+ *
+ * @author Stanislas Rolland <typo3(arobas)sjbr.ca>
+ *
+ * TYPO3 SVN ID: $Id: class.tx_rtehtmlarea_copypaste.php  $
+ *
+ */
+
+require_once(t3lib_extMgm::extPath('rtehtmlarea').'class.tx_rtehtmlareaapi.php');
+
+class tx_rtehtmlarea_copypaste extends tx_rtehtmlareaapi {
+
+	protected $extensionKey = 'rtehtmlarea';			// The key of the extension that is extending htmlArea RTE
+	protected $pluginName = 'CopyPaste';				// 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 $relativePathToSkin = 'extensions/CopyPaste/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 = 'copy, cut, paste';
+	protected $convertToolbarForHtmlAreaArray = array (
+		'copy'	=> 'Copy',
+		'cut'	=> 'Cut',
+		'paste'	=> 'Paste',
+		);
+	protected $hideButtonsFromClient = array (			// Hide buttons not implemented in client browsers
+		'safari'	=>	array('paste'),
+ 		);
+	
+	public function main($parentObject) {
+		$enabled = parent::main($parentObject) && $this->htmlAreaRTE->client['BROWSER'] != 'opera';
+			// Hiding some buttons
+		if ($enabled && is_array($this->hideButtonsFromClient[$this->htmlAreaRTE->client['BROWSER']])) {
+			$this->pluginButtons = implode(',', array_diff(t3lib_div::trimExplode(',', $this->pluginButtons, 1), $this->hideButtonsFromClient[$this->htmlAreaRTE->client['BROWSER']]));
+		}
+		return $enabled;
+	}
+	
+	/**
+	 * Return JS configuration of the htmlArea plugins registered by the extension
+	 *
+	 * @param	integer		Relative id of the RTE editing area in the form
+	 *
+	 * @return string		JS configuration for registered plugins
+	 *
+	 * The returned string will be a set of JS instructions defining the configuration that will be provided to the plugin(s)
+	 * Each of the instructions should be of the form:
+	 * 	RTEarea['.$RTEcounter.'].buttons.button-id.property = "value";
+	 */
+	public function buildJavascriptConfiguration($RTEcounter) {
+		global $TSFE, $LANG;
+		
+		$registerRTEinJavascriptString = '';
+		return $registerRTEinJavascriptString;
+	}
+
+} // end of class
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/extensions/CopyPaste/class.tx_rtehtmlarea_copypaste.php']) {
+	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/extensions/CopyPaste/class.tx_rtehtmlarea_copypaste.php']);
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/rtehtmlarea/extensions/CopyPaste/skin/htmlarea.css
===================================================================
--- typo3/sysext/rtehtmlarea/extensions/CopyPaste/skin/htmlarea.css	(r�vision 0)
+++ typo3/sysext/rtehtmlarea/extensions/CopyPaste/skin/htmlarea.css	(r�vision 0)
@@ -0,0 +1,5 @@
+/* Selectors for the CopyPaste extension of htmlArea RTE */
+/* TYPO3 SVN ID: $Id htmlarea.css $ */
+.htmlarea .toolbar .Copy, .htmlarea-context-menu .Copy  {background-image:url("images/copy.gif");}
+.htmlarea .toolbar .Cut, .htmlarea-context-menu .Cut  {background-image:url("images/cut.gif");}
+.htmlarea .toolbar .Paste, .htmlarea-context-menu .Paste {background-image:url("images/paste.gif");}
Index: typo3/sysext/rtehtmlarea/extensions/CopyPaste/skin/images/copy.gif
===================================================================
Impossible d'afficher : fichier consid�r� comme binaire.
svn:mime-type = application/octet-stream

Modification de propri�t�s sur typo3\sysext\rtehtmlarea\extensions\CopyPaste\skin\images\copy.gif
___________________________________________________________________
Ajout� : svn:mime-type
   + application/octet-stream

Index: typo3/sysext/rtehtmlarea/extensions/CopyPaste/skin/images/cut.gif
===================================================================
Impossible d'afficher : fichier consid�r� comme binaire.
svn:mime-type = application/octet-stream

Modification de propri�t�s sur typo3\sysext\rtehtmlarea\extensions\CopyPaste\skin\images\cut.gif
___________________________________________________________________
Ajout� : svn:mime-type
   + application/octet-stream

Index: typo3/sysext/rtehtmlarea/extensions/CopyPaste/skin/images/paste.gif
===================================================================
Impossible d'afficher : fichier consid�r� comme binaire.
svn:mime-type = application/octet-stream

Modification de propri�t�s sur typo3\sysext\rtehtmlarea\extensions\CopyPaste\skin\images\paste.gif
___________________________________________________________________
Ajout� : svn:mime-type
   + application/octet-stream

Index: typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js	(r�vision 3931)
+++ typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js	(copie de travail)
@@ -289,15 +289,11 @@
 	this.btnList = {
 		InsertHorizontalRule:	["Horizontal Rule", "ed_hr.gif",false, function(editor) {editor.execCommand("InsertHorizontalRule");}],
 		HtmlMode:		["Toggle HTML Source", "ed_html.gif", true, function(editor) {editor.execCommand("HtmlMode");}],
-		SelectAll:		["SelectAll", "", true, function(editor) {editor.execCommand("SelectAll");}, null, true, false],
-		Cut:			["Cut selection", "ed_cut.gif", false, function(editor) {editor.execCommand("Cut");}],
-		Copy:			["Copy selection", "ed_copy.gif", false, function(editor) {editor.execCommand("Copy");}],
-		Paste:			["Paste from clipboard", "ed_paste.gif", false, function(editor) {editor.execCommand("Paste");}]
+		SelectAll:		["SelectAll", "", true, function(editor) {editor.execCommand("SelectAll");}, null, true, false]
 	};
 		// Default hotkeys
 	this.hotKeyList = {
-		a:	{ cmd:	"SelectAll", 	action:	null},
-		v:	{ cmd:	"Paste", 	action:	null}
+		a:	{ cmd:	"SelectAll", 	action:	null}
 	};
 
 		// Initialize tooltips from the I18N module, generate correct image path
@@ -1118,9 +1114,6 @@
 		HTMLArea._addEvent((this._iframe.contentWindow ? this._iframe.contentWindow : this._iframe.contentDocument), "unload", HTMLArea.removeEditorEvents);
 	}
 
-		// set enableWordClean and intercept paste, dragdrop and drop events for wordClean
-	//if (this.config.enableWordClean) HTMLArea._addEvents((HTMLArea.is_ie ? doc.body : doc), ["paste","dragdrop","drop"], HTMLArea.wordClean, true);
-
 	window.setTimeout("HTMLArea.generatePlugins(" + this._editorNumber + ");", 100);
 };
 
@@ -1463,7 +1456,7 @@
 		if (this.config.pathToPluginDirectory[pluginId]) {
 			url = this.config.pathToPluginDirectory[pluginId] + "popups/" + popup;
 		} else {
-			url = _editor_url + "plugins/" + pluginId + "/popups/" + popup;
+			url = _typo3_host_url + _editor_url + "plugins/" + pluginId + "/popups/" + popup;
 		}
 	} else {
 		url = _typo3_host_url + _editor_url + this.config.popupURL + file;
@@ -1647,15 +1640,6 @@
 				case "HtmlMode":
 					btn.state("active", text);
 					break;
-				case "Paste":
-					if (!text) {
-						try {
-							btn.state("enabled", doc.queryCommandEnabled('Paste'));
-						} catch(e) {
-							btn.state("enabled", false);
-						}
-					}
-					break;
 				default:
 					break;
 			}
@@ -1802,21 +1786,6 @@
 		case "HtmlMode"	:
 			this.setMode();
 			break;
-		case "Cut"	:
-		case "Copy"	:
-		case "Paste"	:
-			try {
-				this._doc.execCommand(cmdID, false, null);
-					// In FF3, the paste operation will indeed trigger the paste event
-				if (HTMLArea.is_gecko && cmdID == "Paste" && this._toolbarObjects.CleanWord && navigator.productSub < 2008020514) {
-					this._toolbarObjects.CleanWord.cmd(this, "CleanWord");
-				}
-			} catch (e) {
-				if (HTMLArea.is_gecko && !HTMLArea.is_safari && !HTMLArea.is_opera) {
-					this._mozillaPasteException(cmdID, UI, param);
-				}
-			}
-			break;
 		default		:
 			try {
 				this._doc.execCommand(cmdID, UI, param);
@@ -1877,22 +1846,6 @@
 						HTMLArea._stopEvent(ev);
 						return false;
 						break;
-					case "Paste"	:
-						if (HTMLArea.is_ie || HTMLArea.is_safari) {
-							cmd = editor.config.hotKeyList[key].cmd;
-							editor.execCommand(cmd, false, null);
-							HTMLArea._stopEvent(ev);
-							return false;
-							// In FF3, the paste operation will indeed trigger the paste event
-						} else if (HTMLArea.is_opera || (HTMLArea.is_gecko && navigator.productSub < 2008020514)) {
-							if (editor._toolbarObjects.CleanWord) {
-								var cleanLaterFunctRef = editor.plugins.DefaultClean ? editor.plugins.DefaultClean.instance.cleanLaterFunctRef : (editor.plugins.TYPO3HtmlParser ? editor.plugins.TYPO3HtmlParser.instance.cleanLaterFunctRef : null);
-								if (cleanLaterFunctRef) {
-									window.setTimeout(cleanLaterFunctRef, 50);
-								}
-							}
-						}
-						break;
 					default:
 						if (editor.config.hotKeyList[key] && editor.config.hotKeyList[key].action) {
 							if (!editor.config.hotKeyList[key].action(editor, key)) {
@@ -2572,7 +2525,7 @@
 
 HTMLArea.allElementsAreDisplayed = function(elements) {
 	for (var i=0, length=elements.length; i < length; i++) {
-		if (document.getElementById(elements[i]).style.display == 'none') {
+		if (document.getElementById(elements[i]).style.display == "none") {
 			return false;
 		}
 	}
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/CopyPaste/copy-paste.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/CopyPaste/copy-paste.js	(r�vision 0)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/CopyPaste/copy-paste.js	(r�vision 0)
@@ -0,0 +1,340 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2008 Stanislas Rolland <typo3(arobas)sjbr.ca>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/*
+ * Copy Paste for TYPO3 htmlArea RTE
+ *
+ * TYPO3 SVN ID: $Id: copy-paste.js $
+ */
+CopyPaste = 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;
+		
+		/*
+		 * Registering plugin "About" information
+		 */
+		var pluginInformation = {
+			version		: "1.0",
+			developer	: "Stanislas Rolland",
+			developerUrl	: "http://www.sjbr.ca/",
+			copyrightOwner	: "Stanislas Rolland",
+			sponsor		: this.localize("Technische Universitat Ilmenau"),
+			sponsorUrl	: "http://www.tu-ilmenau.de/",
+			license		: "GPL"
+		};
+		this.registerPluginInformation(pluginInformation);
+		
+		/*
+		 * Registering the buttons
+		 */
+		for (var buttonId in this.buttonList) {
+			if (this.buttonList.hasOwnProperty(buttonId)) {
+				var button = this.buttonList[buttonId];
+				var buttonConfiguration = {
+					id		: buttonId,
+					tooltip		: this.localize(buttonId.toLowerCase()),
+					action		: "onButtonPress",
+					context		: button[0],
+					hotKey		: (this.buttonsConfiguration[button[2]] ? this.buttonsConfiguration[button[2]].hotKey : (button[1] ? button[1] : null))
+				};
+				this.registerButton(buttonConfiguration);
+			}
+		}
+		
+		return true;
+	 },
+	 
+	/*
+	 * The list of buttons added by this plugin
+	 */
+	buttonList : {
+		Copy	: [null, "c", "copy"],
+		Cut	: [null, "x", "cut"],
+		Paste	: [null, "v", "paste"]
+	},
+	
+	/*
+	 * This function gets called when a button or a hotkey was pressed.
+	 *
+	 * @param	object		editor: the editor instance
+	 * @param	string		id: the button id or the key
+	 * @param	object		target: the target element of the contextmenu event, when invoked from the context menu
+	 *
+	 * @return	boolean		false if action is completed
+	 */
+	onButtonPress : function (editor, id, target) {
+			// Could be a button or its hotkey
+		var buttonId = this.translateHotKey(id);
+		buttonId = buttonId ? buttonId : id;
+		this.editor.focusEditor();
+		if (!this.applyToTable(buttonId, target)) {
+			switch (buttonId) {
+				case "Copy":
+				case "Cut" :
+					this.applyBrowserCommand(buttonId);
+					break;
+				case "Paste":
+					if (!HTMLArea.is_opera) {
+						this.applyBrowserCommand(buttonId, (buttonId != id));
+					}
+						// In FF3, the paste operation will indeed trigger the paste event
+					if (HTMLArea.is_opera || (HTMLArea.is_gecko && navigator.productSub < 2008020514)) {
+						if (this.editor._toolbarObjects.CleanWord) {
+							var cleanLaterFunctRef = this.editor.plugins.DefaultClean ? this.editor.plugins.DefaultClean.instance.cleanLaterFunctRef : (this.editor.plugins.TYPO3HtmlParser ? this.editor.plugins.TYPO3HtmlParser.instance.cleanLaterFunctRef : null);
+							if (cleanLaterFunctRef) {
+								window.setTimeout(cleanLaterFunctRef, 50);
+							}
+						}
+					}
+					break;
+			}
+		}
+		return false;
+	},
+	
+	applyBrowserCommand : function (buttonId, buttonPress) {
+		try {
+			this.editor._doc.execCommand(buttonId, false, null);
+		} catch (e) {
+			if (buttonId == "Paste" && HTMLArea.is_gecko && !HTMLArea.is_safari && !HTMLArea.is_opera) {
+				this.editor._mozillaPasteException(buttonId, buttonPress, null);
+			}
+		}
+	},
+	
+	/*
+	 * This function gets called by the main editor when a copy/cut/paste operation is to be performed
+	 */
+	applyToTable : function (buttonId, target) {
+		var selection = this.editor._getSelection();
+		var range = this.editor._createRange(selection);
+		var parent = this.editor.getParentElement(selection, range);
+		var endBlocks = this.editor.getEndBlocks(selection);
+		switch (buttonId) {
+			case "Copy":
+			case "Cut" :
+				HTMLArea.copiedCells = null;
+				var endBlocks = this.editor.getEndBlocks(selection);
+				if ((/^(tr)$/i.test(parent.nodeName) && HTMLArea.is_gecko) || (/^(td|th)$/i.test(endBlocks.start.nodeName) && /^(td|th)$/i.test(endBlocks.end.nodeName) && (HTMLArea.is_ie || HTMLArea.is_safari || HTMLArea.is_opera) && endBlocks.start != endBlocks.end)) {
+					HTMLArea.copiedCells = this.collectCells(buttonId, selection, endBlocks);
+					if (buttonId === "Cut") return true;
+				}
+				break;
+			case "Paste":
+				if (/^(tr|td|th)$/i.test(parent.nodeName) && HTMLArea.copiedCells) {
+					return this.pasteCells(selection, endBlocks);
+				}
+				break;
+		}
+		return false;
+	},
+	
+	pasteCells : function (selection, endBlocks) {
+		var cell = null;
+		if (HTMLArea.is_gecko && !HTMLArea.is_safari && !HTMLArea.is_opera) {
+			range = selection.getRangeAt(0);
+			cell = range.startContainer.childNodes[range.startOffset];
+			while (cell && !HTMLArea.isBlockElement(cell)) {
+				cell = cell.parentNode;
+			}
+		}
+		if (!cell && /^(td|th)$/i.test(endBlocks.start.nodeName)) {
+			cell = endBlocks.start;
+		}
+		if (!cell) return false;
+		var tableParts = ["thead", "tbody", "tfoot"];
+		var tablePartsIndex = { thead : 0, tbody : 1, tfoot : 2 };
+		var tablePart = cell.parentNode.parentNode;
+		var tablePartIndex = tablePartsIndex[tablePart.nodeName.toLowerCase()]
+		var rows = HTMLArea.copiedCells[tablePartIndex];
+		if (rows && rows[0]) {
+			for (var i = 0, rowIndex = cell.parentNode.sectionRowIndex-1; i < rows.length && ++rowIndex < tablePart.rows.length; ++i) {
+				var cells = rows[i];
+				if (!cells) break;
+				var row = tablePart.rows[rowIndex];
+				for (var j = 0, cellIndex = cell.cellIndex-1; j < cells.length && ++cellIndex < row.cells.length; ++j) {
+					row.cells[cellIndex].innerHTML = cells[j];
+				}
+			}
+		}
+		var table = tablePart.parentNode;
+		for (var k = tablePartIndex +1; k < 3; ++k) {
+			tablePart = table.getElementsByTagName(tableParts[k])[0];
+			if (tablePart) {
+				var rows = HTMLArea.copiedCells[k];
+				for (var i = 0; i < rows.length && i < tablePart.rows.length; ++i) {
+					var cells = rows[i];
+					if (!cells) break;
+					var row = tablePart.rows[i];
+					for (var j = 0, cellIndex = cell.cellIndex-1; j < cells.length && ++cellIndex < row.cells.length; ++j) {
+						row.cells[cellIndex].innerHTML = cells[j];
+					}
+				}
+			}
+		}
+		return true;
+	},
+	
+	/*
+	 * This function collects the selected table cells for copy/cut operations
+	 */
+	collectCells : function (operation, selection, endBlocks) {
+		var tableParts = ["thead", "tbody", "tfoot"];
+		var tablePartsIndex = { thead : 0, tbody : 1, tfoot : 2 };
+		var selection = this.editor._getSelection();
+		var range, i = 0, cell, cells = null;
+		var rows = new Array();
+		for (var k = tableParts.length; --k >= 0;) {
+			rows[k] = [];
+		}
+		var row = null;
+		var cutRows = [];
+		if (HTMLArea.is_gecko && !HTMLArea.is_safari && !HTMLArea.is_opera) {  // Firefox
+			if (selection.rangeCount == 1) { // Collect the cells in the selected row
+				cells = [];
+				for (var i = 0, n = endBlocks.start.cells.length; i < n; ++i) {
+					cell = endBlocks.start.cells[i];
+					cells.push(cell.innerHTML);
+					if (operation === "Cut") {
+						cell.innerHTML = "<br />";
+					}
+					if (operation === "Cut") {
+						cutRows.push(endBlocks.start);
+					}
+				}
+				rows[tablePartsIndex[endBlocks.start.parentNode.nodeName.toLowerCase()]].push(cells);
+			} else {
+				try { // Collect the cells in some region of the table
+					var firstCellOfRow = false;
+					var lastCellOfRow = false;
+					while (range = selection.getRangeAt(i++)) {
+						cell = range.startContainer.childNodes[range.startOffset];
+						if (cell.parentNode != row) {
+							(cells) && rows[tablePartsIndex[row.parentNode.nodeName.toLowerCase()]].push(cells);
+							if (operation === "Cut" && firstCellOfRow && lastCellOfRow) cutRows.push(row);
+							row = cell.parentNode;
+							cells = [];
+							firstCellOfRow = false;
+							lastCellOfRow = false;
+						}
+						cells.push(cell.innerHTML);
+						if (operation === "Cut") {
+							cell.innerHTML = "<br />";
+						}
+						if (!cell.previousSibling) firstCellOfRow = true;
+						if (!cell.nextSibling) lastCellOfRow = true;
+					}
+				} catch(e) {
+					/* finished walking through selection */
+				}
+				try { rows[tablePartsIndex[row.parentNode.nodeName.toLowerCase()]].push(cells); } catch(e) { }
+				if (row && operation === "Cut" && firstCellOfRow && lastCellOfRow) {
+					cutRows.push(row);
+				}
+			}
+		} else { // Internet Explorer, Safari and Opera
+			var firstRow = endBlocks.start.parentNode;
+			var lastRow = endBlocks.end.parentNode;
+			cells = [];
+			var firstCellOfRow = false;
+			var lastCellOfRow = false;
+			if (firstRow == lastRow) { // Collect the selected cells on the row
+				cell = endBlocks.start;
+				while (cell) {
+					cells.push(cell.innerHTML);
+					if (operation === "Cut") {
+						cell.innerHTML = "";
+					}
+					if (!cell.previousSibling) firstCellOfRow = true;
+					if (!cell.nextSibling) lastCellOfRow = true;
+					if (cell == endBlocks.end) break;
+					cell = cell.nextSibling;
+				}
+				rows[tablePartsIndex[firstRow.parentNode.nodeName.toLowerCase()]].push(cells);
+				if (operation === "Cut" && firstCellOfRow && lastCellOfRow) cutRows.push(firstRow);
+			} else { // Collect all cells on selected rows
+				row = firstRow;
+				while (row) {
+					cells = [];
+					for (var i = 0, n = row.cells.length; i < n ; ++i) {
+						cells.push(row.cells[i].innerHTML);
+						if (operation === "Cut") {
+							row.cells[i].innerHTML = "";
+						}
+					}
+					rows[tablePartsIndex[row.parentNode.nodeName.toLowerCase()]].push(cells);
+					if (operation === "Cut") cutRows.push(row);
+					if (row == lastRow) break;
+					row = row.nextSibling;
+				}
+			}
+		}
+		for (var i = 0, n = cutRows.length; i < n; ++i) {
+			if (i == n-1) {
+				var tablePart = cutRows[i].parentNode;
+				var next = cutRows[i].nextSibling;
+				cutRows[i].parentNode.removeChild(cutRows[i]);
+				if (next) {
+					this.editor.selectNodeContents(next.cells[0], true);
+				} else if (tablePart.parentNode.rows.length) {
+					this.editor.selectNodeContents(tablePart.parentNode.rows[0].cells[0], true);
+				}
+			} else {
+				cutRows[i].parentNode.removeChild(cutRows[i]);
+			}
+		}
+		return rows;
+	},
+	
+	/*
+	 * This function gets called when the toolbar is updated
+	 */
+	onUpdateToolbar : function () {
+		if (this.editor.getMode() === "wysiwyg" || this.editor.isEditable()) {
+			var buttonId = "Paste";
+			if (typeof(this.editor._toolbarObjects[buttonId]) !== "undefined") {
+				try {
+					this.editor._toolbarObjects[buttonId].state("enabled", this.editor._doc.queryCommandEnabled(buttonId));
+				} catch(e) {
+					this.editor._toolbarObjects[buttonId].state("enabled", false);
+				}
+			}
+		}
+	}
+});
+
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/CopyPaste/locallang.xml
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/CopyPaste/locallang.xml	(r�vision 0)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/CopyPaste/locallang.xml	(r�vision 0)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- TYPO3 SVN ID: $Id: locallang.xml 2975 2008-01-29 23:01:39Z stanrolland $ -->
+<T3locallang>
+	<meta type="array">
+		<description>Labels for Copy Paste plugin of htmlArea RTE</description>
+		<type>module</type>
+	</meta>
+	<data type="array">
+		<languageKey index="default" type="array">
+			<label index="How many columns would you like to copy?">How many columns would you like to copy?</label>
+			<label index="How many rows would you like to copy?">How many rows would you like to copy?</label>
+			<label index="How many columns would you like to cut?">How many columns would you like to cut?</label>
+			<label index="How many rows would you like to cut?">How many rows would you like to cut?</label>
+			<label index="Technische Universitat Ilmenau">Technische Universität Ilmenau</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
