Index: /FCKeditor/trunk/editor/_source/commandclasses/fcktablecommand.js
===================================================================
--- /FCKeditor/trunk/editor/_source/commandclasses/fcktablecommand.js	(revision 690)
+++ /FCKeditor/trunk/editor/_source/commandclasses/fcktablecommand.js	(revision 691)
@@ -91,9 +91,28 @@
 FCKTableCommand.prototype.GetState = function()
 {
-	if ( FCK.EditorDocument != null )
+	if ( FCK.EditorDocument != null && FCKSelection.HasAncestorNode( 'TABLE' ) )
 	{
-		if( FCKSelection.HasAncestorNode( 'TABLE' ) ) 
-			return FCK_TRISTATE_OFF ;
+		switch ( this.Name )
+		{
+			case 'TableHorizontalSplitCell' :
+			case 'TableVerticalSplitCell' :
+			case 'TableMergeRight' :
+			case 'TableMergeDown' :
+				if ( FCKTableHandler.GetSelectedCells().length == 1 )
+					return FCK_TRISTATE_OFF ;
+				else
+					return FCK_TRISTATE_DISABLED ;
+				break ;
+			case 'TableMergeCells' :
+				if ( FCKTableHandler.CheckIsSelectionRectangular() 
+						&& FCKTableHandler.GetSelectedCells().length > 1 )
+					return FCK_TRISTATE_OFF ;
+				else
+					return FCK_TRISTATE_DISABLED ;
+			default :
+				return FCK_TRISTATE_OFF ;
+		}
 	}
-	return FCK_TRISTATE_DISABLED; 
+	else
+		return FCK_TRISTATE_DISABLED; 
 }
Index: /FCKeditor/trunk/editor/_source/internals/fck_contextmenu.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fck_contextmenu.js	(revision 690)
+++ /FCKeditor/trunk/editor/_source/internals/fck_contextmenu.js	(revision 691)
@@ -71,18 +71,24 @@
 					menu.AddSeparator() ;
 					var oItem = menu.AddItem( 'Cell'	, FCKLang.CellCM ) ;
-					oItem.AddItem( 'TableInsertCellBefore'	, FCKLang.InsertCellBefore, 69 ) ;
+					oItem.AddItem( 'TableInsertCellBefore'	, FCKLang.InsertCellBefore, 69 ) ; 
 					oItem.AddItem( 'TableInsertCellAfter'	, FCKLang.InsertCellAfter, 58 ) ;
 					oItem.AddItem( 'TableDeleteCells'	, FCKLang.DeleteCells, 59 ) ;
 					if ( FCKBrowserInfo.IsIE )
 					{
-						oItem.AddItem( 'TableMergeRight'	, FCKLang.MergeRight, 60 ) ;
-						oItem.AddItem( 'TableMergeDown'		, FCKLang.MergeDown, 60 ) ;
+						oItem.AddItem( 'TableMergeRight'	, FCKLang.MergeRight, 60, 
+							FCKCommands.GetCommand( 'TableMergeRight' ).GetState() == FCK_TRISTATE_DISABLED ) ;
+						oItem.AddItem( 'TableMergeDown'		, FCKLang.MergeDown, 60,
+							FCKCommands.GetCommand( 'TableMergeDown' ).GetState() == FCK_TRISTATE_DISABLED ) ;
 					}
 					else
-						oItem.AddItem( 'TableMergeCells'	, FCKLang.MergeCells, 60 ) ;
-					oItem.AddItem( 'TableHorizontalSplitCell'	, FCKLang.HorizontalSplitCell, 61 ) ;
-					oItem.AddItem( 'TableVerticalSplitCell'	, FCKLang.VerticalSplitCell, 61 ) ;
+						oItem.AddItem( 'TableMergeCells'	, FCKLang.MergeCells, 60,
+							FCKCommands.GetCommand( 'TableMergeCells' ).GetState() == FCK_TRISTATE_DISABLED ) ;
+					oItem.AddItem( 'TableHorizontalSplitCell'	, FCKLang.HorizontalSplitCell, 61,
+						FCKCommands.GetCommand( 'TableHorizontalSplitCell' ).GetState() == FCK_TRISTATE_DISABLED ) ;
+					oItem.AddItem( 'TableVerticalSplitCell'	, FCKLang.VerticalSplitCell, 61,
+						FCKCommands.GetCommand( 'TableVerticalSplitCell' ).GetState() == FCK_TRISTATE_DISABLED ) ;
 					oItem.AddSeparator() ;
