/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#include <svx/sdr/table/tablecontroller.hxx>
#include <tablemodel.hxx>

#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/container/XIndexAccess.hpp>

#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/table/XMergeableCellRange.hpp>
#include <com/sun/star/table/XMergeableCell.hpp>

#include <sal/config.h>

#include <vcl/svapp.hxx>
#include <svl/whiter.hxx>

#include <sfx2/request.hxx>

#include <editeng/scripttypeitem.hxx>
#include <svx/svdotable.hxx>
#include <svx/sdr/overlay/overlayobjectcell.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <svx/svxids.hrc>
#include <editeng/outlobj.hxx>
#include <svx/svdoutl.hxx>
#include <svx/svdpagv.hxx>
#include <svx/svdetc.hxx>
#include <editeng/editobj.hxx>
#include "editeng/editstat.hxx"
#include "editeng/unolingu.hxx"
#include "svx/sdrpagewindow.hxx"
#include <svx/selectioncontroller.hxx>
#include <svx/svdmodel.hxx>
#include "svx/sdrpaintwindow.hxx"
#include <svx/svxdlg.hxx>
#include <editeng/boxitem.hxx>
#include "cell.hxx"
#include <editeng/borderline.hxx>
#include <editeng/colritem.hxx>
#include "editeng/bolnitem.hxx"
#include "svx/svdstr.hrc"
#include "svx/svdglob.hxx"
#include "svx/svdpage.hxx"
#include "tableundo.hxx"
#include "tablelayouter.hxx"

using ::rtl::OUString;
using namespace ::sdr::table;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::table;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::style;

namespace sdr { namespace table {

// --------------------------------------------------------------------
// class SvxTableControllerModifyListener
// --------------------------------------------------------------------

class SvxTableControllerModifyListener : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XModifyListener >
{
public:
	SvxTableControllerModifyListener( SvxTableController* pController )
		: mpController( pController ) {}

	// XModifyListener
    virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);

    // XEventListener
    virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);

	SvxTableController* mpController;
};

// --------------------------------------------------------------------
// XModifyListener
// --------------------------------------------------------------------

void SAL_CALL SvxTableControllerModifyListener::modified( const ::com::sun::star::lang::EventObject&  ) throw (::com::sun::star::uno::RuntimeException)
{
	if( mpController )
		mpController->onTableModified();
}

// --------------------------------------------------------------------
// XEventListener
// --------------------------------------------------------------------

void SAL_CALL SvxTableControllerModifyListener::disposing( const ::com::sun::star::lang::EventObject&  ) throw (::com::sun::star::uno::RuntimeException)
{
	mpController = 0;
}

// --------------------------------------------------------------------
// class SvxTableController
// --------------------------------------------------------------------

rtl::Reference< sdr::SelectionController > CreateTableController( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController )
{
	return SvxTableController::create( pView, pObj, xRefController );
}

// --------------------------------------------------------------------

rtl::Reference< sdr::SelectionController > SvxTableController::create( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController )
{
	if( xRefController.is() )
	{
		SvxTableController* pController = dynamic_cast< SvxTableController* >( xRefController.get() );
		if( pController && (pController->mxTableObj.get() == pObj) && (pController->mpView == pView)  )
			return xRefController;
	}
	return new SvxTableController( pView, pObj );
}

// --------------------------------------------------------------------

SvxTableController::SvxTableController( SdrObjEditView* pView, const SdrObject* pObj )
: mbCellSelectionMode(false)
, mbLeftButtonDown(false)
, mpSelectionOverlay(0)
, mpView( dynamic_cast< SdrView* >( pView ) )
, mxTableObj( dynamic_cast< SdrTableObj* >( const_cast< SdrObject* >( pObj ) ) ) 
, mpModel( 0 )
, mnUpdateEvent( 0 )
{
	if( pObj )
		mpModel = pObj->GetModel();

	if( mxTableObj.is() )
	{
		static_cast< const SdrTableObj* >( pObj )->getActiveCellPos( maCursorFirstPos );
		maCursorLastPos = maCursorFirstPos;

		Reference< XTable > xTable( static_cast< const SdrTableObj* >( pObj )->getTable() );
		if( xTable.is() )
		{
			mxModifyListener = new SvxTableControllerModifyListener( this );
			xTable->addModifyListener( mxModifyListener );

			mxTable.set( dynamic_cast< TableModel* >( xTable.get() ) );
		}
	}
}

// --------------------------------------------------------------------

SvxTableController::~SvxTableController()
{
	if( mnUpdateEvent )
	{
		Application::RemoveUserEvent( mnUpdateEvent );
	}

	if( mxModifyListener.is() && mxTableObj.get() )
	{
		Reference< XTable > xTable( static_cast< SdrTableObj* >( mxTableObj.get() )->getTable() );
		if( xTable.is() )
		{
			xTable->removeModifyListener( mxModifyListener );
			mxModifyListener.clear();
		}
	}
}

// --------------------------------------------------------------------

const sal_uInt16 ACTION_NONE = 0;
const sal_uInt16 ACTION_GOTO_FIRST_CELL = 1;
const sal_uInt16 ACTION_GOTO_FIRST_COLUMN = 2;
const sal_uInt16 ACTION_GOTO_FIRST_ROW = 3;
const sal_uInt16 ACTION_GOTO_LEFT_CELL = 4;
const sal_uInt16 ACTION_GOTO_UP_CELL = 5;
const sal_uInt16 ACTION_GOTO_RIGHT_CELL = 6;
const sal_uInt16 ACTION_GOTO_DOWN_CELL = 7;
const sal_uInt16 ACTION_GOTO_LAST_CELL = 8;
const sal_uInt16 ACTION_GOTO_LAST_COLUMN = 9;
const sal_uInt16 ACTION_GOTO_LAST_ROW = 10;
const sal_uInt16 ACTION_EDIT_CELL = 11;
const sal_uInt16 ACTION_STOP_TEXT_EDIT = 12;
const sal_uInt16 ACTION_REMOVE_SELECTION = 13;
const sal_uInt16 ACTION_START_SELECTION = 14;
const sal_uInt16 ACTION_HANDLED_BY_VIEW = 15;
const sal_uInt16 ACTION_TAB = 18;

bool SvxTableController::onKeyInput(const KeyEvent& rKEvt, Window* pWindow )
{
	if( !checkTableObject() )
		return false;

	// check if we are read only
	if( mpModel && mpModel->IsReadOnly())
	{
		switch( rKEvt.GetKeyCode().GetCode() )
		{
		case awt::Key::DOWN:
		case awt::Key::UP:
		case awt::Key::LEFT:
		case awt::Key::RIGHT:
		case awt::Key::TAB:
		case awt::Key::HOME:
		case awt::Key::END:
		case awt::Key::NUM2:
		case awt::Key::NUM4:
		case awt::Key::NUM6:
		case awt::Key::NUM8:
		case awt::Key::ESCAPE:
		case awt::Key::F2:
			break;
		default:
			// tell the view we eat the event, no further processing needed
			return true;
		}
	}

	sal_uInt16 nAction = getKeyboardAction( rKEvt, pWindow );

	return executeAction( nAction, ( rKEvt.GetKeyCode().IsShift() ) ? sal_True : sal_False, pWindow );
}

// --------------------------------------------------------------------
// ::com::sun::star::awt::XMouseClickHandler:
// --------------------------------------------------------------------

bool SvxTableController::onMouseButtonDown(const MouseEvent& rMEvt, Window* pWindow )
{
	if( !pWindow || !checkTableObject() )
		return false;

	SdrViewEvent aVEvt;
	if( !rMEvt.IsRight() && mpView->PickAnything(rMEvt,SDRMOUSEBUTTONDOWN, aVEvt) == SDRHIT_HANDLE )
		return false;

	TableHitKind eHit = static_cast< SdrTableObj* >(mxTableObj.get())->CheckTableHit( pWindow->PixelToLogic(rMEvt.GetPosPixel()), maMouseDownPos.mnCol, maMouseDownPos.mnRow, 0 );

	mbLeftButtonDown = (rMEvt.GetClicks() == 1) && rMEvt.IsLeft();

	if( eHit == SDRTABLEHIT_CELL )
	{
		StartSelection( maMouseDownPos );
		return true;
	}

	if( rMEvt.IsRight() && eHit != SDRTABLEHIT_NONE )
		return true; // right click will become context menu

	// for cell selektion with the mouse remember our first hit
	if( mbLeftButtonDown )
	{
		RemoveSelection();
	
		Point aPnt(rMEvt.GetPosPixel());
		if (pWindow!=NULL)
			aPnt=pWindow->PixelToLogic(aPnt);

		SdrHdl* pHdl = mpView->PickHandle(aPnt);

		if( pHdl )
		{
			mbLeftButtonDown = false;
		}
		else
		{
			::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );

			if( !pWindow || !pTableObj || eHit  == SDRTABLEHIT_NONE)
			{
				mbLeftButtonDown = false;
			}
		}
	}

	return false;
}

// --------------------------------------------------------------------

bool SvxTableController::onMouseButtonUp(const MouseEvent& rMEvt, Window* /*pWin*/)
{
	if( !checkTableObject() )
		return false;

	mbLeftButtonDown = false;

	if( rMEvt.GetClicks() == 2 )
		return true;

	return false;
}

// --------------------------------------------------------------------

bool SvxTableController::onMouseMove(const MouseEvent& rMEvt, Window* pWindow )
{
	if( !checkTableObject() )
		return false;

	if( rMEvt.IsLeft() )
	{
		int i = 0;
		i++;
	}

	SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
	CellPos aPos;
	if( mbLeftButtonDown && pTableObj && pTableObj->CheckTableHit( pWindow->PixelToLogic(rMEvt.GetPosPixel()), aPos.mnCol, aPos.mnRow, 0 ) != SDRTABLEHIT_NONE )
	{
		if(aPos != maMouseDownPos) 
		{
			if( mbCellSelectionMode )
			{
				setSelectedCells( maMouseDownPos, aPos );
				return true;
			}
			else
			{
				StartSelection( maMouseDownPos );
			}
		}
		else if( mbCellSelectionMode )
		{
			UpdateSelection( aPos );
			return true;
		}
	}
    return false;
}

// --------------------------------------------------------------------

void SvxTableController::onSelectionHasChanged()
{
	bool bSelected = false;

	SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
	if( pTableObj && pTableObj->IsTextEditActive() )
	{
		pTableObj->getActiveCellPos( maCursorFirstPos );
		maCursorLastPos = maCursorFirstPos;
		mbCellSelectionMode = false;
	}
	else
	{
		const SdrMarkList& rMarkList= mpView->GetMarkedObjectList();
		if( rMarkList.GetMarkCount() == 1 )
			bSelected = mxTableObj.get() == rMarkList.GetMark(0)->GetMarkedSdrObj();
	}

	if( bSelected )
	{
		updateSelectionOverlay();
	}
	else
	{
		destroySelectionOverlay();
	}
}

// --------------------------------------------------------------------

