Index: /FCKeditor/trunk/editor/_source/classes/fckcontextmenu.js
===================================================================
--- /FCKeditor/trunk/editor/_source/classes/fckcontextmenu.js	(revision 434)
+++ /FCKeditor/trunk/editor/_source/classes/fckcontextmenu.js	(revision 435)
Index: /FCKeditor/trunk/editor/_source/classes/fckdomrange_gecko.js
===================================================================
--- /FCKeditor/trunk/editor/_source/classes/fckdomrange_gecko.js	(revision 434)
+++ /FCKeditor/trunk/editor/_source/classes/fckdomrange_gecko.js	(revision 435)
@@ -30,5 +30,5 @@
 	var oSel = this.Window.getSelection() ;
 
-	if ( oSel.rangeCount == 1 )
+	if ( oSel.rangeCount > 0 )
 	{
 		this._Range = FCKW3CRange.CreateFromRange( this.Window.document, oSel.getRangeAt(0) ) ;
Index: /FCKeditor/trunk/editor/_source/commandclasses/fcktablecommand.js
===================================================================
--- /FCKeditor/trunk/editor/_source/commandclasses/fcktablecommand.js	(revision 434)
+++ /FCKeditor/trunk/editor/_source/commandclasses/fcktablecommand.js	(revision 435)
@@ -34,18 +34,27 @@
 	switch ( this.Name )
 	{
-		case 'TableInsertRow' :
-			FCKTableHandler.InsertRow() ;
+		case 'TableInsertRowAfter' :
+			FCKTableHandler.InsertRow( false ) ;
+			break ;
+		case 'TableInsertRowBefore' :
+			FCKTableHandler.InsertRow( true ) ;
 			break ;
 		case 'TableDeleteRows' :
 			FCKTableHandler.DeleteRows() ;
 			break ;
-		case 'TableInsertColumn' :
-			FCKTableHandler.InsertColumn() ;
+		case 'TableInsertColumnAfter' :
+			FCKTableHandler.InsertColumn( false ) ;
+			break ;
+		case 'TableInsertColumnBefore' :
+			FCKTableHandler.InsertColumn( true ) ;
 			break ;
 		case 'TableDeleteColumns' :
 			FCKTableHandler.DeleteColumns() ;
 			break ;
-		case 'TableInsertCell' :
-			FCKTableHandler.InsertCell() ;
+		case 'TableInsertCellAfter' :
+			FCKTableHandler.InsertCell( null, false ) ;
+			break ;
+		case 'TableInsertCellBefore' :
+			FCKTableHandler.InsertCell( null, true ) ;
 			break ;
 		case 'TableDeleteCells' :
Index: /FCKeditor/trunk/editor/_source/internals/fck_contextmenu.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fck_contextmenu.js	(revision 434)
+++ /FCKeditor/trunk/editor/_source/internals/fck_contextmenu.js	(revision 435)
@@ -71,5 +71,6 @@
 					menu.AddSeparator() ;
 					var oItem = menu.AddItem( 'Cell'	, FCKLang.CellCM ) ;
-					oItem.AddItem( 'TableInsertCell'	, FCKLang.InsertCell, 58 ) ;
+					oItem.AddItem( 'TableInsertCellBefore'	, FCKLang.InsertCellBefore, 58 ) ;
+					oItem.AddItem( 'TableInsertCellAfter'	, FCKLang.InsertCellAfter, 58 ) ;
 					oItem.AddItem( 'TableDeleteCells'	, FCKLang.DeleteCells, 59 ) ;
 					oItem.AddItem( 'TableMergeCells'	, FCKLang.MergeCells, 60 ) ;
@@ -80,10 +81,12 @@
 					menu.AddSeparator() ;
 					oItem = menu.AddItem( 'Row'			, FCKLang.RowCM ) ;
-					oItem.AddItem( 'TableInsertRow'		, FCKLang.InsertRow, 62 ) ;
+					oItem.AddItem( 'TableInsertRowBefore'		, FCKLang.InsertRowBefore, 62 ) ;
+					oItem.AddItem( 'TableInsertRowAfter'		, FCKLang.InsertRowAfter, 62 ) ;
 					oItem.AddItem( 'TableDeleteRows'	, FCKLang.DeleteRows, 63 ) ;
 
 					menu.AddSeparator() ;
 					oItem = menu.AddItem( 'Column'		, FCKLang.ColumnCM ) ;
-					oItem.AddItem( 'TableInsertColumn'	, FCKLang.InsertColumn, 64 ) ;
+					oItem.AddItem( 'TableInsertColumnBefore', FCKLang.InsertColumnBefore, 64 ) ;
+					oItem.AddItem( 'TableInsertColumnAfter'	, FCKLang.InsertColumnAfter, 64 ) ;
 					oItem.AddItem( 'TableDeleteColumns'	, FCKLang.DeleteColumns, 65 ) ;
 				}
Index: /FCKeditor/trunk/editor/_source/internals/fckcommands.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fckcommands.js	(revision 434)
+++ /FCKeditor/trunk/editor/_source/internals/fckcommands.js	(revision 435)
@@ -79,9 +79,12 @@
 		case 'PasteWord'	: oCommand = new FCKPasteWordCommand() ; break ;
 
-		case 'TableInsertRow'		: oCommand = new FCKTableCommand('TableInsertRow') ; break ;
+		case 'TableInsertRowAfter'		: oCommand = new FCKTableCommand('TableInsertRowAfter') ; break ;
+		case 'TableInsertRowBefore'		: oCommand = new FCKTableCommand('TableInsertRowBefore') ; break ;
 		case 'TableDeleteRows'		: oCommand = new FCKTableCommand('TableDeleteRows') ; break ;
-		case 'TableInsertColumn'	: oCommand = new FCKTableCommand('TableInsertColumn') ; break ;
+		case 'TableInsertColumnAfter'	: oCommand = new FCKTableCommand('TableInsertColumnAfter') ; break ;
+		case 'TableInsertColumnBefore'	: oCommand = new FCKTableCommand('TableInsertColumnBefore') ; break ;
 		case 'TableDeleteColumns'	: oCommand = new FCKTableCommand('TableDeleteColumns') ; break ;
-		case 'TableInsertCell'		: oCommand = new FCKTableCommand('TableInsertCell') ; break ;
+		case 'TableInsertCellAfter'		: oCommand = new FCKTableCommand('TableInsertCellAfter') ; break ;
+		case 'TableInsertCellBefore'		: oCommand = new FCKTableCommand('TableInsertCellBefore') ; break ;
 		case 'TableDeleteCells'		: oCommand = new FCKTableCommand('TableDeleteCells') ; break ;
 		case 'TableMergeCells'		: oCommand = new FCKTableCommand('TableMergeCells') ; break ;
Index: /FCKeditor/trunk/editor/_source/internals/fcktablehandler.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fcktablehandler.js	(revision 434)
+++ /FCKeditor/trunk/editor/_source/internals/fcktablehandler.js	(revision 435)
@@ -24,5 +24,5 @@
 var FCKTableHandler = new Object() ;
 
-FCKTableHandler.InsertRow = function()
+FCKTableHandler.InsertRow = function( insertBefore )
 {
 	// Get the row where the selection is placed in.
@@ -36,6 +36,6 @@
 	oRow.parentNode.insertBefore( oNewRow, oRow ) ;
 
-	// Clean the row (it seems that the new row has been added after it).
-	FCKTableHandler.ClearRow( oRow ) ;
+	// Clean one of the rows to produce the illusion of inserting an empty row before or after.
+	FCKTableHandler.ClearRow( insertBefore ? oNewRow : oRow ) ;
 }
 
@@ -80,16 +80,29 @@
 }
 