-					oItem.AddItem( 'TableCellProp'		, FCKLang.CellProperties, 57 ) ;
+					oItem.AddItem( 'TableCellProp'		, FCKLang.CellProperties, 57,
+						FCKCommands.GetCommand( 'TableCellProp' ).GetState() == FCK_TRISTATE_DISABLED ) ;
 
 					menu.AddSeparator() ;
Index: /FCKeditor/trunk/editor/_source/internals/fckcommands.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fckcommands.js	(revision 690)
+++ /FCKeditor/trunk/editor/_source/internals/fckcommands.js	(revision 691)
@@ -58,5 +58,5 @@
 		case 'Table'		: oCommand = new FCKDialogCommand( 'Table'		, FCKLang.DlgTableTitle			, 'dialog/fck_table.html'		, 450, 250 ) ; break ;
 		case 'TableProp'	: oCommand = new FCKDialogCommand( 'Table'		, FCKLang.DlgTableTitle			, 'dialog/fck_table.html?Parent', 400, 250 ) ; break ;
-		case 'TableCellProp': oCommand = new FCKDialogCommand( 'TableCell'	, FCKLang.DlgCellTitle			, 'dialog/fck_tablecell.html'	, 550, 250 ) ; break ;
+		case 'TableCellProp': oCommand = new FCKDialogCommand( 'TableCell'	, FCKLang.DlgCellTitle			, 'dialog/fck_tablecell.html'	, 550, 250, FCKTableHandler.TableCellPropGetStatus, null ) ; break ;
 
 		case 'Style'		: oCommand = new FCKStyleCommand() ; break ;
Index: /FCKeditor/trunk/editor/_source/internals/fcktablehandler.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fcktablehandler.js	(revision 690)
+++ /FCKeditor/trunk/editor/_source/internals/fcktablehandler.js	(revision 691)
@@ -238,4 +238,107 @@
 }
 