void SvxTableController::GetState( SfxItemSet& rSet )
{
	if( !mxTable.is() || !mxTableObj.is() || !mxTableObj->GetModel() )
		return;

	SfxItemSet* pSet = 0;

	bool bVertDone = false;

    // Iterate over all requested items in the set.
	SfxWhichIter aIter( rSet );
	sal_uInt16 nWhich = aIter.FirstWhich();
	while (nWhich)
	{
		switch (nWhich)
		{
			case SID_TABLE_VERT_BOTTOM:
			case SID_TABLE_VERT_CENTER:
			case SID_TABLE_VERT_NONE:
				{
					if( !mxTable.is() || !mxTableObj->GetModel() )
					{
						rSet.DisableItem(nWhich);
					}
					else if(!bVertDone)
					{
						if( !pSet )
						{
							pSet = new SfxItemSet( mxTableObj->GetModel()->GetItemPool() );
							MergeAttrFromSelectedCells(*pSet, sal_False);
						}

						SdrTextVertAdjust eAdj = SDRTEXTVERTADJUST_BLOCK;

						if( pSet->GetItemState( SDRATTR_TEXT_VERTADJUST ) != SFX_ITEM_DONTCARE )
							eAdj = ((SdrTextVertAdjustItem&)(pSet->Get(SDRATTR_TEXT_VERTADJUST))).GetValue();

						rSet.Put(SfxBoolItem(SID_TABLE_VERT_BOTTOM, eAdj == SDRTEXTVERTADJUST_BOTTOM));
						rSet.Put(SfxBoolItem(SID_TABLE_VERT_CENTER, eAdj == SDRTEXTVERTADJUST_CENTER));
						rSet.Put(SfxBoolItem(SID_TABLE_VERT_NONE, eAdj == SDRTEXTVERTADJUST_TOP));
						bVertDone = true;
					}
					break;
				}
			case SID_TABLE_DELETE_ROW:
				if( !mxTable.is() || !hasSelectedCells() || (mxTable->getRowCount() <= 1) )
					rSet.DisableItem(SID_TABLE_DELETE_ROW);
				break;
			case SID_TABLE_DELETE_COL:
				if( !mxTable.is() || !hasSelectedCells() || (mxTable->getColumnCount() <= 1) )
					rSet.DisableItem(SID_TABLE_DELETE_COL);
				break;
			case SID_TABLE_MERGE_CELLS:
				if( !mxTable.is() || !hasSelectedCells() )
					rSet.DisableItem(SID_TABLE_MERGE_CELLS);
				break;
			case SID_TABLE_SPLIT_CELLS:
				if( !hasSelectedCells() || !mxTable.is() )
					rSet.DisableItem(SID_TABLE_SPLIT_CELLS);
				break;

			case SID_OPTIMIZE_TABLE:
			case SID_TABLE_DISTRIBUTE_COLUMNS:
			case SID_TABLE_DISTRIBUTE_ROWS:
			{
				bool bDistributeColumns = false;
				bool bDistributeRows = false;
				if( mxTable.is() )
				{
					CellPos aStart, aEnd;
					getSelectedCells( aStart, aEnd );

					bDistributeColumns = aStart.mnCol != aEnd.mnCol;
					bDistributeRows = aStart.mnRow != aEnd.mnRow;
				}
				if( !bDistributeColumns && !bDistributeRows )
					rSet.DisableItem(SID_OPTIMIZE_TABLE);
				if( !bDistributeColumns )
					rSet.DisableItem(SID_TABLE_DISTRIBUTE_COLUMNS);
				if( !bDistributeRows )
					rSet.DisableItem(SID_TABLE_DISTRIBUTE_ROWS);
				break;
			}

			case SID_AUTOFORMAT:
			case SID_TABLE_SORT_DIALOG:
			case SID_TABLE_AUTOSUM:
//				if( !mxTable.is() )
//					rSet.DisableItem( nWhich );
				break;
			default:
				break;
        }
		nWhich = aIter.NextWhich();
	}
	if( pSet )
		delete pSet;
}

// --------------------------------------------------------------------

void SvxTableController::onInsert( sal_uInt16 nSId, const SfxItemSet* pArgs )
{
	::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
	if( !pTableObj )
		return;

	if( mxTable.is() ) try
	{
		// 
		bool bInsertAfter = true;
		sal_uInt16 nCount = 0;
    	if( pArgs )
    	{
    	    const SfxPoolItem* pItem = 0;
    	    pArgs->GetItemState(nSId, sal_False, &pItem);
			if (pItem)
			{
				nCount = ((const SfxInt16Item* )pItem)->GetValue();
				if(SFX_ITEM_SET == pArgs->GetItemState(SID_TABLE_PARAM_INSERT_AFTER, sal_True, &pItem))
					bInsertAfter = ((const SfxBoolItem* )pItem)->GetValue();
			}
    	}
    		
		CellPos aStart, aEnd;
		if( hasSelectedCells() )
		{
			getSelectedCells( aStart, aEnd );
		}
		else
		{
		    if( bInsertAfter )
		    {		        
			    aStart.mnCol = mxTable->getColumnCount() - 1;
			    aStart.mnRow = mxTable->getRowCount() - 1;
			    aEnd = aStart;
		    }
		}

		if( pTableObj->IsTextEditActive() )
			mpView->SdrEndTextEdit(sal_True);

		RemoveSelection();	
		
		const OUString sSize( RTL_CONSTASCII_USTRINGPARAM( "Size" ) );

		const bool bUndo = mpModel && mpModel->IsUndoEnabled();

		switch( nSId )
		{
		case SID_TABLE_INSERT_COL:
		{
			TableModelNotifyGuard aGuard( mxTable.get() );
	
			if( bUndo )
			{
				mpModel->BegUndo( ImpGetResStr(STR_TABLE_INSCOL) );
				mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
			}

			Reference< XTableColumns > xCols( mxTable->getColumns() );
			const sal_Int32 nNewColumns = (nCount == 0) ? (aEnd.mnCol - aStart.mnCol + 1) : nCount;
			const sal_Int32 nNewStartColumn = aEnd.mnCol + (bInsertAfter ? 1 : 0);
			xCols->insertByIndex( nNewStartColumn, nNewColumns );
			
			for( sal_Int32 nOffset = 0; nOffset < nNewColumns; nOffset++ )
			{
				Reference< XPropertySet >( xCols->getByIndex( aEnd.mnCol + nOffset + 1 ), UNO_QUERY_THROW )->
					setPropertyValue( sSize,
						Reference< XPropertySet >( xCols->getByIndex( aStart.mnCol + nOffset ), UNO_QUERY_THROW )->
							getPropertyValue( sSize ) );
			}

			if( bUndo )
				mpModel->EndUndo();

			aStart.mnCol = nNewStartColumn;
			aStart.mnRow = 0;
			aEnd.mnCol = aStart.mnCol + nNewColumns - 1;
			aEnd.mnRow = mxTable->getRowCount() - 1;
			break;
		}
		
		case SID_TABLE_INSERT_ROW:
		{
			TableModelNotifyGuard aGuard( mxTable.get() );
	
			if( bUndo )
			{
				mpModel->BegUndo( ImpGetResStr(STR_TABLE_INSROW ) );
				mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
			}

			Reference< XTableRows > xRows( mxTable->getRows() );
			const sal_Int32 nNewRows = (nCount == 0) ? (aEnd.mnRow - aStart.mnRow + 1) : nCount;
			const sal_Int32 nNewRowStart = aEnd.mnRow + (bInsertAfter ? 1 : 0);
			xRows->insertByIndex( nNewRowStart, nNewRows );

			for( sal_Int32 nOffset = 0; nOffset < nNewRows; nOffset++ )
			{
				Reference< XPropertySet >( xRows->getByIndex( aEnd.mnRow + nOffset + 1 ), UNO_QUERY_THROW )->
					setPropertyValue( sSize,
						Reference< XPropertySet >( xRows->getByIndex( aStart.mnRow + nOffset ), UNO_QUERY_THROW )->
							getPropertyValue( sSize ) );
			}

			if( bUndo )
				mpModel->EndUndo();

			aStart.mnCol = 0;
			aStart.mnRow = nNewRowStart;
			aEnd.mnCol = mxTable->getColumnCount() - 1;
			aEnd.mnRow = aStart.mnRow + nNewRows - 1;
			break;
		}
		}

		StartSelection( aStart );
		UpdateSelection( aEnd );
	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR("svx::SvxTableController::onInsert(), exception caught!");
	}
}

// --------------------------------------------------------------------

void SvxTableController::onDelete( sal_uInt16 nSId )
{
	::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
	if( !pTableObj )
		return;

	if( mxTable.is() && hasSelectedCells() )
	{
		CellPos aStart, aEnd;
		getSelectedCells( aStart, aEnd );

		if( pTableObj->IsTextEditActive() )
			mpView->SdrEndTextEdit(sal_True);

		RemoveSelection();

		bool bDeleteTable = false;
		switch( nSId )
		{
		case SID_TABLE_DELETE_COL:
		{
			const sal_Int32 nRemovedColumns = aEnd.mnCol - aStart.mnCol + 1;
			if( nRemovedColumns == mxTable->getColumnCount() )
			{
				bDeleteTable = true;
			}
			else
			{
				Reference< XTableColumns > xCols( mxTable->getColumns() );
				xCols->removeByIndex( aStart.mnCol, nRemovedColumns );
			}
			break;
		}
		
		case SID_TABLE_DELETE_ROW:
		{
			const sal_Int32 nRemovedRows = aEnd.mnRow - aStart.mnRow + 1;
			if( nRemovedRows == mxTable->getRowCount() )
			{
				bDeleteTable = true;
			}
			else
			{
				Reference< XTableRows > xRows( mxTable->getRows() );
				xRows->removeByIndex( aStart.mnRow, nRemovedRows );
			}
			break;
		}
		}

		if( bDeleteTable )
			mpView->DeleteMarkedObj();
		else
			UpdateTableShape();
	}
}

// --------------------------------------------------------------------

void SvxTableController::onSelect( sal_uInt16 nSId )
{
	if( mxTable.is() )
	{
		const sal_Int32 nRowCount = mxTable->getRowCount();
		const sal_Int32 nColCount = mxTable->getColumnCount();
		if( nRowCount && nColCount )
		{
			CellPos aStart, aEnd;
			getSelectedCells( aStart, aEnd );

			switch( nSId )
			{
			case SID_TABLE_SELECT_ALL:
				aEnd.mnCol = 0; aEnd.mnRow = 0;
				aStart.mnCol = nColCount - 1; aStart.mnRow = nRowCount - 1; 
				break;
			case SID_TABLE_SELECT_COL:
				aEnd.mnRow = nRowCount - 1;
				aStart.mnRow = 0;
				break;
			case SID_TABLE_SELECT_ROW:
				aEnd.mnCol = nColCount - 1;
				aStart.mnCol = 0;
				break;
			}

			StartSelection( aEnd );
			gotoCell( aStart, true, 0 );
		}
	}
}