-FCKTableHandler.InsertColumn = function()
+FCKTableHandler.InsertColumn = function( insertBefore )
 {
 	// Get the cell where the selection is placed in.
 	var oCell = FCKSelection.MoveToAncestorNode('TD') || FCKSelection.MoveToAncestorNode('TH') ;
 
-	if ( !oCell ) return ;
+	if ( !oCell ) 
+	{
+		// oCell not fouund could be due to multiple selection ranges on tables in Gecko.
+		// We have another function to find the table cell for this special case.
+		if ( ! FCKBrowserInfo.IsIE )
+		{
+			var node = this._GetSelectedCellFromGecko( true ) ;
+			if ( node )
+				oCell = node ;
+			else
+				return null ;
+		}
+		else
+			return null ;
+	}
 
 	// Get the cell's table.
 	var oTable = FCKTools.GetElementAscensor( oCell, 'TABLE' ) ;
 
-	// Get the index of the column to be created (based on the cell).
-	var iIndex = oCell.cellIndex + 1 ;
+	var iIndex = oCell.cellIndex ;
 
 	// Loop throw all rows available in the table.
@@ -100,20 +113,21 @@
 
 		// If the row doens't have enought cells, ignore it.
-		if ( oRow.cells.length < iIndex )
+		if ( oRow.cells.length < ( iIndex + 1 ) )
 			continue ;
 
-		oCell = oRow.cells[iIndex-1].cloneNode(false) ;
+		oCell = oRow.cells[iIndex].cloneNode(false) ;
 
 		if ( FCKBrowserInfo.IsGecko )
 			oCell.innerHTML = GECKO_BOGUS ;
 
-		// Get the cell that is placed in the new cell place.
+		// Get back the currently selected cell.
 		var oBaseCell = oRow.cells[iIndex] ;
 
-		// If the cell is available (we are not in the last cell of the row).
-		if ( oBaseCell )
-			oRow.insertBefore( oCell, oBaseCell ) ;	// Insert the new cell just before of it.
+		if ( insertBefore )
+			oRow.insertBefore( oCell, oBaseCell ) ;
+		else if ( oBaseCell.nextSibling )
+			oRow.insertBefore( oCell, oBaseCell.nextSibling ) ;
 		else
-			oRow.appendChild( oCell ) ;				// Append the cell at the end of the row.
+			oRow.appendChild( oCell ) ;
 	}
 }
