/**************************************************************
 *
 * 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 selection 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;
}
} }