// --------------------------------------------------------------------
void SvxTableController::onFormatTable( SfxRequest& rReq )
{
	::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
	if( !pTableObj )
		return;

	const SfxItemSet* pArgs = rReq.GetArgs();

	if( !pArgs && pTableObj->GetModel() )
	{
		SfxItemSet aNewAttr( pTableObj->GetModel()->GetItemPool() );
		MergeAttrFromSelectedCells(aNewAttr, sal_False);

		// merge drawing layer text distance items into SvxBoxItem used by the dialog
		SvxBoxItem aBoxItem( static_cast< const SvxBoxItem& >( aNewAttr.Get( SDRATTR_TABLE_BORDER ) ) );
		aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextLeftDistItem&)(aNewAttr.Get(SDRATTR_TEXT_LEFTDIST))).GetValue()), BOX_LINE_LEFT );
		aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextRightDistItem&)(aNewAttr.Get(SDRATTR_TEXT_RIGHTDIST))).GetValue()), BOX_LINE_RIGHT );
		aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextUpperDistItem&)(aNewAttr.Get(SDRATTR_TEXT_UPPERDIST))).GetValue()), BOX_LINE_TOP );
		aBoxItem.SetDistance( sal::static_int_cast< sal_uInt16 >( ((SdrTextLowerDistItem&)(aNewAttr.Get(SDRATTR_TEXT_LOWERDIST))).GetValue()), BOX_LINE_BOTTOM );
		aNewAttr.Put( aBoxItem );

		SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
		std::auto_ptr< SfxAbstractTabDialog > pDlg( pFact ? pFact->CreateSvxFormatCellsDialog( NULL, &aNewAttr, pTableObj->GetModel(), pTableObj) : 0 );
		if( pDlg.get() && pDlg->Execute() )
		{
			SfxItemSet aNewSet( *(pDlg->GetOutputItemSet ()) );

			SvxBoxItem aNewBoxItem( static_cast< const SvxBoxItem& >( aNewSet.Get( SDRATTR_TABLE_BORDER ) ) );

			if( aNewBoxItem.GetDistance( BOX_LINE_LEFT ) != aBoxItem.GetDistance( BOX_LINE_LEFT ) )
				aNewSet.Put(SdrTextLeftDistItem( aNewBoxItem.GetDistance( BOX_LINE_LEFT ) ) );

			if( aNewBoxItem.GetDistance( BOX_LINE_RIGHT ) != aBoxItem.GetDistance( BOX_LINE_RIGHT ) )
				aNewSet.Put(SdrTextRightDistItem( aNewBoxItem.GetDistance( BOX_LINE_RIGHT ) ) );

			if( aNewBoxItem.GetDistance( BOX_LINE_TOP ) != aBoxItem.GetDistance( BOX_LINE_TOP ) )
				aNewSet.Put(SdrTextUpperDistItem( aNewBoxItem.GetDistance( BOX_LINE_TOP ) ) );

			if( aNewBoxItem.GetDistance( BOX_LINE_BOTTOM ) != aBoxItem.GetDistance( BOX_LINE_BOTTOM ) )
				aNewSet.Put(SdrTextLowerDistItem( aNewBoxItem.GetDistance( BOX_LINE_BOTTOM ) ) );

			SetAttrToSelectedCells(aNewSet, sal_False);
		}
		UpdateTableShape();
	}
}

// --------------------------------------------------------------------

void SvxTableController::Execute( SfxRequest& rReq )
{
	const sal_uInt16 nSId = rReq.GetSlot();
	switch( nSId )
	{
	case SID_TABLE_INSERT_ROW:
	case SID_TABLE_INSERT_COL:
		onInsert( nSId, rReq.GetArgs() );
		break;
	case SID_TABLE_DELETE_ROW:
	case SID_TABLE_DELETE_COL:
		onDelete( nSId );
		break;
	case SID_TABLE_SELECT_ALL:
	case SID_TABLE_SELECT_COL:
	case SID_TABLE_SELECT_ROW:
		onSelect( nSId );
		break;
	case SID_FORMAT_TABLE_DLG:
		onFormatTable( rReq );
		break;

	case SID_FRAME_LINESTYLE:
	case SID_FRAME_LINECOLOR:
	case SID_ATTR_BORDER:
		{
			const SfxItemSet* pArgs = rReq.GetArgs();
			if( pArgs )
				ApplyBorderAttr( *pArgs );
		}
		break;

	case SID_ATTR_FILL_STYLE:
		{
			const SfxItemSet* pArgs = rReq.GetArgs();
			if( pArgs )
				SetAttributes( *pArgs, false );
		}
		break;

	case SID_TABLE_MERGE_CELLS:
		MergeMarkedCells();
		break;

	case SID_TABLE_SPLIT_CELLS:
		SplitMarkedCells();
		break;

	case SID_TABLE_DISTRIBUTE_COLUMNS:
		DistributeColumns();
		break;

	case SID_TABLE_DISTRIBUTE_ROWS:
		DistributeRows();
		break;

	case SID_TABLE_VERT_BOTTOM:
	case SID_TABLE_VERT_CENTER:
	case SID_TABLE_VERT_NONE:
		SetVertical( nSId );
		break;

	case SID_AUTOFORMAT:
	case SID_TABLE_SORT_DIALOG:
	case SID_TABLE_AUTOSUM:
	default:
		break;

	case SID_TABLE_STYLE:
		SetTableStyle( rReq.GetArgs() );
		break;

	case SID_TABLE_STYLE_SETTINGS:
		SetTableStyleSettings( rReq.GetArgs() );
		break;
	}
}

void SvxTableController::SetTableStyle( const SfxItemSet* pArgs )
{
	SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
	SdrModel* pModel = pTableObj ? pTableObj->GetModel() : 0;

	if( !pTableObj || !pModel || !pArgs || (SFX_ITEM_SET != pArgs->GetItemState(SID_TABLE_STYLE, sal_False)) )
		return;

	const SfxStringItem* pArg = dynamic_cast< const SfxStringItem* >( &pArgs->Get( SID_TABLE_STYLE ) );
	if( pArg && mxTable.is() ) try
	{
		Reference< XStyleFamiliesSupplier > xSFS( pModel->getUnoModel(), UNO_QUERY_THROW );
		Reference< XNameAccess > xFamilyNameAccess( xSFS->getStyleFamilies(), UNO_QUERY_THROW );
		const OUString sFamilyName( RTL_CONSTASCII_USTRINGPARAM( "table" ) );
		Reference< XNameAccess > xTableFamilyAccess( xFamilyNameAccess->getByName( sFamilyName ), UNO_QUERY_THROW );

		if( xTableFamilyAccess->hasByName( pArg->GetValue() ) )
		{
			// found table style with the same name
			Reference< XIndexAccess > xNewTableStyle( xTableFamilyAccess->getByName( pArg->GetValue() ), UNO_QUERY_THROW );

			const bool bUndo = pModel->IsUndoEnabled();

			if( bUndo )
			{
				pModel->BegUndo( ImpGetResStr(STR_TABLE_STYLE) );
				pModel->AddUndo( new TableStyleUndo( *pTableObj ) );
			}

			pTableObj->setTableStyle( xNewTableStyle );

			const sal_Int32 nRowCount = mxTable->getRowCount();
			const sal_Int32 nColCount = mxTable->getColumnCount();
			for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
			{
				for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ ) try
				{
					CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
					if( xCell.is() )
					{
                        SfxItemSet aSet( xCell->GetItemSet() );
                        bool bChanges = false;                        
	                    const SfxItemSet& rStyleAttribs = xCell->GetStyleSheet()->GetItemSet();

	                    for ( sal_uInt16 nWhich = SDRATTR_START; nWhich <= SDRATTR_TABLE_LAST; nWhich++ )
	                    {
		                    if( (rStyleAttribs.GetItemState( nWhich ) == SFX_ITEM_ON) && (aSet.GetItemState( nWhich ) == SFX_ITEM_ON) )
		                    {
			                    aSet.ClearItem( nWhich );					
			                    bChanges = true;
			                }
	                    }
	                    
	                    if( bChanges )
	                    {
						    if( bUndo )
							    xCell->AddUndo();
							    
							xCell->SetMergedItemSetAndBroadcast( aSet, sal_True );	                    
	                    }
                    }
				}
				catch( Exception& e )
				{
					(void)e;
					DBG_ERROR( "svx::SvxTableController::SetTableStyle(), exception caught!" );
				}
			}

			if( bUndo )
				pModel->EndUndo();
		}
	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR( "svx::SvxTableController::SetTableStyle(), exception caught!" );
	}
}

void SvxTableController::SetTableStyleSettings( const SfxItemSet* pArgs )
{
	SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
	SdrModel* pModel = pTableObj ? pTableObj->GetModel() : 0;

	if( !pTableObj || !pModel )
		return;

	TableStyleSettings aSettings( pTableObj->getTableStyleSettings() );

	const SfxPoolItem *pPoolItem=NULL;

	if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEFIRSTROWSTYLE, sal_False,&pPoolItem)) )
		aSettings.mbUseFirstRow = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();

	if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USELASTROWSTYLE, sal_False,&pPoolItem)) )
		aSettings.mbUseLastRow = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();

	if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEBANDINGROWSTYLE, sal_False,&pPoolItem)) )
		aSettings.mbUseRowBanding = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();

	if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEFIRSTCOLUMNSTYLE, sal_False,&pPoolItem)) )
		aSettings.mbUseFirstColumn = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();

	if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USELASTCOLUMNSTYLE, sal_False,&pPoolItem)) )
		aSettings.mbUseLastColumn = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();

	if( (SFX_ITEM_SET == pArgs->GetItemState(ID_VAL_USEBANDINGCOLUMNSTYLE, sal_False,&pPoolItem)) )
		aSettings.mbUseColumnBanding = static_cast< const SfxBoolItem* >(pPoolItem)->GetValue();

	if( aSettings == pTableObj->getTableStyleSettings() )
		return;

	const bool bUndo = pModel->IsUndoEnabled();

	if( bUndo )
	{
		pModel->BegUndo( ImpGetResStr(STR_TABLE_STYLE_SETTINGS) );
		pModel->AddUndo( new TableStyleUndo( *pTableObj ) );
	}

	pTableObj->setTableStyleSettings( aSettings );

	if( bUndo )
		pModel->EndUndo();
}

void SvxTableController::SetVertical( sal_uInt16 nSId )
{
	SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
	if( mxTable.is() && pTableObj )
	{
		TableModelNotifyGuard aGuard( mxTable.get() );

		CellPos aStart, aEnd;
		getSelectedCells( aStart, aEnd );

		SdrTextVertAdjust eAdj = SDRTEXTVERTADJUST_TOP;

		switch( nSId )
		{
			case SID_TABLE_VERT_BOTTOM:
				eAdj = SDRTEXTVERTADJUST_BOTTOM;
				break;
			case SID_TABLE_VERT_CENTER:
				eAdj = SDRTEXTVERTADJUST_CENTER;
				break;
			//case SID_TABLE_VERT_NONE:
			default:
				break;
		}

		SdrTextVertAdjustItem aItem( eAdj );

		for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
		{
			for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
			{
				CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
				if( xCell.is() )
					xCell->SetMergedItem(aItem);
			}
		}

		UpdateTableShape();
	}
}