@@ -153,9 +167,23 @@
 }
 
-FCKTableHandler.InsertCell = function( cell )
+FCKTableHandler.InsertCell = function( cell, insertBefore )
 {
 	// Get the cell where the selection is placed in.
 	var oCell = cell ? cell : FCKSelection.MoveToAncestorNode( 'TD' ) ;
-	if ( !oCell ) return null ;
+	if ( !oCell ) 
+	{
+		// oCell not fouund could be due to multiple selection ranges on tables in Gecko.
+		// We have another function to find the table cell for this special case.
+		if ( ! FCKBrowserInfo.IsIE )
+		{
+			var node = this._GetSelectedCellFromGecko( true ) ;
+			if ( node )
+				oCell = node ;
+			else
+				return null ;
+		}
+		else
+			return null ;
+	}
 
 	// Create the new cell element to be added.
@@ -165,15 +193,8 @@
 //	oNewCell.innerHTML = "&nbsp;" ;
 
-	// If it is the last cell in the row.
-	if ( oCell.cellIndex == oCell.parentNode.cells.length - 1 )
-	{
-		// Add the new cell at the end of the row.
+	if ( !insertBefore && oCell.cellIndex == oCell.parentNode.cells.length - 1 )
 		oCell.parentNode.appendChild( oNewCell ) ;
-	}
 	else
-	{
-		// Add the new cell before the next cell (after the active one).
-		oCell.parentNode.insertBefore( oNewCell, oCell.nextSibling ) ;
-	}
+		oCell.parentNode.insertBefore( oNewCell, insertBefore ? oCell : oCell.nextSibling ) ;
 
 	return oNewCell ;
@@ -273,5 +294,5 @@
 		if ( aCollCells[i] == aCells[0] )
 		{
-			var oNewCell = this.InsertCell( aCells[0] ) ;
+			var oNewCell = this.InsertCell( aCells[0], false ) ;
 			if ( !isNaN( aCells[0].rowSpan ) && aCells[0].rowSpan > 1 )
 				oNewCell.rowSpan = aCells[0].rowSpan ;
@@ -384,2 +405,39 @@
 	}
 }