+FCKTableHandler._MarkCells = function( cells, label )
+{
+	for ( var i = 0 ; i < cells.length ; i++ )
+		cells[i][label] = true ;
+}
+
+FCKTableHandler._UnmarkCells = function( cells, label )
+{
+	for ( var i = 0 ; i < cells.length ; i++ )
+	{
+		if ( FCKBrowserInfo.IsIE )
+			cells[i].removeAttribute( label ) ;
+		else
+			delete cells[i][label] ;
+	}
+}
+
+FCKTableHandler._GetMarkerGeometry = function( tableMap, rowIdx, colIdx, markerName )
+{
+	var selectionWidth = 0 ;
+	var selectionHeight = 0 ;
+	var cellsLeft = 0 ;
+	var cellsUp = 0 ;
+	for ( var i = colIdx ; tableMap[rowIdx][i] && tableMap[rowIdx][i][markerName] ; i++ )
+		selectionWidth++ ;
+	for ( var i = colIdx - 1 ; tableMap[rowIdx][i] && tableMap[rowIdx][i][markerName] ; i-- )
+	{
+		selectionWidth++ ;
+		cellsLeft++ ;
+	}
+	for ( var i = rowIdx ; tableMap[i] && tableMap[i][colIdx] && tableMap[i][colIdx][markerName] ; i++ )
+		selectionHeight++ ;
+	for ( var i = rowIdx - 1 ; tableMap[i] && tableMap[i][colIdx] && tableMap[i][colIdx][markerName] ; i-- )
+	{
+		selectionHeight++ ;
+		cellsUp++ ;
+	}
+	return { width : selectionWidth, height : selectionHeight, x : cellsLeft, y : cellsUp } ;
+}
+
+FCKTableHandler.CheckIsSelectionRectangular = function()
+{
+	// If every row and column in an area on a plane are of the same width and height,
+	// Then the area is a rectangle.
+	var cells = FCKTableHandler.GetSelectedCells() ;
+	if ( cells.length < 1 )
+		return false ;
+
+	this._MarkCells( cells, '_CellSelected' ) ;
+
+	var tableMap = this._CreateTableMap( cells[0].parentNode.parentNode ) ;
+	var rowIdx = cells[0].parentNode.rowIndex ;
+	var colIdx = this._GetCellIndexSpan( tableMap, rowIdx, cells[0] ) ;
+
+	var geometry = this._GetMarkerGeometry( tableMap, rowIdx, colIdx, '_CellSelected' ) ;
+	var baseColIdx = colIdx - geometry.x ;
+	var baseRowIdx = rowIdx - geometry.y ;
+
+	if ( geometry.width >= geometry.height )
+	{
+		for ( colIdx = baseColIdx ; colIdx < baseColIdx + geometry.width ; colIdx++ )
+		{
+			rowIdx = baseRowIdx + ( colIdx - baseColIdx ) % geometry.height ;
+			if ( ! tableMap[rowIdx] || ! tableMap[rowIdx][colIdx] )
+			{
+				FCKDebug.Output( rowIdx + "," + colIdx + " not found" ) ;
+				this._UnmarkCells( cells, '_CellSelected' ) ;
+				return false ;
+			}
+			var g = this._GetMarkerGeometry( tableMap, rowIdx, colIdx, '_CellSelected' ) ;
+			if ( g.width != geometry.width || g.height != geometry.height )
+			{
+				FCKDebug.Output( "size " + g.width + "x" + g.height + " not match" ) ;
+				this._UnmarkCells( cells, '_CellSelected' ) ;
+				return false ;
+			}
+		}
+	}
+	else
+	{
+		for ( rowIdx = baseRowIdx ; rowIdx < baseRowIdx + geometry.height ; rowIdx++ )
+		{
+			colIdx = baseColIdx + ( rowIdx - baseRowIdx ) % geometry.width ;
+			if ( ! tableMap[rowIdx] || ! tableMap[rowIdx][colIdx] )
+			{
+				FCKDebug.Output( rowIdx + "," + colIdx + " not found" ) ;
+				this._UnmarkCells( cells, '_CellSelected' ) ;
+				return false ;
+			}
+			var g = this._GetMarkerGeometry( tableMap, rowIdx, colIdx, '_CellSelected' ) ;
+			if ( g.width != geometry.width || g.height != geometry.height )
+			{
+				FCKDebug.Output( "size " + g.width + "x" + g.height + " not match" ) ;
+				this._UnmarkCells( cells, '_CellSelected' ) ;
+				return false ;
+			}
+		}
+	}
+
+	this._UnmarkCells( cells, '_CellSelected' ) ;
+	return true ;
+}
+
 FCKTableHandler.MergeCells = function()
 {
@@ -244,4 +347,5 @@
 
 	// TODO: Reimplement MergeCells() with this._InstallTableMap().
+
 }
 
@@ -582,6 +686,14 @@
 		{
 			var cell = tableMap[i][j] ;
-			cell.removeAttribute( '_colScanned' ) ;
-			cell.removeAttribute( '_rowScanned' ) ;
+			if ( FCKBrowser.IsIE )
+			{
+				cell.removeAttribute( '_colScanned' ) ;
+				cell.removeAttribute( '_rowScanned' ) ;
+			}
+			else
+			{
+				delete cell._colScanned ;
+				delete cell._rowScanned ;
+			}
 		}
 	}
@@ -624,2 +736,10 @@
 	}
 }
+
+FCKTableHandler.TableCellPropGetStatus = function()
+{
+	if ( FCKTableHandler.GetSelectedCells().length == 1 )
+		return FCK_TRISTATE_OFF ;
+	else
+		return FCK_TRISTATE_DISABLED ;
+}
Index: /FCKeditor/trunk/editor/_source/internals/fcktools_gecko.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fcktools_gecko.js	(revision 690)
+++ /FCKeditor/trunk/editor/_source/internals/fcktools_gecko.js	(revision 691)
@@ -224,7 +224,8 @@
 
 		/*
-		FCKDebug.Output( el.tagName + ":" + "offset=" + el.offsetLeft + "," + el.offsetTop + "  " + "scroll=" + el.scrollLeft + "," +
-			      el.scrollTop ) ;
+		FCKDebug.Output( el.tagName + ":" + "offset=" + el.offsetLeft + "," + el.offsetTop + "  " 
+				+ "scroll=" + el.scrollLeft + "," + el.scrollTop ) ;
 		*/
+
 		c.X += el.offsetLeft - el.scrollLeft ;
 		c.Y += el.offsetTop - el.scrollTop  ;