void SvxTableController::MergeMarkedCells()
{
	CellPos aStart, aEnd;
	getSelectedCells( aStart, aEnd );
	SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
	if( pTableObj )
	{
	    if( pTableObj->IsTextEditActive() )
		    mpView->SdrEndTextEdit(sal_True);

        TableModelNotifyGuard aGuard( mxTable.get() );
		MergeRange( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow );
	}
}

void SvxTableController::SplitMarkedCells()
{
	if( mxTable.is() )
	{
		CellPos aStart, aEnd;
		getSelectedCells( aStart, aEnd );

		SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
		std::auto_ptr< SvxAbstractSplittTableDialog > xDlg( pFact ? pFact->CreateSvxSplittTableDialog( NULL, false, 99, 99 ) : 0 );
		if( xDlg.get() && xDlg->Execute() )
		{
			const sal_Int32 nCount = xDlg->GetCount() - 1;
			if( nCount < 1 )
				return;

			getSelectedCells( aStart, aEnd );

			Reference< XMergeableCellRange > xRange( mxTable->createCursorByRange( mxTable->getCellRangeByPosition( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow ) ), UNO_QUERY_THROW );

			const sal_Int32 nRowCount = mxTable->getRowCount();
			const sal_Int32 nColCount = mxTable->getColumnCount();


			SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
			if( pTableObj )
			{
        	    if( pTableObj->IsTextEditActive() )
		            mpView->SdrEndTextEdit(sal_True);

                TableModelNotifyGuard aGuard( mxTable.get() );

				const bool bUndo = mpModel && mpModel->IsUndoEnabled();
				if( bUndo )
				{
					mpModel->BegUndo( ImpGetResStr(STR_TABLE_SPLIT) );
					mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
				}

				if( xDlg->IsHorizontal() )
				{
					xRange->split( 0, nCount );
				}
				else
				{
					xRange->split( nCount, 0 );
				}

				if( bUndo )
					mpModel->EndUndo();
			}
			aEnd.mnRow += mxTable->getRowCount() - nRowCount;
			aEnd.mnCol += mxTable->getColumnCount() - nColCount;

			setSelectedCells( aStart, aEnd );
		}
	}
}

void SvxTableController::DistributeColumns()
{
	SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
	if( pTableObj )
	{
		const bool bUndo = mpModel && mpModel->IsUndoEnabled();
		if( bUndo )
		{
			mpModel->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_COLUMNS) );
			mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
		}

		CellPos aStart, aEnd;
		getSelectedCells( aStart, aEnd );
		pTableObj->DistributeColumns( aStart.mnCol, aEnd.mnCol );

		if( bUndo )
			mpModel->EndUndo();
	}
}

void SvxTableController::DistributeRows()
{
	SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >( mxTableObj.get() );
	if( pTableObj )
	{
		const bool bUndo = mpModel && mpModel->IsUndoEnabled();
		if( bUndo )
		{
			mpModel->BegUndo( ImpGetResStr(STR_TABLE_DISTRIBUTE_ROWS) );
			mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*pTableObj) );
		}

		CellPos aStart, aEnd;
		getSelectedCells( aStart, aEnd );
		pTableObj->DistributeRows( aStart.mnRow, aEnd.mnRow );

		if( bUndo )
			mpModel->EndUndo();
	}
}

bool SvxTableController::DeleteMarked()
{
	if( mbCellSelectionMode )
	{
		if( mxTable.is() )
		{
			CellPos aStart, aEnd;
			getSelectedCells( aStart, aEnd );
			for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
			{
				for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
				{
					CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
					if( xCell.is() )
						xCell->SetOutlinerParaObject( 0 );
				}
			}

			UpdateTableShape();
			return true;
		}
	}

	return false;
}

bool SvxTableController::GetStyleSheet( SfxStyleSheet*& rpStyleSheet ) const
{
	if( hasSelectedCells() )
	{
		rpStyleSheet = 0;

		if( mxTable.is() )
		{
			SfxStyleSheet* pRet=0;
			bool b1st=true;

			CellPos aStart, aEnd;
			const_cast<SvxTableController&>(*this).getSelectedCells( aStart, aEnd );

			for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
			{
				for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
				{
					CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
					if( xCell.is() )
					{
						SfxStyleSheet* pSS=xCell->GetStyleSheet();
						if(b1st)
						{
							pRet=pSS;
						}
						else if(pRet != pSS)
						{
							return true;
						}
						b1st=false;
					}
				}
			}
			rpStyleSheet = pRet;
			return true;
		}
	}
	return false;
}

bool SvxTableController::SetStyleSheet( SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr )
{
	if( hasSelectedCells() && (!pStyleSheet || pStyleSheet->GetFamily() == SFX_STYLE_FAMILY_FRAME) )
	{
		if( mxTable.is() )
		{
			CellPos aStart, aEnd;
			getSelectedCells( aStart, aEnd );

			for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
			{
				for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
				{
					CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
					if( xCell.is() )
						xCell->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
				}
			}

			UpdateTableShape();
			return true;
		}
	}
	return false;
}

// --------------------------------------------------------------------
// internals
// --------------------------------------------------------------------

bool SvxTableController::checkTableObject()
{
	return mxTableObj.is();
}

// --------------------------------------------------------------------

sal_uInt16 SvxTableController::getKeyboardAction( const KeyEvent& rKEvt, Window* /*pWindow*/ )
{
	const bool bMod1 = rKEvt.GetKeyCode().IsMod1(); // ctrl
	const bool bMod2 = rKEvt.GetKeyCode().IsMod2() != 0; // Alt

	const bool bTextEdit = mpView->IsTextEdit();

	sal_uInt16 nAction = ACTION_HANDLED_BY_VIEW;

	::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
	if( !pTableObj )
		return nAction;

	// handle special keys
	const sal_Int16 nCode = rKEvt.GetKeyCode().GetCode();
	switch( nCode )
	{
	case awt::Key::ESCAPE:			// handle escape
	{
		if( bTextEdit )
		{
			// escape during text edit ends text edit
			nAction = ACTION_STOP_TEXT_EDIT;
		}
		if( mbCellSelectionMode )
		{
			// escape with selected cells removes selection
			nAction = ACTION_REMOVE_SELECTION;
		}
		break;
	}
	case awt::Key::RETURN:		// handle return
	{
		if( !bMod1 && !bMod2 && !bTextEdit )
		{
			// when not already editing, return starts text edit
			setSelectionStart( pTableObj->getFirstCell() );
			nAction = ACTION_EDIT_CELL;
		}
		break;
	}
	case awt::Key::F2:			// f2 toggles text edit
	{
		if( bMod1 || bMod2 )	// f2 with modifiers is handled by the view
		{
		}
		else if( bTextEdit )
		{
			// f2 during text edit stops text edit
			nAction = ACTION_STOP_TEXT_EDIT;
		}
		else if( mbCellSelectionMode )
		{
			// f2 with selected cells removes selection
			nAction = ACTION_REMOVE_SELECTION;
		}
		else
		{
			// f2 with no selection and no text edit starts text edit
			setSelectionStart( pTableObj->getFirstCell() );
			nAction = ACTION_EDIT_CELL;
		}
		break;
	}
	case awt::Key::HOME:
	case awt::Key::NUM7:
	{
		if( (bMod1 ||  bMod2) && (bTextEdit || mbCellSelectionMode) )
		{
			if( bMod1 && !bMod2 )
			{
				// strg + home jumps to first cell
				nAction = ACTION_GOTO_FIRST_CELL;
			}
			else if( !bMod1 && bMod2 )
			{
				// alt + home jumps to first column
				nAction = ACTION_GOTO_FIRST_COLUMN;
			}
		}
		break;
	}
	case awt::Key::END:
	case awt::Key::NUM1:
	{
		if( (bMod1 ||  bMod2) && (bTextEdit || mbCellSelectionMode) )
		{
			if( bMod1 && !bMod2 )
			{
				// strg + end jumps to last cell
				nAction = ACTION_GOTO_LAST_CELL;
			}
			else if( !bMod1 && bMod2 )
			{
				// alt + home jumps to last column
				nAction = ACTION_GOTO_LAST_COLUMN;
			}
		}
		break;
	}

	case awt::Key::TAB:
	{
		if( bTextEdit || mbCellSelectionMode )
			nAction = ACTION_TAB;
		break;
	}

	case awt::Key::UP:
	case awt::Key::NUM8:
	case awt::Key::DOWN:
	case awt::Key::NUM2:
	case awt::Key::LEFT:
	case awt::Key::NUM4:
	case awt::Key::RIGHT:
	case awt::Key::NUM6:
	{
		bool bTextMove = false;

		if( !bMod1 && bMod2 )
		{
			if( (nCode == awt::Key::UP) || (nCode == awt::Key::NUM8) )
			{
				nAction = ACTION_GOTO_LEFT_CELL;
			}
			else if( (nCode == awt::Key::DOWN) || (nCode == awt::Key::NUM2) )
			{
				nAction = ACTION_GOTO_RIGHT_CELL;
			}
			break;
		}

		if( !bTextMove )
		{
			OutlinerView* pOLV = mpView->GetTextEditOutlinerView();
			if( pOLV )
			{
				RemoveSelection();
				// during text edit, check if we navigate out of the cell
				ESelection aOldSelection = pOLV->GetSelection();
				pOLV->PostKeyEvent(rKEvt);
				bTextMove = pOLV && ( aOldSelection.IsEqual(pOLV->GetSelection()) );
				if( !bTextMove )
				{
					nAction = ACTION_NONE;
				}
			}
		}
		
		if( mbCellSelectionMode || bTextMove )
		{
			// no text edit, navigate in cells if selection active
			switch( nCode )
			{
			case awt::Key::LEFT:
			case awt::Key::NUM4:
				nAction = ACTION_GOTO_LEFT_CELL;
				break;
			case awt::Key::RIGHT:
			case awt::Key::NUM6:
				nAction = ACTION_GOTO_RIGHT_CELL;
				break;
			case awt::Key::DOWN:
			case awt::Key::NUM2:
				nAction = ACTION_GOTO_DOWN_CELL;
				break;
			case awt::Key::UP:
			case awt::Key::NUM8:
				nAction = ACTION_GOTO_UP_CELL;
				break;
			}
		}
		break;
	}
	case awt::Key::PAGEUP:
		if( bMod2 )
			nAction = ACTION_GOTO_FIRST_ROW;
		break;

	case awt::Key::PAGEDOWN:
		if( bMod2 )
			nAction = ACTION_GOTO_LAST_ROW;
		break;
	}
	return nAction;
}