+
+FCKTableHandler._GetSelectedCellFromGecko = function( getLastCell )
+{
+	var sel = FCK.EditorWindow.getSelection() ;
+	if ( sel.rangeCount < 1 )
+		return null ;
+	var range = getLastCell ? sel.getRangeAt( sel.rangeCount - 1 ) : sel.getRangeAt( 0 ) ;
+	var node = getLastCell ? range.endContainer : range.startContainer ;
+
+	// Gecko returns a <TR> as startContainer and endContainer when cells are selected.
+	// We need to find back the final <TD|TH> that's being selected.
+	if ( node.nodeType == 1 && node.tagName.toLowerCase() == 'tr' )
+	{
+		for ( var i = range.startOffset ; i <= range.endOffset ; i++ )
+		{
+			var candidate = node.childNodes[i] ;
+			var tag = candidate.tagName.toLowerCase() ;
+			if ( candidate.nodeType == 1 && ( tag == 'td' || tag == 'th' ) )
+			{
+				node = node.childNodes[i] ;
+				break ;
+			}
+		}
+	}
+	// For safety, we have to be ready for the 'usual' case as well.
+	else
+	{
+		while ( node && node.tagName.toLowerCase() != 'td' && node.tagName.toLowerCase() != 'th' )
+			node = node.parentNode ;
+	}
+
+	// Have we found the <TD|TH> node we wanted, finally? If yes, return the found node. If not, abort.
+	if ( node.tagName.toLowerCase() != 'td' && node.tagName.toLowerCase() != 'th' )
+		return null ;
+	else
+		return node ;
+}
Index: /FCKeditor/trunk/editor/lang/en-au.js
===================================================================
--- /FCKeditor/trunk/editor/lang/en-au.js	(revision 434)
+++ /FCKeditor/trunk/editor/lang/en-au.js	(revision 435)
@@ -110,9 +110,12 @@
 RowCM				: "Row",
 ColumnCM			: "Column",
-InsertRow			: "Insert Row",
+InsertRowAfter			: "Insert Row After",
+InsertRowBefore			: "Insert Row Before",
 DeleteRows			: "Delete Rows",
-InsertColumn		: "Insert Column",
+InsertColumnAfter		: "Insert Column After",
+InsertColumnBefore		: "Insert Column Before",
 DeleteColumns		: "Delete Columns",
-InsertCell			: "Insert Cell",
+InsertCellAfter			: "Insert Cell After",
+InsertCellBefore		: "Insert Cell Before",
 DeleteCells			: "Delete Cells",
 MergeCells			: "Merge Cells",
Index: /FCKeditor/trunk/editor/lang/en-ca.js
===================================================================
--- /FCKeditor/trunk/editor/lang/en-ca.js	(revision 434)
+++ /FCKeditor/trunk/editor/lang/en-ca.js	(revision 435)
@@ -110,9 +110,12 @@
 RowCM				: "Row",
 ColumnCM			: "Column",
-InsertRow			: "Insert Row",
+InsertRowAfter			: "Insert Row After",
+InsertRowBefore			: "Insert Row Before",
 DeleteRows			: "Delete Rows",
-InsertColumn		: "Insert Column",
+InsertColumnAfter		: "Insert Column After",
+InsertColumnBefore		: "Insert Column Before",
 DeleteColumns		: "Delete Columns",
-InsertCell			: "Insert Cell",
+InsertCellAfter			: "Insert Cell After",
+InsertCellBefore		: "Insert Cell Before",
 DeleteCells			: "Delete Cells",
 MergeCells			: "Merge Cells",