bool SvxTableController::executeAction( sal_uInt16 nAction, bool bSelect, Window* pWindow )
{
	::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
	if( !pTableObj )
		return false;

	switch( nAction )
	{
	case ACTION_GOTO_FIRST_CELL:
	{
		gotoCell( pTableObj->getFirstCell(), bSelect, pWindow, nAction );
		break;
	}

	case ACTION_GOTO_LEFT_CELL:
	{
		gotoCell( pTableObj->getLeftCell( getSelectionEnd(), !bSelect ), bSelect, pWindow, nAction );
		break;
	}

	case ACTION_GOTO_RIGHT_CELL:
	{
		gotoCell( pTableObj->getRightCell( getSelectionEnd(), !bSelect ), bSelect, pWindow, nAction);
		break;
	}

	case ACTION_GOTO_LAST_CELL:
	{
		gotoCell( pTableObj->getLastCell(), bSelect, pWindow, nAction );
		break;
	}

	case ACTION_GOTO_FIRST_COLUMN:
	{
		CellPos aPos( pTableObj->getFirstCell().mnCol, getSelectionEnd().mnRow );
		gotoCell( aPos, bSelect, pWindow, nAction );
		break;
	}

	case ACTION_GOTO_LAST_COLUMN:
	{
		CellPos aPos( pTableObj->getLastCell().mnCol, getSelectionEnd().mnRow );
		gotoCell( aPos, bSelect, pWindow, nAction );
		break;
	}

	case ACTION_GOTO_FIRST_ROW:
	{
		CellPos aPos( getSelectionEnd().mnCol, pTableObj->getFirstCell().mnRow );
		gotoCell( aPos, bSelect, pWindow, nAction );
		break;
	}

	case ACTION_GOTO_UP_CELL:
	{
		gotoCell( pTableObj->getUpCell(getSelectionEnd(), !bSelect), bSelect, pWindow, nAction );
		break;
	}

	case ACTION_GOTO_DOWN_CELL:
	{
		gotoCell( pTableObj->getDownCell(getSelectionEnd(), !bSelect), bSelect, pWindow, nAction );
		break;
	}

	case ACTION_GOTO_LAST_ROW:
	{
		CellPos aPos( getSelectionEnd().mnCol, pTableObj->getLastCell().mnRow );
		gotoCell( aPos, bSelect, pWindow, nAction );
		break;
	}

	case ACTION_EDIT_CELL:
		EditCell( getSelectionStart(), pWindow, 0, nAction );
		break;

	case ACTION_STOP_TEXT_EDIT:
		StopTextEdit();
		break;

	case ACTION_REMOVE_SELECTION:
		RemoveSelection();
		break;

	case ACTION_START_SELECTION:
		StartSelection( getSelectionStart() );
		break;

	case ACTION_TAB:
	{
		if( bSelect )
			gotoCell( pTableObj->getPreviousCell( getSelectionEnd(), true ), false, pWindow, nAction );
		else
        {
            CellPos aSelectionEnd( getSelectionEnd() );
            CellPos aNextCell( pTableObj->getNextCell( aSelectionEnd, true ) );
            if( aSelectionEnd == aNextCell )
            {
                onInsert( SID_TABLE_INSERT_ROW, 0 );
                aNextCell = pTableObj->getNextCell( aSelectionEnd, true );
            }
			gotoCell( aNextCell, false, pWindow, nAction );
        }
		break;
	}
	}

	return nAction != ACTION_HANDLED_BY_VIEW;
}

// --------------------------------------------------------------------

void SvxTableController::gotoCell( const CellPos& rPos, bool bSelect, Window* pWindow, sal_uInt16 nAction )
{
	if( mxTableObj.is() && static_cast<SdrTableObj*>(mxTableObj.get())->IsTextEditActive() )
		mpView->SdrEndTextEdit(sal_True);

	if( bSelect )
	{
		maCursorLastPos = rPos;
		if( mxTableObj.is() )
			static_cast< SdrTableObj* >( mxTableObj.get() )->setActiveCell( rPos );
		
		if( !mbCellSelectionMode )
		{
			setSelectedCells( maCursorFirstPos, rPos );
		}
		else
		{
			UpdateSelection( rPos );
		}
	}
	else
	{
		RemoveSelection();
		EditCell( rPos, pWindow, 0, nAction );
	}
}

// --------------------------------------------------------------------

const CellPos& SvxTableController::getSelectionStart()
{
	checkCell( maCursorFirstPos );
	return maCursorFirstPos;
}

// --------------------------------------------------------------------

void SvxTableController::setSelectionStart( const CellPos& rPos )
{
	maCursorFirstPos = rPos;
}

// --------------------------------------------------------------------

const CellPos& SvxTableController::getSelectionEnd()
{
	checkCell( maCursorLastPos );
	return maCursorLastPos;
}

// --------------------------------------------------------------------

Reference< XCellCursor > SvxTableController::getSelectionCursor()
{
	Reference< XCellCursor > xCursor;

	if( mxTable.is() )
	{
		if( hasSelectedCells() )
		{
			CellPos aStart, aEnd;
			getSelectedCells( aStart, aEnd );
			xCursor = mxTable->createCursorByRange( mxTable->getCellRangeByPosition( aStart.mnCol, aStart.mnRow, aEnd.mnCol, aEnd.mnRow ) );
		}
		else
		{
			xCursor = mxTable->createCursor();
		}
	}

	return xCursor;
}

void SvxTableController::MergeRange( sal_Int32 nFirstCol, sal_Int32 nFirstRow, sal_Int32 nLastCol, sal_Int32 nLastRow )
{
	if( mxTable.is() ) try
	{
		Reference< XMergeableCellRange > xRange( mxTable->createCursorByRange( mxTable->getCellRangeByPosition( nFirstCol, nFirstRow,nLastCol, nLastRow ) ), UNO_QUERY_THROW );
		if( xRange->isMergeable() )
		{
			const bool bUndo = mpModel && mpModel->IsUndoEnabled();
			if( bUndo )
			{
				mpModel->BegUndo( ImpGetResStr(STR_TABLE_MERGE) );
				mpModel->AddUndo( mpModel->GetSdrUndoFactory().CreateUndoGeoObject(*mxTableObj.get()) );
			}

			xRange->merge();

			if( bUndo )
				mpModel->EndUndo();
		}
	}
	catch( Exception& )
	{
		DBG_ASSERT( false, "sdr::table::SvxTableController::MergeRange(), exception caught!" );
	}
}



// --------------------------------------------------------------------

void SvxTableController::checkCell( CellPos& rPos )
{
	if( mxTable.is() ) try
	{
		if( rPos.mnCol >= mxTable->getColumnCount() )
			rPos.mnCol = mxTable->getColumnCount()-1;

		if( rPos.mnRow >= mxTable->getRowCount() )
			rPos.mnRow = mxTable->getRowCount()-1;
	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR("sdr::table::SvxTableController::checkCell(), exception caught!" );
	}
}

// --------------------------------------------------------------------

void SvxTableController::findMergeOrigin( CellPos& rPos )
{
	if( mxTable.is() ) try
	{
		Reference< XMergeableCell > xCell( mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ), UNO_QUERY_THROW );
		if( xCell.is() && xCell->isMerged() )
		{
			::findMergeOrigin( mxTable, rPos.mnCol, rPos.mnRow, rPos.mnCol, rPos.mnRow );
		}
	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR("sdr::table::SvxTableController::findMergeOrigin(), exception caught!" );
	}
}

// --------------------------------------------------------------------

void SvxTableController::EditCell( const CellPos& rPos, ::Window* pWindow, const awt::MouseEvent* pMouseEvent /*= 0*/, sal_uInt16 nAction /*= ACTION_NONE */ )
{
	SdrPageView* pPV = mpView->GetSdrPageView();

	::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
	if( pTableObj && pTableObj->GetPage() == pPV->GetPage() )
	{
		bool bEmptyOutliner = false;

		if(!pTableObj->GetOutlinerParaObject() && mpView->GetTextEditOutliner())
		{
			::Outliner* pOutl = mpView->GetTextEditOutliner();
			sal_uIntPtr nParaAnz = pOutl->GetParagraphCount();
			Paragraph* p1stPara = pOutl->GetParagraph( 0 );

			if(nParaAnz==1 && p1stPara)
			{
				// Bei nur einem Pararaph
				if (pOutl->GetText(p1stPara).Len() == 0)
				{
					bEmptyOutliner = true;
				}
			}
		}

		CellPos aPos( rPos );
		findMergeOrigin( aPos );

		if( pTableObj != mpView->GetTextEditObject() || bEmptyOutliner || !pTableObj->IsTextEditActive( aPos ) )
		{
			if( pTableObj->IsTextEditActive() )
				mpView->SdrEndTextEdit(sal_True);

			pTableObj->setActiveCell( aPos );

			// create new outliner, owner will be the SdrObjEditView
			SdrOutliner* pOutl = SdrMakeOutliner( OUTLINERMODE_OUTLINEOBJECT, mpModel );
			if( pTableObj->IsVerticalWriting() )
				pOutl->SetVertical( sal_True );

			if(mpView->SdrBeginTextEdit(pTableObj, pPV, pWindow, sal_True, pOutl))
			{
				maCursorLastPos = maCursorFirstPos = rPos;

				OutlinerView* pOLV = mpView->GetTextEditOutlinerView();

				bool bNoSel = true;

				if( pMouseEvent )
				{
					::MouseEvent aMEvt( *pMouseEvent );

					SdrViewEvent aVEvt;
					SdrHitKind eHit = mpView->PickAnything(aMEvt, SDRMOUSEBUTTONDOWN, aVEvt);

					if (eHit == SDRHIT_TEXTEDIT)
					{
						// Text getroffen
						pOLV->MouseButtonDown(aMEvt);
						pOLV->MouseMove(aMEvt);
						pOLV->MouseButtonUp(aMEvt);
//						pOLV->MouseButtonDown(aMEvt);
						bNoSel = false;
					}
					else
					{
						nAction = ACTION_GOTO_LEFT_CELL;
					}
				}

				if( bNoSel )
				{
					// Move cursor to end of text
					ESelection aNewSelection;

					const WritingMode eMode = pTableObj->GetWritingMode();
					if( ((nAction == ACTION_GOTO_LEFT_CELL) || (nAction == ACTION_GOTO_RIGHT_CELL)) && (eMode != WritingMode_TB_RL) )
					{
						const bool bLast = ((nAction == ACTION_GOTO_LEFT_CELL) && (eMode == WritingMode_LR_TB)) ||
											 ((nAction == ACTION_GOTO_RIGHT_CELL) && (eMode == WritingMode_RL_TB));

						if( bLast )
							aNewSelection = ESelection(EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND, EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND);
					}
					pOLV->SetSelection(aNewSelection);
				}
			}
		}
	}
}

// --------------------------------------------------------------------

bool SvxTableController::StopTextEdit()
{
	if(mpView->IsTextEdit())
	{
		mpView->SdrEndTextEdit();
		mpView->SetCurrentObj(OBJ_TABLE);
		mpView->SetEditMode(SDREDITMODE_EDIT);
		return true;
	}
	else
	{
		return false;
	}
}

// --------------------------------------------------------------------

void SvxTableController::DeleteTable()
{
	//
}

// --------------------------------------------------------------------

void SvxTableController::getSelectedCells( CellPos& rFirst, CellPos& rLast )
{
	if( mbCellSelectionMode )
	{
		checkCell( maCursorFirstPos );
		checkCell( maCursorLastPos );

		rFirst.mnCol = std::min( maCursorFirstPos.mnCol, maCursorLastPos.mnCol );
		rFirst.mnRow = std::min( maCursorFirstPos.mnRow, maCursorLastPos.mnRow );
		rLast.mnCol = std::max( maCursorFirstPos.mnCol, maCursorLastPos.mnCol );
		rLast.mnRow = std::max( maCursorFirstPos.mnRow, maCursorLastPos.mnRow );

		bool bExt = false;
		if( mxTable.is() ) do
		{
			bExt = false;
			for( sal_Int32 nRow = rFirst.mnRow; nRow <= rLast.mnRow && !bExt; nRow++ )
			{
				for( sal_Int32 nCol = rFirst.mnCol; nCol <= rLast.mnCol && !bExt; nCol++ )
				{
					Reference< XMergeableCell > xCell( mxTable->getCellByPosition( nCol, nRow ), UNO_QUERY );
					if( !xCell.is() )
						continue;
						
					if( xCell->isMerged() )
					{
						CellPos aPos( nCol, nRow );
						findMergeOrigin( aPos );
						if( (aPos.mnCol < rFirst.mnCol) || (aPos.mnRow < rFirst.mnRow) )
						{
							rFirst.mnCol = std::min( rFirst.mnCol, aPos.mnCol );
							rFirst.mnRow = std::min( rFirst.mnRow, aPos.mnRow );
							bExt = true;
						}
					}
					else
					{
						if( ((nCol + xCell->getColumnSpan() - 1) > rLast.mnCol) || (nRow + xCell->getRowSpan() - 1 ) > rLast.mnRow )
						{
							rLast.mnCol = std::max( rLast.mnCol, nCol + xCell->getColumnSpan() - 1 );
							rLast.mnRow = std::max( rLast.mnRow, nRow + xCell->getRowSpan() - 1 );
							bExt = true;
						}
					}
				}
			}
		}
		while(bExt);
	}
	else if( mpView && mpView->IsTextEdit() )
	{
		rFirst = getSelectionStart();
		findMergeOrigin( rFirst );
		rLast = rFirst;

		if( mxTable.is() )
		{
			Reference< XMergeableCell > xCell( mxTable->getCellByPosition( rLast.mnCol, rLast.mnRow ), UNO_QUERY );
			if( xCell.is() )
			{
				rLast.mnCol += xCell->getColumnSpan() - 1;
				rLast.mnRow += xCell->getRowSpan() - 1;
			}
		}
	}
	else
	{
		rFirst.mnCol = 0;
		rFirst.mnRow = 0;
		if( mxTable.is() )
		{
			rLast.mnRow = mxTable->getRowCount()-1;
			rLast.mnCol = mxTable->getColumnCount()-1;
		}
		else
		{
			rLast.mnRow = 0;
			rLast.mnCol = 0;
		}
	}
}

// --------------------------------------------------------------------

void SvxTableController::StartSelection( const CellPos& rPos )
{
	StopTextEdit();
	mbCellSelectionMode = true;
	maCursorLastPos = maCursorFirstPos = rPos;
	mpView->MarkListHasChanged();
}

// --------------------------------------------------------------------

void SvxTableController::setSelectedCells( const CellPos& rStart, const CellPos& rEnd )
{
	StopTextEdit();
	mbCellSelectionMode = true;
	maCursorFirstPos = rStart;
	UpdateSelection( rEnd );
}

// --------------------------------------------------------------------

void SvxTableController::UpdateSelection( const CellPos& rPos )
{
	maCursorLastPos = rPos;
	mpView->MarkListHasChanged();
}

// --------------------------------------------------------------------

void SvxTableController::clearSelection()
{
	RemoveSelection();
}

// --------------------------------------------------------------------

void SvxTableController::selectAll()
{
	if( mxTable.is() )
	{
		CellPos aPos1, aPos2( mxTable->getColumnCount()-1, mxTable->getRowCount()-1 );
		if( (aPos2.mnCol >= 0) && (aPos2.mnRow >= 0) )
		{
			setSelectedCells( aPos1, aPos2 );
		}
	}
}

// --------------------------------------------------------------------

void SvxTableController::RemoveSelection()
{
	if( mbCellSelectionMode )
	{
		mbCellSelectionMode = false;
		mpView->MarkListHasChanged();
	}
}

// --------------------------------------------------------------------

void SvxTableController::onTableModified()
{
	if( mnUpdateEvent == 0 )
		mnUpdateEvent = Application::PostUserEvent( LINK( this, SvxTableController, UpdateHdl ) );
}
// --------------------------------------------------------------------

void SvxTableController::updateSelectionOverlay()
{
	destroySelectionOverlay();
	if( mbCellSelectionMode )
	{
		::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
		if( pTableObj )
		{
			sdr::overlay::OverlayObjectCell::RangeVector aRanges;

			Rectangle aRect;
			CellPos aStart,aEnd;
			getSelectedCells( aStart, aEnd );
			pTableObj->getCellBounds( aStart, aRect );

			basegfx::B2DRange a2DRange( basegfx::B2DPoint(aRect.Left(), aRect.Top()) );
			a2DRange.expand( basegfx::B2DPoint(aRect.Right(), aRect.Bottom()) );

			findMergeOrigin( aEnd );
			pTableObj->getCellBounds( aEnd, aRect );
			a2DRange.expand( basegfx::B2DPoint(aRect.Left(), aRect.Top()) );
			a2DRange.expand( basegfx::B2DPoint(aRect.Right(), aRect.Bottom()) );
			aRanges.push_back( a2DRange );

			::Color aHighlight( COL_BLUE );
			OutputDevice* pOutDev = mpView->GetFirstOutputDevice();
			if( pOutDev )
				aHighlight = pOutDev->GetSettings().GetStyleSettings().GetHighlightColor();

			const sal_uInt32 nCount = mpView->PaintWindowCount();
			for( sal_uInt32 nIndex = 0; nIndex < nCount; nIndex++ )
			{
				SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow(nIndex);
				if( pPaintWindow )
				{
					::sdr::overlay::OverlayManager* pOverlayManager = pPaintWindow->GetOverlayManager();
					if( pOverlayManager )
					{
						// sdr::overlay::CellOverlayType eType = sdr::overlay::CELL_OVERLAY_INVERT;
						sdr::overlay::CellOverlayType eType = sdr::overlay::CELL_OVERLAY_TRANSPARENT;

						sdr::overlay::OverlayObjectCell* pOverlay = new sdr::overlay::OverlayObjectCell( eType, aHighlight, aRanges );

						pOverlayManager->add(*pOverlay);
						mpSelectionOverlay = new ::sdr::overlay::OverlayObjectList;
						mpSelectionOverlay->append(*pOverlay);
					}
				}
			}
		}
	}
}

// --------------------------------------------------------------------

void SvxTableController::destroySelectionOverlay()
{
	if( mpSelectionOverlay )
	{
		delete mpSelectionOverlay;
		mpSelectionOverlay = 0;
	}
}

// --------------------------------------------------------------------

void SvxTableController::MergeAttrFromSelectedCells(SfxItemSet& rAttr, bool bOnlyHardAttr) const
{
	if( mxTable.is() )
	{
		CellPos aStart, aEnd;
		const_cast<SvxTableController&>(*this).getSelectedCells( aStart, aEnd );

		for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
		{
			for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
			{
				CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
				if( xCell.is() && !xCell->isMerged() )
				{
					const SfxItemSet& rSet = xCell->GetItemSet();
					SfxWhichIter aIter(rSet);
					sal_uInt16 nWhich(aIter.FirstWhich());
					while(nWhich)
					{
						if(!bOnlyHardAttr)
						{
							if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, sal_False))
								rAttr.InvalidateItem(nWhich);
							else
								rAttr.MergeValue(rSet.Get(nWhich), sal_True);
						}
						else if(SFX_ITEM_SET == rSet.GetItemState(nWhich, sal_False))
						{
							const SfxPoolItem& rItem = rSet.Get(nWhich);
							rAttr.MergeValue(rItem, sal_True);
						}

						nWhich = aIter.NextWhich();
					}
				}
			}
		}
	}

	if( mpView->IsTextEdit() )
	{
	}
}

// --------------------------------------------------------------------

const sal_uInt16 CELL_BEFORE = 0x0001;
const sal_uInt16 CELL_LEFT   = 0x0002;
const sal_uInt16 CELL_RIGHT  = 0x0004;
const sal_uInt16 CELL_AFTER  = 0x0008;

const sal_uInt16 CELL_UPPER  = 0x0010;
const sal_uInt16 CELL_TOP    = 0x0020;
const sal_uInt16 CELL_BOTTOM = 0x0040;
const sal_uInt16 CELL_LOWER  = 0x0080;

// --------------------------------------------------------------------

static void ImplSetLinePreserveColor( SvxBoxItem& rNewFrame, const SvxBorderLine* pNew, sal_uInt16 nLine )
{
	if( pNew )
	{
		const SvxBorderLine* pOld = rNewFrame.GetLine(nLine);
		if( pOld )
		{
			SvxBorderLine aNewLine( *pNew );
			aNewLine.SetColor( pOld->GetColor() );
			rNewFrame.SetLine( &aNewLine, nLine );
			return;
		}
	}
	rNewFrame.SetLine( pNew, nLine );
}

// --------------------------------------------------------------------