Index: /FCKeditor/trunk/editor/lang/en-uk.js
===================================================================
--- /FCKeditor/trunk/editor/lang/en-uk.js	(revision 434)
+++ /FCKeditor/trunk/editor/lang/en-uk.js	(revision 435)
@@ -110,9 +110,12 @@
 RowCM				: "Row",
 ColumnCM			: "Column",
-InsertRow			: "Insert Row",
+InsertRowAfter			: "Insert Row After",
+InsertRowBefore			: "Insert Row Before",
 DeleteRows			: "Delete Rows",
-InsertColumn		: "Insert Column",
+InsertColumnAfter		: "Insert Column After",
+InsertColumnBefore		: "Insert Column Before",
 DeleteColumns		: "Delete Columns",
-InsertCell			: "Insert Cell",
+InsertCellAfter			: "Insert Cell After",
+InsertCellBefore		: "Insert Cell Before",
 DeleteCells			: "Delete Cells",
 MergeCells			: "Merge Cells",
Index: /FCKeditor/trunk/editor/lang/en.js
===================================================================
--- /FCKeditor/trunk/editor/lang/en.js	(revision 434)
+++ /FCKeditor/trunk/editor/lang/en.js	(revision 435)
@@ -110,9 +110,12 @@
 RowCM				: "Row",
 ColumnCM			: "Column",
-InsertRow			: "Insert Row",
+InsertRowAfter			: "Insert Row After",
+InsertRowBefore			: "Insert Row Before",
 DeleteRows			: "Delete Rows",
-InsertColumn		: "Insert Column",
+InsertColumnAfter		: "Insert Column After",
+InsertColumnBefore		: "Insert Column Before",
 DeleteColumns		: "Delete Columns",
-InsertCell			: "Insert Cell",
+InsertCellAfter			: "Insert Cell After",
+InsertCellBefore		: "Insert Cell Before",
 DeleteCells			: "Delete Cells",
 MergeCells			: "Merge Cells",
Index: /FCKeditor/trunk/editor/lang/zh-cn.js
===================================================================
--- /FCKeditor/trunk/editor/lang/zh-cn.js	(revision 434)
+++ /FCKeditor/trunk/editor/lang/zh-cn.js	(revision 435)
@@ -110,9 +110,12 @@
 RowCM				: "行",
 ColumnCM			: "列",
-InsertRow			: "插入行",
+InsertRowBefore			: "上插入行",
+InsertRowAfter			: "下插入行",
 DeleteRows			: "删除行",
-InsertColumn		: "插入列",
-DeleteColumns		: "删除列",
-InsertCell			: "插入单元格",
+InsertColumnBefore		: "左插入列",
+InsertColumnAfter		: "右插入列",
+DeleteColumns			: "删除列",
+InsertCellBefore		: "左插入单元格",
+InsertCellAfter			: "右插入单元格",
 DeleteCells			: "删除单元格",
 MergeCells			: "合并单元格",
Index: /FCKeditor/trunk/editor/lang/zh.js
===================================================================
--- /FCKeditor/trunk/editor/lang/zh.js	(revision 434)
+++ /FCKeditor/trunk/editor/lang/zh.js	(revision 435)
@@ -110,9 +110,12 @@
 RowCM				: "列",
 ColumnCM			: "欄",
-InsertRow			: "插入列",
+InsertRowBefore			: "向上插入列",
+InsertRowAfter			: "向下插入列",
 DeleteRows			: "刪除列",
-InsertColumn		: "插入欄",
+InsertColumnBefore		: "向左插入欄",
+InsertColumnAfter		: "向右插入欄",
 DeleteColumns		: "刪除欄",
-InsertCell			: "插入儲存格",
+InsertCellBefore		: "向左插入儲存格",
+InsertCellAfter			: "向右插入儲存格",
 DeleteCells			: "刪除儲存格",
 MergeCells			: "合併儲存格",