static void ImplApplyBoxItem( sal_uInt16 nCellFlags, const SvxBoxItem* pBoxItem, const SvxBoxInfoItem* pBoxInfoItem, SvxBoxItem& rNewFrame )
{
	if( (nCellFlags & (CELL_BEFORE|CELL_AFTER|CELL_UPPER|CELL_LOWER)) != 0 )
	{
		// current cell is outside the selection

		if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER)) == 0 ) // check if its not nw or ne corner
		{
			if( nCellFlags & CELL_UPPER )
			{
				if( pBoxInfoItem->IsValid(VALID_TOP) )
					rNewFrame.SetLine(0, BOX_LINE_BOTTOM );
			}
			else if( nCellFlags & CELL_LOWER )
			{
				if( pBoxInfoItem->IsValid(VALID_BOTTOM) )
					rNewFrame.SetLine( 0, BOX_LINE_TOP );
			}
		}
		else if( (nCellFlags & ( CELL_UPPER|CELL_LOWER)) == 0 ) // check if its not sw or se corner
		{
			if( nCellFlags & CELL_BEFORE )
			{
				if( pBoxInfoItem->IsValid(VALID_LEFT) )
					rNewFrame.SetLine( 0, BOX_LINE_RIGHT );
			}
			else if( nCellFlags & CELL_AFTER )
			{
				if( pBoxInfoItem->IsValid(VALID_RIGHT) )
					rNewFrame.SetLine( 0, BOX_LINE_LEFT );
			}
		}
	}
	else
	{
		// current cell is inside the selection

		if( (nCellFlags & CELL_LEFT) ? pBoxInfoItem->IsValid(VALID_LEFT) : pBoxInfoItem->IsValid(VALID_VERT) )
			rNewFrame.SetLine( (nCellFlags & CELL_LEFT) ? pBoxItem->GetLeft() : pBoxInfoItem->GetVert(), BOX_LINE_LEFT );

		if( (nCellFlags & CELL_RIGHT) ? pBoxInfoItem->IsValid(VALID_RIGHT) : pBoxInfoItem->IsValid(VALID_VERT) )
			rNewFrame.SetLine( (nCellFlags & CELL_RIGHT) ? pBoxItem->GetRight() : pBoxInfoItem->GetVert(), BOX_LINE_RIGHT );

		if( (nCellFlags & CELL_TOP) ? pBoxInfoItem->IsValid(VALID_TOP) : pBoxInfoItem->IsValid(VALID_HORI) )
			rNewFrame.SetLine( (nCellFlags & CELL_TOP) ? pBoxItem->GetTop() : pBoxInfoItem->GetHori(), BOX_LINE_TOP );

		if( (nCellFlags & CELL_BOTTOM) ? pBoxInfoItem->IsValid(VALID_BOTTOM) : pBoxInfoItem->IsValid(VALID_HORI) )
			rNewFrame.SetLine( (nCellFlags & CELL_BOTTOM) ? pBoxItem->GetBottom() : pBoxInfoItem->GetHori(), BOX_LINE_BOTTOM );

		// apply distance to borders
		if( pBoxInfoItem->IsValid( VALID_DISTANCE ) )
			for( sal_uInt16 nLine = 0; nLine < 4; ++nLine )
				rNewFrame.SetDistance( pBoxItem->GetDistance( nLine ), nLine );
	}
}

// --------------------------------------------------------------------

static void ImplSetLineColor( SvxBoxItem& rNewFrame, sal_uInt16 nLine, const Color& rColor )
{
	const SvxBorderLine* pSourceLine = rNewFrame.GetLine( nLine );
	if( pSourceLine )
	{
		SvxBorderLine aLine( *pSourceLine );
		aLine.SetColor( rColor );
		rNewFrame.SetLine( &aLine, nLine );
	}
}

// --------------------------------------------------------------------

static void ImplApplyLineColorItem( sal_uInt16 nCellFlags, const SvxColorItem* pLineColorItem, SvxBoxItem& rNewFrame )
{
	const Color aColor( pLineColorItem->GetValue() );

	if( (nCellFlags & (CELL_LOWER|CELL_BEFORE|CELL_AFTER)) == 0 )
		ImplSetLineColor( rNewFrame, BOX_LINE_BOTTOM, aColor );

	if( (nCellFlags & (CELL_UPPER|CELL_BEFORE|CELL_AFTER)) == 0 )
		ImplSetLineColor( rNewFrame, BOX_LINE_TOP, aColor );

	if( (nCellFlags & (CELL_UPPER|CELL_LOWER|CELL_AFTER)) == 0 )
		ImplSetLineColor( rNewFrame, BOX_LINE_RIGHT, aColor );

	if( (nCellFlags & (CELL_UPPER|CELL_LOWER|CELL_BEFORE)) == 0 )
		ImplSetLineColor( rNewFrame, BOX_LINE_LEFT, aColor );
}

// --------------------------------------------------------------------

static void ImplApplyBorderLineItem( sal_uInt16 nCellFlags, const SvxBorderLine* pBorderLineItem, SvxBoxItem& rNewFrame )
{
	if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER|CELL_UPPER|CELL_LOWER)) != 0 )
	{
		if( (nCellFlags & ( CELL_BEFORE|CELL_AFTER)) == 0 ) // check if its not nw or ne corner
		{
			if( nCellFlags & CELL_UPPER )
			{
				if( rNewFrame.GetBottom() )
					ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_BOTTOM );
			}
			else if( nCellFlags & CELL_LOWER )
			{
				if( rNewFrame.GetTop() )
					ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_TOP );
			}
		}
		else if( (nCellFlags & ( CELL_UPPER|CELL_LOWER)) == 0 ) // check if its not sw or se corner
		{
			if( nCellFlags & CELL_BEFORE )
			{
				if( rNewFrame.GetRight() )
					ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_RIGHT );
			}
			else if( nCellFlags & CELL_AFTER )
			{
				if( rNewFrame.GetLeft() )
					ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_LEFT );
			}
		}
	}
	else
	{
		if( rNewFrame.GetBottom() )
			ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_BOTTOM );
		if( rNewFrame.GetTop() )
			ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_TOP );
		if( rNewFrame.GetRight() )
			ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_RIGHT );
		if( rNewFrame.GetLeft() )
			ImplSetLinePreserveColor( rNewFrame, pBorderLineItem, BOX_LINE_LEFT );
	}
}

// --------------------------------------------------------------------

void SvxTableController::ApplyBorderAttr( const SfxItemSet& rAttr )
{
	if( mxTable.is() )
	{
		const sal_Int32 nRowCount = mxTable->getRowCount();
		const sal_Int32 nColCount = mxTable->getColumnCount();
		if( nRowCount && nColCount )
		{
			const SvxBoxItem* pBoxItem = 0;
			if(SFX_ITEM_SET == rAttr.GetItemState(SDRATTR_TABLE_BORDER, sal_False) )
				pBoxItem = dynamic_cast< const SvxBoxItem* >( &rAttr.Get( SDRATTR_TABLE_BORDER ) );

			const SvxBoxInfoItem* pBoxInfoItem = 0;
			if(SFX_ITEM_SET == rAttr.GetItemState(SDRATTR_TABLE_BORDER_INNER, sal_False) )
				pBoxInfoItem = dynamic_cast< const SvxBoxInfoItem* >( &rAttr.Get( SDRATTR_TABLE_BORDER_INNER ) );

			const SvxColorItem* pLineColorItem = 0;
			if(SFX_ITEM_SET == rAttr.GetItemState(SID_FRAME_LINECOLOR, sal_False) )
				pLineColorItem = dynamic_cast< const SvxColorItem* >( &rAttr.Get( SID_FRAME_LINECOLOR ) );

			const SvxBorderLine* pBorderLineItem = 0;
			if(SFX_ITEM_SET == rAttr.GetItemState(SID_FRAME_LINESTYLE, sal_False) )
				pBorderLineItem = ((const SvxLineItem&)rAttr.Get( SID_FRAME_LINESTYLE )).GetLine();

			if( pBoxInfoItem && !pBoxItem )
			{
				const static SvxBoxItem gaEmptyBoxItem( SDRATTR_TABLE_BORDER );
				pBoxItem = &gaEmptyBoxItem;
			}
			else if( pBoxItem && !pBoxInfoItem )
			{
				const static SvxBoxInfoItem gaEmptyBoxInfoItem( SDRATTR_TABLE_BORDER_INNER );
				pBoxInfoItem = &gaEmptyBoxInfoItem;
			}

			CellPos aStart, aEnd;
			getSelectedCells( aStart, aEnd );

			const sal_Int32 nLastRow = std::min( aEnd.mnRow + 2, nRowCount );
			const sal_Int32 nLastCol = std::min( aEnd.mnCol + 2, nColCount );

			for( sal_Int32 nRow = std::max( aStart.mnRow - 1, (sal_Int32)0 ); nRow < nLastRow; nRow++ )
			{
				sal_uInt16 nRowFlags = 0;
				nRowFlags |= (nRow == aStart.mnRow) ? CELL_TOP : 0;
				nRowFlags |= (nRow == aEnd.mnRow)   ? CELL_BOTTOM : 0;
				nRowFlags |= (nRow < aStart.mnRow)  ? CELL_UPPER : 0;
				nRowFlags |= (nRow > aEnd.mnRow)    ? CELL_LOWER : 0;

				for( sal_Int32 nCol = std::max( aStart.mnCol - 1, (sal_Int32)0 ); nCol < nLastCol; nCol++ )
				{
					CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
					if( !xCell.is() )
						continue;

					const SfxItemSet& rSet = xCell->GetItemSet();
					const SvxBoxItem* pOldOuter = (const SvxBoxItem*)	  &rSet.Get( SDRATTR_TABLE_BORDER );

					SvxBoxItem aNewFrame( *pOldOuter );

					sal_uInt16 nCellFlags = nRowFlags;
					nCellFlags |= (nCol == aStart.mnCol) ? CELL_LEFT : 0;
					nCellFlags |= (nCol == aEnd.mnCol)   ? CELL_RIGHT : 0;
					nCellFlags |= (nCol < aStart.mnCol)  ? CELL_BEFORE : 0;
					nCellFlags |= (nCol > aEnd.mnCol)    ? CELL_AFTER : 0;

					if( pBoxItem && pBoxInfoItem )
						ImplApplyBoxItem( nCellFlags, pBoxItem, pBoxInfoItem, aNewFrame );

					if( pLineColorItem )
						ImplApplyLineColorItem( nCellFlags, pLineColorItem, aNewFrame );

					if( pBorderLineItem )
						ImplApplyBorderLineItem( nCellFlags, pBorderLineItem, aNewFrame );

					if (aNewFrame != *pOldOuter)
					{
						SfxItemSet aAttr(*rSet.GetPool(), rSet.GetRanges());
						aAttr.Put(aNewFrame);
						xCell->SetMergedItemSetAndBroadcast( aAttr, false );
					}
				}
			}
		}
	}
}

// --------------------------------------------------------------------

void SvxTableController::UpdateTableShape()
{
	SdrObject* pTableObj = mxTableObj.get();
	if( pTableObj )
	{
		pTableObj->ActionChanged();
		pTableObj->BroadcastObjectChange();
	}
	updateSelectionOverlay();
}


// --------------------------------------------------------------------

void SvxTableController::SetAttrToSelectedCells(const SfxItemSet& rAttr, bool bReplaceAll)
{
	if( mxTable.is() )
	{
		const bool bUndo = mpModel && mpModel->IsUndoEnabled();

		if( bUndo )
			mpModel->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT) );

		CellPos aStart, aEnd;
		getSelectedCells( aStart, aEnd );

		SfxItemSet aAttr(*rAttr.GetPool(), rAttr.GetRanges());
		aAttr.Put(rAttr, sal_True);

		const bool bFrame = (rAttr.GetItemState( SDRATTR_TABLE_BORDER ) == SFX_ITEM_SET) || (rAttr.GetItemState( SDRATTR_TABLE_BORDER_INNER ) == SFX_ITEM_SET);

		if( bFrame )
		{
			aAttr.ClearItem( SDRATTR_TABLE_BORDER );
			aAttr.ClearItem( SDRATTR_TABLE_BORDER_INNER );
		}

		for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
		{
			for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
			{
				CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
				if( xCell.is() )
				{
					if( bUndo )
						xCell->AddUndo();
					xCell->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll);
				}
			}
		}

		if( bFrame )
		{
			ApplyBorderAttr( rAttr );
		}

		UpdateTableShape();

		if( bUndo )
			mpModel->EndUndo();

	}
}

// --------------------------------------------------------------------

bool SvxTableController::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const
{
	if( mxTableObj.is() && hasSelectedCells() )
	{
		MergeAttrFromSelectedCells( rTargetSet, bOnlyHardAttr );

		if( mpView->IsTextEdit() )
		{
			if( mxTableObj->GetOutlinerParaObject() )
				rTargetSet.Put( SvxScriptTypeItem( mxTableObj->GetOutlinerParaObject()->GetTextObject().GetScriptType() ) );

			OutlinerView* pTextEditOutlinerView = mpView->GetTextEditOutlinerView();
			if(pTextEditOutlinerView)
			{
				// FALSE= InvalidItems nicht al Default, sondern als "Loecher" betrachten
				rTargetSet.Put(pTextEditOutlinerView->GetAttribs(), sal_False);
				rTargetSet.Put( SvxScriptTypeItem( pTextEditOutlinerView->GetSelectedScriptType() ), sal_False );
			}
		}

		return true;
	}
	else
	{
		return false;
	}
}

// --------------------------------------------------------------------

bool SvxTableController::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll)
{
	if( mbCellSelectionMode || mpView->IsTextEdit()  )
	{
		SetAttrToSelectedCells( rSet, bReplaceAll );
		return true;
	}
	return false;
}

// --------------------------------------------------------------------

bool SvxTableController::GetMarkedObjModel( SdrPage* pNewPage )
{
	if( mxTableObj.is() && mbCellSelectionMode && pNewPage ) try
	{
		::sdr::table::SdrTableObj& rTableObj = *static_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );

		CellPos aStart, aEnd;
		getSelectedCells( aStart, aEnd );

		SdrTableObj* pNewTableObj = rTableObj.CloneRange( aStart, aEnd );

		pNewTableObj->SetPage( pNewPage );
		pNewTableObj->SetModel( pNewPage->GetModel() );

		SdrInsertReason aReason(SDRREASON_VIEWCALL);
		pNewPage->InsertObject(pNewTableObj,CONTAINER_APPEND,&aReason);
		
		return true;
	}
	catch( Exception& )
	{
		DBG_ERROR( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" );
	}
	return false;
}

// --------------------------------------------------------------------

bool SvxTableController::PasteObjModel( const SdrModel& rModel )
{
	if( mxTableObj.is() && mpView && (rModel.GetPageCount() >= 1) )
	{
		const SdrPage* pPastePage = rModel.GetPage(0);
		if( pPastePage && pPastePage->GetObjCount() == 1 )
		{
			SdrTableObj* pPasteTableObj = dynamic_cast< SdrTableObj* >( pPastePage->GetObj(0) );
			if( pPasteTableObj )
			{
				return PasteObject( pPasteTableObj );
			}
		}
	}

	return false;
}

// --------------------------------------------------------------------

bool SvxTableController::PasteObject( SdrTableObj* pPasteTableObj )
{
	if( !pPasteTableObj )
		return false;

	Reference< XTable > xPasteTable( pPasteTableObj->getTable() );
	if( !xPasteTable.is() )
		return false;

	if( !mxTable.is() )
		return false;

	sal_Int32 nPasteColumns = xPasteTable->getColumnCount();
	sal_Int32 nPasteRows = xPasteTable->getRowCount();

	CellPos aStart, aEnd;
	getSelectedCells( aStart, aEnd );

	if( mpView->IsTextEdit() )
		mpView->SdrEndTextEdit(sal_True);

	sal_Int32 nColumns = mxTable->getColumnCount();
	sal_Int32 nRows = mxTable->getRowCount();

	const sal_Int32 nMissing = nPasteRows - ( nRows - aStart.mnRow );
	if( nMissing > 0 )
	{
		Reference< XTableRows > xRows( mxTable->getRows() );
		xRows->insertByIndex( nRows, nMissing );
		nRows = mxTable->getRowCount();
	}

	nPasteRows = std::min( nPasteRows, nRows - aStart.mnRow );
	nPasteColumns = std::min( nPasteColumns, nColumns - aStart.mnCol );

	// copy cell contents
	for( sal_Int32 nRow = 0; nRow < nPasteRows; ++nRow )
	{
		for( sal_Int32 nCol = 0; nCol < nPasteColumns; ++nCol )
		{
			CellRef xTargetCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( aStart.mnCol + nCol, aStart.mnRow + nRow ).get() ) );
			if( xTargetCell.is() && !xTargetCell->isMerged() )
			{
				xTargetCell->AddUndo();
				xTargetCell->cloneFrom( dynamic_cast< Cell* >( xPasteTable->getCellByPosition( nCol, nRow ).get() ) );
				nCol += xTargetCell->getColumnSpan() - 1;
			}
		}
	}

	UpdateTableShape();

	return true;
}

bool SvxTableController::TakeFormatPaintBrush( boost::shared_ptr< SfxItemSet >& /*rFormatSet*/  )
{
    // SdrView::TakeFormatPaintBrush() is enough
    return false;
}

bool SvxTableController::ApplyFormatPaintBrush( SfxItemSet& rFormatSet, bool bNoCharacterFormats, bool bNoParagraphFormats )
{
	if( mbCellSelectionMode )
	{
    	SdrTextObj* pTableObj = dynamic_cast<SdrTextObj*>( mxTableObj.get() );
    	if( !pTableObj )
    	    return false;
	
		const bool bUndo = mpModel && mpModel->IsUndoEnabled();

		if( bUndo )
			mpModel->BegUndo( ImpGetResStr(STR_TABLE_NUMFORMAT) );

		CellPos aStart, aEnd;
		getSelectedCells( aStart, aEnd );

		SfxItemSet aAttr(*rFormatSet.GetPool(), rFormatSet.GetRanges());
		aAttr.Put(rFormatSet, sal_True);

		const bool bFrame = (rFormatSet.GetItemState( SDRATTR_TABLE_BORDER ) == SFX_ITEM_SET) || (rFormatSet.GetItemState( SDRATTR_TABLE_BORDER_INNER ) == SFX_ITEM_SET);

		if( bFrame )
		{
			aAttr.ClearItem( SDRATTR_TABLE_BORDER );
			aAttr.ClearItem( SDRATTR_TABLE_BORDER_INNER );
		}
		
        const sal_uInt16* pRanges = rFormatSet.GetRanges();
        bool bTextOnly = true;
        
        while( *pRanges )
        {
            if( (*pRanges != EE_PARA_START) && (*pRanges != EE_CHAR_START) )
            {
                bTextOnly = true;
                break;
            }
            pRanges += 2;
        }		

        const bool bReplaceAll = false;
		for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ )
		{
			for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ )
			{
				CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
				if( xCell.is() )
				{
					if( bUndo )
						xCell->AddUndo();
				    if( !bTextOnly )
					    xCell->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll);
					
                    SdrText* pText = static_cast< SdrText* >( xCell.get() );
                    mpView->ApplyFormatPaintBrushToText( rFormatSet, *pTableObj, pText, bNoCharacterFormats, bNoParagraphFormats );
				}
			}
		}

		if( bFrame )
		{
			ApplyBorderAttr( rFormatSet );
		}

		UpdateTableShape();

		if( bUndo )
			mpModel->EndUndo();
			
	    return true;

	}
    return false;
}


// --------------------------------------------------------------------

IMPL_LINK( SvxTableController, UpdateHdl, void *, EMPTYARG )
{
	mnUpdateEvent = 0;

	if( mbCellSelectionMode )
	{
		CellPos aStart( maCursorFirstPos );
		CellPos aEnd( maCursorLastPos );
		checkCell(aStart);
		checkCell(aEnd);
		if( aStart != maCursorFirstPos  || aEnd != maCursorLastPos )
		{
			setSelectedCells( aStart, aEnd );
		}
	}
	updateSelectionOverlay();

	return 0;
}

sal_Bool SvxTableController::selectRow( sal_Int32 row )
{
	if( !mxTable.is() )
		return sal_False;
	CellPos aStart( 0, row ), aEnd( mxTable->getColumnCount() - 1, row );
	StartSelection( aEnd );
	gotoCell( aStart, true, 0 );
	return sal_True;
}
sal_Bool SvxTableController::selectColumn( sal_Int32 column )
{
	if( !mxTable.is() )
		return sal_False;
	CellPos aStart( column, 0 ), aEnd( column, mxTable->getRowCount() - 1 );
	StartSelection( aEnd );
	gotoCell( aStart, true, 0 );
	return sal_True;
}
sal_Bool SvxTableController::deselectRow( sal_Int32 row )
{
	if( !mxTable.is() )
		return sal_False;
	CellPos aStart( 0, row ), aEnd( mxTable->getColumnCount() - 1, row );
	StartSelection( aEnd );
	gotoCell( aStart, false, 0 );
	return sal_True;
}
sal_Bool SvxTableController::deselectColumn( sal_Int32 column )
{
	if( !mxTable.is() )
		return sal_False;
	CellPos aStart( column, 0 ), aEnd( column, mxTable->getRowCount() - 1 );
	StartSelection( aEnd );
	gotoCell( aStart, false, 0 );
	return sal_True;
}
sal_Bool SvxTableController::isRowSelected( sal_Int32 nRow )
{
	if( hasSelectedCells() )
	{
		CellPos aFirstPos, aLastPos;
		getSelectedCells( aFirstPos, aLastPos );
		if( (aFirstPos.mnCol == 0) && (nRow >= aFirstPos.mnRow && nRow <= aLastPos.mnRow) && (mxTable->getColumnCount() - 1 == aLastPos.mnCol) )
			return sal_True;
	}
	return sal_False;
}
sal_Bool SvxTableController::isColumnSelected( sal_Int32 nColumn )
{
	if( hasSelectedCells() )
	{
		CellPos aFirstPos, aLastPos;
		getSelectedCells( aFirstPos, aLastPos );
		if( (aFirstPos.mnRow == 0) && (nColumn >= aFirstPos.mnCol && nColumn <= aLastPos.mnCol) && (mxTable->getRowCount() - 1 == aLastPos.mnRow) )
			return sal_True;
	}
	return sal_False;
}

sal_Bool SvxTableController::isRowHeader()
{
	SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
	SdrModel* pModel = pTableObj ? pTableObj->GetModel() : 0;

	if( !pTableObj || !pModel )
		return sal_False;

	TableStyleSettings aSettings( pTableObj->getTableStyleSettings() );

	return aSettings.mbUseFirstRow;
}

sal_Bool SvxTableController::isColumnHeader()
{
	SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( mxTableObj.get() );
	SdrModel* pModel = pTableObj ? pTableObj->GetModel() : 0;

	if( !pTableObj || !pModel )
		return sal_False;

	TableStyleSettings aSettings( pTableObj->getTableStyleSettings() );

	return aSettings.mbUseFirstColumn;
}
} }
